summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2BitImage.cpp
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-06-14 00:50:34 +0100
committerAsh Wolf <ninji@wuffs.org>2023-06-14 00:50:34 +0100
commit37e364b2c6cc7487a1c888d256a73e5337bb7189 (patch)
treeeaf6e857382eef16c2dd940eb4125536fbe068bd /src/T2DLL/T2BitImage.cpp
downloadt2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.tar.gz
t2win-37e364b2c6cc7487a1c888d256a73e5337bb7189.zip
initial commit
Diffstat (limited to '')
-rw-r--r--src/T2DLL/T2BitImage.cpp1228
1 files changed, 1228 insertions, 0 deletions
diff --git a/src/T2DLL/T2BitImage.cpp b/src/T2DLL/T2BitImage.cpp
new file mode 100644
index 0000000..ea00253
--- /dev/null
+++ b/src/T2DLL/T2BitImage.cpp
@@ -0,0 +1,1228 @@
+#include "GlobalFunc.h"
+#include "T2BitImage.h"
+
+#define ALIGN_ROW_SIZE(s) ((((s) + 3) / 4) * 4)
+
+T2BitImage::T2BitImage(const char* path, unsigned int id, BOOL flip) {
+ mMemHandle = NULL;
+
+ SUBPLUGINFSENTRY fsEntry;
+ CFile *file = OpenSubPluginFS(path, id, 0, &fsEntry);
+ if (!file) {
+ CString idStr;
+ idStr.Format("%d", id);
+
+ CString err = "T2BitImage::T2BitImage ERROR : " + idStr + " @" + path + "\n";
+ OutputDebugString(err);
+ throw 0;
+ }
+
+ void *data = malloc(fsEntry.spfse_mC);
+ file->Read(data, fsEntry.spfse_mC);
+ SetupBitmap((BITMAPINFO *) data, flip);
+ free(data);
+
+ file->Close();
+ delete file;
+}
+
+T2BitImage::T2BitImage(HINSTANCE instance, unsigned int id, BOOL flip) {
+ mMemHandle = NULL;
+
+ HRSRC rsrc = FindResource(instance, MAKEINTRESOURCE(id), MAKEINTRESOURCE(2));
+ if (!rsrc) {
+ CString idStr;
+ idStr.Format("%d", id);
+
+ CString err = "T2BitImage::T2BitImage ERROR : " + idStr + " @" + GetModuleName(instance) + "\n";
+ OutputDebugString(err);
+ throw 0;
+ }
+
+ HGLOBAL h = LoadResource(instance, rsrc);
+ void *data = LockResource(h);
+ SetupBitmap((BITMAPINFO *) data, flip);
+ UnlockResource(h);
+ FreeResource(rsrc);
+}
+
+void T2BitImage::SetupBitmap(BITMAPINFO* info, BOOL flip) {
+ mBitmap.header = info->bmiHeader;
+
+ int colorCount = 256;
+ if (mBitmap.header.biClrUsed != 0)
+ colorCount = mBitmap.header.biClrUsed;
+
+ int dataSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth) * mBitmap.header.biHeight;
+ mMemHandle = GlobalAlloc(GHND, dataSize);
+ mData = (unsigned char *) GlobalLock(mMemHandle);
+
+ for (int i = 0; i < colorCount; i++)
+ mBitmap.palette[i] = i;
+
+ memcpy(mData, info->bmiColors + colorCount, dataSize);
+
+ if (flip) {
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ void *tmp = malloc(rowSize);
+ for (int y = 0; y < mBitmap.header.biHeight / 2; y++) {
+ int otherY = mBitmap.header.biHeight - y - 1;
+ memcpy(tmp, mData + y * rowSize, rowSize);
+ memcpy(mData + y * rowSize, mData + otherY * rowSize, rowSize);
+ memcpy(mData + otherY * rowSize, tmp, rowSize);
+ }
+ free(tmp);
+ }
+
+ mBackGndColor = -1;
+ mForeGndColor = -1;
+ mOrigin.x = 0;
+ mOrigin.y = 0;
+ mHalftoneMode = false;
+ SetClipRect(NULL);
+}
+
+T2BitImage::T2BitImage(const RECT& rect) {
+ int w = rect.right - rect.left;
+ int h = rect.bottom - rect.top;
+
+ memset(&mBitmap.header, 0, sizeof(mBitmap.header));
+ mBitmap.header.biSize = sizeof(mBitmap.header);
+ mBitmap.header.biWidth = w;
+ mBitmap.header.biHeight = h;
+ mBitmap.header.biPlanes = 1;
+ mBitmap.header.biBitCount = 8;
+ mBitmap.header.biSizeImage = ALIGN_ROW_SIZE(w) * h;
+ mBitmap.header.biClrUsed = 256;
+
+ for (int i = 0; i < 256; i++)
+ mBitmap.palette[i] = i;
+
+ mMemHandle = GlobalAlloc(GHND, mBitmap.header.biSizeImage);
+ mData = (unsigned char *) GlobalLock(mMemHandle);
+
+ mBackGndColor = -1;
+ mForeGndColor = -1;
+ mOrigin.x = 0;
+ mOrigin.y = 0;
+ mHalftoneMode = false;
+ SetClipRect(NULL);
+}
+
+/*virtual*/ T2BitImage::~T2BitImage() {
+ if (mMemHandle) {
+ GlobalUnlock(mMemHandle);
+ GlobalFree(mMemHandle);
+ }
+}
+
+BOOL T2BitImage::BeginDrawing() {
+ return true;
+}
+
+void T2BitImage::EndDrawing() {
+}
+
+void T2BitImage::CopyImage(T2BitImage& destImg, const RECT& inSrc, const RECT& inDest, int, CRgn* rgn) {
+ RECT src;
+ src.top = inSrc.top;
+ src.left = inSrc.left;
+ src.bottom = inSrc.bottom;
+ src.right = inSrc.right;
+ OffsetRect(&src, -mOrigin.x, -mOrigin.y);
+
+ RECT dest;
+ dest.top = inDest.top;
+ dest.left = inDest.left;
+ dest.bottom = inDest.bottom;
+ dest.right = inDest.right;
+ OffsetRect(&dest, -destImg.mOrigin.x, -destImg.mOrigin.y);
+
+ RECT clipSrc = mClipRect;
+ OffsetRect(&clipSrc, -mOrigin.x, -mOrigin.y);
+
+ RECT clipDest = destImg.mClipRect;
+ OffsetRect(&clipDest, -destImg.mOrigin.x, -destImg.mOrigin.y);
+
+ int align;
+
+ if ((dest.bottom - dest.top) == ((src.bottom - src.top) * 4)) {
+ align = 1; // Y scale /4
+ } else if ((dest.bottom - dest.top) == ((src.bottom - src.top) * 2)) {
+ align = 2; // Y scale /2
+ } else if ((dest.bottom - dest.top) == (src.bottom - src.top)) {
+ align = 4; // No scaling
+ } else if (((dest.bottom - dest.top) * 2) == (src.bottom - src.top)) {
+ align = 8; // Y scale *2
+ } else if (((dest.bottom - dest.top) * 4) == (src.bottom - src.top)) {
+ align = 16; // Y scale *4
+ } else {
+ CString err;
+ err.Format("不正な拡大縮小率\nSrc(%d,%d),Dest(%d,%d)", dest.top, dest.bottom, src.top, src.bottom);
+#line 183
+ __Rep0(__FILE__, __LINE__, err);
+ }
+
+ if (
+ ((src.right - src.left) != (((dest.right - dest.left) * align) / 4)) ||
+ ((src.bottom - src.top) != (((dest.bottom - dest.top) * align) / 4))
+ ) {
+ CString err;
+ err.Format("不正な拡大縮小率\nSrc(%d,%d),Dest(%d,%d)", dest.top, dest.bottom, src.top, src.bottom);
+#line 190
+ __Rep0(__FILE__, __LINE__, err);
+ }
+
+ RECT rect2;
+
+ int srcX = src.left;
+ int srcY = src.top;
+ rect2.top = 0;
+ rect2.left = 0;
+ rect2.bottom = mBitmap.header.biHeight;
+ rect2.right = mBitmap.header.biWidth;
+
+ if (!IntersectRect(&src, &rect2, &src))
+ return;
+ if (mHasClipRect && !IntersectRect(&src, &clipSrc, &src))
+ return;
+
+ int destX = dest.left;
+ int destY = dest.top;
+ rect2.top = 0;
+ rect2.left = 0;
+ rect2.bottom = destImg.mBitmap.header.biHeight;
+ rect2.right = destImg.mBitmap.header.biWidth;
+
+ if (!IntersectRect(&dest, &rect2, &dest))
+ return;
+ if (destImg.mHasClipRect && !IntersectRect(&dest, &clipDest, &dest))
+ return;
+
+ OffsetRect(&src, -srcX, -srcY);
+ OffsetRect(&dest, -destX, -destY);
+
+ dest.right = (dest.right * align) / 4;
+ dest.bottom = (dest.bottom * align) / 4;
+ dest.left = (dest.left * align) / 4;
+ dest.top = (dest.top * align) / 4;
+
+ if (!IntersectRect(&dest, &src, &dest))
+ return;
+
+ src = dest;
+
+ dest.right = (dest.right * 4) / align;
+ dest.bottom = (dest.bottom * 4) / align;
+ dest.left = (dest.left * 4) / align;
+ dest.top = (dest.top * 4) / align;
+
+ OffsetRect(&src, srcX, srcY);
+ OffsetRect(&dest, destX, destY);
+
+ int width = dest.right - dest.left;
+ int height = dest.bottom - dest.top;
+
+ int destRowSize = ALIGN_ROW_SIZE(destImg.mBitmap.header.biWidth);
+ int srcRowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+
+ unsigned char *destP = destImg.mData + dest.top * destRowSize + dest.left;
+ unsigned char *srcP = mData + src.top * srcRowSize + src.left;
+
+ int foreGndColor = mForeGndColor;
+ int backGndColor = mBackGndColor;
+ BOOL halftoneMode = mHalftoneMode;
+
+ int xAdjust = 0;
+ if (dest.left < 0) {
+ xAdjust = -dest.left;
+ destP += xAdjust;
+ width -= xAdjust;
+ }
+
+ int yAdjust = 0;
+ if (dest.top < 0) {
+ yAdjust = -dest.top;
+ destP += destRowSize * yAdjust;
+ height -= yAdjust;
+ }
+
+#define INC_SRC_ROW \
+ __asm mov eax, srcP \
+ __asm add eax, srcRowSize \
+ __asm mov srcP, eax
+
+#define INC_SRC_ROW_2 \
+ __asm mov eax, srcP \
+ __asm add eax, srcRowSize \
+ __asm add eax, srcRowSize \
+ __asm mov srcP, eax
+
+#define INC_SRC_ROW_4 \
+ __asm mov eax, srcP \
+ __asm mov ebx, srcRowSize \
+ __asm add eax, ebx \
+ __asm add eax, ebx \
+ __asm add eax, ebx \
+ __asm add eax, ebx \
+ __asm mov srcP, eax
+
+#define INC_DEST_ROW \
+ __asm mov eax, destP \
+ __asm add eax, destRowSize \
+ __asm mov destP, eax
+
+ if (!halftoneMode && foreGndColor == -1 && backGndColor == -1) {
+ // Simple drawing
+ if (align == 2) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ simple2_rowLoop:
+ or ecx, ecx
+ jle simple2_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ mov eax, xAdjust
+ or eax, eax
+ jnz simple2_midXAdjust
+ simple2_loopXAdjust:
+ or edx, edx
+ jle simple2_afterXAdjust
+ mov al, [esi]
+ mov [edi], al
+ inc edi
+ dec edx
+ or edx, edx
+ jle simple2_afterXAdjust
+ simple2_midXAdjust:
+ mov al, [esi]
+ mov [edi], al
+ inc esi
+ inc edi
+ dec edx
+ jmp simple2_loopXAdjust
+ simple2_afterXAdjust:
+ mov eax, yAdjust
+ inc eax
+ mov yAdjust, eax
+ and eax, 1
+ jnz simple2_skipRowInc
+ INC_SRC_ROW
+ simple2_skipRowInc:
+ INC_DEST_ROW
+ dec ecx
+ jmp simple2_rowLoop
+ simple2_end:
+ }
+#endif
+ } else if (align == 4) {
+ // No Y scaling at all
+ if ((width % 8) == 0) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ simple4a_outerLoop:
+ or ecx, ecx
+ jle simple4a_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ shr edx, 3
+ simple4a_innerLoop:
+ or edx, edx
+ jle simple4a_rowDone
+ ; copy an 8-byte chunk
+ mov eax, [esi]
+ mov [edi], eax
+ mov eax, [esi+4]
+ mov [edi+4], eax
+ add esi, 8
+ add edi, 8
+ dec edx
+ jmp simple4a_innerLoop
+ simple4a_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp simple4a_outerLoop
+ simple4a_end:
+ }
+#endif
+ } else {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ simple4b_outerLoop:
+ or ecx, ecx
+ jle simple4b_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ simple4b_innerLoop:
+ or edx, edx
+ jle simple4b_rowDone
+ cmp edx, 4
+ jc simple4b_byteCopy
+ mov eax, [esi]
+ mov [edi], eax
+ add esi, 4
+ add edi, 4
+ sub edx, 4
+ jmp simple4b_innerLoop
+ simple4b_byteCopy:
+ mov al, [esi]
+ mov [edi], al
+ inc esi
+ inc edi
+ dec edx
+ jmp simple4b_innerLoop
+ simple4b_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp simple4b_outerLoop
+ simple4b_end:
+ }
+#endif
+ }
+ } else if (align == 8) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ simple8_outerLoop:
+ or ecx, ecx
+ jle simple8_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ simple8_innerLoop:
+ or edx, edx
+ jle simple8_rowDone
+ mov al, [esi]
+ mov [edi], al
+ add esi, 4
+ inc edi
+ dec edx
+ jmp simple8_innerLoop
+ simple8_rowDone:
+ INC_SRC_ROW_2
+ INC_DEST_ROW
+ dec ecx
+ jmp simple8_outerLoop
+ simple8_end:
+ }
+#endif
+ } else if (align == 16) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ simple16_outerLoop:
+ or ecx, ecx
+ jle simple16_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ simple16_innerLoop:
+ or edx, edx
+ jle simple16_rowDone
+ mov al, [esi]
+ mov [edi], al
+ add esi, 4
+ inc edi
+ dec edx
+ jmp simple16_innerLoop
+ simple16_rowDone:
+ INC_SRC_ROW_4
+ INC_DEST_ROW
+ dec ecx
+ jmp simple16_outerLoop
+ simple16_end:
+ }
+#endif
+ }
+ return;
+ }
+
+ if (!halftoneMode && foreGndColor == -1 && backGndColor != -1) {
+ // Drawing with a background colour only
+ if (align == 4) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ bgc4_outerLoop:
+ or ecx, ecx
+ jle bgc4_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ bgc4_innerLoop:
+ or edx, edx
+ jle bgc4_rowDone
+ mov al, [esi]
+ cmp al, ah
+ jz bgc4_skipPixel
+ mov [edi], al
+ bgc4_skipPixel:
+ inc esi
+ inc edi
+ dec edx
+ jmp bgc4_innerLoop
+ bgc4_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp bgc4_outerLoop
+ bgc4_end:
+ }
+#endif
+ } else if (align == 8) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ bgc8_outerLoop:
+ or ecx, ecx
+ jle bgc8_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ bgc8_innerLoop:
+ or edx, edx
+ jle bgc8_rowDone
+ mov al, [esi]
+ cmp al, ah
+ jz bgc8_skipPixel
+ mov [edi], al
+ bgc8_skipPixel:
+ add esi, 2
+ inc edi
+ dec edx
+ jmp bgc8_innerLoop
+ bgc8_rowDone:
+ INC_SRC_ROW_2
+ INC_DEST_ROW
+ dec ecx
+ jmp bgc8_outerLoop
+ bgc8_end:
+ }
+#endif
+ } else if (align == 16) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ bgc16_outerLoop:
+ or ecx, ecx
+ jle bgc16_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ bgc16_innerLoop:
+ or edx, edx
+ jle bgc16_rowDone
+ mov al, [esi]
+ cmp al, ah
+ jz bgc16_skipPixel
+ mov [edi], al
+ bgc16_skipPixel:
+ add esi, 4
+ inc edi
+ dec edx
+ jmp bgc16_innerLoop
+ bgc16_rowDone:
+ INC_SRC_ROW_4
+ INC_DEST_ROW
+ dec ecx
+ jmp bgc16_outerLoop
+ bgc16_end:
+ }
+#endif
+ }
+ return;
+ }
+
+ if (halftoneMode && foreGndColor == -1 && backGndColor == -1) {
+ // Simple drawing in halftone mode
+ if (align == 4) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ ht4_outerLoop:
+ or ecx, ecx
+ jle ht4_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ mov ebx, ecx
+ ht4_innerLoop:
+ or edx, edx
+ jle ht4_rowDone
+ test ebx, 1
+ jz ht4_skipPixel
+ mov al, [esi]
+ mov [edi], al
+ ht4_skipPixel:
+ inc esi
+ inc edi
+ dec edx
+ inc ebx
+ jmp ht4_innerLoop
+ ht4_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp ht4_outerLoop
+ ht4_end:
+ }
+#endif
+ } else if (align == 8) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ ht8_outerLoop:
+ or ecx, ecx
+ jle ht8_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ mov ebx, ecx
+ ht8_innerLoop:
+ or edx, edx
+ jle ht8_rowDone
+ test ebx, 1
+ jz ht8_skipPixel
+ mov al, [esi]
+ mov [edi], al
+ ht8_skipPixel:
+ add esi, 2
+ inc edi
+ dec edx
+ inc ebx
+ jmp ht8_innerLoop
+ ht8_rowDone:
+ INC_SRC_ROW_2
+ INC_DEST_ROW
+ dec ecx
+ jmp ht8_outerLoop
+ ht8_end:
+ }
+#endif
+ } else if (align == 16) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ ht16_outerLoop:
+ or ecx, ecx
+ jle ht16_end
+ mov esi, srcP
+ mov edi, destP
+ mov edx, width
+ mov ebx, ecx
+ ht16_innerLoop:
+ or edx, edx
+ jle ht16_rowDone
+ test ebx, 1
+ jz ht16_skipPixel
+ mov al, [esi]
+ mov [edi], al
+ ht16_skipPixel:
+ add esi, 4
+ inc edi
+ dec edx
+ inc ebx
+ jmp ht16_innerLoop
+ ht16_rowDone:
+ INC_SRC_ROW_4
+ INC_DEST_ROW
+ dec ecx
+ jmp ht16_outerLoop
+ ht16_end:
+ }
+#endif
+ }
+ return;
+ }
+
+ if (halftoneMode && foreGndColor == -1 && backGndColor != -1) {
+ // Drawing with a background colour in halftone mode
+ if (align == 4) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ htBg4_outerLoop:
+ or ecx, ecx
+ jle htBg4_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ mov ebx, ecx
+ htBg4_innerLoop:
+ or edx, edx
+ jle htBg4_rowDone
+ test ebx, 1
+ jz htBg4_skipPixel
+ mov al, [esi]
+ cmp al, ah
+ jz htBg4_skipPixel
+ mov [edi], al
+ htBg4_skipPixel:
+ inc esi
+ inc edi
+ dec edx
+ inc ebx
+ jmp htBg4_innerLoop
+ htBg4_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp htBg4_outerLoop
+ htBg4_end:
+ }
+#endif
+ } else if (align == 8) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ htBg8_outerLoop:
+ or ecx, ecx
+ jle htBg8_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ mov ebx, ecx
+ htBg8_innerLoop:
+ or edx, edx
+ jle htBg8_rowDone
+ test ebx, 1
+ jz htBg8_skipPixel
+ mov al, [esi]
+ cmp al, ah
+ jz htBg8_skipPixel
+ mov [edi], al
+ htBg8_skipPixel:
+ add esi, 2
+ inc edi
+ dec edx
+ inc ebx
+ jmp htBg8_innerLoop
+ htBg8_rowDone:
+ INC_SRC_ROW_2
+ INC_DEST_ROW
+ dec ecx
+ jmp htBg8_outerLoop
+ htBg8_end:
+ }
+#endif
+ } else if (align == 16) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ htBg16_outerLoop:
+ or ecx, ecx
+ jle htBg16_end
+ mov esi, srcP
+ mov edi, destP
+ mov ah, byte ptr [backGndColor]
+ mov edx, width
+ mov ebx, ecx
+ htBg16_innerLoop:
+ or edx, edx
+ jle htBg16_rowDone
+ test ebx, 1
+ jz htBg16_skipPixel
+ mov al, [esi]
+ cmp al, ah
+ jz htBg16_skipPixel
+ mov [edi], al
+ htBg16_skipPixel:
+ add esi, 4
+ inc edi
+ dec edx
+ inc ebx
+ jmp htBg16_innerLoop
+ htBg16_rowDone:
+ INC_SRC_ROW_4
+ INC_DEST_ROW
+ dec ecx
+ jmp htBg16_outerLoop
+ htBg16_end:
+ }
+#endif
+ }
+ return;
+ }
+
+ if (!halftoneMode && foreGndColor != -1 && backGndColor != -1) {
+ // Drawing with a foreground and background colour
+ if (align == 4) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ fgBg4_outerLoop:
+ or ecx, ecx
+ jle fgBg4_end
+ mov esi, srcP
+ mov edi, destP
+ mov bh, byte ptr [foreGndColor]
+ mov bl, byte ptr [backGndColor]
+ mov edx, width
+ fgBg4_innerLoop:
+ or edx, edx
+ jle fgBg4_rowDone
+ mov al, [esi]
+ cmp al, bl
+ jz fgBg4_skipPixel
+ mov [edi], bh
+ fgBg4_skipPixel:
+ inc esi
+ inc edi
+ dec edx
+ jmp fgBg4_innerLoop
+ fgBg4_rowDone:
+ INC_SRC_ROW
+ INC_DEST_ROW
+ dec ecx
+ jmp fgBg4_outerLoop
+ fgBg4_end:
+ }
+#endif
+ } else if (align == 8) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ fgBg8_outerLoop:
+ or ecx, ecx
+ jle fgBg8_end
+ mov esi, srcP
+ mov edi, destP
+ mov bh, byte ptr [foreGndColor]
+ mov bl, byte ptr [backGndColor]
+ mov edx, width
+ fgBg8_innerLoop:
+ or edx, edx
+ jle fgBg8_rowDone
+ mov al, [esi]
+ cmp al, bl
+ jz fgBg8_skipPixel
+ mov [edi], bh
+ fgBg8_skipPixel:
+ add esi, 2
+ inc edi
+ dec edx
+ jmp fgBg8_innerLoop
+ fgBg8_rowDone:
+ INC_SRC_ROW_2
+ INC_DEST_ROW
+ dec ecx
+ jmp fgBg8_outerLoop
+ fgBg8_end:
+ }
+#endif
+ } else if (align == 16) {
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, height
+ fgBg16_outerLoop:
+ or ecx, ecx
+ jle fgBg16_end
+ mov esi, srcP
+ mov edi, destP
+ mov bh, byte ptr [foreGndColor]
+ mov bl, byte ptr [backGndColor]
+ mov edx, width
+ fgBg16_innerLoop:
+ or edx, edx
+ jle fgBg16_rowDone
+ mov al, [esi]
+ cmp al, bl
+ jz fgBg16_skipPixel
+ mov [edi], bh
+ fgBg16_skipPixel:
+ add esi, 4
+ inc edi
+ dec edx
+ jmp fgBg16_innerLoop
+ fgBg16_rowDone:
+ INC_SRC_ROW_4
+ INC_DEST_ROW
+ dec ecx
+ jmp fgBg16_outerLoop
+ fgBg16_end:
+ }
+#endif
+ }
+ return;
+ }
+
+ _CrtDbgBreak();
+}
+
+void T2BitImage::CopyImage(CDC* dc, const RECT& inSrc, const RECT& inDest, int, CRgn*) {
+ RECT src;
+ src.top = inSrc.top;
+ src.left = inSrc.left;
+ src.bottom = inSrc.bottom;
+ src.right = inSrc.right;
+ OffsetRect(&src, -mOrigin.x, -mOrigin.y);
+
+ RECT dest;
+ dest.top = inDest.top;
+ dest.left = inDest.left;
+ dest.bottom = inDest.bottom;
+ dest.right = inDest.right;
+
+ if ((src.right - src.left) != (dest.right - dest.left) ||
+ (src.top - src.bottom) != (dest.top - dest.bottom))
+ return;
+
+ int diffX = src.left - dest.left;
+ int diffY = src.top - dest.top;
+
+ RECT tmp;
+ tmp.top = 0;
+ tmp.left = 0;
+ tmp.right = mBitmap.header.biWidth;
+ tmp.bottom = mBitmap.header.biHeight;
+
+ if (tmp.top > tmp.bottom) {
+ int save = tmp.top;
+ tmp.top = tmp.bottom;
+ tmp.bottom = save;
+ }
+
+ if (src.top > src.bottom) {
+ int save = src.top;
+ src.top = src.bottom;
+ src.bottom = save;
+ }
+
+ if (!IntersectRect(&src, &tmp, &src))
+ return;
+
+ OffsetRect(&dest, diffX, diffY);
+ if (!IntersectRect(&dest, &dest, &src))
+ return;
+ OffsetRect(&dest, -diffX, -diffY);
+
+ Bitmap bmp = mBitmap;
+ bmp.header.biHeight = -bmp.header.biHeight;
+
+ SetDIBitsToDevice(
+ dc->m_hDC,
+ dest.left,
+ dest.top,
+ src.right - src.left,
+ src.bottom - src.top,
+ src.left,
+ abs(bmp.header.biHeight) - src.bottom,
+ 0,
+ -bmp.header.biHeight,
+ mData,
+ (BITMAPINFO *) &bmp,
+ 1
+ );
+}
+
+void T2BitImage::Clear(int c) {
+ memset(mData, c, ALIGN_ROW_SIZE(mBitmap.header.biWidth) * abs(mBitmap.header.biHeight));
+}
+
+void T2BitImage::SetBackGndColor(int c) {
+ mBackGndColor = c;
+}
+
+void T2BitImage::SetForeGndColor(int c) {
+ mForeGndColor = c;
+}
+
+void T2BitImage::SetOrigin(int x, int y) {
+ mOrigin.x = x;
+ mOrigin.y = y;
+}
+
+void T2BitImage::SetClipRect(RECT* rect) {
+ if (!rect) {
+ SetRect(&mClipRect, 0, 0, mBitmap.header.biWidth, mBitmap.header.biHeight);
+ mHasClipRect = false;
+ } else {
+ mClipRect = *rect;
+ mHasClipRect = true;
+ }
+}
+
+void T2BitImage::SetHalftoneMode(BOOL m) {
+ mHalftoneMode = m;
+}
+
+void T2BitImage::DrawFocusRect(RECT rect) {
+ DrawFocusRect2(rect);
+ InsetRect(&rect, 1, 1);
+ DrawFocusRect2(rect);
+}
+
+void T2BitImage::DrawFocusRect2(RECT rect) {
+ OffsetRect(&rect, -mOrigin.x, -mOrigin.y);
+
+ RECT bitmapRect;
+ SetRect(&bitmapRect, 0, 0, mBitmap.header.biWidth, mBitmap.header.biHeight);
+
+ IntersectRect(&rect, &rect, &bitmapRect);
+
+ if (rect.top >= 0)
+ DrawFocusLine(rect.left, rect.top, rect.right, rect.top);
+ if (rect.right < mBitmap.header.biWidth)
+ DrawFocusLine(rect.right - 1, rect.top, rect.right - 1, rect.bottom);
+ if (rect.bottom < mBitmap.header.biHeight)
+ DrawFocusLine(rect.left, rect.bottom - 1, rect.right, rect.bottom - 1);
+ if (rect.left >= 0)
+ DrawFocusLine(rect.left, rect.top, rect.left, rect.bottom);
+}
+
+void T2BitImage::DrawFocusLine(int x1, int y1, int x2, int y2) {
+ if (x1 > x2) {
+ int tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ } else if (y1 > y2) {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ int counter = 0;
+ unsigned char *p = mData + y1 * rowSize + x1;
+
+ if (x1 == x2) {
+ for (int y = y1; y < y2; y++) {
+ *p = (counter >= 3) ? 254 : 253;
+ p += rowSize;
+ counter++;
+ if (counter == 6)
+ counter = 0;
+ }
+ } else if (y1 == y2) {
+ for (int x = x1; x < x2; x++) {
+ *p = (counter >= 3) ? 254 : 253;
+ p++;
+ counter++;
+ if (counter == 6)
+ counter = 0;
+ }
+ } else {
+ _CrtDbgBreak();
+ }
+}
+
+void T2BitImage::FillMesh(RECT rect, int c) {
+ OffsetRect(&rect, -mOrigin.x, -mOrigin.y);
+
+ RECT bitmapRect;
+ SetRect(&bitmapRect, 0, 0, mBitmap.header.biWidth, mBitmap.header.biHeight);
+
+ if (mHasClipRect) {
+ RECT clipRect = mClipRect;
+ OffsetRect(&clipRect, -mOrigin.x, -mOrigin.y);
+ IntersectRect(&bitmapRect, &bitmapRect, &clipRect);
+ }
+
+ IntersectRect(&rect, &rect, &bitmapRect);
+ if (!IsRectEmpty(&rect)) {
+ unsigned char parity = rect.left + rect.top;
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ unsigned char *p = mData + rect.top * rowSize + rect.left;
+ int width = rect.right - rect.left;
+ int height = rect.bottom - rect.top;
+ unsigned char cByte = c;
+
+ if (width > 0 && height > 0) {
+#ifdef _MSC_VER
+ __asm {
+ mov al, cByte
+ mov ebx, p
+ mov ecx, height
+ rowLoop:
+ mov ah, parity
+ mov edi, ebx
+ mov edx, width
+ pixelLoop:
+ test ah, 1
+ jz skip
+ mov [edi], al
+ skip:
+ inc edi
+ inc ah
+ dec edx
+ jnz pixelLoop
+ add ebx, rowSize
+ mov ah, parity
+ inc ah
+ mov parity, ah
+ dec ecx
+ jnz rowLoop
+ }
+#endif
+ }
+ }
+}
+
+void T2BitImage::FillRect(RECT rect, int c) {
+ OffsetRect(&rect, -mOrigin.x, -mOrigin.y);
+
+ RECT bitmapRect;
+ SetRect(&bitmapRect, 0, 0, mBitmap.header.biWidth, mBitmap.header.biHeight);
+
+ if (mHasClipRect) {
+ RECT clipRect = mClipRect;
+ OffsetRect(&clipRect, -mOrigin.x, -mOrigin.y);
+ IntersectRect(&bitmapRect, &bitmapRect, &clipRect);
+ }
+
+ IntersectRect(&rect, &rect, &bitmapRect);
+ if (!IsRectEmpty(&rect)) {
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ unsigned char *p = mData + rect.top * rowSize + rect.left;
+ int width = rect.right - rect.left;
+ int height = rect.bottom - rect.top;
+ unsigned char cByte = c;
+
+ if (width > 0 && height > 0) {
+#ifdef _MSC_VER
+ __asm {
+ mov al, cByte
+ mov ebx, p
+ mov ecx, height
+ rowLoop:
+ mov edi, ebx
+ mov edx, width
+ pixelLoop:
+ mov [edi], al
+ inc edi
+ dec edx
+ jnz pixelLoop
+ add ebx, rowSize
+ dec ecx
+ jnz rowLoop
+ }
+#endif
+ }
+ }
+}
+
+int T2BitImage::GetPixel(int x, int y) {
+ x -= mOrigin.x;
+ y -= mOrigin.y;
+
+ if (x < 0 || x >= mBitmap.header.biWidth || y < 0 || y >= mBitmap.header.biHeight)
+ return -1;
+
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ return mData[y * rowSize + x];
+}
+
+int T2BitImage::GetPixel(const POINT& pt) {
+ return GetPixel(pt.x, pt.y);
+}
+
+/*virtual*/ BOOL T2BitImage::IsExist() {
+ return mMemHandle != NULL;
+}
+
+void T2BitImage::DrawFrameRect(RECT rect, int c) {
+ OffsetRect(&rect, -mOrigin.x, -mOrigin.y);
+
+ RECT bitmapRect;
+ SetRect(&bitmapRect, 0, 0, mBitmap.header.biWidth, mBitmap.header.biHeight);
+
+ if (mHasClipRect) {
+ RECT clipRect = mClipRect;
+ OffsetRect(&clipRect, -mOrigin.x, -mOrigin.y);
+ IntersectRect(&bitmapRect, &bitmapRect, &clipRect);
+ }
+
+ RECT frameRect;
+ IntersectRect(&frameRect, &rect, &bitmapRect);
+ if (!IsRectEmpty(&frameRect)) {
+ if (frameRect.top == rect.top)
+ DrawFrameLine(frameRect.left, frameRect.top, frameRect.right, frameRect.top, c);
+ if (frameRect.left == rect.left)
+ DrawFrameLine(frameRect.left, frameRect.top, frameRect.left, frameRect.bottom, c);
+ if (frameRect.bottom == rect.bottom)
+ DrawFrameLine(frameRect.left, frameRect.bottom - 1, frameRect.right, frameRect.bottom - 1, c);
+ if (frameRect.right == rect.right)
+ DrawFrameLine(frameRect.right - 1, frameRect.top, frameRect.right - 1, frameRect.bottom, c);
+ }
+}
+
+void T2BitImage::DrawFrameLine(int x1, int y1, int x2, int y2, int c) {
+ if (x1 == x2) {
+ if (y1 != y2) {
+ if (y2 < y1) {
+ int tmp = y1;
+ y1 = y2;
+ y2 = tmp;
+ }
+
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ unsigned char *p = mData + y1 * rowSize + x1;
+ int count = y2 - y1;
+ unsigned char cByte = c;
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, count
+ mov edi, p
+ mov al, cByte
+ mov edx, rowSize
+ pixelLoop:
+ mov [edi], al
+ add edi, edx
+ dec ecx
+ jnz pixelLoop
+ }
+#else
+ do {
+ *p = cByte;
+ p += rowSize;
+ } while (--count != 0);
+#endif
+ }
+ } else if (y1 == y2) {
+ if (x1 != x2) {
+ if (x2 < x1) {
+ int tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+
+ int rowSize = ALIGN_ROW_SIZE(mBitmap.header.biWidth);
+ unsigned char *p = mData + y1 * rowSize + x1;
+ int count = x2 - x1;
+ unsigned char cByte = c;
+#ifdef _MSC_VER
+ __asm {
+ mov ecx, count
+ mov edi, p
+ mov al, cByte
+ pixelLoop2:
+ mov [edi], al
+ inc edi
+ dec ecx
+ jnz pixelLoop2
+ }
+#else
+ do {
+ *p = cByte;
+ p++;
+ } while (--count != 0);
+#endif
+ }
+ } else {
+#line 1457
+ _ASSERT(0);
+ }
+}