//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Shadow_F.h" #include "MainImage.h" #include "Palette.h" #include "Undo.h" #include "MoveCopy_F.h" #include "LogData.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "RzButton" #pragma link "RzTrkBar" #pragma resource "*.dfm" //--------------------------------------------------------------------------- #define IDS_SHADOWCOLOR StringTable[0] #define IDS_ANGLE StringTable[1] #define IDS_DISTANCE StringTable[2] #define IDS_APPLYSHADOW StringTable[3] TShadowForm *ShadowForm; //--------------------------------------------------------------------------- __fastcall TShadowForm::TShadowForm(TComponent* Owner) : TForm(Owner) { hWnd = ((TWinControl *)Owner)->Handle; StringTable.Create(DirectoryItem, Language, "Shadow_F"); SetSmallFont(Font); lbColor->Caption = IDS_SHADOWCOLOR; ImgAngle->Hint = IDS_ANGLE; ImgDistance->Hint = IDS_DISTANCE; rzbitRun->Caption = IDS_APPLYSHADOW; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::FormCreate(TObject *Sender) { // } //--------------------------------------------------------------------------- void __fastcall TShadowForm::rztrackbarAngleChange(TObject *Sender) { BEGIN_LOG(""); lbAngle->Caption = rztrackbarAngle->Position; ShowShadowMask(); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::rztrackbarDistanceChange(TObject *Sender) { BEGIN_LOG(""); lbDistance->Caption = rztrackbarDistance->Position; ShowShadowMask(); END_LOG; } //--------------------------------------------------------------------------- //Private Method //--------------------------------------------------------------------------- void __fastcall TShadowForm::CalculatePosition() { double rad = DegToRad((Extended) (360 - rztrackbarAngle->Position)); int distance = rztrackbarDistance->Position; pos.x = range.left + distance * cos(rad); pos.y = range.top + distance * sin(rad); } //--------------------------------------------------------------------------- //Public Method //--------------------------------------------------------------------------- void __fastcall TShadowForm::InitForm() { BEGIN_LOG(""); RGBQUAD rgb[256]; SIZE size; RECT undorange; TPException ec = EC_NONE; ClientHeight = 86; range = MainImageForm->WorkArea->Range; pos.x = range.left; pos.y = range.top; size.cx = range.right - range.left; size.cy = range.bottom - range.top; Image = MainImageForm->iMainImage; undorange.left = range.left - 100; if (undorange.left < 0) undorange.left = 0; undorange.right = range.right + 100; if (undorange.right > Image->uBitmap->Width) undorange.right = Image->uBitmap->Width; undorange.top = range.top - 100; if (undorange.top < 0) undorange.top = 0; undorange.bottom = range.bottom + 100; if (undorange.bottom > Image->uBitmap->Height) undorange.bottom = Image->uBitmap->Height; MainImageForm->UndoSave(UK_PATTERN, undorange); InitShadow(); FGChange(PaletteForm->DIB256Palette->ChoiceIndex); END_LOG; return; fail: EXCEPTION_MESSAGE_OK(ec); PostMessage(hWnd, TPM_EXITFUNCTION, 0, 0); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::ExitForm() { BEGIN_LOG(""); if (ShadowBitmap) { delete ShadowBitmap; ShadowBitmap = NULL; } if (ShadowMask) { delete ShadowMask; ShadowMask = NULL; } MainImageForm->iMainImage->SubEnabled = false; MainImageForm->iMainImage->SubVisible = false; END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::FGChange(int Value) { BEGIN_LOG(""); if (Image->uBitmap->BitsPerPixel == 8) { color = Value; shColor->Brush->Color = PaletteForm->DIB256Palette->Palette->ColorData[Value]->Color; } else { color = PaletteForm->DIB256Palette->Palette->ColorData[Value]->Color; shColor->Brush->Color = (TColor)color; } ShowShadowMask(); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::PaletteColorChange(int Value) // by celberus { BEGIN_LOG(""); RGBQUAD rgb[256]; if (Image->uBitmap->BitsPerPixel == 8) { color = Value; shColor->Brush->Color = PaletteForm->DIB256Palette->Palette->ColorData[Value]->Color; Image->uBitmap->GetColors(0, 256, rgb); ShadowBitmap->PutColors(0, 256, rgb); ShadowMask->PutColors(0, 256, rgb); } else { color = PaletteForm->DIB256Palette->Palette->ColorData[Value]->Color; shColor->Brush->Color = (TColor)color; } ShowShadowMask(); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::rzbitRunClick(TObject *Sender) { BEGIN_LOG(""); THistoryData *ud = MainImageForm->Undo->GetLast(); RECT undorange = ud->getRectRange(); MainImageForm->iMainImage->uBitmap->CopyToRect(pos.x, pos.y, Image->SubBitmap, SRCCOPY); if (Image->LayerMask) MainImageForm->iMainImage->LayerMask->CopyToRect(pos.x, pos.y, Image->SubMask, SRCCOPY); MainImageForm->UndoSave(UK_PATTERN, undorange); MainImageForm->iMainImage->SubEnabled = false; MainImageForm->iMainImage->SubVisible = false; PostMessage(hWnd, TPM_EXITFUNCTION, 0, 0); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::FormClose(TObject *Sender, TCloseAction &Action) { BEGIN_LOG(""); PostMessage(hWnd, TPM_EXITFUNCTION, 0, 0); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::InitShadow() { BEGIN_LOG(""); TPException ec = EC_NONE; RGBQUAD rgb[256]; TPItemImage *Image = MainImageForm->iMainImage; int width = MainImageForm->WorkArea->Range.right - MainImageForm->WorkArea->Range.left; int height = MainImageForm->WorkArea->Range.bottom - MainImageForm->WorkArea->Range.top; Image->SubEnabled = true; ShadowBitmap = new TUnionBitmap(); ShadowMask = new TUnionBitmap(); if (Image->uBitmap->BitsPerPixel==8) { MainImageForm->Palette->ToRGBQUAD(rgb, 256); if (!Image->SubBitmap->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!Image->SubMask->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!ShadowBitmap->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!ShadowMask->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } Image->SubMask->BackgroundColor = PALETTEINDEX(0xFF); ShadowBitmap->BackgroundColor = PALETTEINDEX(0x00); ShadowMask->BackgroundColor = PALETTEINDEX(0xFF); } else { if (!Image->SubBitmap->Create(width, height, 24)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!Image->SubMask->Create(width, height, 1)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!ShadowBitmap->Create(width, height, 24)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!ShadowMask->Create(width, height, 1)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } Image->SubMask->BackgroundColor = 0xFFFFFF; ShadowBitmap->BackgroundColor = 0; ShadowMask->BackgroundColor = 0xFFFFFF; } MakeShadowMask(); END_LOG; return; fail: EXCEPTION_MESSAGE_OK(ec); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::MakeShadowMask() { // ±×¸²ÀÚ¿µ¿ªÀÇ ¸¶½ºÅ©¸¦ ¸¸µç´Ù //ShadowMask : ¹è°æ Èò»ö, ±×¸²ÀںκР°ËÁ¤ BEGIN_LOG(""); TPException ec = EC_NONE; TWindowData window; WAItr *waItr; WindowItr *windowItr; RGBQUAD rgb[256]; COLORREF bgc; TPItemImage *Image = MainImageForm->iMainImage; window.s.x = MainImageForm->WorkArea->Range.left; window.s.y = MainImageForm->WorkArea->Range.top; window.e.x = MainImageForm->WorkArea->Range.right; window.e.y = MainImageForm->WorkArea->Range.bottom; window.size.x = window.e.x - window.s.x; window.size.y = window.e.y - window.s.y; int width = window.size.x; int height = window.size.y; if ((window.Bitmap = new TUnionBitmap) == NULL) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } // convert by celberus if ((window.Mask = new TUnionBitmap) == NULL) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } // convert by celberus if ((window.Back = new TUnionBitmap) == NULL) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } // convert by celberus if (Image->uBitmap->BitsPerPixel==8) { waItr = (WAItr *) new WAItr_8(Image->uBitmap, Image->LayerMask, MainImageForm->WorkArea, &window); windowItr = (WindowItr *) new WindowItr_8(&window); MainImageForm->Palette->ToRGBQUAD(rgb, 256); if (!window.Bitmap->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!window.Mask->Create(width, height, 8, rgb)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } window.Bitmap->BackgroundColor = PALETTEINDEX(0x00); window.Mask->BackgroundColor = PALETTEINDEX(0xFF); } else { waItr = (WAItr *) new WAItr_24(Image->uBitmap, Image->LayerMask, MainImageForm->WorkArea, &window); windowItr = (WindowItr *) new WindowItr_24(&window); if (!window.Bitmap->Create(width, height, 24)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!window.Mask->Create(width, height, 1)) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } window.Bitmap->BackgroundColor = 0; window.Mask->BackgroundColor = 0xFFFFFF; bgc = PaletteForm->DIB256Palette->GetBGCOLORREF(24); waItr->setBGColor(bgc); } if (!windowItr->startScanLine()) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } if (!waItr->startScanLine()) { ec = EC_MEMORY_LACK; SAVE_EXCEPTION(ec); goto fail; } for (int i=0; igetScanLine(i, 0, window.size.x); waItr->getScanLine(i); for (int j=0; jisInArea(j)) { if (waItr->isNotBGColor(j)) { windowItr->copyPixel(j, waItr->getPixelPointer(j)); } else { windowItr->copyAndBlank(j, waItr->getPixelPointer(j)); } } } windowItr->putScanLine(i, 0, window.size.x); } windowItr->stopScanLine(); waItr->stopScanLine(); ShadowMask->Copy(window.Mask, SRCCOPY); if(waItr) delete waItr; if(windowItr) delete windowItr; if (window.Bitmap) { delete window.Bitmap; window.Bitmap = NULL; } if (window.Mask) { delete window.Mask; window.Mask = NULL; } if (window.Back) { delete window.Back; window.Back = NULL; } END_LOG; return; fail: windowItr->stopScanLine(); waItr->stopScanLine(); if(waItr) delete waItr; if(windowItr) delete windowItr; EXCEPTION_MESSAGE_OK(ec); END_LOG; } //--------------------------------------------------------------------------- void __fastcall TShadowForm::ShowShadowMask() { // Àӽ÷Πȭ¸éÀ§¿¡ Shadow°¡ ½ÇÇàµÇ´Â °ÍÀ» ³ªÅ¸³»±â À§ÇØ SubBitmap°ú SubMask¸¦ ÀÌ¿ëÇÑ´Ù. // CalculatePosition() ÇÔ¼ö¿¡¼­ ±¸ÇÑ pos¿¡ SubBitmapÀ» À§Ä¡½ÃÄÑ È­¸é¿¡ º¸ÀδÙ. /* 1. SubBitmap°ú SubMask¿¡ ÇöÀç º¸¿©Áö°í ÀÖ´Â ºñÆ®¸ÊÀÇ ÀÛ¾÷±¸¿ª ¿µ¿ªÀ» º¹»çÇØµÐ´Ù. 2. SubBitmap°ú SubMask À§¿¡ ShadowMask¿¡ ±×·ÁÁø ¿µ¿ª(0, black)¿¡ shadowcolorÀ» Ä¥ÇØ¾ßÇϴµ¥ Shadow¸¦ ³ªÅ¸³»°íÀÚÇÏ´Â Source À§¿¡´Â ±×¸®Áö¾Ê¾Æ¾ßÇϹǷΠÇöÀçÀÇ pos¿¡ µû¸¥ »ó´ëÀûÀÎ À§Ä¡¸¦ °è»êÇÑ´Ù. sx, sy : SubBitmapÀÌ Source¿Í °ãÃÄÁö´Â ½ÃÀÛÀ§Ä¡ masksx, masksy : Source°¡ SubBitmap°ú °ãÃÄÁö´Â ºÎºÐÀÇ ½ÃÀÛÀ§Ä¡ shm : pos¿¡ µû¸¥ ShadowMask°¡ ±×·ÁÁú ºÎºÐÀÇ µ¥ÀÌÅÍ shmmask : Á¦¿ÜÇØ¾ß ÇÒ SourceºÎºÐÀÇ µ¥ÀÌÅÍ wid, hei : SubBitmap°ú Source°¡ °ãÃÄÁö´Â ¿µ¿ª shmmask¿¡ ±×·ÁÁø ºÎºÐÀÌ ¾Æ´Ï¸é¼­( != 0, Source) shm¿¡´Â ±×·ÁÁø ºÎºÐ( == 0, Shadow)¿¡ shadowcolor¸¦ Ä¥ÇÑ´Ù. */ BEGIN_LOG(""); TPItemImage *Image = MainImageForm->iMainImage; Byte *shb, *shm, *subb, *subm, mm; Byte *shmmask; int width = ShadowBitmap->Width; int height = ShadowBitmap->Height; COLORREF shadowcolor = color; CalculatePosition(); int sx = 0, sy = 0, masksx = 0, masksy = 0, wid = 0, hei = 0; if (pos.x > MainImageForm->WorkArea->Range.left){ wid = width - (pos.x - MainImageForm->WorkArea->Range.left); sx = 0; masksx = width - wid; } else { wid = width - (MainImageForm->WorkArea->Range.left - pos.x); sx = width - wid; masksx = 0; } if (pos.y > MainImageForm->WorkArea->Range.top){ hei = height - (pos.y - MainImageForm->WorkArea->Range.top); sy = 0; masksy = height - hei; } else { hei = height - (MainImageForm->WorkArea->Range.top - pos.y); sy = height - hei; masksy = 0; } Image->SubRange.left = pos.x; Image->SubRange.top = pos.y; if (Image->LayerMask){ Image->SubBitmap->CopyFromRect(Image->uBitmap, pos.x, pos.y, SRCCOPY); Image->SubMask->CopyFromRect(Image->LayerMask, pos.x, pos.y, SRCCOPY); if (Image->uBitmap->BitsPerPixel==8) { Image->SubBitmap->StartScanLine(); Image->SubMask->StartScanLine(); ShadowMask->StartScanLineN(2); for (int y = 0, sty = 0; y < ShadowBitmap->Height; y++){ subb = Image->SubBitmap->GetScanLine(y); subm = Image->SubMask->GetScanLine(y); shm = ShadowMask->GetScanLineN(y, 0); if (y >= sy && sty < hei) shmmask = ShadowMask->GetScanLineN(masksy+sty, 1); for (int x = 0, stx = 0; x < ShadowBitmap->Width; x++){ if (x >= sx && stx < wid && y >= sy && sty < hei){ if (shmmask[masksx+stx] != 0 && shm[x] == 0){ subb[x] = shadowcolor; subm[x] = shm[x]; } stx++; } else { if (shm[x] == 0){ subb[x] = shadowcolor; subm[x] = shm[x]; } } } if (y >= sy && sty < hei) sty++; Image->SubBitmap->PutScanLine(y); Image->SubMask->PutScanLine(y); } Image->SubBitmap->StopScanLine(); Image->SubMask->StopScanLine(); ShadowMask->StopScanLine(); } else { Image->SubBitmap->StartScanLine(); Image->SubMask->StartScanLine(); ShadowMask->StartScanLineN(2); for (int y = 0, sty = 0; y < ShadowBitmap->Height; y++){ subb = Image->SubBitmap->GetScanLine(y); subm = Image->SubMask->GetScanLine(y); shm = ShadowMask->GetScanLineN(y, 0); if (y >= sy && sty < hei) shmmask = ShadowMask->GetScanLineN(masksy+sty, 1); for (int x = 0, stx = 0; x < ShadowBitmap->Width; x++){ mm = 0x80; if (x >= sx && stx < wid && y >= sy && sty < hei){ if( ((shm[(x) >> 3] & (0x80 >> ((x) & 7))) == 0) && (shmmask[(masksx+stx) >> 3] & (0x80 >> ((masksx+stx) & 7))) ){ SetPixel24(subb, shadowcolor); *(subm + (x>>3)) &= ~(0x80 >> (x&7)); *shmmask |= mm; *shm |= mm; } stx++; } else { if((shm[(x) >> 3] & (0x80 >> ((x) & 7))) == 0){ SetPixel24(subb, shadowcolor); *(subm + (x>>3)) &= ~(0x80 >> (x&7)); *shm |= mm; } } subb += 3; if (mm == 1) { mm = 0x80; } else mm >>= 1; } if (y >= sy && sty < hei) sty++; Image->SubBitmap->PutScanLine(y); Image->SubMask->PutScanLine(y); } Image->SubBitmap->StopScanLine(); Image->SubMask->StopScanLine(); ShadowMask->StopScanLine(); } } else { if (Image->uBitmap->BitsPerPixel==8) { Image->SubBitmap->CopyFromRect(Image->uBitmap, pos.x, pos.y, SRCCOPY); Image->SubMask->FillRect(Rect(0, 0, Image->SubMask->Width, Image->SubMask->Height), 0); Image->SubBitmap->StartScanLine(); ShadowMask->StartScanLineN(2); for (int y = 0, sty = 0; y < ShadowBitmap->Height; y++){ subb = Image->SubBitmap->GetScanLine(y); shm = ShadowMask->GetScanLineN(y, 0); if (y >= sy && sty < hei) shmmask = ShadowMask->GetScanLineN(masksy+sty, 1); for (int x = 0, stx = 0; x < ShadowBitmap->Width; x++){ if (x >= sx && stx < wid && y >= sy && sty < hei){ if (shmmask[masksx+stx] != 0 && shm[x] == 0){ subb[x] = shadowcolor; } stx++; } else { if (shm[x] == 0) subb[x] = shadowcolor; } } if (y >= sy && sty < hei) sty++; Image->SubBitmap->PutScanLine(y); } Image->SubBitmap->StopScanLine(); ShadowBitmap->StopScanLine(); ShadowMask->StopScanLine(); } else { Image->SubBitmap->CopyFromRect(Image->uBitmap, pos.x, pos.y, SRCCOPY); Image->SubMask->FillRect(Rect(0, 0, Image->SubMask->Width, Image->SubMask->Height), clBlack); Image->SubBitmap->StartScanLine(); ShadowMask->StartScanLineN(2); for (int y = 0, sty = 0; y < ShadowBitmap->Height; y++){ subb = Image->SubBitmap->GetScanLine(y); shm = ShadowMask->GetScanLineN(y, 0); if (y >= sy && sty < hei) shmmask = ShadowMask->GetScanLineN(masksy+sty, 1); mm = 0x80; for (int x = 0, stx = 0; x < ShadowBitmap->Width; x++){ if (x >= sx && stx < wid && y >= sy && sty < hei){ if( ((shm[(x) >> 3] & (0x80 >> ((x) & 7))) == 0) && (shmmask[(masksx+stx) >> 3] & (0x80 >> ((masksx+stx) & 7))) ){ SetPixel24(subb, shadowcolor); *shmmask |= mm; *shm |= mm; } stx++; } else { if((shm[(x) >> 3] & (0x80 >> ((x) & 7))) == 0){ SetPixel24(subb, shadowcolor); } } subb += 3; if (mm == 1) { mm = 0x80; } else mm >>= 1; } if (y >= sy && sty < hei) sty++; Image->SubBitmap->PutScanLine(y); } Image->SubBitmap->StopScanLine(); ShadowMask->StopScanLine(); } } Image->SubVisible = true; Image->Repaint(); END_LOG; } //---------------------------------------------------------------------------