//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Undo.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- TUndo *Undo; //--------------------------------------------------------------------------- // TUndoData //--------------------------------------------------------------------------- __fastcall TUndoData::TUndoData(int inst, char *szTmpFile) { Instance = inst; Filename = szTmpFile; IsMemory = true; IsFile = false; IsUse = false; Bitmap = Mask = Mark = NULL; Palette = NULL; Region = NULL; } //--------------------------------------------------------------------------- __fastcall TUndoData::~TUndoData() { if (IsFile) DeleteFile(Filename); if (Region) DeleteObject(Region); if (Palette) delete Palette; if (Mask) delete Mask; if (Mark) delete Mark; if (Bitmap) delete Bitmap; } //--------------------------------------------------------------------------- TPException __fastcall TUndoData::SaveToFile(HANDLE fh, TTexpiaBitmap *Bitmap) { int w, h, ec = EC_NONE; WORD bpp; DWORD dwWrite; RGBQUAD rgb[256]; if (Bitmap) { w = Bitmap->Width; h = Bitmap->Height; bpp = Bitmap->BitsPerPixel; if (!WriteFile(fh, &w, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &h, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &bpp, sizeof(WORD), &dwWrite, NULL)) goto fail; if (bpp == 8) { Bitmap->GetColors(0, 256, rgb); if (!WriteFile(fh, &rgb, 256*sizeof(RGBQUAD), &dwWrite, NULL)) goto fail; } if (!Bitmap->SaveToTexpiaFile(fh, cmZLib)) { ec = EC_MEMORY_LACK; goto fail; } } return EC_NONE; fail: if (ec == EC_NONE) ec = EC_FILE_NOT_WRITE; return ec; } //--------------------------------------------------------------------------- TPException __fastcall TUndoData::LoadFromFile(HANDLE fh, TTexpiaBitmap *Bitmap) { int w, h, ec = EC_NONE; WORD bpp; DWORD dwRead; RGBQUAD rgb[256]; if (Bitmap) { if (!ReadFile(fh, &w, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &h, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &bpp, sizeof(WORD), &dwRead, NULL)) goto fail; if (bpp == 8) { if (!ReadFile(fh, &rgb, 256*sizeof(RGBQUAD), &dwRead, NULL)) goto fail; if (!Bitmap->Create(w, h, bpp, rgb)) { ec = EC_MEMORY_LACK; goto fail; } } else { if (!Bitmap->Create(w, h, bpp)) { ec = EC_MEMORY_LACK; goto fail; } } if (!Bitmap->LoadFromTexpiaFile(fh, cmZLib)) { ec = EC_MEMORY_LACK; goto fail; } } return EC_NONE; fail: if (ec == EC_NONE) ec = EC_FILE_NOT_READ; return ec; } //--------------------------------------------------------------------------- TPException __fastcall TUndoData::SaveToFile() { int ec = EC_NONE; HANDLE hFile = INVALID_HANDLE_VALUE; if ((hFile = CreateFile(Filename.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { ec = EC_FILE_NOT_CREATE; goto fail; } if (Bitmap) { if ((ec = SaveToFile(hFile, Bitmap)) != EC_NONE) goto fail; Bitmap->Destroy(); } if (Mask) { if ((ec = SaveToFile(hFile, Mask)) != EC_NONE) goto fail; Mask->Destroy(); } if (Mark) { if ((ec = SaveToFile(hFile, Mark)) != EC_NONE) goto fail; Mark->Destroy(); } CloseHandle(hFile); IsFile = true; IsMemory = false; return EC_NONE; fail: if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return ec; } //--------------------------------------------------------------------------- TPException __fastcall TUndoData::LoadFromFile() { int ec = EC_NONE; HANDLE hFile = INVALID_HANDLE_VALUE; if (!IsMemory) { if ((hFile = CreateFile(Filename.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { ec = EC_FILE_NOT_OPEN; goto fail; } if (Bitmap) { if ((ec = LoadFromFile(hFile, Bitmap)) != EC_NONE) goto fail; } if (Mask) { if ((ec = LoadFromFile(hFile, Mask)) != EC_NONE) goto fail; } if (Mark) { if ((ec = LoadFromFile(hFile, Mark)) != EC_NONE) goto fail; } CloseHandle(hFile); IsMemory = true; } return EC_NONE; fail: if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile); return ec; } //--------------------------------------------------------------------------- void __fastcall TUndoData::Complete() { IsUse = true; } //--------------------------------------------------------------------------- void __fastcall TUndoData::DestroyInMemory(bool bStart) { if (IsUse) return; if (IsFile) { if (IsMemory) { if (Bitmap) Bitmap->Destroy(); if (Mask) Mask->Destroy(); if (Mark) Mark->Destroy(); IsMemory = false; } } else { if (bStart) SaveToFile(); } } //--------------------------------------------------------------------------- bool __fastcall TUndoData::Equal(int inst) { return Instance == inst; } //--------------------------------------------------------------------------- // TUndo //--------------------------------------------------------------------------- __fastcall TUndo::TUndo() { Number = 0; DataList = new TList; FMethod = UM_STACK; Maximum = 3; } //--------------------------------------------------------------------------- __fastcall TUndo::~TUndo() { TUndoData *data; while (DataList->Count>0) { data = (TUndoData *)DataList->Last(); DataList->Remove(data); delete data; } delete DataList; } //--------------------------------------------------------------------------- // Private Function //--------------------------------------------------------------------------- int __fastcall TUndo::GetCount() { int count = 0; for (int i=DataList->Count-1; i>=0; i--) { TUndoData *data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) count++; } return count; } //--------------------------------------------------------------------------- TUndoData *__fastcall TUndo::GetLast() { for (int i=DataList->Count-1; i>=0; i--) { TUndoData *data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { if (data->LoadFromFile() != EC_NONE) goto fail; data->IsUse = true; return data; } } fail: return NULL; } //--------------------------------------------------------------------------- void __fastcall TUndo::SetMethod(EUndoMethod Value) { if (FMethod != Value) FMethod = Value; } //--------------------------------------------------------------------------- bool __fastcall TUndo::SaveData(int k, RECT r, bool down) { TUndoData *data = NULL; RGBQUAD rgb[256]; BITMAPHANDLE *bh; RGNXFORM XForm; char szTmpFile[MAX_PATH+1]; sprintf(szTmpFile, "%s\\TPU%05x.TMP", DirectoryTemp.c_str(), Number); if (Number & 0xFFFFF) Number++; else Number = 1; if ((data = new TUndoData(Instance, szTmpFile))==NULL) goto fail; if (down == false) { int temp = Image->ArrayBitmap[0].Height - r.bottom; r.bottom = Image->ArrayBitmap[0].Height - r.top; r.top = temp; } data->Range = r; if (k&UK_PATTERN) { if ((data->Bitmap = new TTexpiaBitmap)==NULL) goto fail; if (data->Bitmap->Create(r.right-r.left, r.bottom-r.top, Image->ArrayBitmap[0].BitsPerPixel)==false) goto fail; if (Image->ArrayBitmap[0].BitsPerPixel==8) { if (Palette) Palette->ToRGBQUAD(rgb, 256); else Image->Bitmap->GetColors(0, 256, rgb); data->Bitmap->PutColors(0, 256, rgb); } data->Bitmap->CopyFromRect(&Image->ArrayBitmap[0], r.left, r.top, SRCCOPY); if (Palette) { if ((data->Palette = new TPalette)==NULL) goto fail; data->Palette->SetPalette(Palette); } } if (k&UK_MASK) { if (Image->Mask) { if ((data->Mask = new TTexpiaBitmap)==NULL) goto fail; if (data->Mask->Create(r.right-r.left, r.bottom-r.top, Image->Mask->BitsPerPixel)==false) goto fail; if (Image->Mask->BitsPerPixel==8) { Image->Mask->GetColors(0, 256, rgb); data->Mask->PutColors(0, 256, rgb); } data->Mask->CopyFromRect(Image->Mask, r.left, r.top, SRCCOPY); } } if (k&UK_WORKAREA) { bh = Image->Bitmap->Handle; if (bh) { if (L_BitmapHasRgn(bh)) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_GetBitmapRgnHandle(bh, &XForm, &data->Region); } } } if (k&UK_MARK) { if (&Image->ArrayBitmap[1]) { if ((data->Mark = new TTexpiaBitmap)==NULL) goto fail; if (data->Mark->Create(r.right-r.left, r.bottom-r.top, 8)==false) goto fail; if (Image->ArrayBitmap[1].BitsPerPixel==8) { Image->ArrayBitmap[1].GetColors(0, 256, rgb); data->Mark->PutColors(0, 256, rgb); } data->Mark->CopyFromRect(&Image->ArrayBitmap[1], r.left, r.top, SRCCOPY); } } data->Kind = k; DataList->Add(data); // if (bSave) Arrange(); return true; fail: if (data) delete data; return false; } //--------------------------------------------------------------------------- void __fastcall TUndo::ReadData(TUndoData *data) { RGBQUAD rgb[256]; RGNXFORM XForm; if (data->Kind&UK_PATTERN) { if (data->Bitmap->BitsPerPixel==8) { if (data->Palette) data->Palette->ToRGBQUAD(rgb, 256); else Image->ArrayBitmap[0].GetColors(0, 256, rgb); Image->ArrayBitmap[0].PutColors(0, 256, rgb); } Image->ArrayBitmap[0].CopyToRect(data->Range.left, data->Range.top, data->Bitmap, SRCCOPY); if (Palette) Palette->SetPalette(data->Palette); } if (data->Kind&UK_MASK) { if (Image->Mask) { if (data->Mask->BitsPerPixel==8) { data->Mask->GetColors(0, 256, rgb); Image->Mask->PutColors(0, 256, rgb); } Image->Mask->CopyToRect(data->Range.left, data->Range.top, data->Mask, SRCCOPY); } } if (data->Kind&UK_WORKAREA) { if (data->Region) { XForm.uViewPerspective = TOP_LEFT; XForm.nXScalarNum = 1; XForm.nXScalarDen = 1; XForm.nYScalarNum = 1; XForm.nYScalarDen = 1; XForm.nXOffset = 0; XForm.nYOffset = 0; L_SetBitmapRgnHandle(Image->Bitmap->Handle, &XForm, data->Region, L_RGN_SET); //¹º°¡ ¹®Á¦µÉ ¼ÒÁö°¡ ÀÖÀ½. //¾Ö¸¦ µé¾î ArrayBitmap[1]¿¡¼­ ÀÛ¾÷±¸¿ª Àâ°í ArrayBitmap[0]¿¡¼­ ÀÛ¾÷±¸¿ª ´Ù½Ã Àâ´Â °æ¿ìµî.. /*if (data->Kind&UK_MARK) L_SetBitmapRgnHandle(Image->ArrayBitmap[1].Handle, &XForm, data->Region, L_RGN_SET); else L_SetBitmapRgnHandle(Image->ArrayBitmap[0].Handle, &XForm, data->Region, L_RGN_SET);*/ WorkArea->SetMask(data->Region); } else { WorkArea->Reset(); } } if (data->Kind&UK_MARK) { if (&Image->ArrayBitmap[1]) { Image->ArrayBitmap[1].CopyToRect(data->Range.left, data->Range.top, data->Mark, SRCCOPY); } } } //--------------------------------------------------------------------------- void __fastcall TUndo::Arrange() { int i, n; TUndoData *data; if (DataList->Count <= 0) return; if (FMethod == UM_STACK) { n = 0; for (i = DataList->Count - 1; i >= 0; i--) { data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { if (n > 0) { if (!data->IsFile) { data->SaveToFile(); } } else { data->DestroyInMemory(false); } n++; } else { data->DestroyInMemory(true); } } } else { for (i = DataList->Count - 1; i >= 0; i--) { data = (TUndoData *)DataList->Items[i]; if (!data->Equal(Instance)) { delete data; DataList->Remove(data); } } } } //--------------------------------------------------------------------------- // Public Function //--------------------------------------------------------------------------- void __fastcall TUndo::Set(int instance, TPItemImage *image, TPalette *palette, TPWorkArea *workarea) { Instance = instance; Image = image; Palette = palette; WorkArea = workarea; Arrange(); } //--------------------------------------------------------------------------- bool __fastcall TUndo::Save(int k, RECT r, bool down) { TUndoData *data; int max; if (SaveData(k, r, down)) { if (FMethod==UM_STACK) max = Maximum; else max = 1; if (DataList->Count>max) { data = (TUndoData *)DataList->First(); DataList->Remove(data); delete data; } return true; } return false; } //--------------------------------------------------------------------------- bool __fastcall TUndo::Save(int k) { return Save(k, Rect(0, 0, Image->ArrayBitmap[0].Width, Image->ArrayBitmap[0].Height), false); } //--------------------------------------------------------------------------- void __fastcall TUndo::Read(bool bDelete) { TUndoData *data = NULL; int i, ec = EC_NONE; if (FMethod == UM_STACK) { if (DataList->Count) { for (i = DataList->Count - 1; i >= 0; i--) { data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) break; } if (i >= 0) { if ((ec = data->LoadFromFile()) != EC_NONE) goto fail; data->IsUse = true; ReadData(data); data->IsUse = false; if (bDelete) { delete data; DataList->Remove(data); } } } if (DataList->Count) { for (i = DataList->Count - 1; i >= 0; i--) { data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { data->LoadFromFile(); } } } } else { if (DataList->Count) { data = (TUndoData *)DataList->Items[DataList->Count - 1]; if (bDelete) { SaveData(data->Kind, data->Range, false); ReadData(data); delete data; DataList->Remove(data); } else { ReadData(data); } } } return; fail: EXCEPTION_MESSAGE_OK(ec); } //--------------------------------------------------------------------------- void __fastcall TUndo::RemoveLast() { for (int i=DataList->Count-1; i>=0; i--) { TUndoData *data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { DataList->Remove(data); delete data; break; } } } //--------------------------------------------------------------------------- void __fastcall TUndo::RemoveAll() { for (int i=0; iCount;) { TUndoData *data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { DataList->Remove(data); delete data; } else { i++; } } } //--------------------------------------------------------------------------- bool __fastcall TUndo::InsertMarkData() { TUndoData *data; bool find = false; RGBQUAD rgb[256]; RECT r; int ec = EC_NONE; for (int i= DataList->Count-1; i>=0; i--) { data = (TUndoData *)DataList->Items[i]; if (data->Equal(Instance)) { find = true; break; } } if (find) { bool bMemory = data->IsMemory; if (!bMemory) if ((ec = data->LoadFromFile()) != EC_NONE) goto fail; if (&Image->ArrayBitmap[1]) { r = data->Range; data->Kind |= UK_MARK; if (!data->Mark) { if ((data->Mark = new TTexpiaBitmap)==NULL) goto fail; } if (!data->Mark->Create(r.right-r.left, r.bottom-r.top, 8)) goto fail; if (Image->ArrayBitmap[1].BitsPerPixel==8) { Image->ArrayBitmap[1].GetColors(0, 256, rgb); data->Mark->PutColors(0, 256, rgb); } } data->Mark->CopyFromRect(&Image->ArrayBitmap[1], r.left, r.top, SRCCOPY); if (data->IsFile) { data->SaveToFile(); if (!bMemory) data->DestroyInMemory(false); } } return true; fail: ::doDestroy(data->Mark); if (ec != EC_NONE) EXCEPTION_MESSAGE_OK(ec); return false; } //---------------------------------------------------------------------------