#include "StdAfx.h" #define ATOI_KLUDGE #include "GlobalFunc.h" #include "T2BitImage.h" #include "T2ImageObj.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif T2ImageObj::T2ImageObj() { mCount = 0; mHandle = GlobalAlloc(GHND, 1); mData = (ObjectData *) GlobalLock(mHandle); } /*virtual*/ T2ImageObj::~T2ImageObj() { GlobalUnlock(mHandle); GlobalFree(mHandle); } void T2ImageObj::AddObject(HINSTANCE instance, unsigned int resourceID, T2BitImage* image) { #line 36 _ASSERT(image); HRSRC rsrc = FindResource(instance, MAKEINTRESOURCE(resourceID), "OBJMAP"); if (!rsrc) { CString nameStr; nameStr.Format("%d", resourceID); CString error = "T2ImageObj::AddObject ERROR : " + nameStr + " @" + GetModuleName(instance) + "\n"; OutputDebugString(error); } #line 45 _ASSERT(rsrc); HGLOBAL theHandle = LoadResource(instance, rsrc); #line 47 _ASSERT(theHandle); void *theRes = LockResource(theHandle); DWORD theResSize = SizeofResource(instance, rsrc); char *theData = (char *) malloc(theResSize); memcpy(theData, theRes, theResSize); UnlockResource(theHandle); FreeResource(theHandle); char *theCmd = strtok(theData, " \t\r\n\x1A"); while (theCmd) { if (!_stricmp(theCmd, "End")) break; if (!_stricmp(theCmd, "DefParts")) { mCount++; mHandle = GlobalReAlloc(mHandle, mCount * sizeof(ObjectData), GHND); mData = (ObjectData *) GlobalLock(mHandle); memset(&mData[mCount - 1], 0, sizeof(ObjectData)); mData[mCount - 1].image = image; strcpy(mData[mCount - 1].name, ""); mData[mCount - 1].id = 0; mData[mCount - 1].pattern = -1; mData[mCount - 1].grade = 0; mData[mCount - 1].span = 0; mData[mCount - 1].offset = -1; } else if (!_stricmp(theCmd, "Name")) { strcpy(mData[mCount - 1].name, strtok(NULL, "\t\r\n\x1A")); } else if (!_stricmp(theCmd, "ID")) { mData[mCount - 1].id = atoi(strtok(NULL, " \t\r\n\x1A")); } else if (!_stricmp(theCmd, "Pattern")) { mData[mCount - 1].pattern = atoi(strtok(NULL, " \t\r\n\x1A")); } else if (!_stricmp(theCmd, "Grade")) { mData[mCount - 1].grade = atoi(strtok(NULL, " \t\r\n\x1A")); } else if (!_stricmp(theCmd, "Span")) { mData[mCount - 1].span = atoi(strtok(NULL, " \t\r\n\x1A")); } else if (!_stricmp(theCmd, "Offset")) { mData[mCount - 1].offset = atoi(strtok(NULL, " \t\r\n\x1A")); } else if (!_stricmp(theCmd, "Roof")) { if (!_stricmp(strtok(NULL, " \t\r\n\x1A"), "Yes")) mData[mCount - 1].roof = true; } else if (!_stricmp(theCmd, "Floor")) { if (!_stricmp(strtok(NULL, " \t\r\n\x1A"), "Yes")) mData[mCount - 1].floor = true; } else if (!_stricmp(theCmd, "List")) { // nothing } else if (!_stricmp(theCmd, "Loop")) { mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags |= SPD_LOOP; } else if (!_stricmp(theCmd, "Transparent")) { mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags |= SPD_TRANSPARENT; } else if (!_stricmp(theCmd, "Halftone")) { mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags |= SPD_HALFTONE; } else if (!_stricmp(theCmd, "Rect")) { mData[mCount - 1].subPartCount++; mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags = SPD_RECT; char *arg = strtok(NULL, " \t\r\n\x1A"); char *argCopy = (char *) malloc(strlen(arg) + 1); strcpy(argCopy, arg); char *p; while ((p = strchr(argCopy, ','))) *p = ' '; sscanf( argCopy, "%hd %hd %hd %hd", &mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].left, &mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].top, &mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].right, &mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].bottom ); free(argCopy); } else if (!_stricmp(theCmd, "Parts")) { char *arg = strtok(NULL, " \t\r\n\x1A"); if (arg[0] != '#') { int i; for (i = 0; i < (mCount - 1); i++) { if (!strcmp(mData[i].name, arg)) { mData[mCount - 1].subPartCount++; mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags = SPD_PARTS_BY_NAME; mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].partIndex = i; break; } } if (i == (mCount - 1)) { char buf[256]; wsprintf(buf, "Undefined parts [%s]", arg); MessageBox(NULL, buf, "ERROR", MB_OK | MB_ICONWARNING | MB_TASKMODAL); } } else { mData[mCount - 1].subPartCount++; mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].flags = SPD_PARTS_BY_ID; mData[mCount - 1].subParts[mData[mCount - 1].subPartCount - 1].objectID = atoi(&arg[1]); } } else if (theCmd[0] == '#') { // nothing } else { char buf[256]; wsprintf(buf, "Undefined theCmd [%s]", theCmd); MessageBox(NULL, buf, "ERROR", MB_OK | MB_ICONWARNING | MB_TASKMODAL); } theCmd = strtok(NULL, " \t\r\n\x1A"); } free(theData); } void T2ImageObj::AddObject(const char* name, int pattern, T2BitImage& image, const RECT* rect, BOOL transparent, BOOL halftoneMode) { mCount++; mHandle = GlobalReAlloc(mHandle, mCount * sizeof(ObjectData), GHND); mData = (ObjectData *) GlobalLock(mHandle); memset(&mData[mCount - 1], 0, sizeof(ObjectData)); mData[mCount - 1].image = ℑ strcpy(mData[mCount - 1].name, name); mData[mCount - 1].id = 0; mData[mCount - 1].pattern = pattern; mData[mCount - 1].grade = 0; mData[mCount - 1].span = 0; mData[mCount - 1].offset = -1; mData[mCount - 1].subPartCount = 1; mData[mCount - 1].subParts[0].flags = SPD_RECT | (transparent ? SPD_TRANSPARENT : 0) | (halftoneMode ? SPD_HALFTONE : 0); if (rect) { mData[mCount - 1].subParts[0].top = rect->top; mData[mCount - 1].subParts[0].left = rect->left; mData[mCount - 1].subParts[0].bottom = rect->bottom; mData[mCount - 1].subParts[0].right = rect->right; } else { mData[mCount - 1].subParts[0].top = 0; mData[mCount - 1].subParts[0].left = 0; mData[mCount - 1].subParts[0].bottom = abs(image.mBitmap.header.biHeight); mData[mCount - 1].subParts[0].right = abs(image.mBitmap.header.biWidth); } } void T2ImageObj::AddObject(int id, int pattern, T2BitImage& image, const RECT* rect, BOOL transparent, BOOL halftoneMode) { mCount++; mHandle = GlobalReAlloc(mHandle, mCount * sizeof(ObjectData), GHND); mData = (ObjectData *) GlobalLock(mHandle); memset(&mData[mCount - 1], 0, sizeof(ObjectData)); mData[mCount - 1].image = ℑ strcpy(mData[mCount - 1].name, ""); mData[mCount - 1].id = id; mData[mCount - 1].pattern = pattern; mData[mCount - 1].grade = 0; mData[mCount - 1].span = 0; mData[mCount - 1].offset = -1; mData[mCount - 1].subPartCount = 1; mData[mCount - 1].subParts[0].flags = SPD_RECT | (transparent ? SPD_TRANSPARENT : 0) | (halftoneMode ? SPD_HALFTONE : 0); if (rect) { mData[mCount - 1].subParts[0].top = rect->top; mData[mCount - 1].subParts[0].left = rect->left; mData[mCount - 1].subParts[0].bottom = rect->bottom; mData[mCount - 1].subParts[0].right = rect->right; } else { mData[mCount - 1].subParts[0].top = 0; mData[mCount - 1].subParts[0].left = 0; mData[mCount - 1].subParts[0].bottom = abs(image.mBitmap.header.biHeight); mData[mCount - 1].subParts[0].right = abs(image.mBitmap.header.biWidth); } } int T2ImageObj::FindObject(int id, int pattern, int grade, int span, int offset) { ObjectData *obj = mData; int index; for (index = 0; index < mCount; index++, obj++) { if ( (obj->id == id) && (obj->pattern == pattern || obj->pattern == -1 || pattern == -1) && (obj->grade == grade || obj->grade == 0 || grade == 0) && (obj->span == span || obj->span == 0 || span == 0) && (obj->offset == offset || obj->offset == 255 || offset == 255) ) break; } if (index == mCount) return -1; else return index; } int T2ImageObj::FindObject(const char* name, int pattern, int grade, int span, int offset) { ObjectData *obj = mData; int index; for (index = 0; index < mCount; index++, obj++) { if ( !strcmp(obj->name, name) && (obj->pattern == pattern || obj->pattern == -1 || pattern == -1) && (obj->grade == grade || obj->grade == 0 || grade == 0) && (obj->span == span || obj->span == 0 || span == 0) && (obj->offset == offset || obj->offset == 255 || offset == 255) ) break; } if (index == mCount) return -1; else return index; } void T2ImageObj::EnumParts(int index, int width, PARTSLIST* outParts, int* outCount) { #line 272 _ASSERT(index >= 0); int i = 0; width = width * 8; while (width > 0 && i < mData[index].subPartCount) { if (mData[index].subParts[i].flags & SPD_RECT) { // Draw a piece of the image outParts[*outCount].image = mData[index].image; outParts[*outCount].rect.top = mData[index].subParts[i].top; outParts[*outCount].rect.left = mData[index].subParts[i].left; outParts[*outCount].rect.bottom = mData[index].subParts[i].bottom; outParts[*outCount].rect.right = mData[index].subParts[i].right; if ((mData[index].subParts[i].flags & SPD_TRANSPARENT) == 0) outParts[*outCount].transparent = false; else outParts[*outCount].transparent = true; if ((mData[index].subParts[i].flags & SPD_HALFTONE) == 0) outParts[*outCount].halftoneMode = false; else outParts[*outCount].halftoneMode = true; width -= (outParts[*outCount].rect.right - outParts[*outCount].rect.left); (*outCount)++; } else if (mData[index].subParts[i].flags & SPD_PARTS_BY_NAME) { // Include another part list int prevCount = *outCount; EnumParts(mData[index].subParts[i].partIndex, width, outParts, outCount); for (; prevCount < *outCount; prevCount++) width -= (outParts[prevCount].rect.right - outParts[prevCount].rect.left); } else if (mData[index].subParts[i].flags & SPD_PARTS_BY_ID) { // Search for an object and include its part list int prevCount = *outCount; EnumParts(FindObject(mData[index].subParts[i].objectID), width, outParts, outCount); for (; prevCount < *outCount; prevCount++) width -= (outParts[prevCount].rect.right - outParts[prevCount].rect.left); } if (!(mData[index].subParts[i].flags & SPD_LOOP)) i++; } } BOOL T2ImageObj::WithRoof(int index) { return mData[index].roof; } BOOL T2ImageObj::WithFloor(int index) { return mData[index].floor; } void T2ImageObj::DrawObject(T2BitImage* image, int index, RECT rect, int factor, int foreGndColor) { DrawObject(image, index, rect, factor, false, foreGndColor); } void T2ImageObj::DrawObject(CDC* dc, int index, RECT rect, int factor, int foreGndColor) { DrawObject(dc, index, rect, factor, true, foreGndColor); } void T2ImageObj::DrawObject(void* target, int index, RECT rect, int factor, BOOL targetIsDC, int foreGndColor) { #line 338 _ASSERT(index >= 0); static PARTSLIST parts[500]; RECT srcRect, dstRect; int theSize = rect.right - rect.left; int numOfParts = 0; EnumParts(index, theSize, parts, &numOfParts); if (numOfParts >= 500) MessageBox(NULL, "Too many parts", "T2ImageObj::DrawObject", MB_OK | MB_ICONERROR | MB_TASKMODAL); for (int n = 0; n < numOfParts; n++) { srcRect = parts[n].rect; dstRect = rect; if ((srcRect.right - srcRect.left) > ((dstRect.right - dstRect.left) << factor)) srcRect.right = srcRect.left + ((dstRect.right - dstRect.left) << factor); if ((dstRect.right - dstRect.left) > ((srcRect.right - srcRect.left) >> factor)) dstRect.right = dstRect.left + ((srcRect.right - srcRect.left) >> factor); if ((srcRect.bottom - srcRect.top) > ((dstRect.bottom - dstRect.top) << factor)) srcRect.bottom = srcRect.top + ((dstRect.bottom - dstRect.top) << factor); if ((dstRect.bottom - dstRect.top) > ((srcRect.bottom - srcRect.top) >> factor)) dstRect.bottom = dstRect.top + ((srcRect.bottom - srcRect.top) >> factor); if (parts[n].transparent) parts[n].image->SetBackGndColor(0); else parts[n].image->SetBackGndColor(-1); if (parts[n].halftoneMode) parts[n].image->SetHalftoneMode(true); else parts[n].image->SetHalftoneMode(false); parts[n].image->SetForeGndColor(foreGndColor); if (targetIsDC) { parts[n].image->CopyImage((CDC *) target, srcRect, dstRect, false, NULL); } else { parts[n].image->CopyImage(*((T2BitImage *) target), srcRect, dstRect, false, NULL); } parts[n].image->SetHalftoneMode(false); rect.left += (dstRect.right - dstRect.left); } } BOOL T2ImageObj::GetObjectSize(int index, SIZE* outSize) { #line 383 _ASSERT(index >= 0); PARTSLIST part; int num = 0; EnumParts(index, 1, &part, &num); if (num != 1) return false; outSize->cx = part.rect.right - part.rect.left; outSize->cy = part.rect.bottom - part.rect.top; return true; } T2BitImage* T2ImageObj::GetObjectImage(int index, RECT& outRect) { #line 397 _ASSERT(index >= 0); PARTSLIST part; int num = 0; EnumParts(index, 1, &part, &num); if (num != 1) return NULL; outRect = part.rect; return part.image; }