mactype/cache.cpp
2020-12-06 11:38:08 +01:00

169 lines
3.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "override.h"
//CreateDIB计数将在绘制下列次数后更新DIB区
#define BITMAP_REDUCE_COUNTER 256//默认1024
HDC CBitmapCache::CreateDC(HDC dc)
{
if(!m_hdc) {
m_hdc = CreateCompatibleDC(dc);
m_exthdc = dc;
}
return m_hdc;
}
HBITMAP CBitmapCache::CreateDIB(int width, int height, BYTE** lplpPixels)
{
SIZE& dibSize = m_dibSize;
width = (width + 3) & ~3;
if (dibSize.cx >= width && dibSize.cy >= height) {
if (++m_counter < BITMAP_REDUCE_COUNTER) {
*lplpPixels = m_lpPixels;
return m_hbmp;
}
//カウンタ超過
//ただしサイズが全く同じなら再生成しない
if (dibSize.cx == width && dibSize.cy == height) {
m_counter = 0;
*lplpPixels = m_lpPixels;
return m_hbmp;
}
} else {
if (dibSize.cx > width) {
width = dibSize.cx;
}
if (dibSize.cy > height) {
height = dibSize.cy;
}
}
BITMAPINFOHEADER bmiHeader = { sizeof(BITMAPINFOHEADER), width, -height, 1, 32, BI_RGB };
HBITMAP hbmpNew = CreateDIBSection(CreateDC(m_exthdc), (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS, (LPVOID*)lplpPixels, NULL, 0);
if (!hbmpNew) {
return NULL;
}
TRACE(_T("width=%d, height=%d\n"), width, height);
//メモリ不足等でhbmpNew==NULLの場合を想定し、
//成功したときのみキャッシュを更新
if (m_hbmp) {
DeleteBitmap(m_hbmp);
}
m_hbmp = hbmpNew;
dibSize.cx = width;
dibSize.cy = height;
//CreateDIBSectionは多分ページ境界かセグメント境界
m_lpPixels = *lplpPixels;
m_counter = 0;
return m_hbmp;
}
void CBitmapCache::FillSolidRect(COLORREF rgb, const RECT* lprc)
{
if (!m_brush || rgb!=m_bkColor)
{
if (m_brush)
DeleteObject(m_brush);
m_brush = CreateSolidBrush(rgb);
m_bkColor = rgb;
}
FillRect(m_hdc, lprc, m_brush);
//DrawHorizontalLine(lprc->left, lprc->top, lprc->right, rgb, lprc->bottom - lprc->top);
/* LPBYTE lpPixels = m_lpPixels;
const DWORD dwBmpBytes = m_dibSize.cx * m_dibSize.cy;
rgb = RGB2DIB(rgb);
//TODO: MMX or SSE化
__asm {
mov edi, dword ptr [lpPixels]
mov ecx, dword ptr [dwBmpBytes]
mov eax, dword ptr [rgb]
cld
rep stosd
}*/
// DWORD* p = (DWORD*)m_lpPixels;
// DWORD* const pend = p + dwBmpBytes;
// while (p < pend) {
// *p++ = rgb;
// }
}
//水平線を引く
//(X1,Y1) (X2,Y1)
// +-----------------+ ^
// | rgb | | width
// +-----------------+ v
void CBitmapCache::DrawHorizontalLine(int X1, int Y1, int X2, COLORREF rgb, int width)
{
if (!m_dibSize.cx || !m_dibSize.cy) {
return;
}
if (X1 > X2) {
const int xx = X1;
X1 = X2;
X2 = xx;
}
//クリッピング
const int xSize = m_dibSize.cx;
const int ySize = m_dibSize.cy;
X1 = Bound(X1, 0, xSize);
X2 = Bound(X2, 0, xSize);
Y1 = Bound(Y1, 0, ySize);
width = Max(width, 1);
const int Y2 = Bound(Y1 + width, 0, ySize);
rgb = RGB2DIB(rgb);
DWORD* lpPixels = (DWORD*)m_lpPixels + (Y1 * xSize + X1);
const int Xd = X2 - X1;
const int Yd = Y2 - Y1;
/* for (int yy=Y1; yy<Y2; yy++) {
for (int xx=X1; xx<X2; xx++) {
_SetPixelV(xx, yy, rgb);
}
}
for (int yy=Y1; yy<Y2; yy++, lpPixels += xSize) {
__asm {
mov edi, dword ptr [lpPixels]
mov ecx, dword ptr [Xd]
mov eax, dword ptr [rgb]
cld
rep stosd
}
}*/
/*#ifdef _M_IX86
//無意味にアセンブリ化
__asm {
mov ebx, dword ptr [Yd]
mov edx, dword ptr [lpPixels]
mov esi, dword ptr [xSize]
cld
L1:
mov edi, edx
mov ecx, dword ptr [Xd]
mov eax, dword ptr [rgb]
rep stosd
lea edx, dword ptr [edx+esi*4]
dec ebx
jnz L1
}
#else*/ //对于64位系统使用C语言
for (int yy=Y1; yy<Y2; yy++) {
for (int xx=X1; xx<X2; xx++) {
*( (DWORD*)m_lpPixels + (yy * xSize + xx) ) = rgb;
}
}
//#endif
}