//--------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include "TPUnion.h" #define min(a, b) (((a) < (b)) ? (a) : (b)) #define max(a, b) (((a) > (b)) ? (a) : (b)) //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "ltdis_bc.lib" #pragma link "ltkrn_bc.lib" #pragma link "ltfil_bc.lib" #define GFSR_SYSTEMRESOURCES 0 #define GFSR_GDIRESOURCES 1 #define GFSR_USERRESOURCES 2 typedef LONG (CALLBACK* GETRES)(int); //TUnionBitmap //--------------------------------------------------------------------------- // À̸§ Á¤ÇÏ´Â ÇÔ¼ö //--------------------------------------------------------------------------- static AnsiString __fastcall TempUnionFileName() { char tp[MAX_PATH+1], fn[MAX_PATH+1]; GetTempPath(MAX_PATH, tp); if (tp[strlen(tp)-1]=='\\') tp[strlen(tp)-1] = 0; while (1) { sprintf(fn, "%s\\TU%05X.tub", tp, rand() & 0xFFFFF); if (!FileExists(fn)) break; } return (AnsiString)fn; } //--------------------------------------------------------------------------- __fastcall TUnionBitmap::TUnionBitmap() { FColorSpace = csRGB; FWidth = FHeight = 0; FBitsPerPixel = 0; FCountX = FCountY = 0; FZoomCnt = 0; FIsUse = false; FCoordinateSystem = csTopLeft; hTempFile = INVALID_HANDLE_VALUE; FileName = TempUnionFileName(); FBitmap = NULL; btRect = NULL; Table = NULL; ActivateList = NULL; FRgnBitmap = NULL; Frgb = NULL; // by celberus PartialUndo = NULL; //by jeegeo ShareCount = 0; hBuffer = NULL; pBuffer[0] = NULL; FBackgroundColor = 0x00FFFFFF; LENGTH = DEFAULT_LENGTH; first = true; alwaysCheck = false; // by celberus #ifdef SPDTESTT swapInCounter = new TickCounter("SwapIn"); swapInCounter->reset(); swapOutCounter = new TickCounter("SwapOut"); swapOutCounter->reset(); #endif } //--------------------------------------------------------------------------- __fastcall TUnionBitmap::~TUnionBitmap() { Destroy(); #ifdef SPDTESTT swapInCounter->reportOut(); delete swapInCounter; swapOutCounter->reportOut(); delete swapOutCounter; #endif } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::Create(int width, int height, int bpp, RGBQUAD *rgb) { int totalSize; Destroy(); FWidth = width; FHeight = height; FBitsPerPixel = bpp; FBytesPerLine = (bpp*width)/8; if((bpp*width)%8) FBytesPerLine++; FBytesPerLine = (FBytesPerLine + 3) / 4 * 4; // bpp´Â Ç×»ó 8ÀÇ ¹è¼ö¶ó º»´Ù. FZoomCnt = CalculateFZoomCount(); TPoint p = CalculateFCount(); FCountX = p.x; FCountY = p.y; CreateRegionBitmap(); MakeRgb(rgb); AllocBase(); totalSize = InitializeEachBitmap(true); CreateSwapFile(totalSize); ActiveManager = new TPActiveList(); ActiveManager->Set(FCountX,FCountY); // PartialUndo = new TUndoManager(FZoomCnt, FCountX, FCountY, FBitmap, Table, FileName, Checkload ); //by linuxjun PartialUndo = new TUndoManager(FZoomCnt, FCountX, FCountY, FBitmap, Table, btRect, FileName ); //by linuxjun PartialUndo->SetBitsPerPixel(FBitsPerPixel); PartialUndo->SetBytesPerLine(FBytesPerLine); PartialUndo->OnCheckLoad = CheckLoad; PartialUndo->OnIsMemory = IsMemory; PartialUndo->OnReCreate = ReCreate; PartialUndo->OnUnion2PartN = Union2PartN; // TReCreateEvent // PartialUndo = new TUndoManager(this); //by linuxjun return true; } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::Destroy() { AnsiString fn; TbmPoint *pt; if (FBitmap == NULL) return; for (int k = 0; k < FZoomCnt; k++) { for (int i = 0; i < FCountX * FCountY; i++) { if (FBitmap[k][i]) { FBitmap[k][i]->Destroy(); delete FBitmap[k][i]; } } while(ActivateList[k]->Count) { pt = (TbmPoint *)ActivateList[k]->Last(); ActivateList[k]->Remove(pt); delete pt; } delete[] FBitmap[k]; delete[] btRect[k]; delete[] Table[k]; delete ActivateList[k]; } if (FBitmap) {delete[] FBitmap; FBitmap = NULL;} if (btRect) {delete[] btRect; btRect = NULL;} if (Table) {delete[] Table; Table = NULL;} if (ActivateList) {delete[] ActivateList; ActivateList = NULL;} if (FRgnBitmap) {delete FRgnBitmap; FRgnBitmap = NULL;} // by celberus if (Frgb) {delete[] Frgb; Frgb = NULL;}// by celberus if (hTempFile != INVALID_HANDLE_VALUE) {CloseHandle(hTempFile); hTempFile = INVALID_HANDLE_VALUE;} if (FileExists(FileName)) DeleteFile(FileName); //FileName = NULL; if (PartialUndo) {delete PartialUndo; PartialUndo = NULL;}// ExitUndo(); //by linuxjun if (ActiveManager) {delete ActiveManager; ActiveManager = NULL;} first = true; alwaysCheck = false; // by celberus } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::IsMemory(int n, int k) { if (FBitmap[k][n]->BitsPerPixel == 0) return false; else return true; } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::ReCreate(int n, int k, RGBQUAD *rgb) { int w = btRect[k][n].right - btRect[k][n].left; int h = btRect[k][n].bottom - btRect[k][n].top; Rearrange(n, k); if (FBitsPerPixel == 8) { FBitmap[k][n]->Create(w, h, 8, rgb); } else { FBitmap[k][n]->Create(w, h, 24); } } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::CheckLoad(int n, int k) { if (FBitmap[k][n]->BitsPerPixel == 0) { LoadFromTempFile(n, FBackgroundColor, k, Frgb); // by celberus } else return; } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::Activate(int n, COLORREF bgcolor, RGBQUAD *rgb) { if (FBitmap[0][n]->BitsPerPixel == 0) { LoadFromTempFile(n, bgcolor, 0, rgb); } } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::LoadFromTempFile(int segmentNumber, COLORREF bgcolor, int zoomLevel, RGBQUAD *rgb) { AnsiString fn; int width = btRect[zoomLevel][segmentNumber].right - btRect[zoomLevel][segmentNumber].left; int height = btRect[zoomLevel][segmentNumber].bottom - btRect[zoomLevel][segmentNumber].top; Rearrange(segmentNumber, zoomLevel); #ifdef SPDTESTT swapInCounter->startCounter(); #endif if (FBitsPerPixel == 8) { FBitmap[zoomLevel][segmentNumber]->Create(width, height, 8, rgb); } else { FBitmap[zoomLevel][segmentNumber]->Create(width, height, FBitsPerPixel); } if (Table[zoomLevel][segmentNumber].blank) {//ÆÄÀÏÀÌ ºñ¾îÀÖ´Â °æ¿ì,óÀ½ ºÒ·¯¿À´Â(¿ø·¡ÀúÀåÀÌ ¾ÈµÇÀÖ´Â) °æ¿ì if(FBitsPerPixel <= 8) { FBitmap[zoomLevel][segmentNumber]->FillRect(Rect(0, 0, width, height), FBackgroundColor); // data¸¦ 01·Î ä¿î´Ù. ù ¹ÙÀÌÆ®°¡ 00ÀÌ¸é ÆÈ·¹Æ® »ö±ò¿¡ ¸ÂÃç¼­ Ä¥ÇØÁִµ¥ bg color °¡ °ËÁ¤»öÀ̸é enlargeµî¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇÏ°Ô µÈ´Ù. by celberus } else if(FBitsPerPixel == 24) { FBitmap[zoomLevel][segmentNumber]->FillRect(Rect(0, 0, width, height), bgcolor); } } else { MoveFilePointer(segmentNumber, zoomLevel); if (!FBitmap[zoomLevel][segmentNumber]->LoadFromTexpiaFile(hTempFile, cmNone)) goto fail; // if (!FBitmap[zoomLevel][segmentNumber]->LoadFromSwapFile(hTempFile)) goto fail; } #ifdef SPDTESTT swapInCounter->endCounter(); #endif return true; fail: return false; } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::SaveToTempFile(int n, int k) { AnsiString fn = Format("%s_%d.TMP", OPENARRAY(TVarRec, (FileName, n))); #ifdef SPDTESTT swapOutCounter->startCounter(); #endif if (!Table[0][n].blank) { MoveFilePointer(n, k); if (!FBitmap[k][n]->SaveToTexpiaFile(hTempFile, cmNone)) goto fail; // if (!FBitmap[k][n]->SaveToSwapFile(hTempFile)) goto fail; } FBitmap[k][n]->Destroy(); #ifdef SPDTESTT swapOutCounter->endCounter(); #endif return true; fail: return false; } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::Rearrange(int n, int k) { static long access_time = 0; TbmPoint *pt = new TbmPoint(n % FCountX, n / FCountX, n, ++access_time); //ÃÖ´ë ¿¢Æ¼ºê °¹¼ö¸¦ Á¤ÇÔ if(first){ OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); osVERSION = osvi.dwPlatformId; //WINDOWS 98 == 1, WIN_NT==2; if(osVERSION < 2) alwaysCheck = true; if(osVERSION<2){ MEMORYSTATUS mem_state; mem_state.dwLength = sizeof(MEMORYSTATUS); // sizeof(MEMORYSTATUS) //mem_state.dwMemoryLoad; // percent of memory in use //mem_state.dwTotalPhys; // bytes of physical memory // RAM //mem_state.dwAvailPhys; // free physical memory bytes //mem_state.dwTotalPageFile; // bytes of paging file //mem_state.dwAvailPageFile; // free bytes of paging file //mem_state.dwTotalVirtual; // user bytes of address space //mem_state.dwAvailVirtual; // free user bytes GlobalMemoryStatus(&mem_state); int unit_size[4], /*unit_size_total, */avail_ram; unit_size[0] = (BytesPerLine * DEFAULT_LENGTH); unit_size[1] = (BytesPerLine * DEFAULT_LENGTH)*0.5; unit_size[2] = (BytesPerLine * DEFAULT_LENGTH)*0.25; unit_size[3] = (BytesPerLine * DEFAULT_LENGTH)*0.125; // unit_size_total = (FBytesPerLine * DEFAULT_LENGTH) * 2; // 2 > 1.875, (1.875 = 1.0+0.5+0.25+0.125) // Å« ºñÆ® ¸ÊÀº ·¹ÀÌ¾î ¾øÀÌ ÇÑÀ常 ¿¬´Ù°í °¡Á¤ÇÏÀÚ avail_ram = mem_state.dwTotalPhys * 0.66; // ³ª¸ÓÁö´Â À©µµ¿ì µîÀÌ »ç¿ëÇϵµ·Ï ¾çº¸ÇÑ´Ù for(int i=0;i<4;i++){ if(unit_size[i]<1024) unit_size[i]=1024; } ActiveCnt[0] = 0.50*avail_ram/unit_size[0];//1À̸é avail_ramÀ» ´Ù¸Ô±â ¶§¹®¿¡ Àû´çÈ÷ 1º¸´Ù ÀÛÀº °ªÀ¸·Î ÇÑ´Ù ActiveCnt[1] = 0.42*avail_ram/unit_size[1]; ActiveCnt[2] = 0.37*avail_ram/unit_size[2]; ActiveCnt[3] = 0.33*avail_ram/unit_size[3]; } else { ActiveCnt[0] = 0x7FFFFFFF;//À©µµ¿ì 2000À̻󿡼­´Â À©µµ¿ì¿¡ ¸Ã±ä´Ù ActiveCnt[1] = 0x7FFFFFFF; ActiveCnt[2] = 0x7FFFFFFF; ActiveCnt[3] = 0x7FFFFFFF; // alwaysCheck = true; } first=false; } //ÃÖ´ë ÇѰ踦 ³Ñ¾î°¡´Â ³à¼®À» µð¿¢Æ¼ºê ½ÃÅ´ if(ActivateList[k]->Count > 0) { if(!alwaysCheck) { while(ActivateList[k]->Count >= ActiveCnt[k]){ if(!swapOutPartition(k))break; } } else { // alwayscheck if(osVERSION<2) { HINSTANCE hInst = LoadLibrary("RSRC32.dll"); if (hInst != NULL) // 98 or 95ÀÎ °æ¿ì { GETRES pGetRes = (GETRES) GetProcAddress(hInst, "_MyGetFreeSystemResources32@4");//); if (pGetRes) { long lSysRes = (*pGetRes)(GFSR_SYSTEMRESOURCES); if(lSysRes < 25) // ¸®¼Ò½º ºÎÁ·ÀÏ ¶§ { swapOutPartition(k); } else // ¸®¼Ò½º°¡ »ì¦Äô ³²¾ÆÀÖÀ»¶§.. { while(ActivateList[k]->Count >= ActiveCnt[k]) if(!swapOutPartition(k)) break; } } else ShowMessage("Error getting pointer to _MyGetFreeSystemResources32()"); } // if( hInst != NULL) end FreeLibrary(hInst); } else { MEMORYSTATUS mem_state; mem_state.dwLength = sizeof(MEMORYSTATUS); // sizeof(MEMORYSTATUS) GlobalMemoryStatus(&mem_state); if ((mem_state.dwAvailPhys < Table[k][0].size * 2) || (mem_state.dwAvailPhys + mem_state.dwAvailPageFile < (mem_state.dwTotalPhys + mem_state.dwTotalPageFile) / 10)) { while ((mem_state.dwAvailPhys < Table[k][0].size * 2) || (mem_state.dwAvailPhys < Table[k][0].size * FWidth / DEFAULT_LENGTH)) { if (!swapOutPartition(k)) break; GlobalMemoryStatus(&mem_state); } } //mem_state.dwMemoryLoad; // percent of memory in use //mem_state.dwTotalPhys; // bytes of physical memory // RAM //mem_state.dwAvailPhys; // free physical memory bytes //mem_state.dwTotalPageFile; // bytes of paging file //mem_state.dwAvailPageFile; // free bytes of paging file //mem_state.dwTotalVirtual; // user bytes of address space //mem_state.dwAvailVirtual; // free user bytes } } // else end } // if(ActivateList[k]->Count > 0) end ActivateList[k]->Add(pt); /* MEMORYSTATUS mem_state; mem_state.dwLength = sizeof(MEMORYSTATUS); // sizeof(MEMORYSTATUS) GlobalMemoryStatus(&mem_state); int avail_ram = mem_state.dwAvailPhys * 0.8; if(Table[k][n].size * FBitsPerPixel / 8 > avail_ram || mem_state.dwAvailPhys < mem_state.dwTotalPhys * 0.2) { // check memory lack swapOutPartition(k); //ShowMessage("oops"); } else { while(ActivateList[k]->Count >= ActiveCnt[k]){ if(!swapOutPartition(k)) break; } } } } ActivateList[k]->Add(pt);*/ } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::swapOutPartition(int zoomLevel) { int lat1, lat2; TbmPoint *lpt; if (ActivateList[zoomLevel]->Count <= 0) return false; for (int i = 0; i < ActivateList[zoomLevel]->Count-1; i++) { lat1=((TbmPoint *)ActivateList[zoomLevel]->Items[i])->lat; lat2=((TbmPoint *)ActivateList[zoomLevel]->Items[i+1])->lat; if (lat2 > lat1) ActivateList[zoomLevel]->Exchange(i, i+1); } lpt = (TbmPoint *)ActivateList[zoomLevel]->Last(); if(!FBitmap[zoomLevel][lpt->n]->IsUse){ ActivateList[zoomLevel]->Remove(lpt); SaveToTempFile(lpt->n, zoomLevel); delete lpt; return true; } else { for (int j = ActivateList[zoomLevel]->Count-2; j >= 0; j--) { lpt = (TbmPoint *)ActivateList[zoomLevel]->Items[j]; if(!FBitmap[zoomLevel][lpt->n]->IsUse){ ActivateList[zoomLevel]->Remove(lpt); SaveToTempFile(lpt->n, zoomLevel); delete lpt; return true; } } return false; } } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::FillRect(RECT Range, COLORREF Color) { RECT rt; int i, j; for (j = 0; j < FCountY; j++) { if ((Range.top < btRect[0][j * FCountX].bottom) && (Range.bottom > btRect[0][j * FCountX].top)) { for (i = 0; i < FCountX; i++) { if ((Range.left < btRect[0][i].right) && (Range.right > btRect[0][i].left)) { rt.left = max(Range.left, btRect[0][i].left); rt.top = max(Range.top, btRect[0][j * FCountX].top); rt.right = min(Range.right, btRect[0][i].right); rt.bottom = min(Range.bottom, btRect[0][j * FCountX].bottom); rt.left -= btRect[0][i].left; rt.top -= btRect[0][j * FCountX].top; rt.right -= btRect[0][i].left; rt.bottom -= btRect[0][j * FCountX].top; CheckLoad(j * FCountX + i, 0); FBitmap[0][j * FCountX + i]->FillRect(rt, Color); Table[0][j * FCountX + i].modify = true; Table[0][j * FCountX + i].blank = false; } } } } } //--------------------------------------------------------------------------- //get X-axis value in current bitmap segement int __fastcall TUnionBitmap::Union2PartX(int X) { for (int i = 0; i < FCountX; i++) { if (X >= btRect[0][i].left && X < btRect[0][i].right) return (X - btRect[0][i].left); } return 0; } //--------------------------------------------------------------------------- //get Y-axis value in current bitmap segement int __fastcall TUnionBitmap::Union2PartY(int Y) { for (int j = 0; j < FCountY; j++) { if (Y >= btRect[0][j * FCountX].top && Y < btRect[0][j * FCountX].bottom) return (Y - btRect[0][j * FCountX].top); } return 0; } //--------------------------------------------------------------------------- //get part number of current coordinate int __fastcall TUnionBitmap::Union2PartN(int X, int Y) { int i, j; for (i = 0; i < FCountX; i++) { if (X >= btRect[0][i].left && X < btRect[0][i].right) break; } for (j = 0; j < FCountY; j++) { if (Y >= btRect[0][j * FCountX].top && Y < btRect[0][j * FCountX].bottom) break; } if (i == FCountX) i = FCountX - 1; if (j == FCountY) j = FCountY - 1; return (j * FCountX + i); } //--------------------------------------------------------------------------- int __fastcall TUnionBitmap::getSegmentNumberX(int X) { if (X <= 0) return 0; if (X >= FWidth) return FCountX - 1; return X / LENGTH; } //--------------------------------------------------------------------------- int __fastcall TUnionBitmap::getSegmentNumberY(int Y) { if (Y <= 0) return 0; if (Y >= FHeight) return FCountY - 1; return Y / LENGTH; } //--------------------------------------------------------------------------- int __fastcall TUnionBitmap::getSegmentNumber(int X, int Y) { return getSegmentNumberY(Y) * FCountX + getSegmentNumberX(X); } //--------------------------------------------------------------------------- // ±³ÁýÇÕÀ» ¹Ýȯ¹Þ´Â´Ù. RECT __fastcall TUnionBitmap::GetCommonRect(RECT rt, int n, bool bPart) { RECT irt; IntersectRect(&irt, &rt, &btRect[0][n]); if (bPart) OffsetRect(&irt, -btRect[0][n].left, -btRect[0][n].top); return irt; } //--------------------------------------------------------------------- HDC __fastcall TUnionBitmap::CreateDC() { return CreateDC(-1, 0); } //--------------------------------------------------------------------- HDC __fastcall TUnionBitmap::CreateDC(int n) { return CreateDC(n, 0); } //--------------------------------------------------------------------- HDC __fastcall TUnionBitmap::CreateDC(int n, int k) { if (n == -1) { if (ActivateList[k]->Count > 0) n = ((TbmPoint *)ActivateList[k]->Items[0])->n; else n = 0; } CheckLoad(n, k); if (k != 0) CheckUpdate(n, k); return FBitmap[k][n]->CreateDC(); } //--------------------------------------------------------------------- HDC __fastcall TUnionBitmap::CreateIgnoredDC(int n, int k) { if (n == -1) { if (ActivateList[k]->Count > 0) n = ((TbmPoint *)ActivateList[k]->Items[0])->n; else n = 0; } CheckLoad(n, k); if (k != 0) CheckUpdate(n, k); return FBitmap[k][n]->CreateIgnoredDC(); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::CheckUpdate(int n, int k) { HDC dcDst, dcSrc; if (k == 0) { return; } CheckUpdate(n, k-1); // À­´Ü°èÀÇ ¾÷µ¥ÀÌÆ®°¡ ÇÊ¿äÇѰ¡.. À̹ÌÁö º¯Çü½Ã¿¡ ¸ðµç modify°ªÀÌ true·Î ¹Ù²î¸é À̰ÍÀº ÇÊ¿ä¾ø´Ù. if (Table[k-1][n].modify == true) { // À­´Ü°èÀÇ º¯ÇüÀÌ ÀÌ·ç¾îÁ³À¸¸é if(Table[k-1][n].blank == false) { CheckLoad(n, k); dcDst = FBitmap[k][n]->CreateDC(); CheckLoad(n, k-1); dcSrc = FBitmap[k-1][n]->CreateDC(); SetStretchBltMode(dcDst, COLORONCOLOR); StretchBlt(dcDst, 0, 0, FBitmap[k][n]->Width, FBitmap[k][n]->Height, dcSrc, 0, 0, FBitmap[k-1][n]->Width, FBitmap[k-1][n]->Height, SRCCOPY); if (dcDst) FBitmap[k][n]->DeleteDC(dcDst); if (dcSrc) FBitmap[k-1][n]->DeleteDC(dcSrc); Table[k][n].blank = false; } else { Table[k][n].blank = true; } Table[k][n].modify = true; // ¾Æ·§´Ü°è¸¦ À§ÇØ ÀÌ °ªÀ» true·Î ¹Ù²Û´Ù. Table[k-1][n].modify = false; // À­´Ü°è´Â false·Î ¹Ù²Ù¾îÁØ´Ù. } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::IgnoredCheckUpdate(int n, int k) { HDC dcDst, dcSrc; if (k == 0) { return; } IgnoredCheckUpdate(n, k-1); // À­´Ü°èÀÇ ¾÷µ¥ÀÌÆ®°¡ ÇÊ¿äÇѰ¡.. À̹ÌÁö º¯Çü½Ã¿¡ ¸ðµç modify°ªÀÌ true·Î ¹Ù²î¸é À̰ÍÀº ÇÊ¿ä¾ø´Ù. if (Table[k-1][n].modify == true) { // À­´Ü°èÀÇ º¯ÇüÀÌ ÀÌ·ç¾îÁ³À¸¸é if(Table[k-1][n].blank == false) { CheckLoad(n, k); dcDst = FBitmap[k][n]->CreateIgnoredDC(); CheckLoad(n, k-1); dcSrc = FBitmap[k-1][n]->CreateIgnoredDC(); SetStretchBltMode(dcDst, COLORONCOLOR); StretchBlt(dcDst, 0, 0, FBitmap[k][n]->Width, FBitmap[k][n]->Height, dcSrc, 0, 0, FBitmap[k-1][n]->Width, FBitmap[k-1][n]->Height, SRCCOPY); if (dcDst) FBitmap[k][n]->DeleteDC(dcDst); if (dcSrc) FBitmap[k-1][n]->DeleteDC(dcSrc); Table[k][n].blank = false; } else { Table[k][n].blank = true; } Table[k][n].modify = true; // ¾Æ·§´Ü°è¸¦ À§ÇØ ÀÌ °ªÀ» true·Î ¹Ù²Û´Ù. Table[k-1][n].modify = false; // À­´Ü°è´Â false·Î ¹Ù²Ù¾îÁØ´Ù. } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::DeleteDC(HDC dc) { DeleteDC(dc, -1, 0); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::DeleteDC(HDC dc, int n) { DeleteDC(dc, n, 0); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::DeleteDC(HDC dc, int n, int k) { if (n == -1) { if (ActivateList[k]->Count > 0) n = ((TbmPoint *)ActivateList[k]->Items[0])->n; else n = 0; } FBitmap[k][n]->DeleteDC(dc); } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::GetBytesPerLine() { return FBytesPerLine; } //--------------------------------------------------------------------- BITMAPHANDLE *__fastcall TUnionBitmap::GetHandle() { if (FCountX * FCountY == 0) return NULL; int n; if (ActivateList[0]->Count > 0) n = ((TbmPoint *)ActivateList[0]->Items[0])->n; else { CheckLoad(0, 0); n = 0; } return FBitmap[0][n]->GetHandle(); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::SetBitsPerPixel(WORD bpp) { FBitsPerPixel = bpp; for (int i = 0; i < FCountX * FCountY; i++) FBitmap[0][i]->BitsPerPixel = bpp; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::SetCoordinateSystem(TCoordinateSystem Value) { FCoordinateSystem = Value; for (int i = 0; i < FCountX * FCountY; i++) FBitmap[0][i]->CoordinateSystem = Value; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::SetBGColor(COLORREF bgcolor) { FBackgroundColor = bgcolor; } //--------------------------------------------------------------------------- // Public Function //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::ColorResolution(WORD nBitsPerPixel, UINT uFlags, LPRGBQUAD pPalette, UINT uColors) { TTexpiaBitmap *tempBitmap = NULL; TUnionBitmap *tempUnion = NULL; HDC dc = NULL; RGBQUAD rgb[256], userPalette[256]; int Length = 2000; bool hasWhiteColor = false; int i; if (nBitsPerPixel == 8) { tempBitmap = new TTexpiaBitmap; if (FWidth * FHeight < Length * Length) { tempBitmap->Create(FWidth, FHeight, FBitsPerPixel, Frgb); dc = tempBitmap->CreateDC(); if (!UnionBitBlt(dc, 0, 0, FWidth, FHeight, 0, 0, SRCCOPY, false)) goto fail; tempBitmap->DeleteDC(dc); dc = NULL; } else { tempBitmap->Create(Length * sqrt((double)FWidth / FHeight), Length * sqrt((double)FHeight / FWidth), FBitsPerPixel); dc = tempBitmap->CreateDC(); // -- union stretchblt double ratioX = (double)tempBitmap->Width / FWidth; double ratioY = (double)tempBitmap->Height / FHeight; int SrcSegmentNumber; RECT SourceRect = Rect(0, 0, FWidth, FHeight); RECT dstRect, SegmentRect; SetStretchBltMode(dc, COLORONCOLOR); for (int j = 0; j < FCountY; j++) { for (int i = 0; i < FCountX; i++) { SrcSegmentNumber = j * FCountX + i; dstRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ segmentStretchBlt(dc, dstRect, SegmentRect, SrcSegmentNumber, 0, 0, 0, 0, 0, ratioX, ratioY, 1, SRCCOPY); } } // -- zoomout image »ý¼º ¸·±âÀ§ÇØ by celberus tempBitmap->DeleteDC(dc); dc = NULL; } /* if (tempBitmap->BitsPerPixel == 8) { tempBitmap->GetColors(0, 256, rgb); for (i = 0; i < 256; i++ ) { if (rgb[i].rgbRed == 0xFF && rgb[i].rgbGreen == 0xFF && rgb[i].rgbBlue == 0xFF) { hasWhiteColor = true; rgb[i].rgbRed = 0xFE; rgb[i].rgbGreen = 0xFE; rgb[i].rgbRed = 0xFE; } } if (hasWhiteColor) { tempBitmap->PutColors(0, 256, rgb); } } */ // if(pPalette != NULL || uFlags != CRF_OPTIMIZEDPALETTE) { if (!tempBitmap->ColorResolution(nBitsPerPixel, uFlags, pPalette, uColors)) goto fail; // } // else { // makeReservedPalette(userPalette); // uColors+=2; // if (!tempBitmap->ColorResolution(nBitsPerPixel, CRF_OPTIMIZEDPALETTE, userPalette, uColors)) goto fail; // } tempBitmap->GetColors(0, 256, rgb); //---------------- if (FWidth * FHeight < Length * Length) { if (FBitsPerPixel != nBitsPerPixel) { this->Create(FWidth, FHeight, nBitsPerPixel, rgb); } this->CopyFromRect(tempBitmap, 0, 0, SRCCOPY); } else { if (FBitsPerPixel != nBitsPerPixel) { tempUnion = new TUnionBitmap; tempUnion->Create(FWidth, FHeight, FBitsPerPixel, Frgb); tempUnion->ExactCopy(this); for (int i = 0; i < FCountX * FCountY; i++) { tempUnion->CheckLoad(i); if (!tempUnion->Bitmap[0][i]->ColorResolution(nBitsPerPixel, CRF_USERPALETTE, rgb, uColors)) return false; } tempUnion->BitsPerPixel = nBitsPerPixel; tempUnion->BytesPerLine = (FBitsPerPixel * FWidth / 8 + 3) / 4 * 4;; tempUnion->PutColors(0, 256, rgb); this->Create(FWidth, FHeight, nBitsPerPixel, rgb); this->ExactCopy(tempUnion); delete tempUnion; } else { for (int i = 0; i < FCountX * FCountY; i++) { CheckLoad(i); if (!FBitmap[0][i]->ColorResolution(nBitsPerPixel, CRF_USERPALETTE, rgb, uColors)) return false; } } } //---------------- /* int totalSize = 0; for (int i = 0; i < FCountX * FCountY; i++) { CheckLoad(i); if (!FBitmap[0][i]->ColorResolution(nBitsPerPixel, CRF_USERPALETTE, rgb, uColors)) return false; int bpl = btRect[0][i].right - btRect[0][i].left; Table[0][i].size = (((bpl + 3) / 4) * 4) * (btRect[0][i].bottom - btRect[0][i].top); //BytesPerLine(4ÀÇ ¹è¼ö ¿Å¸²)°è»ê Table[0][i].pos = totalSize; totalSize += Table[0][i].size; //if (!FBitmap[0][i]->ColorResolution(nBitsPerPixel, CRF_FASTMATCHPALETTE, rgb, uColors)) return false; // FBitmap[0][i]->PutColors(0, 256, rgb); } FBitsPerPixel = nBitsPerPixel; FBytesPerLine = (FBitsPerPixel * FWidth / 8 + 3) / 4 * 4;; int len, width, height, h, w; for (int k = 1; k < FZoomCnt; k++) { len = LENGTH / pow(2, k); width = FWidth / pow(2, k); height = FHeight / pow(2, k); for (int j = 0; j < FCountY; j++) { h = getHeightOfEachBitmap(height, j, len); for (int i = 0; i < FCountX; i++) { w = getWidthOfEachBitmap(width, i, len); if(FBitmap[k][j * FCountX + i]) {delete FBitmap[k][j * FCountX + i]; FBitmap[k][j * FCountX + i] = NULL;} FBitmap[k][j * FCountX + i] = new TTexpiaBitmap; btRect[k][j * FCountX + i] = Rect(i*len, j*len, i*len + w, j*len + h); int bpl = (FBitsPerPixel*w)/8; if((FBitsPerPixel*w)%8) bpl++; Table[k][j * FCountX + i].size = (((bpl + 3) / 4) * 4) * h; //BytesPerLine(4ÀÇ ¹è¼ö ¿Å¸²)°è»ê Table[k][j * FCountX + i].pos = totalSize; Table[k][j * FCountX + i].modify = false; // Table[0][j * FCountX + i].undosave = false; totalSize += Table[k][j * FCountX + i].size; } } } if(!hTempFile){ hTempFile = CreateFile(FileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } SetFilePointer(hTempFile, totalSize, 0, FILE_BEGIN); SetEndOfFile(hTempFile); */ delete tempBitmap; tempBitmap = NULL; /* if (hasWhiteColor) { for (i = 0; i < 256; i++ ) { if (rgb[i].rgbRed == 0xFE && rgb[i].rgbGreen == 0xFE && rgb[i].rgbBlue == 0xFE) { rgb[i].rgbRed = 0xFF; rgb[i].rgbGreen = 0xFF; rgb[i].rgbRed = 0xFF; } } } */ PutColors(0, 256, rgb); SetAllToModified(); } else if (nBitsPerPixel == 16 || nBitsPerPixel == 24){ TUnionBitmap *tempUnionBitmap = new TUnionBitmap; if(!tempUnionBitmap->Create(FWidth, FHeight, FBitsPerPixel, Frgb))goto fail; tempUnionBitmap->ExactCopy(this); if(!this->Create(tempUnionBitmap->Width, tempUnionBitmap->Height, nBitsPerPixel, NULL)) goto fail; this->Copy(0, 0, tempUnionBitmap->Width, tempUnionBitmap->Height, tempUnionBitmap, 0, 0, SRCCOPY); if (tempUnionBitmap) { delete tempUnionBitmap; } FBitsPerPixel = nBitsPerPixel; return true; } return true; fail: if (tempBitmap) { if (dc) tempBitmap->DeleteDC(dc); delete tempBitmap; } return false; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::makeReservedPalette(RGBQUAD *rgb) { rgb[0].rgbRed = 0; rgb[0].rgbGreen = 0; rgb[0].rgbBlue = 0; rgb[0].rgbReserved = RGB_RESERVED; rgb[1].rgbRed = 0xFF; rgb[1].rgbGreen = 0xFF; rgb[1].rgbBlue = 0xFF; rgb[1].rgbReserved = RGB_RESERVED; for(int i = 2;i < 256;i++) { rgb[i].rgbReserved = RGB_EMPTY; } } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::Resize(int width, int height, COLORREF bg) { BITMAPHANDLE *regionHandle; RGBQUAD rgb[256]; RGNXFORM XForm; HRGN rgn, tempRgn; bool bRgn = false, rtn = true; // HDC dcSrc, dcDst; int i, j, zoomLevel; TUnionBitmap *tempBitmap; int oldHeight, oldWidth; if (width<=0 || height<=0) return false; if (FBitmap) { FBackgroundColor = bg; //add by celberus if (FWidth!=width || FHeight!=height) { if (FBitsPerPixel==8) GetColors(0, 256, rgb); if (FRgnBitmap) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; regionHandle = FRgnBitmap->Handle; if(L_BitmapHasRgn(regionHandle)) { L_GetBitmapRgnHandle(regionHandle, &XForm, &rgn); L_FreeBitmapRgn(regionHandle); bRgn = true; } } oldHeight = FHeight; oldWidth = FWidth; tempBitmap = new TUnionBitmap; if (FBitsPerPixel == 8) { if(!tempBitmap->Create(FWidth, FHeight, FBitsPerPixel, rgb)) { rtn = false; goto fail; } } else { if(!tempBitmap->Create(FWidth, FHeight, FBitsPerPixel)) { rtn = false; goto fail; } } tempBitmap->ExactCopy(this); // ÀÌ µÎ ¶óÀÎÀÌ »ó´çÈ÷ ºñÈ¿À²ÀûÀ̳ª ±¸ÇöÀÌ ¾î·Á(±ÍÂú?)¿ö¼­ ±×³É »ç¿ë ( resizeÇÒ ÀÏÀº ±×¸® ¸¹Áö ¾ÊÀ½) if(!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } if (FBitsPerPixel==8){ PutColors(0, 256, rgb); } // L_FillBitmap(&bh, bg); texpiabitmap -> unionbitmap conversion °úÁ¤¿¡¼­ À̺κР¹Ì±¸Çö celberus Copy(0, 0, min(oldWidth, width), min(oldHeight, height), tempBitmap, 0, 0, SRCCOPY); delete tempBitmap; if (bRgn) { tempRgn = CreateRectRgn(0, 0, FWidth, FHeight); CombineRgn(rgn, tempRgn, rgn, RGN_AND); regionHandle = FRgnBitmap->Handle; L_SetBitmapRgnHandle(regionHandle, &XForm, rgn, L_RGN_SET); DeleteObject(tempRgn); DeleteObject(rgn); } } } else { if(!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } } if(FBitsPerPixel == 24 && bg != 0x00FFFFFF) { for(i = 0;i < FCountY;i++) { for(j = 0;j < FCountX;j++) { if(btRect[0][i * FCountX + j].left >= oldWidth || btRect[0][i * FCountX + j].top >= oldHeight) { for(zoomLevel = 0;zoomLevel < FZoomCnt;zoomLevel++) { CheckLoad(i * FCountX + j, zoomLevel); Table[zoomLevel][i * FCountX + j].blank = false; } } } } } // FullColorÀÇ ¹ÙÅÁ»öÀÌ Èò»ö¾Æ´Ò¶§ Enlarge CanvasÇÒ¶§ »ö ä¿öÁöÁö ¾Ê´Â ¹®Á¦ ¶§¹®¿¡.. by celberus return true; fail: if (rtn) { // if (FOnPropertyChange) FOnPropertyChange(); resizestretch ¿¡¼­ ¿¡·¯³ª¼­ Ȥ½Ã³ª ÇØ¼­ ¸·À½ } return rtn; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ARResize(TUnionBitmap *pBitmap,int width, int height, COLORREF bg) { BITMAPHANDLE *regionHandle; RGBQUAD rgb[256]; RGNXFORM XForm; HRGN rgn, tempRgn; bool bRgn = false, rtn = true; // HDC dcSrc, dcDst; int i, j, zoomLevel; TUnionBitmap *tempBitmap = NULL; int oldHeight, oldWidth; if (width<=0 || height<=0) return false; //if (FBitmap) { if (pBitmap->Bitmap) { if(!Create(width, height, pBitmap->BitsPerPixel)) { rtn = false; goto fail; } //if (FWidth!=width || FHeight!=height) { if (pBitmap->Width!=width || pBitmap->Height!=height) { if (pBitmap->BitsPerPixel==8) pBitmap->GetColors(0, 256, rgb); if (pBitmap->RgnBitmap) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; regionHandle = pBitmap->RgnBitmap->Handle; if(L_BitmapHasRgn(regionHandle)) { L_GetBitmapRgnHandle(regionHandle, &XForm, &rgn); L_FreeBitmapRgn(regionHandle); bRgn = true; } } oldHeight = pBitmap->Height; oldWidth = pBitmap->Width; if(!Create(width, height, pBitmap->BitsPerPixel)) { rtn = false; goto fail; } FBackgroundColor = bg; if (pBitmap->BitsPerPixel==8){ PutColors(0, 256, rgb); } // L_FillBitmap(&bh, bg); texpiabitmap -> unionbitmap conversion °úÁ¤¿¡¼­ À̺κР¹Ì±¸Çö celberus Copy(0, 0, min(oldWidth, width), min(oldHeight, height), pBitmap, 0, 0, SRCCOPY); if (bRgn) { tempRgn = CreateRectRgn(0, 0, FWidth, FHeight); CombineRgn(rgn, tempRgn, rgn, RGN_AND); regionHandle = FRgnBitmap->Handle; L_SetBitmapRgnHandle(regionHandle, &XForm, rgn, L_RGN_SET); DeleteObject(tempRgn); DeleteObject(rgn); } }else{ oldHeight = pBitmap->Height; oldWidth = pBitmap->Width; if(!Create(width, height, pBitmap->BitsPerPixel)) { rtn = false; goto fail; } Copy(0, 0, min(oldWidth, width), min(oldHeight, height), pBitmap, 0, 0, SRCCOPY); } } else { if(!Create(width, height, pBitmap->BitsPerPixel)) { rtn = false; goto fail; } } if(pBitmap->BitsPerPixel == 24 && bg != 0x00FFFFFF) { for(i = 0;i < FCountY;i++) { for(j = 0;j < FCountX;j++) { if(btRect[0][i * FCountX + j].left >= oldWidth || btRect[0][i * FCountX + j].top >= oldHeight) { for(zoomLevel = 0;zoomLevel < FZoomCnt;zoomLevel++) { CheckLoad(i * FCountX + j, zoomLevel); Table[zoomLevel][i * FCountX + j].blank = false; } } } } } // FullColorÀÇ ¹ÙÅÁ»öÀÌ Èò»ö¾Æ´Ò¶§ Enlarge CanvasÇÒ¶§ »ö ä¿öÁöÁö ¾Ê´Â ¹®Á¦ ¶§¹®¿¡.. by celberus return true; fail: if (rtn) { // if (FOnPropertyChange) FOnPropertyChange(); resizestretch ¿¡¼­ ¿¡·¯³ª¼­ Ȥ½Ã³ª ÇØ¼­ ¸·À½ } return rtn; /* int nResult; BITMAPHANDLE *regionHandle; RGBQUAD rgb[256]; bool rtn = true; HDC dcSrc, dcDst; int i, j, zoomLevel; if (width<=0 || height<=0) return false; if(pBimtap->BitsPerPixel==8){ pBitmap->GetColor(rgb); if(!Create(width, height, FBitsPerPixel,rgb)) { rtn = false; goto fail; } }else{ if(!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } } return true; fail: if (rtn) { // if (FOnPropertyChange) FOnPropertyChange(); resizestretch ¿¡¼­ ¿¡·¯³ª¼­ Ȥ½Ã³ª ÇØ¼­ ¸·À½ } return rtn; */ } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ResizeStretch(int width, int height, bool resample) // by celberus { TUnionBitmap *tempBitmap = NULL; TTexpiaBitmap *tempTexpia = NULL; bool rtn = true; RGBQUAD rgb[256]; HRGN rgn; RGNXFORM XForm; BITMAPHANDLE *regionHandle; bool bRgn = false; int oldHeight, oldWidth; if (width == FWidth && height == FHeight) return true; if (width<=0 || height<=0) return false; if (FBitmap) { if (FWidth!=width || FHeight!=height) { if (FRgnBitmap) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; regionHandle = FRgnBitmap->Handle; if(L_BitmapHasRgn(regionHandle)) { L_GetBitmapRgnHandle(regionHandle, &XForm, &rgn); L_FreeBitmapRgn(regionHandle); bRgn = true; } } if (resample == false) { tempBitmap = new TUnionBitmap; oldWidth = FWidth; oldHeight = FHeight; if (FBitsPerPixel==8) { GetColors(0, 256, rgb); if(!tempBitmap->Create(width, height, FBitsPerPixel, rgb)) { rtn = false; goto fail; } } else { if(!tempBitmap->Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } } if(!tempBitmap->UnionStretchBlt(0, 0, width, height, this, 0, 0, FWidth, FHeight, SRCCOPY)) { rtn = false; goto fail; } if(!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } if (FBitsPerPixel==8) PutColors(0, 256, rgb); ExactCopy(tempBitmap); delete tempBitmap; tempBitmap = NULL; } else { // repro¿¡¼­ full color¶§ resample À» ÇÔ tempTexpia = new TTexpiaBitmap; oldWidth = FWidth; oldHeight = FHeight; if (FBitsPerPixel==8) { GetColors(0, 256, rgb); if(!tempTexpia->Create(oldWidth, oldHeight, FBitsPerPixel, rgb)) { rtn = false; goto fail; } } else { if(!tempTexpia->Create(oldWidth, oldHeight, FBitsPerPixel)) { rtn = false; goto fail; } } if (!this->CopyToTexpia(tempTexpia, 0, 0, oldWidth, oldHeight, 0, 0, SRCCOPY)) { rtn = false; goto fail; } if (!tempTexpia->ResizeStretch(width, height, resample)) {rtn = false; goto fail; } if (!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } if (FBitsPerPixel==8) PutColors(0, 256, rgb); this->Copy(tempTexpia, SRCCOPY); delete tempTexpia; tempTexpia = NULL; } if (bRgn) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = FWidth; XForm.nXScalarDen = oldWidth; XForm.nYScalarNum = FHeight; XForm.nYScalarDen = oldHeight; XForm.nXOffset = 0; XForm.nYOffset = 0; regionHandle = FRgnBitmap->Handle; L_SetBitmapRgnHandle(regionHandle, &XForm, rgn, L_RGN_SET); DeleteObject(rgn); } } } else { if(!Create(width, height, FBitsPerPixel)) { rtn = false; goto fail; } } fail: if (rtn) { // if (FOnPropertyChange) FOnPropertyChange(); ¿¡·¯³ª¼­ ¸·À½ } else { if (tempBitmap) delete tempBitmap; if (tempTexpia) delete tempTexpia; } return rtn; } //--------------------------------------------------------------------- TCanvas *__fastcall TUnionBitmap::CreateCanvas() { return NULL; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::DeleteCanvas(TCanvas *Canvas) { } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::GetColors(int nIndex, int nCount, RGBQUAD *pPalette) { if(Frgb) { for(int i = nIndex; i < nCount; i++ ) pPalette[i] = Frgb[i]; } else { int n; if (ActivateList[0]->Count > 0) n = ((TbmPoint *)ActivateList[0]->Items[0])->n; else n = 0; return FBitmap[0][n]->GetColors(nIndex, nCount, pPalette); } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutColors(int nIndex, int nCount, RGBQUAD *pPalette) { if(FBitmap) { // new ¸¸ Çϰí create ÇÏÁö ¾ÊÀº »óÅ¿¡¼­ color¸¦ changeÇÏ´Â °æ¿ì¶§¹®¿¡ ¼öÁ¤ ( style form ¿¡¼­ »ç¿ë ) for (int zoomLevel = 0; zoomLevel < FZoomCnt; zoomLevel++) { for (int i = 0; i < FCountX * FCountY; i++) { if(FBitmap[zoomLevel][i]->Handle) { FBitmap[zoomLevel][i]->PutColors(nIndex, nCount, pPalette); } } } // for(int i = nIndex; i < nCount; i++ ) // by celberus ÀÌ·² ¼ö ¹Û¿¡ ¾øÀ»±î.. // { if(!Frgb) { Frgb = new RGBQUAD[256]; } memcpy(&Frgb[nIndex], pPalette, nCount * sizeof(RGBQUAD)); // nCount ´Â ¹Ù²Ü °³¼ö°¡ ¾Æ´Ô.. leadtools °¡ À߸øµÆÀ½ // } } /* if(nIndex <= 1 && nCount >= 1) { FBackgroundColor = (pPalette[1].rgbBlue << 16) + (pPalette[1].rgbGreen << 8) + pPalette[1].rgbRed; } */ } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ConvertColorSpace(TColorSpace Value) // 3d ¿Í mainimage µî¿¡¼­ »ç¿ë { if (Value!=FColorSpace) { for (int num = 0; num < FCountX * FCountY; num++) { for (int zoomLevel = 0; zoomLevel < ZoomCnt; zoomLevel++ ) { CheckLoad(num, zoomLevel); FBitmap[zoomLevel][num]->ConvertColorSpace(Value); } } FColorSpace = Value; } return true; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::setColorSpace(TColorSpace Value) { for (int num = 0; num < FCountX * FCountY; num++) { for (int zoomLevel = 0; zoomLevel < ZoomCnt; zoomLevel++ ) { FBitmap[zoomLevel][num]->ColorSpace = Value; } } FColorSpace = Value; } //--------------------------------------------------------------------- COLORREF __fastcall TUnionBitmap::GetPixelColor(int X, int Y) { int n = getSegmentNumber(X, Y); if(Table[0][n].blank) { if(FBitsPerPixel == 8) { return FBackgroundColor % 256; } else { return FBackgroundColor; } } CheckLoad(n); X -= btRect[0][n].left; Y -= btRect[0][n].top; return FBitmap[0][n]->GetPixelColor(X , Y); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutPixelColor(int X, int Y, COLORREF Color) { int n = getSegmentNumber(X, Y); CheckLoad(n); X -= btRect[0][n].left; Y -= btRect[0][n].top; if (Table[0][n].undosave == false) PartialUndo->SaveUndo(n); //for Undo_Method by linuxjun FBitmap[0][n]->PutPixelColor(X, Y, Color); Table[0][n].modify = true; // by celberus Table[0][n].blank = false; // by celberus } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::Copy(TTexpiaBitmap *pBitmap, DWORD dwRop) { // by celberus HDC dcSrc = pBitmap->CreateDC(); if(dcSrc == NULL) return false; if(!UnionBitBlt(dcSrc, 0, 0, pBitmap->Width, pBitmap->Height, 0, 0, dwRop, true)) return false; pBitmap->DeleteDC(dcSrc); if(FColorSpace != pBitmap->ColorSpace) { //add by qe setColorSpace(pBitmap->ColorSpace); } return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::Copy(TUnionBitmap *pBitmap, DWORD dwRop) { bool bSucceed; for (int i = 0; i < FCountX * FCountY; i++) { if(pBitmap->Table[0][i].blank == true) { Table[0][i].blank = true; } else { CheckLoad(i); pBitmap->CheckLoad(i); // 03-02-19 by celberus bSucceed = FBitmap[0][i]->Copy(pBitmap->Bitmap[0][i], dwRop); if (bSucceed == false) return false; Table[0][i].modify = true; Table[0][i].blank = false; } } if(FColorSpace != pBitmap->ColorSpace) { setColorSpace(pBitmap->ColorSpace); } return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::Copy(int nXDst, int nYDst, int nWidth, int nHeight, TTexpiaBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop) // by celberus { HDC dcSrc = pBitmap->CreateDC(); if(dcSrc == NULL) return false; if(!UnionBitBlt(dcSrc, nXDst, nYDst, nWidth, nHeight, nXSrc, nYSrc, dwRop, true)) return false; pBitmap->DeleteDC(dcSrc); return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ZeroToZeroCopy(TUnionBitmap *srcBitmap, int Width, int Height, DWORD dwRop) { HDC dcDst = NULL, dcSrc = NULL; RECT rt, r; int i, j; int segCountX, segCountY, srcSegNumY, dstSegNumY; segCountX = getSegmentNumber(Width - 1, 0) + 1; segCountY = getSegmentNumber(0, Height - 1) / FCountX + 1; SetRect(&r, 0, 0, Width, Height); srcSegNumY = 0; dstSegNumY = 0; for (i = 0; i < segCountY; i++) { for (j = 0; j < segCountX; j++) { if (IntersectRect(&rt, &btRect[0][dstSegNumY + j], &r)) { CheckLoad(dstSegNumY + j); srcBitmap->CheckLoad(srcSegNumY + j); if((dcDst = FBitmap[0][dstSegNumY + j]->CreateDC()) == NULL) goto fail; if((dcSrc = srcBitmap->CreateDC(srcSegNumY + j)) == NULL) goto fail; BitBlt(dcDst, 0, 0, rt.right - rt.left, rt.bottom - rt.top, dcSrc, 0, 0, dwRop); FBitmap[0][dstSegNumY + j]->DeleteDC(dcDst); dcDst = NULL; srcBitmap->DeleteDC(dcSrc, srcSegNumY + j); dcSrc = NULL; Table[0][dstSegNumY + j].blank = false; Table[0][dstSegNumY + j].modify = true; } } dstSegNumY += FCountX; srcSegNumY += srcBitmap->CountX; } return true; fail: if(dcDst) FBitmap[0][dstSegNumY + j]->DeleteDC(dcDst);; if(dcSrc) srcBitmap->DeleteDC(dcSrc, srcSegNumY + j);; return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyUsingBitBlt(int nXDst, int nYDst, int nWidth, int nHeight, TUnionBitmap *pBitmap, DWORD dwRop, TStatusProgress *statusProgress) // copy using BitBlt by celberus ABCD { RECT copyRect, dstRect; SetRect(©Rect, nXDst, nYDst, nXDst + nWidth, nYDst + nHeight); int startDstNumX = getSegmentNumberX(nXDst); int startDstNumY = getSegmentNumberY(nYDst); int endDstNumX = getSegmentNumberX(nXDst + nWidth - 1); int endDstNumY = getSegmentNumberY(nYDst + nHeight - 1); int dstNum, srcNum; HDC dcDst = NULL, dcSrc = NULL; if(statusProgress) statusProgress->Maximum = (endDstNumY - startDstNumY + 1) * (endDstNumX - startDstNumX + 1); for ( int i = startDstNumY; i <= endDstNumY; i ++ ) { for ( int j = startDstNumX; j <= endDstNumX; j ++ ) { if(statusProgress) statusProgress->Position = (i - startDstNumY) * (j - startDstNumX); dstNum = i * FCountX + j; if (IntersectRect(&dstRect, &btRect[0][dstNum], ©Rect)) { srcNum = pBitmap->getSegmentNumber(btRect[0][dstNum].left, btRect[0][dstNum].top); CheckLoad(dstNum); dcDst = FBitmap[0][dstNum]->CreateDC(); pBitmap->CheckLoad(srcNum); dcSrc = pBitmap->CreateDC(srcNum); if (dcDst == NULL || dcSrc == NULL) goto fail; if (!BitBlt(dcDst, dstRect.left - btRect[0][dstNum].left, dstRect.top - btRect[0][dstNum].top, dstRect.right - dstRect.left, dstRect.bottom - dstRect.top, dcSrc, dstRect.left - btRect[0][dstNum].left, dstRect.top - btRect[0][dstNum].top, dwRop)) goto fail; FBitmap[0][dstNum]->DeleteDC(dcDst); dcDst = NULL; pBitmap->DeleteDC(dcSrc, srcNum); dcSrc = NULL; Table[0][dstNum].blank = false; Table[0][dstNum].modify = true; } } } if(statusProgress) statusProgress->End(); return true; fail: if (dcDst) FBitmap[0][dstNum]->DeleteDC(dcDst); if (dcSrc) pBitmap->DeleteDC(dcSrc, srcNum); if(statusProgress) statusProgress->End(); return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::Copy(int nXDst, int nYDst, int nWidth, int nHeight, TUnionBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop, TStatusProgress *statusProgress) // by celberus { RECT rectSrc, rectDst; Byte *pSrc, *pDst; if (nXSrc < 0) { nWidth += nXSrc; nXDst -= nXSrc; nXSrc = 0; } if (nYSrc < 0) { nHeight += nYSrc; nYDst -= nYSrc; nYSrc = 0; } if (nXDst < 0) { nWidth += nXDst; nXSrc -= nXDst; nXDst = 0; } if (nYDst < 0) { nHeight += nYDst; nYSrc -= nYDst; nYDst = 0; } int copyWidth = min(min(nWidth, FWidth - nXDst),pBitmap->Width - nXSrc); int copyHeight = min(min(nHeight, FHeight - nYDst),pBitmap->Height - nYSrc); int j; if (copyWidth <= 0 || copyHeight <= 0) return true; // if (nXDst == 0 && nYDst == 0 && nXSrc == 0 && nYSrc == 0) return ZeroToZeroCopy(pBitmap, copyWidth, copyHeight, dwRop); if (nXDst == nXSrc && nYDst == nYSrc) return CopyUsingBitBlt(nXDst, nYDst, nWidth, nHeight, pBitmap, dwRop, statusProgress); // µÎ ºñÆ®¸ÊÀÇ Á¶°¢ ±¸Á¶°¡ °°¾Æ¾ß µÈ´Ù. ABCD SetRect(&rectSrc, nXSrc, nYSrc, nXSrc + copyWidth, nYSrc + copyHeight); // rSrc Àº source ÀÇ copyÇÒ ¿µ¿ª SetRect(&rectDst, nXDst, nYDst, nXDst + copyWidth, nYDst + copyHeight); StartScanLine(); pBitmap->StartScanLine(); for(int i = 0; i < copyHeight; i ++ ) { pDst = GetScanLine(rectDst.top + i, rectDst.left, rectDst.right - rectDst.left); pSrc = pBitmap->GetScanLine(rectSrc.top + i, rectSrc.left, rectSrc.right - rectSrc.left); if(FBitsPerPixel == 8) { pDst += rectDst.left; pSrc += rectSrc.left; } else if(FBitsPerPixel == 24) { pDst += rectDst.left * 3; if(pBitmap->BitsPerPixel == 24) { pSrc += rectSrc.left * 3; } else if(pBitmap->BitsPerPixel == 8) { pSrc += rectSrc.left; } } if(dwRop == SRCCOPY) { if(FBitsPerPixel == 8) { memcpy(pDst, pSrc, copyWidth); } else if(FBitsPerPixel == 24 && pBitmap->BitsPerPixel == 8) { // ÀμâÇÒ ¶§ 8bpp¿¡¼­ 24bpp·Î º¹»çÇÏ´Â °ÍÀ» ±¸ÇöÇϱâ À§ÇØ Ãß°¡ by celberus for(j = 0; j < copyWidth; j ++ ) { memcpy(pDst, &pBitmap->RGB[*pSrc], 3); pDst+=3; pSrc++; } } else if(FBitsPerPixel == 24) { memcpy(pDst, pSrc, copyWidth * 3); } else if(FBitsPerPixel == 1 && pBitmap->BitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(pDst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } else { *(pDst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } } } } else if(dwRop == SRCPAINT) { if(FBitsPerPixel == 8) { for(j = 0; j < copyWidth; j ++ ) { *pDst |= *pSrc; pDst++; pSrc++; } } else if(FBitsPerPixel == 24) { for(j = 0; j < copyWidth; j ++ ) { *(pDst ) |= *(pSrc ); *(pDst + 1) |= *(pSrc + 1); *(pDst + 2) |= *(pSrc + 2); pDst+=3; pSrc+=3; } } else if(FBitsPerPixel == 1 && pBitmap->BitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(pDst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } else { continue; } } } } else if(dwRop == SRCAND) { if(FBitsPerPixel == 8) { for(j = 0; j < copyWidth; j ++ ) { *pDst &= *pSrc; pDst++; pSrc++; } } else if(FBitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { for(j = 0; j < copyWidth; j ++ ) { *(pDst ) &= *(pSrc ); *(pDst + 1) &= *(pSrc + 1); *(pDst + 2) &= *(pSrc + 2); pDst+=3; pSrc+=3; } } else if(pBitmap->BitsPerPixel == 1) { for(j = 0; j < copyWidth; j ++ ) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ ; } else { *(pDst ) = 0; *(pDst + 1) = 0; *(pDst + 2) = 0; } pDst+=3; } } } else if(FBitsPerPixel == 1 && pBitmap->BitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ continue; } else { *(pDst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } } } else if(FBitsPerPixel == 1 && pBitmap->BitsPerPixel == 8) { int mm=0x80; // int MP=0; for(int j = 0; j < copyWidth; j++) { mm=0x80; // MP=j; do{ if( ( *(pSrc + (nXSrc+j)) ) & mm ){ ; } else { *(pDst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } // if(mm == 1) // { // MP++; *MP = 0; mm = 0x80; // }else{ if(mm != 1) { mm >>= 1; } }while(mm != 1); } } } else if(dwRop == NOTSRCCOPY) { if(FBitsPerPixel == 8) { for(j = 0; j < copyWidth; j ++ ) { *pDst = 255 - *pSrc; pDst++; pSrc++; } } else if(FBitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { for(j = 0; j < copyWidth; j ++ ) { *(pDst ) = 255 - *(pSrc ); *(pDst + 1) = 255 - *(pSrc + 1); *(pDst + 2) = 255 - *(pSrc + 2); pDst+=3; pSrc+=3; } } else if(pBitmap->BitsPerPixel == 1) { for(j = 0; j < copyWidth; j ++ ) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(pDst ) = 0; *(pDst + 1) = 0; *(pDst + 2) = 0; } else { *(pDst ) = 255; *(pDst + 1) = 255; *(pDst + 2) = 255; } pDst+=3; } } } else if(FBitsPerPixel == 1 && pBitmap->BitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pSrc + ((nXSrc+j)>>3)) ) & (0x80 >> ((nXSrc+j)&7)) ){ *(pDst + ((nXDst+j)>>3)) &= ~(0x80 >> ((nXDst+j)&7)) ; } else { *(pDst + ((nXDst+j)>>3)) |= (0x80 >> ((nXDst+j)&7)) ; } } } } PutScanLine(rectDst.top + i, rectDst.left, rectDst.right - rectDst.left); } StopScanLine(); pBitmap->StopScanLine(); return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyToItself(int nXDst, int nYDst, int nWidth, int nHeight, int nXSrc, int nYSrc, DWORD dwRop) { RECT rSrc, rDst, rInter; Byte *pTempBuffer, *pScanBuffer; if(nXDst < 0) { nWidth += nXDst; nXSrc -= nXDst; nXDst = 0; } if(nXDst >= FWidth) { return true; } if(nYDst < 0) { nHeight += nYDst; nYSrc -= nYDst; nYDst = 0; } if(nYDst >= FHeight) { return true; } if(nXDst + nWidth > FWidth) nWidth = FWidth - nXDst; if(nYDst + nHeight > FHeight) nHeight = FHeight - nYDst; int SrcWidth = min(nWidth, Width - nXSrc), DstWidth = min(nWidth, Width - nXDst); int SrcHeight = min(nHeight, Height - nYSrc), DstHeight = min(nHeight, Height - nYDst); int copyWidth = min(SrcWidth, DstWidth), copyHeight = min(SrcHeight, DstHeight); SetRect(&rSrc, nXSrc, nYSrc, nXSrc + copyWidth, nYSrc + copyHeight); // rSrc Àº source ÀÇ copyÇÒ ¿µ¿ª SetRect(&rDst, nXDst, nYDst, nXDst + copyWidth, nYDst + copyHeight); if (dwRop == SRCCOPY) { if(!IntersectRect(&rInter, &rSrc, &rDst)) { StartScanLine(); pTempBuffer = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (copyWidth * FBitsPerPixel + 7) / 8); for(int i = 0; i < copyHeight; i ++ ) { pScanBuffer = GetScanLine(rSrc.top + i, rSrc.left, rSrc.right - rSrc.left); if(FBitsPerPixel == 8) memcpy(pTempBuffer, pScanBuffer + rSrc.left, copyWidth); else if(FBitsPerPixel == 24) memcpy(pTempBuffer, pScanBuffer + rSrc.left * 3, copyWidth * 3); else if(FBitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pScanBuffer + ((rSrc.left + j)>>3)) ) & (0x80 >> ((rSrc.left + j)&7)) ){ *(pTempBuffer + (j>>3)) |= (0x80 >> (j&7)) ; } else { *(pTempBuffer + (j>>3)) &= ~(0x80 >> (j&7)) ; } } } pScanBuffer = GetScanLine(rDst.top + i, rDst.left, rDst.right - rDst.left); if(FBitsPerPixel == 8) memcpy(pScanBuffer + rDst.left, pTempBuffer, copyWidth); else if(FBitsPerPixel == 24) memcpy(pScanBuffer + rDst.left * 3, pTempBuffer, copyWidth * 3); else if(FBitsPerPixel == 1) { for(int j = 0; j < copyWidth; j++) { if( ( *(pTempBuffer + (j>>3)) ) & (0x80 >> (j&7)) ){ *(pScanBuffer + ((rDst.left+j)>>3)) |= (0x80 >> ((rDst.left+j)&7)) ; } else { *(pScanBuffer + ((rDst.left+j)>>3)) &= ~(0x80 >> ((rDst.left+j)&7)) ; } } } PutScanLine(rDst.top + i, rDst.left, rDst.right - rDst.left); } // PutScanLineÀÌ copyWidthº¸´Ù ³ÐÀº ¹üÀ§¸¦ ÀúÀåÇÏ°Ô µÇ¹Ç·Î ´ë»ó À§Ä¡ÀÇ Á¤º¸¸¦ º¸Á¸Çϱâ À§ÇØ GetScanLineÀ» Çѹø ´õ ½ÇÇàÇÑ´Ù. // tempBuffer¸¦ »ç¿ëÇÏ´Â °Íµµ ±× ÀÌÀ¯ÀÌ´Ù. StopScanLine(); HeapFree(GetProcessHeap(), 0, pTempBuffer); } else { TUnionBitmap *tempBitmap = new TUnionBitmap; tempBitmap->Create(copyWidth, copyHeight, FBitsPerPixel, Frgb); tempBitmap->Copy(0, 0, copyWidth, copyHeight, this, rSrc.left, rSrc.top, SRCCOPY); this->Copy(rSrc.left, rSrc.top, copyWidth, copyHeight, tempBitmap, 0, 0, SRCCOPY); delete tempBitmap; } } return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyFromRect(TUnionBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop) { if(pBitmap->Width == FWidth && pBitmap->Height == FHeight && nXSrc == 0 && nYSrc == 0) { return ExactCopy(pBitmap); } else { return Copy(0, 0, FWidth, FHeight, pBitmap, nXSrc, nYSrc, dwRop); } } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyToRect(int nXDst, int nYDst, TUnionBitmap *pBitmap, DWORD dwRop) { return Copy(nXDst, nYDst, pBitmap->Width, pBitmap->Height, pBitmap, 0, 0, dwRop); } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ExactCopy(TUnionBitmap *pBitmap) { HDC dcDst = NULL, dcSrc = NULL; int n = 0, i, j; for(i = 0; i < FCountY; i ++ ) { for(j = 0; j < FCountX; j ++ ) { if(pBitmap->Table[0][n].blank){ if(pBitmap->BackgroundColor == FBackgroundColor) { Table[0][n].blank = true; } else { FillRect(btRect[0][n], pBitmap->BackgroundColor); Table[0][n].blank = false; Table[0][n].modify = true; } } else { pBitmap->CheckLoad(n); CheckLoad(n); dcDst = CreateDC(n, 0); dcSrc = pBitmap->CreateDC(n, 0); if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcSrc, 0, 0, SRCCOPY)) goto fail; DeleteDC(dcDst, n, 0); dcDst = NULL; pBitmap->DeleteDC(dcSrc, n, 0); dcSrc = NULL; Table[0][n].blank = false; Table[0][n].modify = true; } n++; } } return true; fail: if (dcDst) {DeleteDC(dcDst, n, 0); } if (dcSrc) {pBitmap->DeleteDC(dcSrc, n, 0); } return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ExactORCopy(TUnionBitmap *pBitmap) { HDC dcDst = NULL, dcSrc = NULL; int n = 0; for(int i = 0; i < FCountY; i ++ ) { for(int j = 0; j < FCountX; j ++ ) { if(FBitsPerPixel == 8&&pBitmap->BitsPerPixel == 8) { if(pBitmap->Table[0][n].blank) { if(pBitmap->BackgroundColor == 0) { n++; continue; } else if(pBitmap->BackgroundColor == PALETTEINDEX(255)) { if(FBackgroundColor == PALETTEINDEX(255)) { Table[0][n].blank = true; n++; continue; } } } } else if(FBitsPerPixel == 24&&pBitmap->BitsPerPixel == 24) { if(pBitmap->Table[0][n].blank) { if(pBitmap->BackgroundColor == 0) { n++; continue; } } } // not simple case (use bitblt) pBitmap->CheckLoad(n); CheckLoad(n); dcDst = CreateDC(n, 0); dcSrc = pBitmap->CreateDC(n, 0); if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcSrc, 0, 0, SRCPAINT)) goto fail; DeleteDC(dcDst, n, 0); dcDst = NULL; pBitmap->DeleteDC(dcSrc, n, 0); dcSrc = NULL; Table[0][n].blank = false; Table[0][n].modify = true; n++; } } return true; fail: if (dcDst) {DeleteDC(dcDst, n, 0); } if (dcSrc) {pBitmap->DeleteDC(dcSrc, n, 0); } return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ExactANDCopy(TUnionBitmap *pBitmap) { HDC dcDst = NULL, dcSrc = NULL; int n = 0; for(int i = 0; i < FCountY; i ++ ) { for(int j = 0; j < FCountX; j ++) { if(FBitsPerPixel == 8&&pBitmap->BitsPerPixel == 8) { if(pBitmap->Table[0][n].blank) { if(pBitmap->BackgroundColor == PALETTEINDEX(255)) { n++; continue; } else if(pBitmap->BackgroundColor == 0) { if(FBackgroundColor == 0) { Table[0][n].blank = true; n++; continue; } } } } else if(FBitsPerPixel == 24||FBitsPerPixel == 1) { if(pBitmap->Table[0][n].blank) { if(pBitmap->BackgroundColor == 0) { if(FBackgroundColor == 0) { Table[0][n].blank = true; n++; continue; } } } } // not simple case (use bitblt) pBitmap->CheckLoad(n); CheckLoad(n); dcDst = CreateDC(n, 0); dcSrc = pBitmap->CreateDC(n, 0); if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcSrc, 0, 0, SRCAND)) goto fail; DeleteDC(dcDst, n, 0); dcDst = NULL; pBitmap->DeleteDC(dcSrc, n, 0); dcSrc = NULL; Table[0][n].blank = false; Table[0][n].modify = true; n++; } } return true; fail: if (dcDst) {DeleteDC(dcDst, n, 0); } if (dcSrc) {pBitmap->DeleteDC(dcSrc, n, 0); } return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::ExactNOTCopy(TUnionBitmap *pBitmap) { HDC dcDst = NULL, dcSrc = NULL; int n = 0; for(int i = 0; i < FCountY; i ++ ) { for(int j = 0; j < FCountX; j ++ ) { if(FBitsPerPixel == 8&&pBitmap->BitsPerPixel == 8) { if(pBitmap->Table[0][n].blank) { if(pBitmap->BackgroundColor == 0) { if(FBackgroundColor == PALETTEINDEX(255)) { Table[0][n].blank = true; n++; continue; } } else if(pBitmap->BackgroundColor == PALETTEINDEX(255)) { if(FBackgroundColor == 0) { Table[0][n].blank = true; n++; continue; } } } } // not simple case (use bitblt) pBitmap->CheckLoad(n); CheckLoad(n); dcDst = CreateDC(n, 0); dcSrc = pBitmap->CreateDC(n, 0); if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcSrc, 0, 0, NOTSRCCOPY)) goto fail; DeleteDC(dcDst, n, 0); dcDst = NULL; pBitmap->DeleteDC(dcSrc, n, 0); dcSrc = NULL; Table[0][n].blank = false; Table[0][n].modify = true; n++; } } return true; fail: if (dcDst) {DeleteDC(dcDst, n, 0); } if (dcSrc) {pBitmap->DeleteDC(dcSrc, n, 0); } return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::MergeBitmap(TUnionBitmap *SrcBitmap, TUnionBitmap *SrcMask) { HDC dcDst = NULL, dcSrc = NULL, dcMask = NULL, dcTemp = NULL; int n = 0; TTexpiaBitmap *tempBitmap; int tempWidth = getLongestWidth(); int tempHeight = getLongestHeight(); tempBitmap = new TTexpiaBitmap; if(!tempBitmap->Create(tempWidth, tempHeight, FBitsPerPixel, Frgb)) goto fail; dcTemp = tempBitmap->CreateDC(); for(int i = 0; i < FCountY; i ++ ) { for(int j = 0; j < FCountX; j ++ ) { if(!SrcBitmap->Table[0][n].blank){ SrcBitmap->CheckLoad(n); SrcMask->CheckLoad(n); CheckLoad(n); dcDst = CreateDC(n, 0); dcSrc = SrcBitmap->CreateDC(n, 0); dcMask = SrcMask->CreateDC(n, 0); if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcMask, 0, 0, SRCAND)) goto fail; if (!BitBlt(dcTemp, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcMask, 0, 0, NOTSRCCOPY)) goto fail; if (!BitBlt(dcTemp, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcSrc, 0, 0, SRCAND)) goto fail; if (!BitBlt(dcDst, 0, 0, btRect[0][n].right - btRect[0][n].left, btRect[0][n].bottom - btRect[0][n].top, dcTemp, 0, 0, SRCPAINT)) goto fail; DeleteDC(dcDst, n, 0); dcDst = NULL; SrcBitmap->DeleteDC(dcSrc, n, 0); dcSrc = NULL; SrcMask->DeleteDC(dcMask, n, 0); dcMask = NULL; Table[0][n].blank = false; Table[0][n].modify = true; } n++; } } tempBitmap->DeleteDC(dcTemp); delete tempBitmap; return true; fail: if(dcDst) DeleteDC(dcDst, n, 0); if(dcSrc) SrcBitmap->DeleteDC(dcSrc, n, 0); if(dcMask) SrcMask->DeleteDC(dcMask, n, 0); if(tempBitmap) { if(dcTemp) tempBitmap->DeleteDC(dcTemp); delete tempBitmap; } return false; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::getLongestWidth() { return btRect[0][0].right - btRect[0][0].left; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::getLongestHeight() { return btRect[0][0].bottom - btRect[0][0].top; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyFromRect(TTexpiaBitmap *pBitmap, int nXSrc, int nYSrc, DWORD dwRop) // by celberus { HDC dcSrc = pBitmap->CreateDC(); if(dcSrc == NULL) return false; if(!UnionBitBlt(dcSrc, 0, 0, FWidth, FHeight, nXSrc, nYSrc, dwRop, true)) return false; pBitmap->DeleteDC(dcSrc); return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyToRect(int nXDst, int nYDst, TTexpiaBitmap *pBitmap, DWORD dwRop) { HDC dcSrc = pBitmap->CreateDC(); if(dcSrc == NULL) return false; if(!UnionBitBlt(dcSrc, nXDst, nYDst, pBitmap->Width, pBitmap->Height, 0, 0, dwRop, true)) return false; pBitmap->DeleteDC(dcSrc); return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyToTexpia(TTexpiaBitmap *pBitmap, int nXDst, int nYDst, int nWidth, int nHeight, int nXSrc, int nYSrc, DWORD dwRop) { HDC dcDst = pBitmap->CreateDC(); if(dcDst == NULL) return false; if(!UnionBitBlt(dcDst, nXDst, nYDst, nWidth, nHeight, nXSrc, nYSrc, dwRop, false)) return false; pBitmap->DeleteDC(dcDst); return true; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::LoadFromMemory(BYTE *mp, int bpl, bool down) { // by celberus scratch¿¡¼­ »ç¿ë int y; int i, k1, k2, length; // if (FBitsPerPixel == 24) length = bpl * 3; // else if (FBitsPerPixel == 8) length = bpl; if (down) { y = FHeight-1; } else { y = 0; } while(true) { k1 = getSegmentNumber( 0, y ); k2 = getSegmentNumber( FWidth - 1, y ); length = bpl; for( i = k1; i <= k2; i ++ ) { checkActivePart(i); if( i != k2 ) { L_PutBitmapRow(FBitmap[0][i]->Handle, mp + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); length -= FBitmap[0][i]->Handle->BytesPerLine; } else { L_PutBitmapRow(FBitmap[0][i]->Handle, mp + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , length); } Table[0][i].blank = false; Table[0][i].modify = true; } mp += bpl; if (down) { y--; if(y < 0) break; } else { y++; if(y >= FHeight) break; } } releaseActivePart(0); } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::LoadFromMemory(BYTE *mp, int bpl, RECT r) { // by celberus smooth µî¿¡¼­ »ç¿ë // BYTE *buf = NULL; int y, length = r.right-r.left, startPos = r.left; switch (FBitsPerPixel) { case 1: length = (length+7)/8; startPos /= 8; break; case 16: length *= 2; startPos *= 2; break; case 24: length *= 3; startPos *= 3; break; } if(!StartScanLine()) return false; for (y=r.top; yCreateDC(); BitBlt(dcDst, rt.left - btRect[0][i].left, rt.top - btRect[0][i].top, rt.right - rt.left, rt.bottom - rt.top, dc, nXSrc - nXDst + rt.left, nYSrc - nYDst + rt.top, dwRop); FBitmap[0][i]->DeleteDC(dcDst); dcDst = NULL; Table[0][i].blank = false; Table[0][i].modify = true; } } } else { //UnionBitmapÀÌ Src. for (i = 0; i < FCountX * FCountY; i++) { SetRect(&r, nXSrc, nYSrc, nXSrc + w, nYSrc + h); if (IntersectRect(&rt, &btRect[0][i], &r)) { CheckLoad(i); dcSrc = FBitmap[0][i]->CreateDC(); BitBlt(dc, nXDst + (rt.left - nXSrc), nYDst + (rt.top - nYSrc), rt.right - rt.left, rt.bottom - rt.top, dcSrc, rt.left - btRect[0][i].left, rt.top - btRect[0][i].top, dwRop); FBitmap[0][i]->DeleteDC(dcDst); dcDst = NULL; } } } return true; }*/ //--------------------------------------------------------------------- void __fastcall TUnionBitmap::ReverseBitmap_8Bit(){ // L_INT result; Byte *src,*dst; StartScanLineN(2); for(int y=0;yCreate(FileInfo.Width, FileInfo.Height, FileInfo.BitsPerPixel, TYPE_DISK)) goto fail; Temp->LoadFromFile(fn, true); if (FileInfo.BitsPerPixel == 8){ Temp->GetColors(0, 256, rgb); PutColors(0, 256, rgb); } if (!Copy(0, 0, FileInfo.Width, FileInfo.Height, Temp, 0, 0, SRCCOPY)) goto fail; delete Temp; } else if (FileInfo.Format == FILE_BMP) { for (int i = 0; i < FCountX * FCountY; i++) { Rearrange(i); Table[0][i].blank = false; if (FBitmap[0][i]->LoadFromFileTile(fn, FileInfo, btRect[0][i].left, btRect[0][i].top, btRect[0][i].right - btRect[0][i].left, btRect[0][i].bottom - btRect[0][i].top) == false) goto fail; } } else { n = 1; while (n) { n = ReDevideLoadFromFile(fn, n); } } return true; fail: return false; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::ReDevideLoadFromFile(AnsiString fn, int n) { int w, h, row, col, i, j; FILEINFO FileInfo; TTexpiaBitmap *Temp = new TTexpiaBitmap; L_FileInfo(fn.c_str(), &FileInfo, 0, NULL); w = FileInfo.Width; h = FileInfo.Height; row = 1; col = 1; for (i = 1; i < n; i *= 2) { if (w > h) { w /= 2; row *= 2; } else { h /= 2; col *= 2; } } for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (!Temp->Create(w, h, FileInfo.BitsPerPixel, TYPE_DISK)) goto fail; if (!Temp->LoadFromFileTile(fn, FileInfo, i*w, j*h, w, h)) goto fail; if (!Copy(i*w, j*h, w, h, Temp, 0, 0, SRCCOPY)) goto fail; } } delete Temp; return 0; //SUCCESS! fail: if (Temp) delete Temp; return (n*2); } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::LoadFromTexpiaFile(HANDLE fh, TCompressMethod cm, TStatusProgress* statusProgress) { int i; DWORD dwRead; int length, zoomCnt; bool *blank; TPoint p; //TUnionBitmap *temp; if (!ReadFile(fh, &length, sizeof(int), &dwRead, NULL)) return false; if (!ReadFile(fh, &zoomCnt, sizeof(int), &dwRead, NULL)) return false; p = CalculateFCount(); blank = new bool[p.x * p.y]; for (i = 0; i < p.x * p.y; i++) if (!ReadFile(fh, &blank[i], sizeof(bool), &dwRead, NULL)) return false; if (length == LENGTH && zoomCnt == FZoomCnt) { if(statusProgress) statusProgress->Maximum = FZoomCnt * FCountX * FCountY - 1; for (int k = 0; k < FZoomCnt; k++) { for (int i = 0; i < FCountX * FCountY; i++) { if (blank[i] == false) { CheckLoad(i, k); FBitmap[k][i]->LoadFromTexpiaFile(fh, cm); //CopyToTempFile(fh, i, k); Table[k][i].blank = false; // 0 -> k by celberus } else { Table[k][i].blank = true; // 0 -> k by celberus } if(statusProgress) statusProgress->Position = k * FCountX * FCountY + i; } } if(statusProgress) statusProgress->End(); } else { //³ªÁß¿¡ ¿©±â´Ù ¸¸µé ÇÊ¿äÀÖÀ¸¸é ¸¸µå¼¼¿ë~ /*temp = new TUnionBitmap; temp->LENGTH = length; temp->FZoomCnt = zoomCnt; temp->Create(FWidth, FHeight, FBitsPerPixel, Frgb); */ } delete[] blank; return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyToTempFile(HANDLE fh, int n, int k) { BYTE *pMem = NULL; DWORD dwWrite; DWORD len; len = Table[k][n].size; Table[0][n].blank = false; // qe ³ªÁß¿¡ À̰ªÀ» loadÇØ¾ß ÇϰÚÁö. if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len))==NULL) goto fail; if (!TPUncompress(fh, pMem, len, cmZLib)) goto fail; MoveFilePointer(n, k); if (!WriteFile(hTempFile, pMem, len, &dwWrite, NULL)) goto fail; HeapFree(GetProcessHeap(), 0, pMem); return true; fail: if (pMem) HeapFree(GetProcessHeap(), 0, pMem); return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::SaveToTexpiaFile(HANDLE fh, TCompressMethod cm, bool oldfile, TStatusProgress *statusProgress) { if (oldfile) { //ÀÌÀü ¹öÀüÀ¸·Î ÀúÀåÇϱâ À§ÇÑ ºÎºÐ... TTexpiaBitmap *temp = new TTexpiaBitmap; HDC dcTmp = NULL; if (!temp->Create(FWidth, FHeight, FBitsPerPixel)) return false; if (BitsPerPixel == 8) temp->PutColors(0, 256, Frgb); if ((dcTmp = temp->CreateDC()) == NULL) return false; if (!UnionBitBlt(dcTmp, 0, 0, FWidth, FHeight, 0, 0, SRCCOPY, false)) return false; temp->DeleteDC(dcTmp); dcTmp = NULL; if (temp->SaveToTexpiaFile(fh, cm) == false) return false; delete temp; return true; } int i, k; DWORD dwWrite; if (!WriteFile(fh, &LENGTH, sizeof(int), &dwWrite, NULL)) return false; if (!WriteFile(fh, &FZoomCnt, sizeof(int), &dwWrite, NULL)) return false; for (i = 0; i < FCountX * FCountY; i++) if (!WriteFile(fh, &Table[0][i].blank, sizeof(bool), &dwWrite, NULL)) return false; if(statusProgress) statusProgress->Maximum = FZoomCnt * FCountX * FCountY - 1; for (k = 0; k < FZoomCnt; k++) { for (i = 0; i < FCountX * FCountY; i++) { if (Table[0][i].blank == false) { CheckLoad(i, k); if (k != 0) CheckUpdate(i, k); if (FBitmap[k][i]->SaveToTexpiaFile(fh, cm) == false) return false; } if(statusProgress) statusProgress->Position = k * FCountX * FCountY + i; } } if(statusProgress) statusProgress->End(); return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::SaveToTexpiaFile(HANDLE fh, RECT r, TCompressMethod cm, bool oldfile, TStatusProgress *statusProgress) { // by celberus TUnionBitmap *tempBitmap = new TUnionBitmap; if((tempBitmap->Create(r.right - r.left, r.bottom - r.top, FBitsPerPixel, Frgb)) == NULL) goto fail; if(!tempBitmap->Copy(0, 0, r.right - r.left, r.bottom - r.top, this, r.left, r.top, SRCCOPY)) goto fail; if(!tempBitmap->SaveToTexpiaFile(fh, cm, oldfile))goto fail; if(tempBitmap) delete tempBitmap; return true; fail: if(tempBitmap) delete tempBitmap; return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::CopyFromTempFile(HANDLE fh, int n, int k) { BYTE *pMem = NULL; DWORD dwRead; DWORD len; AnsiString fn; len = Table[k][n].size; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len))==NULL) goto fail; MoveFilePointer(n, k); if (!ReadFile(hTempFile, pMem, len, &dwRead, NULL)) goto fail; if (!TPCompress(fh, pMem, len, cmZLib)) goto fail; HeapFree(GetProcessHeap(), 0, pMem); return true; fail: if (pMem) HeapFree(GetProcessHeap(), 0, pMem); return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::UnionStretchBlt(int DstX, int DstY, int DstW, int DstH, TUnionBitmap *pBitmap, int SrcX, int SrcY,int SrcW, int SrcH, DWORD dwRop) { // pBitmapÀÌ source int *SrcRowValue, *SrcColInterval, oldX, newX, newY; Byte *pDstLine, *pSrcLine; // float ratioWidth, ratioHeight; // ratioWidth = (float)DstW / SrcW; // ratioHeight = (float)DstH / SrcH; int columnIndex = 0; // for 1 bpp SrcColInterval = new int[DstW]; SrcRowValue = new int[DstH]; oldX = SrcX; for(int i = 1; i <= DstW; i++) { newX = SrcX + (float)i * SrcW / DstW; // destinationÀÇ °¢ x°ª¿¡ ´ëÀÀÇÏ´Â sourceÀÇ x°ª °è»ê if(pBitmap->BitsPerPixel == 8 || pBitmap->BitsPerPixel == 1) { SrcColInterval[i-1] = newX - oldX; // iteration¿¡ ÇÊ¿äÇÑ x¹æÇâÀÇ interval °è»ê } else if(pBitmap->BitsPerPixel == 24) { SrcColInterval[i-1] = (newX - oldX) * 3; } oldX = newX; //colInterval¿¡¼­ °¢ ´Ü°èÀÇ °£°Ý°ªÀ» ÁÖ±âÀ§ÇØ } for(int i = 0; i < DstH; i++) { newY = SrcY + (float)i * SrcH / DstH; // destinationÀÇ °¢ y°ª¿¡ ´ëÀÀÇÏ´Â sourceÀÇ y°ª °è»ê SrcRowValue[i] = newY; // scanline ¿¡¼­´Â yÁÂÇ¥¸¦ Á÷Á¢ »ç¿ëÇϹǷΠvalue¸¦ °è»ê } if(!StartScanLine()) goto fail; if(!pBitmap->StartScanLine()) goto fail; if(dwRop == SRCCOPY) { for(int i = 0; i < DstH; i++) { pDstLine = GetScanLine(DstY + i, DstX, DstW); pSrcLine = pBitmap->GetScanLine(SrcRowValue[i], SrcX, SrcW); if(BitsPerPixel == 8) { // SrcX ÁÂÇ¥·Î À̵¿ pSrcLine += SrcX; pDstLine += DstX; } else if(BitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { pSrcLine += SrcX * 3; } pDstLine += DstX * 3; } columnIndex = 0; for(int j = 0; j < DstW; j++) { if(BitsPerPixel == 8) { *pDstLine = *pSrcLine; pDstLine++; } else if(BitsPerPixel == 24) { memcpy(pDstLine, pSrcLine, 3); pDstLine += 3; } else if(BitsPerPixel == 1) { if( ( *(pSrcLine + ((SrcX + columnIndex)>>3)) ) & (0x80 >> ((SrcX + columnIndex)&7)) ){ *(pDstLine + ((DstX + j)>>3)) |= (0x80 >> ((DstX + j)&7)) ; } else { *(pDstLine + ((DstX + j)>>3)) &= ~(0x80 >> ((DstX + j)&7)) ; } columnIndex += SrcColInterval[j]; } if(pBitmap->BitsPerPixel != 1) { pSrcLine += SrcColInterval[j]; } } PutScanLine(DstY + i, DstX, DstW); } } else if(dwRop == SRCAND) { for(int i = 0; i < DstH; i++) { pDstLine = GetScanLine(DstY + i, DstX, DstW); pSrcLine = pBitmap->GetScanLine(SrcRowValue[i], SrcX, SrcW); if(BitsPerPixel == 8) { // SrcX ÁÂÇ¥·Î À̵¿ pSrcLine += SrcX; pDstLine += DstX; } else if(BitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { pSrcLine += SrcX * 3; } pDstLine += DstX * 3; } columnIndex = 0; for(int j = 0; j < DstW; j++) { if(BitsPerPixel == 8) { *pDstLine &= *pSrcLine; pDstLine++; } else if(BitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { *pDstLine &= *pSrcLine; *(pDstLine + 1) &= *(pSrcLine + 1); *(pDstLine + 2) &= *(pSrcLine + 2); pDstLine += 3; } else if(pBitmap->BitsPerPixel == 1) { if( ( *(pSrcLine + ((SrcX + columnIndex)>>3)) ) & (0x80 >> ((SrcX + columnIndex)&7)) ){ ; } else { // memset(pDstLine, 0, 3); *pDstLine = 0; *(pDstLine + 1) = 0; *(pDstLine + 2) = 0; } pDstLine += 3; columnIndex += SrcColInterval[j]; } } else if(BitsPerPixel == 1) { if( ( *(pSrcLine + ((SrcX + columnIndex)>>3)) ) & (0x80 >> ((SrcX + columnIndex)&7)) ){ ; } else { *(pDstLine + ((DstX + j)>>3)) &= ~(0x80 >> ((DstX + j)&7)) ; } columnIndex += SrcColInterval[j]; } if(pBitmap->BitsPerPixel != 1) { pSrcLine += SrcColInterval[j]; } } PutScanLine(DstY + i, DstX, DstW); } } else if(dwRop == SRCPAINT) { for(int i = 0; i < DstH; i++) { pDstLine = GetScanLine(DstY + i, DstX, DstW); pSrcLine = pBitmap->GetScanLine(SrcRowValue[i], SrcX, SrcW); if(BitsPerPixel == 8) { // SrcX ÁÂÇ¥·Î À̵¿ pSrcLine += SrcX; pDstLine += DstX; } else if(BitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { pSrcLine += SrcX * 3; } pDstLine += DstX * 3; } columnIndex = 0; for(int j = 0; j < DstW; j++) { if(BitsPerPixel == 8) { *pDstLine |= *pSrcLine; pDstLine++; } else if(BitsPerPixel == 24) { *pDstLine |= *pSrcLine; *(pDstLine + 1) |= *(pSrcLine + 1); *(pDstLine + 2) |= *(pSrcLine + 2); pDstLine += 3; } else if(BitsPerPixel == 1) { if( ( *(pSrcLine + ((SrcX + columnIndex)>>3)) ) & (0x80 >> ((SrcX + columnIndex)&7)) ){ *(pDstLine + ((DstX + j)>>3)) |= ~(0x80 >> ((DstX + j)&7)) ; } else { ; } columnIndex += SrcColInterval[j]; } if(BitsPerPixel != 1) { pSrcLine += SrcColInterval[j]; } } PutScanLine(DstY + i, DstX, DstW); } } else if(dwRop == NOTSRCCOPY) { for(int i = 0; i < DstH; i++) { pDstLine = GetScanLine(DstY + i, DstX, DstW); pSrcLine = pBitmap->GetScanLine(SrcRowValue[i], SrcX, SrcW); if(BitsPerPixel == 8) { // SrcX ÁÂÇ¥·Î À̵¿ pSrcLine += SrcX; pDstLine += DstX; } else if(BitsPerPixel == 24) { if(pBitmap->BitsPerPixel == 24) { pSrcLine += SrcX * 3; } pDstLine += DstX * 3; } columnIndex = 0; for(int j = 0; j < DstW; j++) { if(BitsPerPixel == 8) { *pDstLine = 255 - *pSrcLine; pDstLine++; } else if(BitsPerPixel == 24) { *pDstLine = 255 - *pSrcLine; *(pDstLine + 1) = 255 - *(pSrcLine + 1); *(pDstLine + 2) = 255 - *(pSrcLine + 2); pDstLine += 3; } else if(BitsPerPixel == 1) { if( ( *(pSrcLine + ((SrcX + columnIndex)>>3)) ) & (0x80 >> ((SrcX + columnIndex)&7)) ){ *(pDstLine + ((DstX + j)>>3)) &= ~(0x80 >> ((DstX + j)&7)) ; } else { *(pDstLine + ((DstX + j)>>3)) |= (0x80 >> ((DstX + j)&7)) ; } columnIndex += SrcColInterval[j]; } if(BitsPerPixel != 1) { pSrcLine += SrcColInterval[j]; } } PutScanLine(DstY + i, DstX, DstW); } } delete[] SrcRowValue; delete[] SrcColInterval; StopScanLine(); pBitmap->StopScanLine(); return true; fail: StopScanLine(); pBitmap->StopScanLine(); return false; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::UnionStretchBlt(HDC dcDst, int DstX, int DstY, int DstWidth, int DstHeight, int SrcX, int SrcY,int SrcWidth, int SrcHeight, DWORD dwRop) { RECT dstRect, SegmentRect, SourceRect; int SrcSegmentNumber; bool bSucceed; if(SrcWidth == 0 || SrcHeight == 0 || DstWidth == 0 || DstHeight == 0) return true; int startSegmentX = getSegmentNumberX(SrcX); int startSegmentY = getSegmentNumberY(SrcY); int endSegmentX = getSegmentNumberX(SrcX + SrcWidth - 1); int endSegmentY = getSegmentNumberY(SrcY + SrcHeight - 1); double ratioX = (double)DstWidth / SrcWidth; double ratioY = (double)DstHeight / SrcHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(SrcX, SrcY, SrcX + SrcWidth, SrcY + SrcHeight); SetStretchBltMode(dcDst, COLORONCOLOR); for (int j = startSegmentY; j <= endSegmentY; j++) { for (int i = startSegmentX; i <= endSegmentX; i++) { SrcSegmentNumber = j * FCountX + i; dstRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ bSucceed = segmentStretchBlt(dcDst, dstRect, SegmentRect, SrcSegmentNumber, zoomLevel, DstX, DstY, SrcX, SrcY, ratioX, ratioY, dStretchRatio, dwRop); if (bSucceed == false) { return false; } } } return true; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::getZoomLevel(double ratioX, double ratioY) { int result; double dZoomRatio = min(ratioX, ratioY); if (dZoomRatio > 0.5) result = 0; else if (dZoomRatio > 0.25) result = 1; else if (dZoomRatio > 0.125) result = 2; else result = 3; if(result >= ZoomCnt) // zoom outµÈ À̹ÌÁö¸¦ ÀüºÎ °¡ÁöÁö ¾ÊÀ»¼öµµ ÀÖ´Ù. result = ZoomCnt - 1; return result; } //--------------------------------------------------------------------- double __fastcall TUnionBitmap::getStretchRatio(int zoomLevel) { double dDrawRatio[4] = { 1, 0.5, 0.25, 0.125 }; // zoom out image¿¡ µû¸¥ source bitmapÀÇ º¸Á¤ºñÀ² return dDrawRatio[zoomLevel]; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::segmentStretchBlt(HDC dcDst, RECT dstRect, RECT srcRect, int segmentNumber, int zoomLevel, int dstX, int dstY, int srcX, int srcY, double ratioX, double ratioY, double dStretchRatio, DWORD dwRop) { HDC dcSrc = CreateDC(segmentNumber, zoomLevel); if(!StretchBlt(dcDst, dstX + (int)(dstRect.left * ratioX + 0.5) - (int)(srcX * ratioX + 0.5), dstY + (int)(dstRect.top * ratioY + 0.5) - (int)(srcY * ratioY + 0.5), (int)(dstRect.right * ratioX + 0.5) - (int)(dstRect.left * ratioX + 0.5), (int)(dstRect.bottom * ratioY + 0.5) - (int)(dstRect.top * ratioY + 0.5), dcSrc, srcRect.left * dStretchRatio, srcRect.top * dStretchRatio, max(1.0, (srcRect.right - srcRect.left) * dStretchRatio), // 0ÀÌ µÉ¼öµµ ÀÖ´Ù max(1.0, (srcRect.bottom - srcRect.top) * dStretchRatio), dwRop) ) { DeleteDC(dcSrc, segmentNumber, zoomLevel); dcSrc = NULL; return false; } DeleteDC(dcSrc, segmentNumber, zoomLevel); dcSrc = NULL; return true; } // °è»ê»óÀÇ ¹ö±× ¾øÀ½ //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::segmentIgnoredStretchBlt(HDC dcDst, RECT dstRect, RECT srcRect, int segmentNumber, int zoomLevel, int dstX, int dstY, int srcX, int srcY, double ratioX, double ratioY, double dStretchRatio, DWORD dwRop) { HDC dcSrc = CreateIgnoredDC(segmentNumber, zoomLevel); if(!StretchBlt(dcDst, dstX + (int)(dstRect.left * ratioX + 0.5) - (int)(srcX * ratioX + 0.5), dstY + (int)(dstRect.top * ratioY + 0.5) - (int)(srcY * ratioY + 0.5), (int)(dstRect.right * ratioX + 0.5) - (int)(dstRect.left * ratioX + 0.5), (int)(dstRect.bottom * ratioY + 0.5) - (int)(dstRect.top * ratioY + 0.5), dcSrc, srcRect.left * dStretchRatio, srcRect.top * dStretchRatio, max(1.0, (srcRect.right - srcRect.left) * dStretchRatio), // 0ÀÌ µÉ¼öµµ ÀÖ´Ù max(1.0, (srcRect.bottom - srcRect.top) * dStretchRatio), dwRop) ) { DeleteDC(dcSrc, segmentNumber, zoomLevel); dcSrc = NULL; return false; } DeleteDC(dcSrc, segmentNumber, zoomLevel); dcSrc = NULL; return true; } // °è»ê»óÀÇ ¹ö±× ¾øÀ½ //--------------------------------------------------------------------- int __fastcall TUnionBitmap::FullViewUpdate(HDC dcFullView, int ViewWidth, int ViewHeight, bool isUpdateAll, TUnionBitmap *modifiedBitmap) { if(FWidth == 0 || FHeight == 0) return 0; RECT ViewRect, SegmentRect, SourceRect; // HDC dcSrc = NULL; int SrcSegmentNumber; bool anyUpdated; double ratioX = (double)ViewWidth / FWidth; double ratioY = (double)ViewHeight / FHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(0, 0, FWidth, FHeight); HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcFullView, hBrush); hOldPen = SelectObject(dcFullView, hPen); SetStretchBltMode(dcFullView, COLORONCOLOR); for (int j = 0; j < FCountY; j++) { for (int i = 0; i < FCountX; i++) { SrcSegmentNumber = j * FCountX + i; modifiedBitmap->CheckUpdate(SrcSegmentNumber, ZoomCnt - 1); ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(isUpdateAll || modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { if(Table[0][SrcSegmentNumber].blank){ // 256 color¿¡¼­ backgroung°¡ °ËÁ¤»ö ÀÌ¸é µ¥ÀÌŸ°¡ 1·Î ä¿öÁö´Â°Ô ¾Æ´Ï¶ó 0À¸·Î ä¿öÁü Rectangle(dcFullView, ViewRect.left * ratioX + 0.5, ViewRect.top * ratioY + 0.5, ViewRect.right * ratioX + 0.5, ViewRect.bottom * ratioY + 0.5); continue; } if(!segmentStretchBlt(dcFullView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, SRCCOPY)) { SelectObject(dcFullView, hOldBrush); SelectObject(dcFullView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); return -1; } anyUpdated = true; } } } SelectObject(dcFullView, hOldBrush); SelectObject(dcFullView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); #ifdef SPDTESTT swapInCounter->reportOut(); swapOutCounter->reportOut(); #endif if(anyUpdated)return 1; else return 0; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::FullViewLineUpdate(HDC dcFullView, int ViewWidth, int ViewHeight, int segmentY, TUnionBitmap *modifiedBitmap) { if(FWidth == 0 || FHeight == 0) return 0; RECT ViewRect, SegmentRect, SourceRect; // HDC dcSrc = NULL; int SrcSegmentNumber; bool anyUpdated; double ratioX = (double)ViewWidth / FWidth; double ratioY = (double)ViewHeight / FHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(0, 0, FWidth, FHeight); HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcFullView, hBrush); hOldPen = SelectObject(dcFullView, hPen); SetStretchBltMode(dcFullView, COLORONCOLOR); for (int i = 0; i < FCountX; i++) { SrcSegmentNumber = segmentY * FCountX + i; modifiedBitmap->IgnoredCheckUpdate(SrcSegmentNumber, ZoomCnt - 1); ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { if(Table[0][SrcSegmentNumber].blank){ // 256 color¿¡¼­ backgroung°¡ °ËÁ¤»ö ÀÌ¸é µ¥ÀÌŸ°¡ 1·Î ä¿öÁö´Â°Ô ¾Æ´Ï¶ó 0À¸·Î ä¿öÁü Rectangle(dcFullView, ViewRect.left * ratioX + 0.5, ViewRect.top * ratioY + 0.5, ViewRect.right * ratioX + 0.5, ViewRect.bottom * ratioY + 0.5); continue; } if(!segmentIgnoredStretchBlt(dcFullView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, SRCCOPY)) { SelectObject(dcFullView, hOldBrush); SelectObject(dcFullView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); return -1; } anyUpdated = true; } } SelectObject(dcFullView, hOldBrush); SelectObject(dcFullView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); if(anyUpdated)return 1; else return 0; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::MergedFullViewUpdate(HDC dcFullView, int ViewWidth, int ViewHeight, TUnionBitmap *UpperBitmap, TUnionBitmap *UpperMask, bool isAll, TUnionBitmap *modifiedBitmap) { RECT ViewRect, SegmentRect, SourceRect; HDC dcTemp = NULL; // HDC dcSrc = NULL; int SrcSegmentNumber; bool anyUpdated; TTexpiaBitmap *bmTemp = NULL; double ratioX = (double)ViewWidth / FWidth; double ratioY = (double)ViewHeight / FHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(0, 0, FWidth, FHeight); bmTemp = new TTexpiaBitmap; if (!bmTemp->Create(ViewWidth, ViewHeight, FBitsPerPixel, Frgb)) return -1; if ((dcTemp = bmTemp->CreateDC()) == NULL) return -1; HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcFullView, hBrush); hOldPen = SelectObject(dcFullView, hPen); SetStretchBltMode(dcFullView, COLORONCOLOR); SetStretchBltMode(dcTemp, COLORONCOLOR); for (int j = 0; j < FCountY; j++) { for (int i = 0; i < FCountX; i++) { SrcSegmentNumber = j * FCountX + i; modifiedBitmap->CheckUpdate(SrcSegmentNumber, ZoomCnt - 1); if(isAll || modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(UpperBitmap->Table[0][SrcSegmentNumber].blank) { ; } else { /* if(Table[0][SrcSegmentNumber].blank){ if(!UpperBitmap->segmentStretchBlt(dcFullView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, SRCCOPY)) return -1; } else {*/ if(!UpperMask->segmentStretchBlt(dcFullView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, SRCAND)) return -1; if(!UpperMask->segmentStretchBlt(dcTemp, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, NOTSRCCOPY)) return -1; if(!UpperBitmap->segmentStretchBlt(dcTemp, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, 0, 0, ratioX, ratioY, dStretchRatio, SRCAND)) return -1; if(!BitBlt(dcFullView, ViewRect.left * ratioX + 0.5, ViewRect.top * ratioY + 0.5, (int)(ViewRect.right * ratioX + 0.5) - (int)(ViewRect.left * ratioX + 0.5), (int)(ViewRect.bottom * ratioY + 0.5) - (int)(ViewRect.top * ratioY + 0.5), dcTemp, ViewRect.left * ratioX + 0.5, ViewRect.top * ratioY + 0.5, SRCPAINT) ) return -1; // } } anyUpdated = true; } } } if(dcTemp) { bmTemp->DeleteDC(dcTemp); } if(bmTemp) { delete bmTemp; } SelectObject(dcFullView, hOldBrush); SelectObject(dcFullView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); if(anyUpdated)return 1; else return 0; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::ViewUpdate(HDC dcView, int ViewWidth, int ViewHeight, // À̶§ÀÇ view´Â ºñÆ®¸Ê ÀüºÎ¿Í ¸ÅÇεǴ °ÍÀÌ ¾Æ´Ï´Ù. (bmScreen¿¡ »ç¿ë) int SrcX, int SrcY, int SrcWidth, int SrcHeight, bool isAll, TUnionBitmap *modifiedBitmap) { RECT ViewRect, SegmentRect, SourceRect; bool anyUpdated = false; int SrcSegmentNumber; int startSegmentX = getSegmentNumberX(SrcX); int startSegmentY = getSegmentNumberY(SrcY); int endSegmentX = getSegmentNumberX(SrcX + SrcWidth - 1); int endSegmentY = getSegmentNumberY(SrcY + SrcHeight - 1); double ratioX = (double)ViewWidth / SrcWidth; double ratioY = (double)ViewHeight / SrcHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(SrcX, SrcY, SrcX + SrcWidth, SrcY + SrcHeight); HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcView, hBrush); hOldPen = SelectObject(dcView, hPen); SetStretchBltMode(dcView, COLORONCOLOR); for (int j = startSegmentY; j <= endSegmentY; j++) { for (int i = startSegmentX; i <= endSegmentX; i++) { SrcSegmentNumber = j * FCountX + i; modifiedBitmap->CheckUpdate(SrcSegmentNumber, ZoomCnt - 1); ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(isAll || modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { if(Table[0][SrcSegmentNumber].blank){ Rectangle(dcView, (ViewRect.left - SrcX) * ratioX + 0.5, (ViewRect.top - SrcY) * ratioY + 0.5, (ViewRect.right - SrcX) * ratioX + 0.5, (ViewRect.bottom - SrcY) * ratioY + 0.5); continue; } if(!segmentStretchBlt(dcView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, SRCCOPY)) return -1; anyUpdated = true; } } } SelectObject(dcView, hOldBrush); SelectObject(dcView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); if(anyUpdated) return 1; else return 0; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::ViewLineUpdate(HDC dcView, int ViewWidth, int ViewHeight, // À̶§ÀÇ view´Â ºñÆ®¸Ê ÀüºÎ¿Í ¸ÅÇεǴ °ÍÀÌ ¾Æ´Ï´Ù. (bmScreen¿¡ »ç¿ë) int SrcX, int SrcY, int SrcWidth, int SrcHeight, int segmentY, TUnionBitmap *modifiedBitmap) { RECT ViewRect, SegmentRect, SourceRect; bool anyUpdated = false; int SrcSegmentNumber; int startSegmentX = getSegmentNumberX(SrcX); // int segmentY = getSegmentNumberY(y); int endSegmentX = getSegmentNumberX(SrcX + SrcWidth - 1); double ratioX = (double)ViewWidth / SrcWidth; double ratioY = (double)ViewHeight / SrcHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(SrcX, SrcY, SrcX + SrcWidth, SrcY + SrcHeight); HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcView, hBrush); hOldPen = SelectObject(dcView, hPen); SetStretchBltMode(dcView, COLORONCOLOR); for (int i = startSegmentX; i <= endSegmentX; i++) { SrcSegmentNumber = segmentY * FCountX + i; modifiedBitmap->IgnoredCheckUpdate(SrcSegmentNumber, ZoomCnt - 1); ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { if(Table[0][SrcSegmentNumber].blank){ Rectangle(dcView, (ViewRect.left - SrcX) * ratioX + 0.5, (ViewRect.top - SrcY) * ratioY + 0.5, (ViewRect.right - SrcX) * ratioX + 0.5, (ViewRect.bottom - SrcY) * ratioY + 0.5); continue; } if(!segmentIgnoredStretchBlt(dcView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, SRCCOPY)) { SelectObject(dcView, hOldBrush); SelectObject(dcView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); return -1; } anyUpdated = true; } } SelectObject(dcView, hOldBrush); SelectObject(dcView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); if(anyUpdated) return 1; else return 0; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::MergedViewUpdate(HDC dcView, int ViewWidth, int ViewHeight, // À̶§ÀÇ view´Â ºñÆ®¸Ê ÀüºÎ¿Í ¸ÅÇεǴ °ÍÀÌ ¾Æ´Ï´Ù. TUnionBitmap *UpperBitmap, TUnionBitmap *UpperMask, int SrcX, int SrcY, int SrcWidth, int SrcHeight, bool isAll, TUnionBitmap *modifiedBitmap) { // ÇöÀç layer°¡ this À̰í Upper Layer¸¦ ¹Þ¾Æ ÇÕ¼ºµÈ view¸¦ dcview¿¡ ÀúÀåÇÑ´Ù. modyfy ºÎºÐ¸¸ updateÇϸç modify°ªÀ» false·Î ¹Ù²ãÁÖÁö´Â ¾Ê´Â´Ù. RECT ViewRect, SegmentRect, SourceRect; HDC dcTemp = NULL; TTexpiaBitmap *bmTemp = NULL; int SrcSegmentNumber; bool anyUpdated = false; int startSegmentX = getSegmentNumberX(SrcX); int startSegmentY = getSegmentNumberY(SrcY); int endSegmentX = getSegmentNumberX(SrcX + SrcWidth - 1); int endSegmentY = getSegmentNumberY(SrcY + SrcHeight - 1); double ratioX = (double)ViewWidth / SrcWidth; double ratioY = (double)ViewHeight / SrcHeight; int zoomLevel = getZoomLevel(ratioX, ratioY); double dStretchRatio = getStretchRatio(zoomLevel); SourceRect = Rect(SrcX, SrcY, SrcX + SrcWidth, SrcY + SrcHeight); bmTemp = new TTexpiaBitmap; if (!bmTemp->Create(ViewWidth, ViewHeight, /*24*/FBitsPerPixel, Frgb)) return -1; // bmScreen ÀÇ bpp°¡ 24À̱⠶§¹®¿¡. cdViewÀÇ bpp°¡ 24°¡ ¾Æ´Ï¸é ¹Ù²ãÁà¾ßÇÔ if ((dcTemp = bmTemp->CreateDC()) == NULL) return -1; HBRUSH hBrush, hOldBrush; HPEN hOldPen, hPen; if(FBitsPerPixel == 8){ hBrush = CreateSolidBrush(PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); hPen = CreatePen(PS_SOLID, 1, PALETTERGB(Frgb[1].rgbRed, Frgb[1].rgbGreen, Frgb[1].rgbBlue)); } else { hBrush = CreateSolidBrush(0x00FFFFFF); hPen = CreatePen(PS_SOLID, 1, 0x00FFFFFF); } hOldBrush = SelectObject(dcView, hBrush); hOldPen = SelectObject(dcView, hPen); SetStretchBltMode(dcView, COLORONCOLOR); SetStretchBltMode(dcTemp, COLORONCOLOR); for (int j = startSegmentY; j <= endSegmentY; j++) { for (int i = startSegmentX; i <= endSegmentX; i++) { SrcSegmentNumber = j * FCountX + i; modifiedBitmap->CheckUpdate(SrcSegmentNumber, ZoomCnt - 1); if(isAll || modifiedBitmap->Table[ZoomCnt - 1][SrcSegmentNumber].modify == true) { ViewRect = GetCommonRect(SourceRect, SrcSegmentNumber, false); //Àüü ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ SegmentRect = GetCommonRect(SourceRect, SrcSegmentNumber, true); //°¢°¢ÀÇ ºñÆ®¸Ê¿¡¼­ ÁÂÇ¥ if(UpperBitmap->Table[0][SrcSegmentNumber].blank) { ; } else { /* if(Table[0][SrcSegmentNumber].blank){ if(!UpperBitmap->segmentStretchBlt(dcView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, SRCCOPY)) return -1; } else {*/ if(!UpperMask->segmentStretchBlt(dcView, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, SRCAND)) return -1; if(!UpperMask->segmentStretchBlt(dcTemp, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, NOTSRCCOPY)) return -1; if(!UpperBitmap->segmentStretchBlt(dcTemp, ViewRect, SegmentRect, SrcSegmentNumber, zoomLevel, 0, 0, SrcX, SrcY, ratioX, ratioY, dStretchRatio, SRCAND)) return -1; if(!BitBlt(dcView, (ViewRect.left - SrcX) * ratioX + 0.5, (ViewRect.top - SrcY) * ratioY + 0.5, (int)(ViewRect.right * ratioX + 0.5) - (int)(ViewRect.left * ratioX + 0.5), (int)(ViewRect.bottom * ratioY + 0.5) - (int)(ViewRect.top * ratioY + 0.5), dcTemp, (ViewRect.left - SrcX) * ratioX + 0.5, (ViewRect.top - SrcY) * ratioY + 0.5, SRCPAINT) ) return -1; // } } anyUpdated = true; } } } SelectObject(dcView, hOldBrush); SelectObject(dcView, hOldPen); DeleteObject(hBrush); DeleteObject(hPen); if(dcTemp) { bmTemp->DeleteDC(dcTemp); } if(bmTemp) { delete bmTemp; } if(anyUpdated) return 1; else return 0; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::RepaintFinished(int SrcX, int SrcY, int SrcWidth, int SrcHeight) { int nTopLeft = getSegmentNumber(SrcX, SrcY); int Top = nTopLeft % FCountX; int Left = nTopLeft / FCountX; int nBottomRight = getSegmentNumber(SrcX + SrcWidth, SrcY + SrcHeight); int Bottom = nBottomRight % FCountX; int Right = nBottomRight / FCountX; for (int j = Left; j <= Right; j++) { for (int i = Top; i <= Bottom; i++) { Table[ZoomCnt - 1][j * FCountX + i].modify = false; } } } //--------------------------------------------------------------------- //UnionStretchBlt¶û ¹æ½ÄÀÌ ¸¹ÀÌ ´Ù¸¥µ¥, ³ªÁß¿¡ ÅëÀÏ ½Ãų°Í. bool __fastcall TUnionBitmap::UnionBitBlt(HDC dc, int nXDst, int nYDst, int w, int h, int nXSrc, int nYSrc, DWORD dwRop, bool bToUnion) { HDC dcDst = NULL, dcSrc = NULL; RECT rt, r; int i; if (bToUnion) { //UnionBitmapÀÌ Dst. SetRect(&r, nXDst, nYDst, nXDst + w, nYDst + h); for (i = 0; i < FCountX * FCountY; i++) { if (IntersectRect(&rt, &btRect[0][i], &r)) { CheckLoad(i); dcDst = FBitmap[0][i]->CreateDC(); BitBlt(dcDst, rt.left - btRect[0][i].left, rt.top - btRect[0][i].top, rt.right - rt.left, rt.bottom - rt.top, dc, nXSrc - nXDst + rt.left, nYSrc - nYDst + rt.top, dwRop); FBitmap[0][i]->DeleteDC(dcDst); dcDst = NULL; Table[0][i].blank = false; Table[0][i].modify = true; } } } else { //UnionBitmapÀÌ Src. for (i = 0; i < FCountX * FCountY; i++) { SetRect(&r, nXSrc, nYSrc, nXSrc + w, nYSrc + h); if (IntersectRect(&rt, &btRect[0][i], &r)) { CheckLoad(i); dcSrc = FBitmap[0][i]->CreateDC(); BitBlt(dc, nXDst + (rt.left - nXSrc), nYDst + (rt.top - nYSrc), rt.right - rt.left, rt.bottom - rt.top, dcSrc, rt.left - btRect[0][i].left, rt.top - btRect[0][i].top, dwRop); FBitmap[0][i]->DeleteDC(dcSrc); dcSrc = NULL; } } } return true; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::FloodFill(TPoint start, TFloodFillRead read, TFloodFillSave save, TRect &rcBound, TRect *pZone) { // TTexpiaBitmap¿¡¼­ ±×´ë·Î ÆÛ¿È by celberus int x, y, savex, savey, xr, xl; TPoint now, *sp; TList *stack; Byte *p; TRect rcZone = pZone ? *pZone : Rect(0, 0, FWidth, FHeight); stack = new TList; rcBound.Left = start.x; rcBound.Right = start.x+1; rcBound.Top = start.y; rcBound.Bottom = start.y+1; stack->Add(new TPoint(start)); StartScanLine(); while (stack->Count) { sp = (TPoint *)stack->Last(); stack->Remove(sp); x = sp->x; y = sp->y; delete sp; if (yrcBound.Bottom-1) rcBound.Bottom = y+1; p = GetScanLine(y); save(p, x); savex = x; while (1) { x++; if (xrcBound.Right-1) rcBound.Right = xr+1; x = savex; while (1) { x--; if (x>=rcZone.Left && read(p, x)) save(p, x); else break; } xl = x+1; if (xlrcBound.Right-1) rcBound.Right = xl+1; if(xr-xl>=0){ //by linuxjun //PutScanLine(y,rcBound.Left,rcBound.Right-rcBound.Left+1); PutScanLine(y,xl,xr-xl+1); //by linuxjun } //by linuxjun x = xl; savey = y; y++; if (yAdd(new TPoint(now)); } } // } x = xl; } y = savey; y--; if (y>=rcZone.Top) { p = GetScanLine(y); // if (y>=rcZone.Top) { while (x<=xr) { if (!read(p, x)) x++; else { while (1) { if (x<=xr) { if (read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } } } StopScanLine(); delete stack; } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::FloodFillMask(TPoint start, TFloodFillRead read, TFloodFillSave save, TRect &rcBound, TPBitmap *Mask, TRect *pZone) { // TTexpiaBitmap¿¡¼­ ±×´ë·Î ÆÛ¿È by celberus int x, y, savex, savey, xr, xl; TPoint now, *sp; TList *stack = NULL; Byte *p, *m; TRect rcZone = pZone ? *pZone : Rect(0, 0, FWidth, FHeight); if (Mask==NULL) return false; if (!Mask->Create(FWidth, FHeight, 1)) return false; if ((stack = new TList)==NULL) goto fail; rcBound.Left = start.x; rcBound.Right = start.x+1; rcBound.Top = start.y; rcBound.Bottom = start.y+1; stack->Add(new TPoint(start)); // PartialUndo->LoadUndo(); // PartialUndo->LoadRedo(); StartScanLine(); Mask->Lock(); Mask->Fill(0); while (stack->Count) { sp = (TPoint *)stack->Last(); stack->Remove(sp); x = sp->x; y = sp->y; delete sp; if (yrcBound.Bottom-1) rcBound.Bottom = y+1; p = GetScanLine(y); m = Mask->ScanLine(y); *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); savex = x; while (1) { x++; if (x>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } xr = x-1; if (xrrcBound.Right-1) rcBound.Right = xr+1; x = savex; while (1) { x--; if (x>=rcZone.Left && (*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } xl = x+1; if (xlrcBound.Right-1) rcBound.Right = xl+1; x = xl; savey = y; y++; if (yScanLine(y); // if (y>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } x = xl; } y = savey; y--; if (y>=rcZone.Top) { p = GetScanLine(y); m = Mask->ScanLine(y); // if (y>=rcZone.Top) { while (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } } } Mask->Unlock(); StopScanLine(); delete stack; return true; fail: if (stack) delete stack; return false; } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::FloodFillMask2(TPoint start, TFloodFillRead read, TFloodFillSave save, TRect &rcBound, TTexpiaBitmap *Mask, TRect *pZone) { // TTexpiaBitmap¿¡¼­ ±×´ë·Î ÆÛ¿È by celberus int x, y, savex, savey, xr, xl; TPoint now, *sp; TList *stack = NULL; Byte *p, *m; TRect rcZone = pZone ? *pZone : Rect(0, 0, FWidth, FHeight); // rcZone = Ä¥ÇÒ ¼ö ÀÖ´Â ¿µ¿ª if (Mask==NULL) return false; if ((stack = new TList)==NULL) goto fail; rcBound.Left = start.x; rcBound.Right = start.x+1; // rcBound = Ä¥ÇØÁø ¿µ¿ª rcBound.Top = start.y; rcBound.Bottom = start.y+1; // ½ÃÀÛÁ¡À» ½ºÅÿ¡ Ãß°¡ stack->Add(new TPoint(start)); // Mask->FillRect(Rect(0, 0, Mask->Width, Mask->Height), 0); Mask->StartScanLine(); StartScanLine(); while (stack->Count) { // ½ºÅÿ¡¼­ ÇÑ Á¡À» ¾ò¾î ½ÃÀÛÁ¡À¸·Î ÁöÁ¤ sp = (TPoint *)stack->Last(); stack->Remove(sp); x = sp->x; y = sp->y; delete sp; // if (yrcBound.Bottom-1) rcBound.Bottom = y+1; p = GetScanLine(y); m = Mask->GetScanLine(y); // ½ÃÀÛÁ¡ 1pixelÀ» Ä¥ÇÑ´Ù. *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); // savex = x; // ½ÃÀÛÁ¡¿¡¼­ ¿À¸¥ÂÊÀ¸·Î Ä¥ÇÑ´Ù. while (1) { x++; if (x>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } // xr = x-1; if (xrrcBound.Right-1) rcBound.Right = xr+1; x = savex; // ½ÃÀÛÁ¡¿¡¼­ ¿ÞÂÊÀ¸·Î Ä¥ÇÑ´Ù. while (1) { x--; if (x>=rcZone.Left && (*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) { *(m+(x>>3)) |= 0x80>>(x&7); if (save) save(p, x); } else break; } // Mask->PutScanLine(y); xl = x+1; if (xlrcBound.Right-1) rcBound.Right = xl+1; x = xl; // ----- xl ºÎÅÍ xr ±îÁö ÇÑ ¶óÀÎÀ» Ä¥ÇѼÀÀÌ µÇ¾ú´Ù. // savey = y; y++; if (yGetScanLine(y); // if (y>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } x = xl; } y = savey; y--; if (y>=rcZone.Top) { p = GetScanLine(y); m = Mask->GetScanLine(y); // if (y>=rcZone.Top) { while (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7))) || !read(p, x)) x++; else { while (1) { if (x<=xr) { if ((*(m+(x>>3))&(0x80>>(x&7)))==0 && read(p, x)) x++; else { now.x = x-1; x++; break; } } else { now.x = x-1; break; } } now.y = y; stack->Add(new TPoint(now)); } } // } } } // Mask->Unlock(); Mask->StopScanLine(); StopScanLine(); delete stack; return true; fail: if (stack) delete stack; return false; } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::Rotate(int nAngle, bool fResize, COLORREF crFill) { // MoveCopy ¿¡¼­ »ç¿ëÇÑ ¹æ¹ýÀ» »ç¿ëÇÏ¿´´Ù. MoveCopy¿¡¼­´Â Mask±îÁö rotateÇϱ⠶§¹®¿¡ ¹®Á¦°¡ ¾ø¾úÀ¸³ª ¿©±â¼­´Â º¯°æµÈ ÈÄÀÇ ºñÆ®¸Ê »çÀÌÁî µîÀÌ Å©°Ô ¿µÇâÀ» ¹ÌÄ¡±â ¶§¹®¿¡ °ªÀ» Á¶±Ý¾¿ ¼öÁ¤ÇÏ¿´´Ù. URotation *Trans = NULL; int xx, yy, i, j; Extended min_x, min_y, max_x, max_y; Extended dx, dy, px, py; BYTE *tempLine, *thisLine; Extended LX, LY, CenX, CenY; TPoint Cen, RotateArea; Extended Theta; Extended sx[4], sy[4]; TUnionBitmap *tempBitmap = NULL; RGBQUAD tempRGB[256]; if ((nAngle / 100) % 360 == 0) return true; LX = (Extended)(FWidth)/ 2; //TWindowData-window,MoveCopyRect,bendwindow LY = (Extended)(FHeight)/ 2; CenX = LX; CenY = LY; if ((Trans = new URotation) == NULL) goto fail; Theta = DegToRad((Extended)nAngle / 100); Trans->translation(-CenX, -CenY); Trans->rotation(Theta); Trans->convert(0, 0, sx[0], sy[0]); sx[0] = sx[0] + CenX; sy[0] = sy[0] + CenY; Trans->convert(0, FHeight-1, sx[1], sy[1]); sx[1] = sx[1] + CenX; sy[1] = sy[1] + CenY; Trans->convert(FWidth - 1, 0, sx[2], sy[2]); sx[2] = sx[2] + CenX; sy[2] = sy[2] + CenY; Trans->convert(FWidth - 1, FHeight-1, sx[3], sy[3]); sx[3] = sx[3] + CenX; sy[3] = sy[3] + CenY; max_x = sx[0]; min_x = max_x; max_y = sy[0]; min_y = max_y; for (int i = 0; i <= 3; i++) { if (min_x >= sx[i]) min_x = sx[i]; else if (max_x <= sx[i]) max_x = sx[i]; if (min_y >= sy[i]) min_y = sy[i]; else if (max_y <= sy[i]) max_y = sy[i]; } RotateArea = Point(max_x-min_x+1, max_y-min_y+1); Trans->init(); Trans->translation(-CenX, -CenY); Trans->rotation(-Theta); if((tempBitmap = new TUnionBitmap) == NULL) goto fail; if(!tempBitmap->Create(FWidth, FHeight, FBitsPerPixel, Frgb)) goto fail; if(FBitsPerPixel == 8) memcpy(tempRGB, Frgb, 256 * sizeof(RGBQUAD)); tempBitmap->ExactCopy(this); if(!this->Create(RotateArea.x, RotateArea.y, tempBitmap->BitsPerPixel, tempRGB)) goto fail; if(!this->StartScanLine()) goto fail; if(!tempBitmap->StartScanLine()) goto fail; if (FBitsPerPixel == 8) { for (i=0; i<=max_y-min_y; i++) { thisLine = GetScanLine(i); for (j=0; j<=max_x-min_x; j++, thisLine++) { Trans->convert(j+min_x, i+min_y, dx, dy); py = dy+LY; yy = floor(py); if (yy>=0 && yyHeight) { px = dx+LX; xx = floor(px); tempLine = tempBitmap->GetScanLine(yy, xx, 1)+xx; if (xx>=0 && xxWidth) { *thisLine = *tempLine; } else { *thisLine = crFill; } } else { *thisLine = crFill; } } this->PutScanLine(i); } } else if(FBitsPerPixel == 24) { for (i=0; i<=max_y-min_y; i++) { thisLine = GetScanLine(i); for (j=0; j<=max_x-min_x; j++, thisLine+=3) { Trans->convert(j+min_x, i+min_y, dx, dy); py = dy+LY; yy = floor(py); if (yy>=0 && yyHeight) { px = dx+LX; xx = floor(px); tempLine = tempBitmap->GetScanLine(yy, xx, 1)+ 3 * xx; if (xx>=0 && xxWidth) { *thisLine = *tempLine; *(thisLine+1) = *(tempLine+1); *(thisLine+2) = *(tempLine+2); } else { *thisLine = crFill >> 16; *(thisLine+1) = crFill >> 8; *(thisLine+2) = crFill; } } else { *thisLine = crFill >> 16; *(thisLine+1) = crFill >> 8; *(thisLine+2) = crFill; } } this->PutScanLine(i); } } this->StopScanLine(); tempBitmap->StopScanLine(); if(tempBitmap) delete tempBitmap; delete Trans; return true; fail: if(tempBitmap) delete tempBitmap; if(Trans)delete Trans; return false; } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::MoveFilePointer(int n, int k) { SetFilePointer(hTempFile, Table[k][n].pos, NULL, FILE_BEGIN); } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::UnloadAll() { for(int i = 0; i < ZoomCnt; i++ ) { UnloadAll(i); } } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::UnloadAll(int ZoomLevel) { TbmPoint *lpt = NULL; while(ActivateList[ZoomLevel]->Count){ lpt = (TbmPoint *)ActivateList[ZoomLevel]->Last(); ActivateList[ZoomLevel]->Remove(lpt); FBitmap[ZoomLevel][lpt->n]->IsUse = false; // ¿Ö ÇÏÁö?? SaveToTempFile(lpt->n, ZoomLevel); delete lpt; } } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::StartScanLine() { // if (!FHandle.Flags.Allocated) return false; #ifdef SPDTEST scanLineCounter = new TickCounter("ScanLine"); scanLineCounter->reset(); scanLineCounter->startCounter(); getScanLineCounter = new TickCounter("GetScanLine"); getScanLineCounter->reset(); putScanLineCounter = new TickCounter("PutScanLine"); putScanLineCounter->reset(); putDiffScanLineCounter = new TickCounter("PutDiffScanLine"); putDiffScanLineCounter->reset(); undoCounter = new TickCounter("Undo-------"); undoCounter->reset(); #endif ShareCount++; if(hBuffer!=NULL||pBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, FBytesPerLine); // scanlineÀº fixed ¸¦ »ç¿ëÇØµµ µÉ °Í °°À½. zeropoint´Â?? if (hBuffer==NULL) goto fail; pBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pBuffer[0]==NULL) goto fail; //<------------------------------------->// hDiffBuffer = GlobalAlloc(GHND, FBytesPerLine); // scanlineÀº fixed ¸¦ »ç¿ëÇØµµ µÉ °Í °°À½. zeropoint´Â?? if (hDiffBuffer==NULL) goto fail; pDiffBuffer = (BYTE *)GlobalLock(hDiffBuffer); if (pDiffBuffer==NULL) goto fail; //<------------------------------------->// ActiveMin = FHeight + 1; // ¹üÀ§¸¦ ¹þ¾î³­ °ªÀ» ½áÁ༭ óÀ½ getÇÒ¶§ ¹«Á¶°Ç accessbitmapÀ» ÇÏ°Ô ÇÑ´Ù. ActiveMax = -1; return true; fail: StopScanLine(); return false; } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::StartScanLineN(int n) { #ifdef SPDTEST scanLineCounter = new TickCounter(AnsiString("ScanLineN ") + AnsiString("(") + AnsiString(n) + AnsiString(")")); scanLineCounter->reset(); scanLineCounter->startCounter(); getScanLineCounter = new TickCounter("GetScanLineN"); getScanLineCounter->reset(); putScanLineCounter = new TickCounter("PutScanLineN"); putScanLineCounter->reset(); putDiffScanLineCounter = new TickCounter("PutDiffScanLineN"); putDiffScanLineCounter->reset(); undoCounter = new TickCounter("Undo-------N"); undoCounter->reset(); #endif int i; ShareCount++; if(hBuffer!=NULL||pBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, n * FBytesPerLine); if (hBuffer==NULL) goto fail; pBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pBuffer[0]==NULL) goto fail; //<---------------------------------------->// hDiffBuffer = GlobalAlloc(GHND, FBytesPerLine); // scanlineÀº fixed ¸¦ »ç¿ëÇØµµ µÉ °Í °°À½. zeropoint´Â?? if (hDiffBuffer==NULL) goto fail; pDiffBuffer = (BYTE *)GlobalLock(hDiffBuffer); if (pDiffBuffer==NULL) goto fail; //<---------------------------------------->// for (i=1; iStartUndoScanLine(); } //--------------------------------------------------------------------------- bool __fastcall TUnionBitmap::StartUndoScanLineN(int n) { UndoActiveMin = FHeight + 1; UndoActiveMax = -1; return PartialUndo->StartUndoScanLineN(n); } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::StopUndoScanLine() { // undoReleaseActivePart(); undoReleaseActivePart(0); UndoActiveMin = FHeight + 1; UndoActiveMax = -1; PartialUndo->StopUndoScanLine(); return; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::StopScanLine() { #ifdef SPDTEST scanLineCounter->endCounter(); scanLineCounter->reportOut(); delete scanLineCounter; getScanLineCounter->reportOut(); delete getScanLineCounter; putScanLineCounter->reportOut(); delete putScanLineCounter; putDiffScanLineCounter->reportOut(); delete putDiffScanLineCounter; undoCounter->reportOut(); delete undoCounter; #endif #ifdef SPDTESTT swapInCounter->reportOut(); swapOutCounter->reportOut(); #endif ShareCount--; if(ShareCount>0) return; if(ShareCount<0){ ShareCount = 0; } releaseActivePart(0); ActiveMin = FHeight + 1; ActiveMax = -1; if (hBuffer) { if (pBuffer[0]) { GlobalUnlock(hBuffer); pBuffer[0] = NULL; } GlobalFree(hBuffer); hBuffer = NULL; } //<--------------------------------------->// if (hDiffBuffer) { if (pDiffBuffer) { GlobalUnlock(hDiffBuffer); pDiffBuffer = NULL; } GlobalFree(hDiffBuffer); hDiffBuffer = NULL; } //<--------------------------------------->// } /* //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoCheckActivePart(int y, int startPart, int endPart) { // undoscanlineÀ» ÇÒ ¶§ bitmap°ú °°Àº À§Ä¡¸¦ ´ëºÎºÐ ½ºÄµÇÏ°í ±×·¸Áö ¾ÊÀ» °æ¿ì UndoCheckActive... (U°¡ ´ë¹®ÀÚ)¸¦ »ç¿ëÇØÁֹǷΠFBitmapÀÇ access¿Í release´Â ÇØÁÖÁö ¾Ê¾Æµµ µÈ´Ù. ±×·¯³ª.. if(yUndoActiveMax) { undoReleaseActivePart(); undoSetActivePart(startPart, endPart); } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoReleaseActivePart() { if(UndoActiveMax >= 0) { if(UndoActiveMax != ActiveMax) { // Bitmap ÀÌ ÀÌ ºÎºÐÀ» scanlineÇϰí ÀÖ´Ù¸é releaseÇØ¼­´Â ¾ÈµÈ´Ù. À̰ÍÀº ³ªÁß¿¡ bitmapÀÇ scanlineÀÌ ¾Ë¾Æ¼­ releaseÇØÁÙ °ÍÀÌ´Ù. int activePart = getSegmentNumber( 0, UndoActiveMin ); for(int i = 0; i < FCountX; i ++ ) { if(FBitmap[0][activePart]->IsUse) { L_ReleaseBitmap(FBitmap[0][activePart]->Handle); FBitmap[0][activePart]->IsUse = false; } activePart++; } } int activeUndoPart = getSegmentNumber( 0, UndoActiveMin ); for(int i = 0; i < FCountX; i ++ ) { if(PartialUndo->PenUndoBitmap[activeUndoPart]->IsUse) { L_ReleaseBitmap(PartialUndo->PenUndoBitmap[activeUndoPart]->Handle); PartialUndo->PenUndoBitmap[activeUndoPart]->IsUse = false; } activeUndoPart++; } } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoSetActivePart(int startPart, int endPart) { for( int i = startPart; i <= endPart; i ++ ) { if(UndoActiveMax != ActiveMax) { if(FBitmap[0][i]->IsUse == false && PartialUndo->PenUndoBitmap[i]->Blank) { CheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(FBitmap[0][i]->Handle); FBitmap[0][i]->IsUse = true; } } if(PartialUndo->PenUndoBitmap[i]->IsUse == false && !PartialUndo->PenUndoBitmap[i]->Blank) { PartialUndo->UndoCheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(PartialUndo->PenUndoBitmap[i]->Handle); PartialUndo->PenUndoBitmap[i]->IsUse = true; } } UndoActiveMin = btRect[0][startPart].top; UndoActiveMax = btRect[0][startPart].bottom - 1; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::checkActivePart(int y, int startPart, int endPart) { if(yActiveMax) { releaseActivePart(); } setActivePart(startPart, endPart); // copytoitself¶§¹®¿¡ if¹® ¹ÛÀ¸·Î »©³¿ } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::UndoCheckActivePart(int y) { int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; checkActivePart(y, startPart, endPart); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::UndoCheckActivePart(int y, int x, int length) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); checkActivePart(y, startPart, endPart); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::releaseActivePart() { int activePart = getSegmentNumber( 0, ActiveMin ); if(ActiveMax >= 0) { if(UndoActiveMax != ActiveMax) { // Undo Bitmap ÀÌ ÀÌ ºÎºÐÀ» scanlineÇϰí ÀÖ´Ù¸é releaseÇØ¼­´Â ¾ÈµÈ´Ù. À̰ÍÀº ³ªÁß¿¡ undo scanlineÀÌ ¾Ë¾Æ¼­ releaseÇØÁÙ °ÍÀÌ´Ù. for(int i = 0; i < FCountX; i ++ ) { if(FBitmap[0][activePart]->IsUse) { L_ReleaseBitmap(FBitmap[0][activePart]->Handle); FBitmap[0][activePart]->IsUse = false; } activePart++; } } } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::setActivePart(int startPart, int endPart) { for( int i = startPart; i <= endPart; i ++ ) { if( FBitmap[0][i]->IsUse == false ) { CheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(FBitmap[0][i]->Handle); FBitmap[0][i]->IsUse = true; } } ActiveMin = btRect[0][startPart].top; ActiveMax = btRect[0][startPart].bottom - 1; } */ //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoCheckActivePart(int Part) { // undoscanlineÀ» ÇÒ ¶§ bitmap°ú °°Àº À§Ä¡¸¦ ´ëºÎºÐ ½ºÄµÇÏ°í ±×·¸Áö ¾ÊÀ» °æ¿ì UndoCheckActive... (U°¡ ´ë¹®ÀÚ)¸¦ »ç¿ëÇØÁֹǷΠFBitmapÀÇ access¿Í release´Â ÇØÁÖÁö ¾Ê¾Æµµ µÈ´Ù. ±×·¯³ª.. int delNum; undoReleaseActivePart(); undoSetActivePart(Part); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoReleaseActivePart(int limit) { int activePart; while((activePart=ActiveManager->DeleteOneUndoActivatedPart(limit))!=-1) { if(FBitmap[0][activePart]->IsUse) { L_ReleaseBitmap(FBitmap[0][activePart]->Handle); FBitmap[0][activePart]->IsUse = false; } if(PartialUndo->PenUndoBitmap[activePart]->IsUse) { L_ReleaseBitmap(PartialUndo->PenUndoBitmap[activePart]->Handle); PartialUndo->PenUndoBitmap[activePart]->IsUse = false; } } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::undoSetActivePart(int i) { if(PartialUndo->PenUndoBitmap[i]->Blank){ if(FBitmap[0][i]->IsUse == false){ CheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(FBitmap[0][i]->Handle); ActiveManager->ActivatePart(i); FBitmap[0][i]->IsUse = true; }else{ ActiveManager->ActivatePart(i); } }else{ if(PartialUndo->PenUndoBitmap[i]->IsUse == false){ PartialUndo->UndoCheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(PartialUndo->PenUndoBitmap[i]->Handle); ActiveManager->UndoActivatePart(i); PartialUndo->PenUndoBitmap[i]->IsUse = true; }else{ ActiveManager->UndoActivatePart(i); } } /* for( int i = startPart; i <= endPart; i ++ ) { if(UndoActiveMax != ActiveMax) { if(FBitmap[0][i]->IsUse == false && PartialUndo->PenUndoBitmap[i]->Blank) { CheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(FBitmap[0][i]->Handle); FBitmap[0][i]->IsUse = true; } } if(PartialUndo->PenUndoBitmap[i]->IsUse == false && !PartialUndo->PenUndoBitmap[i]->Blank) { PartialUndo->UndoCheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(PartialUndo->PenUndoBitmap[i]->Handle); PartialUndo->PenUndoBitmap[i]->IsUse = true; } } UndoActiveMin = btRect[0][startPart].top; UndoActiveMax = btRect[0][startPart].bottom - 1; */ } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::checkActivePart(int Part) { int delNum; /* while((delNum=ActiveManager->DeleteOneActivatedPart())!=-1) { releaseActivePart(delNum); } */ releaseActivePart(); setActivePart(Part); // copytoitself¶§¹®¿¡ if¹® ¹ÛÀ¸·Î »©³¿ /* if(yActiveMax) { releaseActivePart(); } setActivePart(startPart, endPart); // copytoitself¶§¹®¿¡ if¹® ¹ÛÀ¸·Î »©³¿ */ } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::UndoCheckActivePart(int y) { int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; for(int i=startPart;iDeleteOneActivatedPart(limit))!=-1) { if(FBitmap[0][delNum]->IsUse) { L_ReleaseBitmap(FBitmap[0][delNum]->Handle); FBitmap[0][delNum]->IsUse = false; } } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::setActivePart(int i) { if( FBitmap[0][i]->IsUse == false ) { CheckLoad(i); // ÇÑ line¸¸Å­ÀÇ load´Â °¡´ÉÇÏ´Ù°í °¡Á¤. L_AccessBitmap(FBitmap[0][i]->Handle); ActiveManager->ActivatePart(i); FBitmap[0][i]->IsUse = true; }else{ ActiveManager->ActivatePart(i); } } //--------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetScanLine(int y) { int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); L_GetBitmapRow(FBitmap[0][i]->Handle, pBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); } return pBuffer[0]; } //--------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetScanLine(int y, int x, int length) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); #ifdef SPDTEST getScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); L_GetBitmapRow(FBitmap[0][i]->Handle, pBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); } #ifdef SPDTEST getScanLineCounter->endCounter(); #endif return pBuffer[0]; } //--------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetScanLineN(int y, int num) { int startPart = getSegmentNumber( 0, y); // À̰æ¿ì activeMin, activeMax°ªµµ ¿©·¯°³¾Æ µÇ¾î¾ß ÇÑ´Ù. int endPart = startPart + FCountX - 1; //checkActivePart(y, startPart, endPart); #ifdef SPDTEST getScanLineCounter->startCounter(); #endif for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); L_GetBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); } #ifdef SPDTEST getScanLineCounter->endCounter(); #endif return pBuffer[num]; } //--------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetScanLineN(int y, int x, int length, int num) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); #ifdef SPDTEST getScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); L_GetBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); } #ifdef SPDTEST getScanLineCounter->endCounter(); #endif return pBuffer[num]; } //--------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetUndoScanLine(int y){ BYTE *result; int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; //undoCheckActivePart(y, startPart, endPart); for(int part = startPart; part <= endPart; part++){ undoCheckActivePart(part); result = PartialUndo->GetUndoScanLinePart(y, part); } return result; /* int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; undoCheckActivePart(y, startPart, endPart); return PartialUndo->GetUndoScanLine(y); */ } //--------------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetUndoScanLineN(int y,int num){ BYTE *result; int startPart = getSegmentNumber( 0, y); int endPart = startPart + FCountX - 1; //undoCheckActivePart(y, startPart, endPart); for(int part = startPart; part <= endPart; part++){ undoCheckActivePart(part); result = PartialUndo->GetUndoScanLinePartN(y, part, num); } return result; /* int startPart = getSegmentNumber( 0, y); int endPart = startPart + FCountX - 1; undoCheckActivePart(y, startPart, endPart); return PartialUndo->GetUndoScanLineN(y,num); */ } ///--------------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetUndoScanLine(int y,int x, int length){ BYTE *result; int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); //undoCheckActivePart(y, startPart, endPart); for(int part = startPart; part <= endPart; part++){ undoCheckActivePart(part); result = PartialUndo->GetUndoScanLinePart(y,part); } return result; /* int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); undoCheckActivePart(y, startPart, endPart); return PartialUndo->GetUndoScanLine(y,x,length); */ } //--------------------------------------------------------------------------- Byte *__fastcall TUnionBitmap::GetUndoScanLineN(int y,int x, int length, int num){ BYTE *result; int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); //undoCheckActivePart(y, startPart, endPart); for(int part = startPart; part <= endPart; part++){ undoCheckActivePart(part); result = PartialUndo->GetUndoScanLinePartN(y,part,num); } return result; /* int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); undoCheckActivePart(y, startPart, endPart); return PartialUndo->GetUndoScanLineN(y,x,length,num); */ } //--------------------------------------------------------------------------- void __fastcall TUnionBitmap::LoadLastUb(RGBQUAD *rgb){ StopUndoScanLine(); PartialUndo->LoadLast(rgb); StartUndoScanLine(); } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutScanLine(int y) { int startPart = getSegmentNumber( 0, y ); int endPart = startPart + FCountX - 1; #ifdef SPDTEST putScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); if (Table[0][i].undosave == false) { #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutScanLine(int y, int x, int length) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); #ifdef SPDTEST putScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); if (Table[0][i].undosave == false) { #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutScanLineN(int y, int num) { int startPart = getSegmentNumber( 0, y); int endPart = startPart + FCountX - 1; #ifdef SPDTEST putScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); if (Table[0][i].undosave == false) { #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutScanLineN(int y, int x, int length, int num) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); #ifdef SPDTEST putScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); if (Table[0][i].undosave == false) { #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutDiffScanLineN(int y, int num) { int startPart = getSegmentNumber( 0, y); int endPart = startPart + FCountX - 1; #ifdef SPDTEST putDiffScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); int j; for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); pItr = (DWORD *)(pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8); if (Table[0][i].undosave == false) { //<------------------------------------------------------->// L_GetBitmapRow(FBitmap[0][i]->Handle, pDiffBuffer, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); pDiffItr = (DWORD *)pDiffBuffer; for( j = 0; j < FBitmap[0][i]->Handle->BytesPerLine / 4; j++) { if(pDiffItr[j]!=pItr[j]){ break; } } if(j >= FBitmap[0][i]->Handle->BytesPerLine / 4) continue; //<------------------------------------------------------->// /* //<------------------------------------------------------->// L_GetBitmapRow(FBitmap[0][i]->Handle, pDiffBuffer + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); for( j = btRect[0][i].left * FBitsPerPixel / 8 ; j < btRect[0][i].left * FBitsPerPixel / 8 + FBitmap[0][i]->Handle->BytesPerLine ; j++) { if(pDiffBuffer[j]!=pBuffer[num][j]){ break; } } if( j == btRect[0][i].left * FBitsPerPixel / 8 + FBitmap[0][i]->Handle->BytesPerLine) continue; //<------------------------------------------------------->// */ #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putDiffScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutDiffScanLineN(int y, int x, int length, int num) { int startPart = getSegmentNumber( x, y); int endPart = getSegmentNumber( x + length - 1, y); #ifdef SPDTEST putDiffScanLineCounter->startCounter(); #endif //checkActivePart(y, startPart, endPart); int j; for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); pItr = (DWORD *)(pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8); if (Table[0][i].undosave == false) { //<------------------------------------------------------->// L_GetBitmapRow(FBitmap[0][i]->Handle, pDiffBuffer, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); pDiffItr = (DWORD *)pDiffBuffer; for( j = 0; j < FBitmap[0][i]->Handle->BytesPerLine / 4; j++) { if(pDiffItr[j]!=pItr[j]){ break; } } if(j >= FBitmap[0][i]->Handle->BytesPerLine / 4) continue; //<------------------------------------------------------->// /* //<------------------------------------------------------->// L_GetBitmapRow(FBitmap[0][i]->Handle, pDiffBuffer + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); for( j = btRect[0][i].left * FBitsPerPixel / 8 ; j < btRect[0][i].left * FBitsPerPixel / 8 + FBitmap[0][i]->Handle->BytesPerLine ; j++) { if(pDiffBuffer[j]!=pBuffer[num][j]){ break; } } if( j == btRect[0][i].left * FBitsPerPixel / 8 + FBitmap[0][i]->Handle->BytesPerLine) continue; //<------------------------------------------------------->// */ #ifdef SPDTEST undoCounter->startCounter(); #endif PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun #ifdef SPDTEST undoCounter->endCounter(); #endif } L_PutBitmapRow(FBitmap[0][i]->Handle, pBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } #ifdef SPDTEST putDiffScanLineCounter->endCounter(); #endif } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::PutScanLine(int y, Byte *p) { int startPart = getSegmentNumber( 0, y); int endPart = startPart + FCountX - 1; //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { checkActivePart(i); if (Table[0][i].undosave == false) PartialUndo->SaveUndo(i); //for Undo_Method by linuxjun L_PutBitmapRow(FBitmap[0][i]->Handle, p + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); Table[0][i].blank = false; Table[0][i].modify = true; } } //--------------------------------------------------------------------- BYTE *__fastcall TUnionBitmap::GetBufferPointer() { return pBuffer[0]; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::IsUseScanLine(){ if(hBuffer||pBuffer[0]) return true; else return false; } //--------------------------------------------------------------------- TPoint __fastcall TUnionBitmap::CalculateFCount(){ TPoint p; p.x = FWidth / LENGTH; if (FWidth % LENGTH != 0) p.x++; p.y = FHeight / LENGTH; if (FHeight % LENGTH != 0) p.y++; return p; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::CreateRegionBitmap() { if(!FRgnBitmap) FRgnBitmap = new TTexpiaBitmap; //by celberus FRgnBitmap->Create(FWidth, FHeight, 1); //by celberus } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::MakeRgb(RGBQUAD *rgb) { if(rgb) { if(!Frgb) Frgb = new RGBQUAD[256]; //by celberus memcpy(Frgb,rgb,256*sizeof(RGBQUAD)); //by celberus //FBackgroundColor = (rgb[1].rgbBlue << 16) + (rgb[1].rgbGreen << 8) + rgb[1].rgbRed; } else { if(Frgb) delete[] Frgb; Frgb = NULL; } } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::CalculateFZoomCount() { return 4; /* OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); int osVERSION = osvi.dwPlatformId; //WINDOWS 98 == 1, WIN_NT==2; if(osVERSION < 2) return 1; // by celberus .. for test //ºñÆ®¸Ê Å©±â°¡ È­¸é »çÀÌÁî º¸´Ù ÀÛÀ»¶§ ±îÁö zoom À̹ÌÁö ¸¸µê //ºñÆ®¸ÊÀÌ È­¸é º¸´Ù ÀÛÀ¸¸é ´õÀÌ»ó Ãà¼Ò À̹ÌÁö¸¦ ¸¸µå´Â °ÍÀº ¹«ÀÇ¹Ì //win98ÀÇ 1280*1024¿¡¼­ È­¸é »çÀÌÁî´Â 991 * 883 //±×·¡¼­ ´ë·« 1024¸¦ ±âÁØÀ¸·Î.. double w = (double)FWidth; double h = (double)FHeight; int Cnt = 1; while (1) { if(w < 1024 || h < 1024 || Cnt >= MAX_ZOOM_LEVEL) { return Cnt; } else { w /= 2; h /= 2; Cnt++; } } */ } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::AllocBase() { if(!FBitmap) FBitmap = new TTexpiaBitmap **[FZoomCnt]; if(!btRect) btRect = new RECT *[FZoomCnt]; if(!Table) Table = new TFileTable *[FZoomCnt]; if(!ActivateList) ActivateList = new TList *[FZoomCnt]; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::AllocEachZoomLevel(int level) { FBitmap[level] = new TTexpiaBitmap*[FCountX * FCountY]; btRect[level] = new RECT[FCountX * FCountY]; Table[level] = new TFileTable [FCountX * FCountY]; ActivateList[level] = new TList; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::getHeightOfEachBitmap(int height, int num, int len) { int result; if (num == FCountY - 1) result = height - (FCountY - 1) * len; else result = len; if (result == 0) return 1; return result; } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::getWidthOfEachBitmap(int width, int num, int len) { int result; if (num == FCountX - 1) result = width - (FCountX - 1) * len; else result = len; if (result == 0) return 1; return result; } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::CreateSwapFile(int size) { if(hTempFile == INVALID_HANDLE_VALUE){ hTempFile = CreateFile(FileName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hTempFile, size, 0, FILE_BEGIN); SetEndOfFile(hTempFile); } initSwapFile(); } //--------------------------------------------------------------------- int __fastcall TUnionBitmap::InitializeEachBitmap(bool isFirst) // color resolution ¶§ isFirst´Â false { int i, j, k, len, width, height, w, h, fileSize = 100; // 100 is header size for (k = 0; k < FZoomCnt; k++) { if(isFirst) AllocEachZoomLevel(k); len = LENGTH / pow(2, k); width = FWidth / pow(2, k); height = FHeight / pow(2, k); for (j = 0; j < FCountY; j++) { h = getHeightOfEachBitmap(height, j, len); for (i = 0; i < FCountX; i++) { w = getWidthOfEachBitmap(width, i, len); if(isFirst) FBitmap[k][j * FCountX + i] = new TTexpiaBitmap; btRect[k][j * FCountX + i] = Rect(i*len, j*len, i*len + w, j*len + h); int bpl = (FBitsPerPixel*w)/8; if((FBitsPerPixel*w)%8) bpl++; Table[k][j * FCountX + i].size = (((bpl + 3) / 4) * 4) * h; //BytesPerLine(4ÀÇ ¹è¼ö ¿Å¸²)°è»ê Table[k][j * FCountX + i].pos = fileSize; Table[k][j * FCountX + i].modify = false; Table[k][j * FCountX + i].blank = true; // 0 -> k by celberus Table[0][j * FCountX + i].undosave = false; fileSize += Table[k][j * FCountX + i].size; } } } return fileSize; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::PrintBitmap(HDC printDC, int x, int y, int width, int height, bool EndDoc, bool isFast) { RECT rt; double rx = (double)width / FWidth; double ry = (double)height / FHeight; for (int j = 0; j < FCountY; j++) { for (int i = 0; i < FCountX; i++) { rt = btRect[0][j*FCountX + i]; if (isFast) { CheckLoad(j*FCountX + i); if(!L_PrintBitmapFast(printDC, FBitmap[0][j*FCountX + i]->Handle, x + rt.left * rx + 0.5, y + rt.top * ry + 0.5, (int)(rt.right * rx + 0.5) - (int)(rt.left * rx + 0.5) , (int)(rt.bottom * ry + 0.5) - (int)(rt.top * ry + 0.5) , false)) return false; } else { CheckLoad(j*FCountX + i); if(!L_PrintBitmapExt(printDC, FBitmap[0][j*FCountX + i]->Handle, x + rt.left * rx + 0.5, y +rt.top * ry + 0.5, (int)(rt.right * rx + 0.5) - (int)(rt.left * rx + 0.5) , (int)(rt.bottom * ry + 0.5) - (int)(rt.top * ry + 0.5), false)) return false; } } } return true; } //--------------------------------------------------------------------- bool __fastcall TUnionBitmap::SetAllToModified() { for (int i = 0; i < FCountX * FCountY; i ++ ) { Table[0][i].modify = true; } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::SetAllToBlank() { for (int i = 0; i < FCountX * FCountY; i ++ ) { for(int j = 0; j < FZoomCnt; j++ ) { Table[j][i].blank = true; } } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::SetAllToUnblank() // »ç¿ëÇÏ½Ç ¶§´Â ÀÇ»ç¿Í »óÀÇÇϼ¼¿ä by celberus { for (int i = 0; i < FCountX * FCountY; i ++ ) { Table[0][i].blank = false; } } //--------------------------------------------------------------------- void __fastcall TUnionBitmap::initSwapFile() { DWORD dwWrite; BYTE header[4] = "TUH"; DWORD version = 100; if (hTempFile != INVALID_HANDLE_VALUE) { SetFilePointer(hTempFile, 0, 0, FILE_BEGIN); WriteFile(hTempFile, header, 4, &dwWrite, NULL); WriteFile(hTempFile, &version, sizeof(DWORD), &dwWrite, NULL); WriteFile(hTempFile, &FWidth, sizeof(DWORD), &dwWrite, NULL); WriteFile(hTempFile, &FHeight, sizeof(DWORD), &dwWrite, NULL); WriteFile(hTempFile, &FBitsPerPixel, sizeof(WORD), &dwWrite, NULL); } SetFilePointer(hTempFile, 0, NULL, FILE_BEGIN); } //--------------------------------------------------------------------- __fastcall URotation::URotation() { init(); } //--------------------------------------------------------------------------- __fastcall URotation::~URotation() { } //--------------------------------------------------------------------------- void __fastcall URotation::init() { T[0][0] = 1.0; T[0][1] = 0.0; T[0][2] = 0.0; T[1][0] = 0.0; T[1][1] = 1.0; T[1][2] = 0.0; T[2][0] = 0.0; T[2][1] = 0.0; T[2][2] = 1.0; } //--------------------------------------------------------------------------- void __fastcall URotation::scaling(Extended x, Extended y) { Extended t[3][3]; t[0][0] = T[0][0]*x; t[0][1] = T[0][1]*y; t[0][2] = T[0][2]; t[1][0] = T[1][0]*x; t[1][1] = T[1][1]*y; t[1][2] = T[1][2]; t[2][0] = T[2][0]*x; t[2][1] = T[2][1]*y; t[2][2] = T[2][2]; memcpy(T[0], t[0], 9*sizeof(Extended)); } //--------------------------------------------------------------------------- void __fastcall URotation::translation(Extended x, Extended y) { Extended t[3][3]; t[0][0] = T[0][0]+T[0][2]*x; t[0][1] = T[0][1]+T[0][2]*y; t[0][2] = T[0][2]; t[1][0] = T[1][0]+T[1][2]*x; t[1][1] = T[1][1]+T[1][2]*y; t[1][2] = T[1][2]; t[2][0] = T[2][0]+T[2][2]*x; t[2][1] = T[2][1]+T[2][2]*y; t[2][2] = T[2][2]; memcpy(T[0], t[0], 9*sizeof(Extended)); } //--------------------------------------------------------------------------- void __fastcall URotation::rotation(Extended theta) { Extended t[3][3], st = sin(theta), ct =cos(theta); if(st > 0.9999999) st = 1; //added by qe (2001. 1) if(st > -0.001 && st < 0.001) st = 0; //Á¤¹Ðµµ ¹®Á¦ ¶§¹®¿¡.. if(st < -0.9999999) st = -1; //ex) sin90 ÀÌ 1ÀÌ ¾È³ª¿À´Â °æ¿ì°¡ À־.. if(ct > 0.9999999) ct = 1; if(ct > -0.001 && ct < 0.001) ct = 0; if(ct < -0.9999999) ct = -1; t[0][0] = T[0][0]*ct-T[0][1]*st; t[0][1] = T[0][0]*st+T[0][1]*ct; t[0][2] = T[0][2]; t[1][0] = T[1][0]*ct-T[1][1]*st; t[1][1] = T[1][0]*st+T[1][1]*ct; t[1][2] = T[1][2]; t[2][0] = T[2][0]*ct-T[2][1]*st; t[2][1] = T[2][0]*st+T[2][1]*ct; t[2][2] = T[2][2]; memcpy(T[0], t[0], 9*sizeof(Extended)); } //--------------------------------------------------------------------------- void __fastcall URotation::convert(Extended &ox, Extended &oy) { Extended ix = ox, iy = oy; ox = T[0][0]*ix+T[1][0]*iy+T[2][0]; oy = T[0][1]*ix+T[1][1]*iy+T[2][1]; } //--------------------------------------------------------------------------- void __fastcall URotation::convert(Extended ix, Extended iy, Extended &ox, Extended &oy) { ox = T[0][0]*ix+T[1][0]*iy+T[2][0]; oy = T[0][1]*ix+T[1][1]*iy+T[2][1]; } //--------------------------------------------------------------------------- TList ** __fastcall TUnionBitmap::GetActivateList(void) { return ActivateList; } //--------------------------------------------------------------------------- __fastcall TickCounter::TickCounter(AnsiString name) { reportFileName = "C:/performance.log"; functionName = name; totalCalled = 0; totalDelay = 0; longestDelay = shortestDelay = -1; } //--------------------------------------------------------------------------- __fastcall TickCounter::~TickCounter() { // } //--------------------------------------------------------------------------- void __fastcall TickCounter::startCounter() { // startTick = GetTickCount(); QueryPerformanceCounter(&startTick); } //--------------------------------------------------------------------------- void __fastcall TickCounter::endCounter() { // endTick = GetTickCount(); QueryPerformanceCounter(&endTick); lastDelay = endTick.LowPart - startTick.LowPart; totalCalled++; totalDelay += lastDelay; avgDelay = (double)totalDelay / totalCalled; if (longestDelay < lastDelay || longestDelay == -1) { longestDelay = lastDelay; } if (shortestDelay > lastDelay || shortestDelay == -1) { shortestDelay = lastDelay; } } //--------------------------------------------------------------------------- void __fastcall TickCounter::reset() { totalCalled = 0; totalDelay = 0; longestDelay = shortestDelay = -1; } //--------------------------------------------------------------------------- void __fastcall TickCounter::reportOut() { /* DWORD bytesWritten; char newLine = '\r'; HANDLE hFile = CreateFile(reportFileName.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); SetFilePointer(hFile, 0, NULL, FILE_END); WriteFile(hFile, functionName.c_str(), functionName.Length(), &bytesWritten, NULL); WriteFile(hFile, "total called : ", sizeof("total called : "), &bytesWritten, NULL); WriteFile(hFile, IntToStr(totalCalled).c_str(), 10, &bytesWritten, NULL); WriteFile(hFile, &newLine, 1, &bytesWritten, NULL); WriteFile(hFile, "total delay : ", sizeof("total delay : "), &bytesWritten, NULL); WriteFile(hFile, IntToStr(totalDelay).c_str(), 10, &bytesWritten, NULL); WriteFile(hFile, &newLine, 1, &bytesWritten, NULL); WriteFile(hFile, "average delay : ", sizeof("average delay : "), &bytesWritten, NULL); WriteFile(hFile, IntToStr((int)avgDelay).c_str(), 10, &bytesWritten, NULL); WriteFile(hFile, &newLine, 1, &bytesWritten, NULL); WriteFile(hFile, "shortest delay : ", sizeof("shortest delay : "), &bytesWritten, NULL); WriteFile(hFile, IntToStr(shortestDelay).c_str(), 10, &bytesWritten, NULL); WriteFile(hFile, &newLine, 1, &bytesWritten, NULL); WriteFile(hFile, "longest delay : ", sizeof("longest delay : "), &bytesWritten, NULL); WriteFile(hFile, IntToStr(longestDelay).c_str(), 10, &bytesWritten, NULL); WriteFile(hFile, &newLine, 1, &bytesWritten, NULL); CloseHandle(hFile); */ FILE *fp; fp = fopen(reportFileName.c_str(), "at"); fprintf(fp, "%s\t", functionName.c_str()); fprintf(fp, "total called : %6d\t", totalCalled); fprintf(fp, "total delay : %8d\t", totalDelay); fprintf(fp, "average delay : %8d\t", (int)avgDelay); fprintf(fp, "shortest delay : %5d\t", shortestDelay); fprintf(fp, "longest delay : %6d\n", longestDelay); fclose(fp); // } //---------------------------------------------------------------------------