//--------------------------------------------------------------------------- #include #pragma hdrstop #include "TPUnionUndo.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- //Undo À§ÇÑ ºÎºÐ/////////////////////////////////////////////////////// //--------------------------------------------------------------------------- __fastcall TUndoManager::TUndoManager(int ZoomCnt, int CountX, int CountY, TTexpiaBitmap ***Bitmap,TFileTable **TempTable, RECT **btrect, AnsiString Filename) //__fastcall TUndoManager::TUndoManager(int ZoomCnt, int CountX, int CountY, TUnionBitmap *uBitmap,TFileTable **TempTable, RECT **btrect, AnsiString Filename) { FZoomCnt= ZoomCnt; FCountX= CountX; FCountY= CountY; FBitmap= Bitmap; Table= TempTable; FileName= Filename; btRect= btrect; // FBitsPerPixel=BitsPerPixel; InitUndo(FZoomCnt); ActivateList = new TList; } //--------------------------------------------------------------------------- __fastcall TUndoManager::~TUndoManager() { ExitUndo(); if (ActivateList) delete ActivateList; } //--------------------------------------------------------------------------- void __fastcall TUndoManager::InitUndo(int FZoomCnt) { /*for(int i=0;i// FPenUndoBitmap = new TTexpiaBitmap*[FCountX * FCountY]; for(int i=0;i not alloced for than partition } //<----------------------------------------------------->// CurrentFileIndex = 0; CreateUndoFile(CurrentFileIndex); } //--------------------------------------------------------------------- void __fastcall TUndoManager::ExitUndo() { TUndoBundle *ub; AnsiString str = FileName + ".undo"; if (UndoList) { for (int i = 0; i < UndoList->Count; i++) { ub = (TUndoBundle *)UndoList->Items[i]; delete ub; ub = NULL; } UndoList->Clear(); delete UndoList; UndoList = NULL; } for(int i = 0; i < FZoomCnt; i++) { if (hCurrent_File[i]) CloseHandle(hCurrent_File[i]); } if (FileExists(str)) DeleteFile(str); //by linuxjun----delete RedoPosList for (int i = 0; i < FCountX * FCountY; i++) { if (FPenUndoBitmap[i]) { FPenUndoBitmap[i]->Destroy(); delete FPenUndoBitmap[i]; } } if(UndoCheckLoadInfo) delete[] UndoCheckLoadInfo; UndoCheckLoadInfo = NULL; if(UndoCheckLoadBundle) delete[] UndoCheckLoadBundle; UndoCheckLoadBundle=NULL; if(FPenUndoBitmap) delete[] FPenUndoBitmap; FPenUndoBitmap = NULL; if(Next_Alloc_Position) delete[] Next_Alloc_Position; Next_Alloc_Position = NULL; if(Last_Allocated_Position) delete[] Last_Allocated_Position; Last_Allocated_Position = NULL; //caution if(Last_UndoSave_Info) delete[] Last_UndoSave_Info; //by linuxjun----end of delete RedoPosList int *n = NULL; for (int i = 0; i < ActivateList->Count; i++) { n = (int *)ActivateList->Items[i]; delete n; n = NULL; } ActivateList->Clear(); } //--------------------------------------------------------------------------- bool __fastcall TUndoManager::StartUndoScanLine() { //* for UndoScan // if (!FHandle.Flags.Allocated) return false; ShareCount++; if(hBuffer!=NULL||pUndoBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, FBytesPerLine); // scanlineÀº fixed ¸¦ »ç¿ëÇØµµ µÉ °Í °°À½. zeropoint´Â?? if (hBuffer==NULL) goto fail; pUndoBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pUndoBuffer[0]==NULL) goto fail; // ActiveMin = FHeight + 1; // ¹üÀ§¸¦ ¹þ¾î³­ °ªÀ» ½áÁ༭ óÀ½ getÇÒ¶§ ¹«Á¶°Ç accessbitmapÀ» ÇÏ°Ô ÇÑ´Ù. // ActiveMax = -1; return true; fail: StopUndoScanLine(); return false; // */ } //--------------------------------------------------------------------------- bool __fastcall TUndoManager::StartUndoScanLineN(int n) { //* for UndoScan int i; ShareCount++; if(hBuffer!=NULL||pUndoBuffer[0]!=NULL) return true; hBuffer = GlobalAlloc(GHND, n * FBytesPerLine); if (hBuffer==NULL) goto fail; pUndoBuffer[0] = (BYTE *)GlobalLock(hBuffer); if (pUndoBuffer[0]==NULL) goto fail; for (i=1; i0) return; if(ShareCount<0){ ShareCount = 0; } //releaseActivePart(); if (hBuffer) { if (pUndoBuffer[0]) { GlobalUnlock(hBuffer); pUndoBuffer[0] = NULL; } GlobalFree(hBuffer); hBuffer = NULL; } //*/ } //--------------------------------------------------------------------- bool __fastcall TUndoManager::HasPenUndoBitmap(int y){ int startPart = FUnion2PartN( 0, y ); int endPart = startPart + FCountX - 1; for( int i = startPart; i <= endPart; i ++ ) { if (!(FPenUndoBitmap[i]->Blank)||Table[0][i].undosave){ // if (Table[0][i].undosave){ return true; } } return false; } //--------------------------------------------------------------------- bool __fastcall TUndoManager::HasPenUndoBitmap(int y,int StartX,int len){ int startPart = FUnion2PartN( StartX, y ); int endPart = FUnion2PartN( StartX + len -1, y ); for( int i = startPart; i <= endPart; i ++ ) { if (!(FPenUndoBitmap[i]->Blank)||Table[0][i].undosave){ // if (Table[0][i].undosave){ return true; } } return false; } //--------------------------------------------------------------------- bool __fastcall TUndoManager::HasPenUndoBitmap(int y,int StartX,int len,int width){ int startPart = FUnion2PartN( StartX, y ); int endPart = FUnion2PartN( StartX + len -1, y ); for( int i = startPart; i <= endPart; i ++ ) { if (!(FPenUndoBitmap[i]->Blank)||Table[0][i].undosave){ return true; } } if(width == 0)return false; startPart = FUnion2PartN( StartX+width, y ); endPart = FUnion2PartN( StartX+width+len-1, y ); for( int i = startPart; i <= endPart; i ++ ) { if (!(FPenUndoBitmap[i]->Blank)||Table[0][i].undosave){ return true; } } return false; } //--------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLinePart(int y,int part){ if (FPenUndoBitmap[part]->Blank){ L_GetBitmapRow(FBitmap[0][part]->Handle, pUndoBuffer[0] + btRect[0][part].left * FBitsPerPixel / 8, y - btRect[0][part].top , FBitmap[0][part]->Handle->BytesPerLine); }else{ UndoCheckLoad(part); L_GetBitmapRow(FPenUndoBitmap[part]->Handle, pUndoBuffer[0] + btRect[0][part].left * FBitsPerPixel / 8, y - btRect[0][part].top ,FPenUndoBitmap[part]->Handle->BytesPerLine); } return pUndoBuffer[0]; } //--------------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLinePartN(int y,int part,int num){ if (FPenUndoBitmap[part]->Blank){ L_GetBitmapRow(FBitmap[0][part]->Handle, pUndoBuffer[num] + btRect[0][part].left * FBitsPerPixel / 8, y - btRect[0][part].top , FBitmap[0][part]->Handle->BytesPerLine); }else{ UndoCheckLoad(part); L_GetBitmapRow(FPenUndoBitmap[part]->Handle, pUndoBuffer[num] + btRect[0][part].left * FBitsPerPixel / 8, y - btRect[0][part].top , FPenUndoBitmap[part]->Handle->BytesPerLine); } return pUndoBuffer[num]; } //--------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLine(int y){ //* for UndoScan int startPart = FUnion2PartN( 0, y ); int endPart = startPart + FCountX - 1; // checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { if (FPenUndoBitmap[i]->Blank){ L_GetBitmapRow(FBitmap[0][i]->Handle, pUndoBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); }else{ UndoCheckLoad(i); L_GetBitmapRow(FPenUndoBitmap[i]->Handle, pUndoBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top ,FPenUndoBitmap[i]->Handle->BytesPerLine); } } // */ return pUndoBuffer[0]; } //--------------------------------------------------------------------- int __fastcall TUndoManager::getMinimumDeltaY(int y1,int y2,int y3,int y4){ int dy1,dy2,dy3,dy4,y; int startPart1 = FUnion2PartN( 0, y1); int startPart2 = FUnion2PartN( 0, y2); int startPart3 = FUnion2PartN( 0, y3); int startPart4 = FUnion2PartN( 0, y4); dy1 = btRect[0][startPart1].bottom-y1; dy2 = btRect[0][startPart2].bottom-y2; dy3 = btRect[0][startPart3].bottom-y3; dy4 = btRect[0][startPart4].bottom-y4; if(dy1 > dy2){dy1=dy2;} if(dy1 > dy3){dy1=dy3;} if(dy1 > dy4){dy1=dy4;} return dy1-1; // return 1; /* if(dy1>dy2){ return dy2-1; }else{ return dy1-1; } */ } //--------------------------------------------------------------------- int __fastcall TUndoManager::getMinimumDeltaY(int y1,int y2,int y3,int y4,int y5,int y6,int y7,int y8){ int dy1,dy2,dy3,dy4,dy5,dy6,dy7,dy8,y; int startPart1 = FUnion2PartN( 0, y1); int startPart2 = FUnion2PartN( 0, y2); int startPart3 = FUnion2PartN( 0, y3); int startPart4 = FUnion2PartN( 0, y4); int startPart5 = FUnion2PartN( 0, y5); int startPart6 = FUnion2PartN( 0, y6); int startPart7 = FUnion2PartN( 0, y7); int startPart8 = FUnion2PartN( 0, y8); dy1 = btRect[0][startPart1].bottom-y1; dy2 = btRect[0][startPart2].bottom-y2; dy3 = btRect[0][startPart3].bottom-y3; dy4 = btRect[0][startPart4].bottom-y4; dy5 = btRect[0][startPart5].bottom-y5; dy6 = btRect[0][startPart6].bottom-y6; dy7 = btRect[0][startPart7].bottom-y7; dy8 = btRect[0][startPart8].bottom-y8; if(dy1 > dy2){dy1=dy2;} if(dy1 > dy3){dy1=dy3;} if(dy1 > dy4){dy1=dy4;} if(dy1 > dy5){dy1=dy5;} if(dy1 > dy6){dy1=dy6;} if(dy1 > dy7){dy1=dy7;} if(dy1 > dy8){dy1=dy8;} return dy1-1; // return 1; /* if(dy1>dy2){ return dy2-1; }else{ return dy1-1; } */ }//--------------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLineN(int y,int num){ ///* for UndoScan int startPart = FUnion2PartN( 0, y); int endPart = startPart + FCountX - 1; //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { if (FPenUndoBitmap[i]->Blank){ L_GetBitmapRow(FBitmap[0][i]->Handle, pUndoBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); }else{ UndoCheckLoad(i); L_GetBitmapRow(FPenUndoBitmap[i]->Handle, pUndoBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FPenUndoBitmap[i]->Handle->BytesPerLine); } } // */ return pUndoBuffer[num]; } ///--------------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLine(int y,int x, int length){ ///* int startPart = FUnion2PartN( x, y); int endPart = FUnion2PartN( x + length - 1, y); //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { if (FPenUndoBitmap[i]->Blank){ L_GetBitmapRow(FBitmap[0][i]->Handle, pUndoBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); }else{ UndoCheckLoad(i); L_GetBitmapRow(FPenUndoBitmap[i]->Handle, pUndoBuffer[0] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FPenUndoBitmap[i]->Handle->BytesPerLine); } } // */ return pUndoBuffer[0]; } //--------------------------------------------------------------------------- Byte *__fastcall TUndoManager::GetUndoScanLineN(int y,int x, int length, int num){ int startPart = FUnion2PartN( x, y); int endPart = FUnion2PartN( x + length - 1, y); //checkActivePart(y, startPart, endPart); for( int i = startPart; i <= endPart; i ++ ) { if (FPenUndoBitmap[i]->Blank){ L_GetBitmapRow(FBitmap[0][i]->Handle, pUndoBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FBitmap[0][i]->Handle->BytesPerLine); }else{ UndoCheckLoad(i); L_GetBitmapRow(FPenUndoBitmap[i]->Handle, pUndoBuffer[num] + btRect[0][i].left * FBitsPerPixel / 8, y - btRect[0][i].top , FPenUndoBitmap[i]->Handle->BytesPerLine); } } return pUndoBuffer[num]; } //--------------------------------------------------------------------------- void __fastcall TUndoManager::AddUndo(bool ForRedoUse) { TUndoBundle *ub, *rb; TUndoBundle *TempUb; bool hasRedo=false; IsFirstRedoStep = !ForRedoUse; //Redo¿¡¼­ È£ÃâÀÌ µÇ¸é IsFirstRedoStepÀº false·Î setttingµÈ´Ù. for(;CurrentUndoIndexCount-2;) { if (UndoList->Count) { ub = (TUndoBundle *)UndoList->Last(); UndoList->Remove(ub); delete ub; ub = NULL; } hasRedo=true; } if(UndoList->Count>0){ if (UndoList->Count-2 == CurrentUndoIndex) { hasRedo=true; } } CurrentUndoIndex++; //caution!!! 4_29 if(!hasRedo||ForRedoUse){ ub = new TUndoBundle; if (UndoList->Count) { for(int i=0;i< FZoomCnt ;i++) ub->Pos[i] = ((TUndoBundle *)UndoList->Last())->Pos[i]; //by min woo } UndoList->Add(ub); //<---------by linuxjun ------>// UpdateNextAllocPosition(); ub->FileIndex = CurrentFileIndex; //<--------------------------->// } else{ //ReAllocate All Data properly ub = (TUndoBundle *)UndoList->Last(); TUndoBundle * ub_prev; TUndoInfo *undoInfo; Alloc_Position_Info *a_p_i; for (int j = 0; j < FCountX * FCountY; j ++ ) { Next_Alloc_Position[j].Allocated = false; //if -1 => not alloced for than partition } bool reset = true; if(UndoList->Count>1){ ub_prev = (TUndoBundle *)UndoList->Items[UndoList->Count-2]; if(ub->FileIndex!=ub_prev->FileIndex) { reset = false; } } // if(ub->FileIndex == 0 || ub->Pos[0] != 0){ //ÆÄÀÏÀÌ »õ·Î »ý¼ºµÈ »óÅ¿¡¼­ undoÇϰí AddUndoÇϸé error³ª´Â°Í ¶§¹®¿¡ ¸¸µë for (int j = 0; j < ub->NextAllocPos_InCurrentStep_Info_List->Count; j++) { a_p_i = (struct Alloc_Position_Info *)ub->NextAllocPos_InCurrentStep_Info_List->Items[j]; Next_Alloc_Position[a_p_i->Number].Allocated = true; for(int k=0;kNumber].pos[k] = a_p_i->pos[k]; } } for(;ub->UndoInfoList->Count > 0;){ undoInfo = (TUndoInfo *)ub->UndoInfoList->Last(); if(!Next_Alloc_Position[undoInfo->Number].Allocated){ for(int i = 0; i < FZoomCnt; i++){ ub->Pos[i] -= Table[i][undoInfo->Number].size; } } ub->UndoInfoList->Remove(undoInfo); delete undoInfo; undoInfo = NULL; } for(;ub->RedoInfoList->Count > 0;){ undoInfo = (TUndoInfo *)ub->RedoInfoList->Last(); ub->RedoInfoList->Remove(undoInfo); delete undoInfo; undoInfo = NULL; } if (!reset){ if (hCurrent_File[0] != NULL) { for(int i = 0; i < FZoomCnt; i++) CloseHandle(hCurrent_File[i]); } CurrentFileIndex=ub->FileIndex; CreateUndoFile(CurrentFileIndex); for (int i = 0; i < FZoomCnt; i++) ub->Pos[i] = 0; for(int i = 0 ; i < FCountX * FCountY ; i++ ) Next_Alloc_Position[i].Allocated=false; } } for (int i = 0; i < FCountX * FCountY; i ++ ) Table[0][i].undosave = false; } //--------------------------------------------------------------------- void __fastcall TUndoManager::CreateUndoFile(DWORD FileIndex) { AnsiString str; UnicodeString strw; Byte undoCount = 0, current = 0; for(int i=0;iFileIndex != CurrentFileIndex) { CurrentFileIndex = ub->FileIndex; if(hCurrent_File[0] != NULL) { for(int i=0;iPos = ((TUndoBundle *)UndoList->Last())->Pos; //need correction TUndoBundle * ub=(TUndoBundle *)UndoList->Last(); //DWORD ui_pos = ((TUndoBundle *)UndoList->Last())->Pos; DWORD ui_pos[MAX_ZOOM_LEVEL]; for(int i=0;iPos[i]; } for (int i = 0; i < FCountX * FCountY; i ++ ) { // Last_UndoSave_Info[i]=false; //for Using Undosave in loadRedo if (Table[0][i].undosave) { //if (Next_Alloc_Position[i]!=-1) if ( !Next_Alloc_Position[i].Allocated ) { //if allocted is false , then at SaveUndo(), Partition # i is memorized at the End Of File //and allocate new free space for next use,i so make allocated as false , and use that memory space for Partition # i // Last_UndoSave_Info[i]=true; //only used for last Redo Step Next_Alloc_Position[i].Allocated=true; //Next_Alloc_Position[i]=ui_pos; for(int j=0;j=1000000){ ui_pos[j].hUndoFile = CreateFile(str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, ui_pos[j].startpos=0; }*/ } //<----------add Alloc_Pos_info_list---->// Alloc_Position_Info *A_P_I = new Alloc_Position_Info; A_P_I->Number = i; //A_P_I->pos = ui_pos; for(int j=0;jpos[j] = Next_Alloc_Position[i].pos[j]; } ub->Alloced_InCurrentStep_Position_Info_List->Add(A_P_I); //<------------------------------------->// } } } //<---------------------Updated NextAllocation PositionTable-------------->// for (int i = 0; i < FCountX * FCountY; i ++ ) { if ( Next_Alloc_Position[i].Allocated ) { //<----------add Alloc_Pos_info_list---->// Alloc_Position_Info *A_P_I = new Alloc_Position_Info; A_P_I->Number = i; for(int j=0;jpos[j] = Next_Alloc_Position[i].pos[j]; } ub->NextAllocPos_InCurrentStep_Info_List->Add(A_P_I); //<------------------------------------->// } } //<----------------------------------------------------------------------->// for(int i=0;iLast())->Pos[i] = ui_pos[i]; //caution } // if(ub->Pos[0] > 100000) // if(ub->Pos[0] > 0xFFFFFFFF) if(ub->Pos[0] > (DWORD)2*1024*1024*1024) // if(ub->Pos[0] > 2*1024*1024) { if(hCurrent_File[0] != NULL) { for(int i=0;iPos[i] = 0; for(int i = 0 ; i < FCountX * FCountY ; i++ ) Next_Alloc_Position[i].Allocated=false; } // Table[0][i].undosave = false; } //--------------------------------------------------------------------- /* Complete */ void __fastcall TUndoManager::SaveUndo(int n) { if (Table[0][n].undosave==false) { if(UndoList->Count>0){ TUndoBundle *ub = (TUndoBundle *)UndoList->Last(); TUndoInfo *undoInfo = new TUndoInfo; undoInfo->Number = n; undoInfo->BitsPerPixel = FBitmap[0][n]->BitsPerPixel; //need correction //undoInfo->pos = ub->Pos; //need correction if (Next_Alloc_Position[n].Allocated) { for(int i=0;ipos[i] = Next_Alloc_Position[n].pos[i]; //by linuxjun } Next_Alloc_Position[n].Allocated = false; }else { for(int i=0;ipos[i] = ub->Pos[i]; ub->Pos[i] = ub->Pos[i] + Table[i][n].size; } } SaveUndoData(undoInfo); ub->UndoInfoList->Add(undoInfo); Table[0][n].undosave = true; } } } //--------------------------------------------------------------------------- void __fastcall TUndoManager::RangeSaveUndo(int StartX,int StartY,int EndX,int EndY) { int StartColNum,EndColNum,StartRowNum, EndRowNum; StartColNum=FUnion2PartN(StartX,0); EndColNum=FUnion2PartN(EndX,0); StartRowNum=FUnion2PartN(0,StartY)/FCountX; EndRowNum=FUnion2PartN(0, EndY)/FCountX; for(int i=StartRowNum;i<=EndRowNum;i++) { for(int j=StartColNum;j<=EndColNum;j++) { SaveUndo(i*FCountX+j); } } } void __fastcall TUndoManager::LineSaveUndo(int StartX,int StartY,int len) { int StartColNum,EndColNum,StartRowNum, EndRowNum; StartColNum=FUnion2PartN(StartX,0); EndColNum=FUnion2PartN(StartX+len,0); StartRowNum=FUnion2PartN(0,StartY)/FCountX; for(int i=StartColNum;i<=EndColNum;i++) { if (Table[0][StartRowNum*FCountX+i].undosave==false) { SaveUndo(StartRowNum*FCountX+i); } } } //--------------------------------------------------------------------------- void __fastcall TUndoManager::RectSaveUndo(RECT rect) { RangeSaveUndo(rect.left, rect.top , rect.right , rect.bottom); } //--------------------------------------------------------------------------- /*Complete*/ void __fastcall TUndoManager::LoadUndoWithOutIndexChange() { TUndoBundle *ub; TUndoInfo *ui, *ri; if (CurrentUndoIndex>=0) { ub = (TUndoBundle *)UndoList->Items[CurrentUndoIndex]; UpdateFileHandle(ub); for (int i = 0; i < ub->UndoInfoList->Count; i++) { ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; LoadUndoData(ui); } } } //--------------------------------------------------------------------------- /*Complete*/ void __fastcall TUndoManager::LoadAutoRepeatPenUndo() { TUndoBundle *ub; TUndoInfo *ui, *ri; int tempFileIndex=CurrentFileIndex; if (PenUndoCurrentIndex>=-1 && PenUndoStartIndex > -1) { for (int i = 0; i < FCountX*FCountY; i++) { if(FPenUndoBitmap[i]->Blank == false) { //FPenUndoBitmap[i]->Blank=true; FPenUndoBitmap[i]->Destroy(); FPenUndoBitmap[i]->Blank=true; } } if (PenUndoStartIndex >= UndoList->Count){ PenUndoStartIndex = UndoList->Count - 1; } for (int j = PenUndoStartIndex ; j > PenUndoCurrentIndex; j--) { ub = (TUndoBundle *)UndoList->Items[ j ]; UpdateFileHandle(ub); for (int i = 0; i < ub->UndoInfoList->Count; i++) { ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; if(FPenUndoBitmap[ui->Number]->Blank == false) { //FPenUndoBitmap[i]->Blank=true; FPenUndoBitmap[ui->Number]->Destroy(); // FPenUndoBitmap[i]->Blank=true; } FPenUndoBitmap[ui->Number]->Blank=false; UndoCheckLoadInfo[ui->Number]=ui; UndoCheckLoadBundle[ui->Number]=ub; //LoadPenUndoData(ui, rgb); } // PenUndoCurrentIndex--; //UndoIndex is increasing when LoadUndo. //but, PenUndoIndex is decreasing when LoadPenUndo. don't confuse it. } //////////////////////////// UpdateFileHandle(tempFileIndex); //////////////////////////// } } //--------------------------------------------------------------------------- /*Complete*/ void __fastcall TUndoManager::LoadPenUndo(RGBQUAD *rgb) { TUndoBundle *ub; TUndoInfo *ui, *ri; int tempFileIndex=CurrentFileIndex; if (PenUndoCurrentIndex>=0 && UndoList->Count > PenUndoCurrentIndex) { //ub = (TUndoBundle *)UndoList->Items[UndoList->Count - UndoIndex -1]; if (rgb) memcpy(RGB, rgb, sizeof(RGBQUAD)*256); //qe caution UndoCheckLoadIndex=PenUndoCurrentIndex; ub = (TUndoBundle *)UndoList->Items[ PenUndoCurrentIndex-- ]; UpdateFileHandle(ub); /* for (int i = 0; i < FCountX*FCountY; i++) { if(FPenUndoBitmap[i]->Blank == false&&) { //FPenUndoBitmap[i]->Blank=true; FPenUndoBitmap[i]->Destroy(); // FPenUndoBitmap[i]->Blank=true; } //LoadPenUndoData(ui, rgb); } */ for (int i = 0; i < ub->UndoInfoList->Count; i++) { ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; if(FPenUndoBitmap[ui->Number]->Blank == false) { //FPenUndoBitmap[i]->Blank=true; FPenUndoBitmap[ui->Number]->Destroy(); // FPenUndoBitmap[i]->Blank=true; } FPenUndoBitmap[ui->Number]->Blank=false; UndoCheckLoadInfo[ui->Number]=ui; UndoCheckLoadBundle[ui->Number]=ub; //LoadPenUndoData(ui, rgb); } // PenUndoCurrentIndex--; //UndoIndex is increasing when LoadUndo. //but, PenUndoIndex is decreasing when LoadPenUndo. don't confuse it. //////////////////////////// UpdateFileHandle(tempFileIndex); //////////////////////////// } } //--------------------------------------------------------------------------- /*Complete*/ void __fastcall TUndoManager::LoadLast(RGBQUAD *rgb) { TUndoBundle *ub; TUndoInfo *ui, *ri; //ÃʱâÈ­ /* for(int i=0;iBitsPerPixel!=0) FPenUndoBitmap[i]->Destroy(); } */ //loading //qe caution // if (PenUndoCurrentIndex>=0) { //error³ª¸é »ý°¢Çغ¸±æ... if (CurrentUndoIndex>=0) { if (rgb) memcpy(RGB, rgb, sizeof(RGBQUAD)*256); //ub = (TUndoBundle *)UndoList->Items[UndoList->Count - UndoIndex -1]; // ub = (TUndoBundle *)UndoList->Items[ PenUndoCurrentIndex-- ]; for (int i = 0; i < FCountX*FCountY; i++) { if(FPenUndoBitmap[i]->Blank == false) { //FPenUndoBitmap[i]->Blank=true; FPenUndoBitmap[i]->Destroy(); FPenUndoBitmap[i]->Blank=true; } //LoadPenUndoData(ui, rgb); } ub = (TUndoBundle *)UndoList->Items[ CurrentUndoIndex ]; UpdateFileHandle(ub); for (int i = 0; i < ub->UndoInfoList->Count; i++) { ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; FPenUndoBitmap[ui->Number]->Blank=false; UndoCheckLoadInfo[ui->Number]=ui; UndoCheckLoadBundle[ui->Number]=ub; //LoadPenUndoData(ui, rgb); } UndoCheckLoadIndex=CurrentUndoIndex; // PenUndoCurrentIndex--; //UndoIndex is increasing when LoadUndo. //but, PenUndoIndex is decreasing when LoadPenUndo. don't confuse it. } } //<------------------------local function---------------------->// bool __fastcall TUndoManager::LoadPenUndoData(TUndoInfo *penui,RGBQUAD *rgb_quad) { //by min woo if (FPenUndoBitmap[penui->Number]->BitsPerPixel == 0) { SetFilePointer(hCurrent_File[0], penui->pos[0], 0, FILE_BEGIN); int w,h; Rearrange(penui->Number); w=btRect[0][penui->Number].right - btRect[0][penui->Number].left; h=btRect[0][penui->Number].bottom - btRect[0][penui->Number].top; if (penui->BitsPerPixel==8) { // FPenUndoBitmap[penui->Number]->Create(w,h,penui->BitsPerPixel,rgb_quad); FPenUndoBitmap[penui->Number]->Create(w,h,FBitsPerPixel,rgb_quad); }else { // FPenUndoBitmap[penui->Number]->Create(w,h,penui->BitsPerPixel); FPenUndoBitmap[penui->Number]->Create(w,h,FBitsPerPixel); } if (!FPenUndoBitmap[penui->Number]->LoadFromTexpiaFile(hCurrent_File[0], cmNone)) return false; } // Table[i][penui->Number].modify = true; // Table[i][upeni->Number].modify = false; // Table[0][ui->Number].modify = true; // Table[0][penui->Number].blank = false; return true; } //<------------------------------------------------------------>// //--------------------------------------------------------------------- /*Complete*/ void __fastcall TUndoManager::LoadRedo() { TUndoBundle *rb; TUndoInfo *ri; // if (UndoIndex > 0 && UndoIndex <= RedoList->Count) { // if (UndoIndex > 0 && UndoIndex < UndoList->Count) { if (CurrentUndoIndex < UndoList->Count-2) { // rb = (TUndoBundle *)RedoList->Items[UndoIndex]; //by linuxjun // rb = (TUndoBundle *)UndoList->Items[UndoList->Count - UndoIndex -1]; //by linuxjun rb = (TUndoBundle *)UndoList->Items[++CurrentUndoIndex]; //by linuxjun UpdateFileHandle(rb); for (int i = 0; i < rb->RedoInfoList->Count; i++) { ri = (TUndoInfo *)rb->RedoInfoList->Items[i]; LoadUndoData(ri); } // UndoIndex--; } } //--------------------------------------------------------------------------- void __fastcall TUndoManager::LoadUndo() { TUndoBundle *ub; TUndoInfo *ui, *ri; // if (UndoIndex + 1 < UndoList->Count) { if (CurrentUndoIndex>=0) { SaveRedo(); // UndoIndex++; // CurrentUndoIndex--; // ub = (TUndoBundle *)UndoList->Items[UndoList->Count - UndoIndex -1]; ub = (TUndoBundle *)UndoList->Items[CurrentUndoIndex--]; UpdateFileHandle(ub); for (int i = 0; i < ub->UndoInfoList->Count; i++) { ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; LoadUndoData(ui); } //<----needed for refresh Alloc_Position_Table----->// //<------------------------------------------------>// } } //--------------------------------------------------------------------- void __fastcall TUndoManager::SaveRedo() { TUndoBundle *ub, *rb; TUndoInfo *ui, *ri; // when we use undo at first time, we must swap all allocated file space if(IsFirstRedoStep) { // IsFirstRedoStep = false; AddUndo(true); //caution! TUndoBundle * Last_ub=(TUndoBundle *)UndoList->Last(); for(int i =0 ; iNextAllocPos_InCurrentStep_Info_List->Count;i++){ int tempNumber=((Alloc_Position_Info *)Last_ub->NextAllocPos_InCurrentStep_Info_List->Items[i])->Number; for(int j=0;jNextAllocPos_InCurrentStep_Info_List->Items[i])->pos[j]; } Last_Allocated_Position[tempNumber].Allocated = true; } CurrentUndoIndex--; //<------------------------------------------------------------>// } // rb = (TUndoBundle *)UndoList->Items[UndoList->Count - UndoIndex -2]; //by linuxjun rb = (TUndoBundle *)UndoList->Items[CurrentUndoIndex]; //by linuxjun UpdateFileHandle(rb); if( rb->RedoInfoList->Count == 0 ) { //case ii) UndoIndex=0 and RedoList->Count=1 (Undo, Redo) ub = (TUndoBundle *)UndoList->Items[CurrentUndoIndex+1]; //by linuxjun if(ub->FileIndex!=rb->FileIndex) { // IsFirstRedoStep = false; // TUndoBundle * Last_ub=(TUndoBundle *)UndoList->Last(); for(int i =0 ; iNextAllocPos_InCurrentStep_Info_List->Count;i++){ int tempNumber=((Alloc_Position_Info *)ub->NextAllocPos_InCurrentStep_Info_List->Items[i])->Number; for(int j=0;jNextAllocPos_InCurrentStep_Info_List->Items[i])->pos[j]; } Last_Allocated_Position[tempNumber].Allocated = true; } //<------------------------------------------------------------>// } TUndoInfo *undoInfo; for( int i =0 ; i< ub->Alloced_InCurrentStep_Position_Info_List->Count;i++) { undoInfo = new TUndoInfo; undoInfo->Number =((struct Alloc_Position_Info *) ub->Alloced_InCurrentStep_Position_Info_List->Items[i])->Number; for(int j=0;jpos[j] =((struct Alloc_Position_Info *) ub->Alloced_InCurrentStep_Position_Info_List->Items[i])->pos[j]; } //when the data for redo is not saved, save it!!! if(Last_Allocated_Position[undoInfo->Number].pos[0]==undoInfo->pos[0]){ SaveUndoData(undoInfo); //¿©±â¸¦ Á¦´ë·Î Áö³ª´ÂÁö È®ÀÎÇØ¾ßÇÔ. } rb->RedoInfoList->Add(undoInfo); } } } //--------------------------------------------------------------------- void __fastcall TUndoManager::RemoveFirst() { AnsiString str; TUndoBundle *ub; TUndoBundle *next_ub; int FileIndex; if(UndoList->Count>0 && CurrentUndoIndex>=0){ ub = (TUndoBundle *)UndoList->First(); if(UndoList->Count>1){ next_ub= (TUndoBundle *)UndoList->Items[1]; if(ub->FileIndex != next_ub->FileIndex){ FileIndex = ub->FileIndex; for(int i=0;iUndoInfoList->Count; i++) { TUndoInfo *ui = (TUndoInfo *)ub->UndoInfoList->Items[i]; if(FPenUndoBitmap[ui->Number]->Blank == false) { FPenUndoBitmap[ui->Number]->Destroy(); FPenUndoBitmap[ui->Number]->Blank = true; } UndoCheckLoadInfo[ui->Number] = NULL; UndoCheckLoadBundle[ui->Number] = NULL; } UndoList->Remove(ub); CurrentUndoIndex--; delete ub; ub = NULL; } } //--------------------------------------------------------------------- /* Complete */ bool __fastcall TUndoManager::SaveUndoData(TUndoInfo *ui) { //for(int i=0;ipos[i], 0, FILE_BEGIN); FCheckLoad(ui->Number,i); if (!FBitmap[i][ui->Number]->SaveToTexpiaFile(hCurrent_File[i], cmNone)) goto fail; } return true; fail: return false; } //--------------------------------------------------------------------- /* Complete */ bool __fastcall TUndoManager::LoadUndoData(TUndoInfo *ui) { //for(int i=0;ipos[i], 0, FILE_BEGIN); if (!FIsMemory(ui->Number,i)) { FReCreate(ui->Number,i); } if (!FBitmap[i][ui->Number]->LoadFromTexpiaFile(hCurrent_File[i], cmNone)) goto fail; Table[i][ui->Number].modify = true; Table[i][ui->Number].isZoomUpdated = false; } /////Àӽà for(int i=0;iNumber].modify = true; Table[i][ui->Number].isZoomUpdated = false; } /////Àӽà Table[0][ui->Number].blank = false; return true; fail: return false; } //--------------------------------------------------------------------- void __fastcall TUndoManager::UndoCheckLoad(int n) { // if (PenUndoCurrentIndex < -1) return; if (FPenUndoBitmap[n]->BitsPerPixel != 0) return; if (UndoCheckLoadIndex < 0) return; // TUndoBundle *ub = (TUndoBundle *)UndoList->Items[UndoCheckLoadIndex]; /* int i; for(i=0;iUndoInfoList->Count;i++){ TUndoInfo * ui=(TUndoInfo *)ub->UndoInfoList->Items[i]; if(ui->Number==n){ n=i; break; } } if(i==ub->UndoInfoList->Count) return; TUndoInfo *ui = (TUndoInfo *)ub->UndoInfoList->Items[n]; LoadPenUndoData(ui, RGB); */ if(UndoCheckLoadInfo[n]){ int tempFileIndex = CurrentFileIndex; TUndoInfo *ui = UndoCheckLoadInfo[n]; if (ui) { UpdateFileHandle(UndoCheckLoadBundle[n]); LoadPenUndoData(ui, RGB); } UpdateFileHandle(tempFileIndex); } } //--------------------------------------------------------------------------- void __fastcall TUndoManager::Rearrange(int n) { int *Nth = new int; int ActiveCnt = FCountX * 3; if(ActivateList->Count > 0) { while(ActivateList->Count >= ActiveCnt){ if(!swapOutPartition())break; } } *Nth = n; ActivateList->Add(Nth); } //--------------------------------------------------------------------------- bool __fastcall TUndoManager::swapOutPartition() { int *n = (int *)ActivateList->First(); if(!FPenUndoBitmap[*n]->IsUse){ ActivateList->Remove(n); FPenUndoBitmap[*n]->Destroy(); delete n; n = NULL; return true; } else { return false; } } //--------------------------------------------------------------------------- __fastcall TUndoBundle::TUndoBundle() { UndoInfoList = new TList; RedoInfoList = new TList; Alloced_InCurrentStep_Position_Info_List = new TList; NextAllocPos_InCurrentStep_Info_List = new TList; for(int i=0;iCount; i++) { ui = (TUndoInfo *)UndoInfoList->Items[i]; delete ui; ui = NULL; } UndoInfoList->Clear(); for (int i = 0; i < RedoInfoList->Count; i++) { ui = (TUndoInfo *)RedoInfoList->Items[i]; delete ui; ui = NULL; } RedoInfoList->Clear(); Alloc_Position_Info *a_p_i; for (int i = 0; i < Alloced_InCurrentStep_Position_Info_List->Count; i++) { a_p_i = (Alloc_Position_Info *)Alloced_InCurrentStep_Position_Info_List->Items[i]; delete a_p_i; a_p_i = NULL; } Alloced_InCurrentStep_Position_Info_List->Clear(); for (int i = 0; i < NextAllocPos_InCurrentStep_Info_List->Count; i++) { a_p_i = (Alloc_Position_Info *)NextAllocPos_InCurrentStep_Info_List->Items[i]; delete a_p_i; a_p_i = NULL; } NextAllocPos_InCurrentStep_Info_List->Clear(); delete UndoInfoList; UndoInfoList=NULL; delete RedoInfoList; RedoInfoList=NULL; delete Alloced_InCurrentStep_Position_Info_List; Alloced_InCurrentStep_Position_Info_List=NULL; delete NextAllocPos_InCurrentStep_Info_List; NextAllocPos_InCurrentStep_Info_List=NULL; } //--------------------------------------------------------------------------- RECT __fastcall TUndoManager::GetUndoRect() { int startPart = 0; int endPart = FCountY * FCountX - 1; RECT undoRect = {btRect[0][FCountY * FCountX - 1].right, btRect[0][FCountY * FCountX - 1].bottom, 0, 0}; for( int i = startPart; i <= endPart; i ++ ) { if (!(FPenUndoBitmap[i]->Blank)||Table[0][i].undosave){ if (btRect[0][i].left < undoRect.left) { undoRect.left = btRect[0][i].left; } if (btRect[0][i].right > undoRect.right) { undoRect.right = btRect[0][i].right; } if (btRect[0][i].top < undoRect.top) { undoRect.top = btRect[0][i].top; } if (btRect[0][i].bottom > undoRect.bottom) { undoRect.bottom = btRect[0][i].bottom; } } } return undoRect; } //---------------------------------------------------------------------------