forked from snowie2000/mactype
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.cpp
168 lines (147 loc) · 3.5 KB
/
cache.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#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
}