#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); } }