//--------------------------------------------------------------------------- #include #pragma hdrstop #include "VecDraw.h" #include "Vector_F.h" #include "PenManager.h" //#include "Draw_F.h" #include "Palette.h" #include "Math.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- #define MAX_UNDO 200 //--------------------------------------------------------------------------- TVecDraw *VecDraw; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TVecDraw::TVecDraw() { DataCode = T_TILE; DataList = new TList; UndoList = new TList; RedoList = new TList; CopyList = new TList; bFirst = true; bFstLine = true; bSelected = false; bProportion = false; bRotation = false; bClosedState= false; bUndosw = true; bAltState = false; bMergeMode = false; bVectorStyle= false; bExtend = false; bUnGroup = false; bLocked = false; bStyle = false; PathColor = clAqua; nSelPos = 0; ptNumber = -1; TextAngle = 0; OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); osVERSION = osvi.dwPlatformId; } //--------------------------------------------------------------------------- __fastcall TVecDraw::~TVecDraw() { while (DataList->Count) { data = (TVecData *)DataList->First(); delete data; DataList->Remove(data); } while (UndoList->Count) { udata = (TVUndoData *)UndoList->First(); if (udata->VUndoData) delete udata->VUndoData; delete udata; UndoList->Remove(udata); } while (RedoList->Count) { rdata = (TVUndoData *)RedoList->First(); if (rdata->VUndoData) delete rdata->VUndoData; delete rdata; RedoList->Remove(rdata); } while (CopyList->Count) { data = (TVecData *)CopyList->First(); delete data; CopyList->Remove(data); } delete DataList; delete UndoList; delete RedoList; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- ///////////// Class of TVecData //--------------------------------------------------------------------------- __fastcall TVecData::TVecData(int inst) { Instance = inst; bSelected = false; bFill = false; bWinding = false; bPatternFill = false; bClosed = false; bLocked = false; Bitmap = NULL; PenThick = 0; nCount = 0; GroupIndex = 0; TextString = ""; pList = NULL; memset(pMask, 0, 128); // Point MaskÃʱâÈ­ } //--------------------------------------------------------------------------- __fastcall TVecData::~TVecData() { HeapFree(GetProcessHeap(), 0, pList); HeapCompact(GetProcessHeap(), 0); } //--------------------------------------------------------------------------- bool __fastcall TVecData::Equal(int inst) { return Instance == inst; } //--------------------------------------------------------------------------- void __fastcall TVecData::Copy(TVecData *src) { Kind = src->Kind; First.x = src->First.x; First.y = src->First.y; Second.x = src->Second.x; Second.y = src->Second.y; PenStyle = src->PenStyle; PenThick = src->PenThick; nCount = src->nCount; bRound = src->bRound; bFill = src->bFill; Color = src->Color; Brush = src->Brush; Font = src->Font; bPatternFill = src->bPatternFill; bWinding = src->bWinding; bClosed = src->bClosed; GroupIndex = src->GroupIndex; bLocked = src->bLocked; if (src->Kind == V_LINE || src->Kind == V_CURVE) { if (pList != NULL) { HeapFree(GetProcessHeap(), 0, pList); pList = NULL; } pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(nCount*3+1)); // for (int j = 0; j < src->nCount*3+1; j++) { // pList[j].x = src->pList[j].x; // pList[j].y = src->pList[j].y; // } memcpy(pList, src->pList, sizeof(DPOINT)*(nCount*3+1)); memcpy(pMask, src->pMask, 32); } if (src->Kind == V_TEXT) for (int j = 0; j < src->nCount; j++) TextString = src->TextString; } //--------------------------------------------------------------------------- ///////////// Class of TVUndoData //--------------------------------------------------------------------------- __fastcall TVUndoData::TVUndoData(int inst) { Instance = inst; bFirst = true; } //--------------------------------------------------------------------------- __fastcall TVUndoData::~TVUndoData() { // } //--------------------------------------------------------------------------- bool __fastcall TVUndoData::Equal(int inst) { return Instance == inst; } //--------------------------------------------------------------------------- ///////////// Class of TVecDraw //--------------------------------------------------------------------------- #define PAINT_VECTOR \ \ SetROP2(dcDst, R2_COPYPEN); \ \ switch (data->Kind) { \ case V_LINE: \ Polyline(dcDst, pTemp, data->nCount +1); \ break; \ \ case V_CURVE: \ if (data->bFill){ \ BeginPath(dcDst); \ MoveToEx(dcDst, pTemp[0].x, pTemp[0].y, NULL); \ PolyBezierTo (dcDst, pTemp+1, data->nCount*3); \ EndPath(dcDst); \ FillPath(dcDst); \ PolyBezier(dcDst, pTemp, (data->nCount+(data->bClosed&&data->PenStyle==P_SOLID))*3+1); \ }else { \ PolyBezier(dcDst, pTemp, (data->nCount+(data->bClosed&&data->PenStyle==P_SOLID))*3+1); \ } \ break; \ \ case V_RECT: \ if (data->bRound) \ RoundRect(dcDst, FirstX, FirstY, SecondX, SecondY, pw, pw); \ else Rectangle(dcDst, FirstX, FirstY, SecondX, SecondY); \ break; \ \ case V_ELLIPSE: \ Ellipse(dcDst, FirstX, FirstY, SecondX, SecondY); \ break; \ \ case V_TEXT: \ char *tempstr; \ tempstr = (char *)malloc(data->nCount); \ for (int k = 0; k < data->nCount; k++) tempstr[k] = char(data->TextString[k+1]);\ SetTextAlign(dcDst, TA_BOTTOM); \ SetTextColor(dcDst, data->Color); \ SetBkMode(dcDst, TRANSPARENT); \ \ font = CreateFontIndirect(&data->Font); \ oldfont = SelectObject(dcDst, font); \ TextOut(dcDst, FirstX, FirstY, tempstr, data->nCount); \ \ SelectObject(dcDst, oldfont); \ DeleteObject(font); \ data->Font.lfHeight = nTemp; \ free(tempstr); \ break; \ } \ SetROP2(dcDst, nDrawMode); \ SetPolyFillMode(dcDst, nFillMode); \ //--------------------------------------------------------------------------- #define SET_RECT \ \ data->First.x = 59999; data->First.y = 59999; \ data->Second.x = 0; data->Second.y = 0; \ for (int i = 0; i < data->nCount*3+1; i++) { \ if (data->First.x > data->pList[i].x) data->First.x = data->pList[i].x; \ if (data->First.y > data->pList[i].y) data->First.y = data->pList[i].y; \ if (data->Second.x < data->pList[i].x) data->Second.x = data->pList[i].x; \ if (data->Second.y < data->pList[i].y) data->Second.y = data->pList[i].y; \ } \ // Line°ú Curve¿¡¼­ First, Second´Â °¢°¢ÀÇ ÃÖ´ë, ÃÖ¼Ò Á¡ÀÌ µé¾î°£´Ù //--------------------------------------------------------------------------- #define INRECTMETHOD \ if (method == 2 && bRange) { \ bool bInRect = false; \ if (data->Kind == V_LINE || data->Kind == V_CURVE) { \ for (int k = 0; k < data->nCount*3+1; k+=3) { \ if (PtInRect(&Src, data->pList[k].P())) bInRect = true; \ } \ }else { \ if (PtInRect(&Src, data->First) || PtInRect(&Src, data->Second) || \ PtInRect(&Src, Point(data->First.x, data->Second.y)) || \ PtInRect(&Src, Point(data->Second.x, data->First.y))) \ bInRect = true; \ } \ if (!bInRect) continue; \ } \ \ if (method == 3 && bRange) { \ bool bInRect = true; \ if (data->Kind == V_LINE || data->Kind == V_CURVE) { \ for (int k = 0; k < data->nCount*3+1; k+=3) { \ if (!PtInRect(&Src, data->pList[k].P())) bInRect = false; \ } \ }else { \ if (!(PtInRect(&Src, data->First) && PtInRect(&Src, data->Second) && \ PtInRect(&Src, Point(data->First.x, data->Second.y)) && PtInRect(&Src, Point(data->Second.x, data->First.y)))) \ bInRect = false; \ } \ if (!bInRect) continue; \ } \ // ÀÛ¾÷ ±¸¿ª ¾È¿¡ object°¡ ÀÖÀ¸¸é ÁøÇà ¾Æ´Ï¸é continue // Method 2 : ÇÑ Á¡ÀÌ¶óµµ Area¾È¿¡ Àִ°æ¿ì // 3 : ÇÑ Á¡ÀÌ¶óµµ Area¹Û¿¡ ÀÖÀ¸¸é pass //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /////////////// Object Addition Part //--------------------------------------------------------------------------- void __fastcall TVecDraw::LineAdd (EVecKind EKind, POINT pFst, POINT pScd) { /* if (!bFstLine) { data = (TVecData *)DataList->Items[DataList->Count-1]; if (data->Color != PenManagerForm->PenShape->Pen->Color || data->bRound == PenManagerForm->Pen->Shape || data->PenThick != PenManagerForm->Pen->Thick || data->Kind != V_LINE) bFstLine = true; } if (bFstLine) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Kind = EKind; data->pList[0] = pFst; data->pList[1] = pScd; data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; data->bFill = DrawForm->IsFill; data->bSelected = false; data->nCount = 1; DataList->Add(data); bFirst = true; bFstLine = false; } else { data->pList[data->nCount+1] = pScd; data->nCount++; } data->First.x = 9999; data->First.y = 9999; data->Second.x = 0; data->Second.y = 0; for (int i = 0; i < data->nCount+1; i++) { if (data->First.x > data->pList[i].x) data->First.x = data->pList[i].x; if (data->First.y > data->pList[i].y) data->First.y = data->pList[i].y; if (data->Second.x < data->pList[i].x) data->Second.x = data->pList[i].x; if (data->Second.y < data->pList[i].y) data->Second.y = data->pList[i].y; } // Line°ú Curve¿¡¼­ First, Second´Â °¢°¢ÀÇ ÃÖ´ë, ÃÖ¼Ò Á¡ÀÌ µé¾î°£´Ù */ if (VectorForm->LineType == 2) bFstLine = true; if (!bFstLine) { data = (TVecData *)DataList->Items[DataList->Count-1]; CheckFirstLine(); } if (bFstLine) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Kind = V_CURVE; data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; data->PenStyle = P_SOLID; // data->bFill = DrawForm->IsFill; data->Bitmap = NULL; data->bFill = false; data->bSelected = false; data->nCount = 1; data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); data->pList[0].DPoint(pFst); data->pList[1].DPoint(pFst); data->pList[2].DPoint(pScd); data->pList[3].DPoint(pScd); DataList->Add(data); //======= Undo Test UndoSave(VU_CREATE, DataList->Count-1); //======= Undo Test bFirst = true; bFstLine = false; } else { data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); data->pList[data->nCount*3 - 2].DPoint(pFst); data->pList[data->nCount*3 - 1].DPoint(pScd); data->pList[data->nCount*3].DPoint(pScd); } SET_RECT; if (bClosedState) { data->bClosed = true; step = 0; bFstLine = true; MainImageForm->iMainImage->Cursor = crDefault; // bClosedState = false; } bFirst = true; return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DiagramAdd (EVecKind EKind, POINT pFst, POINT pScd) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; /* data->Kind = EKind; data->First = pFst; data->Second = pScd; data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; data->Brush = PenManagerForm->PenShape->Pen->Color; // data->bFill = DrawForm->IsFill; data->PenStyle = P_SOLID; */ //================ data->Kind = V_CURVE; data->First = pFst; data->Second = pScd; data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; data->Brush = PenManagerForm->PenShape->Pen->Color; data->PenStyle = P_SOLID; data->nCount = 4; data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (EKind == V_ELLIPSE) { // Ÿ¿øÀ» º£Áö¿¡¸£·Î º¯È¯ double M = 0.55228474983; int dx = abs(pFst.x-pScd.x)/2, dy = abs(pFst.y-pScd.y)/2; double ddx = dx * M, ddy = dy * M; data->pList[0].DPoint((pFst.x+pScd.x)/2.0, pFst.y+0.0); data->pList[1].DPoint((pFst.x+pScd.x)/2-ddx+0.5, pFst.y); data->pList[2].DPoint(pFst.x, (pFst.y+pScd.y)/2-ddy+0.5); data->pList[3].DPoint(pFst.x, (pFst.y+pScd.y)/2.0); data->pList[4].DPoint(pFst.x, (pFst.y+pScd.y)/2+ddy+0.5); data->pList[5].DPoint((pFst.x+pScd.x)/2-ddx+0.5, pScd.y); data->pList[6].DPoint((pFst.x+pScd.x)/2, pScd.y+0.0); data->pList[7].DPoint((pFst.x+pScd.x)/2+ddx+0.5, pScd.y); data->pList[8].DPoint(pScd.x, (pFst.y+pScd.y)/2+ddy+0.5); data->pList[9].DPoint(pScd.x+0.0, (pFst.y+pScd.y)/2); data->pList[10].DPoint(pScd.x, (pFst.y+pScd.y)/2-ddy+0.5); data->pList[11].DPoint((pFst.x+pScd.x)/2+ddx+0.5, pFst.y); data->pList[12].DPoint((pFst.x+pScd.x)/2, pFst.y+0.0); data->bClosed = true; }else { // »ç°¢ÇüÀ» º£Áö¿¡¸£·Î º¯È¯ data->pList[0].DPoint(pFst.x, pFst.y); data->pList[1].DPoint(pFst.x, pFst.y); data->pList[2].DPoint(pFst.x, pScd.y); data->pList[3].DPoint(pFst.x, pScd.y); data->pList[4].DPoint(pFst.x, pScd.y); data->pList[5].DPoint(pScd.x, pScd.y); data->pList[6].DPoint(pScd.x, pScd.y); data->pList[7].DPoint(pScd.x, pScd.y); data->pList[8].DPoint(pScd.x, pFst.y); data->pList[9].DPoint(pScd.x, pFst.y); data->pList[10].DPoint(pScd.x, pFst.y); data->pList[11].DPoint(pFst.x, pFst.y); data->pList[12].DPoint(pFst.x, pFst.y); data->bClosed = true; } //==================== DataList->Add(data); //======= Undo Test UndoSave(VU_CREATE, DataList->Count-1); //======= Undo Test bFirst = true; return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::CurveAdd(POINT pFst, POINT pScd, POINT pTan2) { POINT Temp2, Temp3, Temp4; if (VectorForm->LineType == 2) bFstLine = true; if (!bFstLine) { data = (TVecData *)DataList->Items[DataList->Count-1]; CheckFirstLine(); } pTan = pTan2; // Àӽà ±â¿ï±â ÀúÀå(´ÙÀ½ °î¼±ÀÇ ½ÃÀÛÁ¡ ±â¿ï±â) pTan2.x = pScd.x *2 - pTan2.x; // IllustraterÀÇ ¹æ½ÄÀ» µû¸£±â À§ÇÔ pTan2.y = pScd.y *2 - pTan2.y; if (bFstLine) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Kind = V_CURVE; data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; data->PenStyle = P_SOLID; data->nCount = 1; data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); data->pList[0].DPoint(pFst); data->pList[3].DPoint(pScd); data->pList[1].DPoint(pFst); data->pList[2].DPoint(pTan2); DataList->Add(data); //======= Undo Test UndoSave(VU_CREATE, DataList->Count-1); //======= Undo Test bFirst = false; bFstLine = false; }else { // ¿¬¼ÓµÈ °î¼± Temp2 = data->pList[data->nCount*3 -1].P(); Temp3 = data->pList[data->nCount*3].P(); if (VectorForm->LineType == 1) { // ±â¿ï±â °øÀ¯ÇÏÁö ¾Ê´Â °î¼± Temp4.x = Temp3.x; Temp4.y = Temp3.y; }else if (VectorForm->LineType == 3) { // ±â¿ï±â À̾îÁö´Â °î¼± Temp4.x = Temp3.x*2 - Temp2.x; Temp4.y = Temp3.y*2 - Temp2.y; } data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); data->pList[data->nCount*3 - 2].DPoint(Temp4); data->pList[data->nCount*3 - 1].DPoint(pTan2); data->pList[data->nCount*3].DPoint(pScd); } SET_RECT; if (bClosedState) { data->bClosed = true; step = 0; bFstLine = true; MainImageForm->iMainImage->Cursor = crDefault; } bFirst = true; return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ExtendObject(EVecKind EKind, POINT pFst, POINT pScd, POINT pTan2) { POINT Temp2, Temp3, Temp4, temp[1024]; data = (TVecData *)DataList->Items[Index]; if (VectorForm->LineType == 2) bFstLine = true; if (!bFstLine) { if (CheckFirstLine()) { // Á¶°ÇÀÌ ´Ù¸¥°æ¿ì objectºÐ¸®Çعö¸°´Ù bExtend = false; if (EKind == V_LINE) { LineAdd(V_LINE, pFst, pScd); }else if (EKind == V_CURVE) { CurveAdd(pFst, pScd, pTan2); } return; } } if (bFstLine) { // ù¹ø¸¸ undo save UndoSave(VU_MODIFY, Index); bFstLine = false; } if (bExtendFirst) { // ùÁ¡À» ¿¬ÀåÇÏ´Â °æ¿ì´Â ùÁ¡À» ¸¶Áö¸·Á¡À¸·Î ¹Ù²Ù°í ¿¬°áÇÑ´Ù for (int i = 0; i < data->nCount*3+1; i++) temp[i] = data->pList[i].P(); for (int i = 0; i < data->nCount*3+1; i++) data->pList[i].DPoint(temp[data->nCount*3 - i]); bExtendFirst = false; } if (EKind == V_LINE) { data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); data->pList[data->nCount*3 - 2].DPoint(pFst); data->pList[data->nCount*3 - 1].DPoint(pScd); data->pList[data->nCount*3].DPoint(pScd); data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; }else if (EKind == V_CURVE) { pTan = pTan2; // Àӽà ±â¿ï±â ÀúÀå(´ÙÀ½ °î¼±ÀÇ ½ÃÀÛÁ¡ ±â¿ï±â) pTan2.x = pScd.x *2 - pTan2.x; // IllustraterÀÇ ¹æ½ÄÀ» µû¸£±â À§ÇÔ pTan2.y = pScd.y *2 - pTan2.y; Temp2 = data->pList[data->nCount*3 -1].P(); Temp3 = data->pList[data->nCount*3].P(); if (VectorForm->LineType == 1) { // ±â¿ï±â °øÀ¯ÇÏÁö ¾Ê´Â °î¼± Temp4.x = Temp3.x; Temp4.y = Temp3.y; }else if (VectorForm->LineType == 3) { // ±â¿ï±â À̾îÁö´Â °î¼± Temp4.x = Temp3.x*2 - Temp2.x; Temp4.y = Temp3.y*2 - Temp2.y; } data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); data->pList[data->nCount*3 - 2].DPoint(Temp4); data->pList[data->nCount*3 - 1].DPoint(pTan2); data->pList[data->nCount*3].DPoint(pScd); data->PenThick = PenManagerForm->Pen->Thick; data->bRound = !PenManagerForm->Pen->Shape; data->Color = PenManagerForm->PenShape->Pen->Color; } SET_RECT; if (bClosedState) { data->bClosed = true; step = 0; bFstLine = true; MainImageForm->iMainImage->Cursor = crDefault; } bFirst = true; return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::TextAdd (POINT pFst, AnsiString Text, bool bFirstText) { AnsiString FontType = MainImageForm->iMainImage->Canvas->Font->Name; HDC hdc = MainImageForm->iMainImage->Canvas->Handle; TPItemImage *Image = MainImageForm->iMainImage; HFONT font = NULL, oldfont = NULL; RECT rc; int widthsum = 0, height; double angle; SIZE sz; char *tempstr = ""; if (bFirstText) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Kind = V_TEXT; data->First = pFst; data->Color = PenManagerForm->PenShape->Pen->Color; data->nCount = Text.Length(); strcpy(data->Font.lfFaceName, FontType.c_str()); data->Font.lfHeight = Image->Canvas->Font->Size; data->Font.lfItalic = Image->Canvas->Font->Style.Contains(fsItalic); data->Font.lfUnderline = Image->Canvas->Font->Style.Contains(fsUnderline); if (Image->Canvas->Font->Style.Contains(fsBold)) data->Font.lfWeight = FW_BOLD; else data->Font.lfWeight = FW_NORMAL; data->Font.lfStrikeOut = Image->Canvas->Font->Style.Contains(fsStrikeOut); data->Font.lfEscapement = TextAngle; data->TextString = Text; // widthsum = Image->Canvas->TextWidth(Text) * 0.75; for (int k = 0; k < data->nCount; k++) tempstr[k] = char(data->TextString[k+1]); font = CreateFontIndirect(&data->Font); oldfont = SelectObject(hdc, font); SelectObject(hdc, font); GetTextExtentPoint32(hdc, tempstr, Text.Length(), &sz); widthsum = sz.cx; SelectObject(hdc, oldfont); DeleteObject(font); font = NULL; height = data->Font.lfHeight; angle = 2*M_PI*data->Font.lfEscapement/10/360; data->Second.x = data->First.x + widthsum*cos(angle) - height*sin(angle); data->Second.y = data->First.y - widthsum*sin(angle) - height*cos(angle); DataList->Add(data); //======= Undo Test UndoSave(VU_CREATE, DataList->Count-1); //======= Undo Test bFirst = true; }else { height = data->Font.lfHeight; angle = 2*M_PI*data->Font.lfEscapement/10/360; data->nCount = Text.Length(); // for (int i = 0; i < data->nCount; i++) { // data->str[i] = char(Text[i+1]); // } data->TextString = Text; for (int k = 0; k < data->nCount; k++) tempstr[k] = char(data->TextString[k+1]); font = CreateFontIndirect(&data->Font); oldfont = SelectObject(hdc, font); SelectObject(hdc, font); GetTextExtentPoint32(hdc, tempstr, Text.Length(), &sz); widthsum = sz.cx; SelectObject(hdc, oldfont); DeleteObject(font); font = NULL; data->Second.x = data->First.x + widthsum*cos(angle) - height*sin(angle); data->Second.y = data->First.y - widthsum*sin(angle) - height*cos(angle); rc.top = min(data->First.y, data->Second.y) - data->Font.lfHeight; rc.bottom = max(data->First.y, data->Second.y) + data->Font.lfHeight; rc.left = min(data->First.x, data->Second.x) - data->Font.lfHeight; rc.right = max(data->First.x, data->Second.x) + data->Font.lfHeight; Image->RectPaint(rc); } return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /////////////// Drawing Part //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TVecDraw::LineDraw (HDC dcDst, int px, int py, TMainImageForm *form) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL, hBrush = NULL; LOGBRUSH logbrush; int nDrawMode, nFillMode, nTemp, nPenStyle; RGBQUAD rgb; POINT pTemp[1024]; HFONT font = NULL, oldfont = NULL; Graphics::TBitmap *TempBitmap = NULL; int ZoomIn = form->iMainImage->ZoomIn; int ZoomOut = form->iMainImage->ZoomOut; int PositionX = form->sbHorz->Position; int PositionY = form->sbVert->Position; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(form->Number)) continue; if (bProportion && data->bSelected) ProportionTransform(); // È®´ëÃà¼Ò½Ã¿¡´Â Á¡µéÀÇ TransformÀÌ °¡ÇØÁü if (bMergeMode && data->bSelected) { // Merge Mode¿¡¼­ ¼±ÅÃµÈ ¿ÀºêÁ§Æ®ÀÇ ¸¶¿ì½º À̵¿¿¡ µû¸¥ ÁÂÇ¥ º¯°æ PositionX -= MergeX; PositionY -= MergeY; } int FirstX = (data->First.x - PositionX) * ZoomIn / ZoomOut -px; int FirstY = (data->First.y - PositionY) * ZoomIn / ZoomOut -py; int SecondX = (data->Second.x - PositionX) * ZoomIn / ZoomOut -px; int SecondY = (data->Second.y - PositionY) * ZoomIn / ZoomOut -py; int pw = data->PenThick/2; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = (data->pList[i].x - PositionX) * ZoomIn / ZoomOut -px; pTemp[i].y = (data->pList[i].y - PositionY) * ZoomIn / ZoomOut -py; } } if (bMergeMode && data->bSelected) { // µÇµ¹¸®±â PositionX += MergeX; PositionY += MergeY; } //////// Closed Path last point and for nicer close if (data->bClosed && data->PenStyle == P_SOLID) { pTemp[data->nCount*3] = pTemp[0]; pTemp[data->nCount*3+1] = pTemp[1]; pTemp[data->nCount*3+2] = pTemp[2]; pTemp[data->nCount*3+3] = pTemp[3]; } //////// nDrawMode = GetROP2(dcDst); nFillMode = GetPolyFillMode(dcDst); if (data->Kind != V_TEXT) { // Text´Â Pen°ú Brush°¡ ÇÊ¿ä ¾ø´Ù logbrush.lbStyle = BS_SOLID; logbrush.lbColor = data->Brush; logbrush.lbHatch = 0; if (data->bPatternFill) { // PatternFill À϶§ SetBrushOrgEx(dcDst, FirstX, FirstY, NULL); if (double(ZoomIn)/double(ZoomOut) == 1.0) { // È®´ë/Ãà¼Ò¸¦ ÇÏÁö ¾ÊÀº »óÅ (Á¶±ÝÀÌ¶óµµ ºü¸£°Ô) hBrush = CreatePatternBrush(data->Bitmap->Handle); hOldBrush = SelectObject(dcDst, hBrush); }else { // È®´ë³ª Ãà¼Ò¸¦ ÇÑ»óÅ¿¡´Â ºñÆ®¸Ê¶ÇÇÑ È®´ë/Ãà¼Ò¸¦ ÇØ ÁØ´Ù TempBitmap = new Graphics::TBitmap; TempBitmap->PixelFormat = pf24bit; TempBitmap->Width = data->Bitmap->Width * ZoomIn / ZoomOut; TempBitmap->Height = data->Bitmap->Height * ZoomIn / ZoomOut; StretchBlt(TempBitmap->Canvas->Handle,0,0,TempBitmap->Width,TempBitmap->Height, data->Bitmap->Canvas->Handle,0,0,data->Bitmap->Width,data->Bitmap->Height,SRCCOPY); hBrush = CreatePatternBrush(TempBitmap->Handle); hOldBrush = SelectObject(dcDst, hBrush); } }else if (data->bFill) { // ColorFill À϶§ hBrush = CreateBrushIndirect(&logbrush); hOldBrush = SelectObject(dcDst, hBrush); }else { // Fill X hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); } if (data->bWinding) SetPolyFillMode(dcDst, WINDING); // ä¿ì±â ¸ðµå ¼±Åà else SetPolyFillMode(dcDst, ALTERNATE); logbrush.lbColor = data->Color; // ÆæÀÇ color¸¦ À§Çؼ­... switch (data->PenStyle) { case 0: nPenStyle = int (PS_SOLID); break; case 1: nPenStyle = int (PS_DASH); break; case 2: nPenStyle = int (PS_DOT); break; case 3: nPenStyle = int (PS_DASHDOT); break; case 4: nPenStyle = int (PS_DASHDOTDOT);break; } if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, int(data->PenThick*ZoomIn/ZoomOut+0.5), data->Color); }else { if (data->bRound) // win 2000, NT¿¡¼­¸¸ Á¦´ë·Î ÀÛµ¿ÇÑ´Ù hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_ROUND | PS_JOIN_ROUND, int(data->PenThick*ZoomIn/ZoomOut+0.5), &logbrush, 0, NULL ); else hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_FLAT | PS_JOIN_MITER, int(data->PenThick*ZoomIn/ZoomOut+0.5), &logbrush, 0, NULL ); } hOldPen = SelectObject(dcDst, hPen); }else { nTemp = data->Font.lfHeight; data->Font.lfHeight = data->Font.lfHeight *ZoomIn / ZoomOut +0.5; if (data->Font.lfHeight == 0) data->Font.lfHeight = 1; } PAINT_VECTOR; if (data->Kind != V_TEXT) { SelectObject(dcDst, hOldBrush); SelectObject(dcDst, hOldPen); } if (hBrush) DeleteObject(hBrush); if (hPen) DeleteObject(hPen); hOldPen = NULL; hOldBrush = NULL; hPen = NULL; hBrush = NULL; if (TempBitmap) { delete TempBitmap; TempBitmap = NULL; } if (bProportion && data->bSelected) ProportionInverseTransform(); // TransformÀÌ °¡ÇØÁø Á¡À» ´Ù½Ã µÇµ¹¸² if (!bSelected) data->bSelected = false; } if (bSelected && !bMergeMode) DrawSelectedLine(dcDst, px, py, form); else { ptNumber = -1; nSelPos = 0; } if (bRotation) DrawRotationLine(dcDst, px, py); if (VectorForm) if (step != 0) DrawCurrentObject(dcDst, px, py); return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::PrintDraw(HDC dcDst, int posx, int posy, int WidthRes, int HeightRes, int dpi, int number) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL, hBrush = NULL; LOGBRUSH logbrush; int nDrawMode, nFillMode, nTemp, nPenStyle; RGBQUAD rgb; POINT pTemp[1024]; HFONT font = NULL, oldfont = NULL; Graphics::TBitmap *TempBitmap = NULL; // int ZoomIn = DPI; int ZoomOut = dpi; int PositionX = posx; int PositionY = posy; int px = 0, py = 0; RECT Src; if (MainImageForm->WorkArea->Mask) { Src = MainImageForm->WorkArea->Range; PositionX += Src.left; PositionY += Src.top; }else { } for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; // if (!data->Equal(MainImageForm->Number)) continue; if (!data->Equal(number)) continue; // Á¤È®ÇÑ °è»êÀ» À§Çؼ­ int FirstX = (data->First.x - PositionX) * WidthRes / ZoomOut -px; int FirstY = (data->First.y - PositionY) * HeightRes / ZoomOut -py; int SecondX = (data->Second.x - PositionX) * WidthRes / ZoomOut -px; int SecondY = (data->Second.y - PositionY) * HeightRes / ZoomOut -py; int pw = data->PenThick/2; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = (data->pList[i].x - PositionX) * WidthRes / ZoomOut -px; pTemp[i].y = (data->pList[i].y - PositionY) * HeightRes / ZoomOut -py; } } //////// Closed Path last point and for nicer close if (data->bClosed && data->PenStyle == P_SOLID) { pTemp[data->nCount*3] = pTemp[0]; pTemp[data->nCount*3+1] = pTemp[1]; pTemp[data->nCount*3+2] = pTemp[2]; pTemp[data->nCount*3+3] = pTemp[3]; } //////// nDrawMode = GetROP2(dcDst); nFillMode = GetPolyFillMode(dcDst); if (data->Kind != V_TEXT) { // Text´Â Pen°ú Brush°¡ ÇÊ¿ä ¾ø´Ù logbrush.lbStyle = BS_SOLID; logbrush.lbColor = data->Brush; logbrush.lbHatch = 0; if (data->bPatternFill) { // PatternFill À϶§ SetBrushOrgEx(dcDst, FirstX, FirstY, NULL); if (double(WidthRes)/double(ZoomOut) == 1.0) { // È®´ë/Ãà¼Ò¸¦ ÇÏÁö ¾ÊÀº »óÅ (Á¶±ÝÀÌ¶óµµ ºü¸£°Ô) hBrush = CreatePatternBrush(data->Bitmap->Handle); hOldBrush = SelectObject(dcDst, hBrush); }else { // È®´ë³ª Ãà¼Ò¸¦ ÇÑ»óÅ¿¡´Â ºñÆ®¸Ê¶ÇÇÑ È®´ë/Ãà¼Ò¸¦ ÇØ ÁØ´Ù TempBitmap = new Graphics::TBitmap; TempBitmap->PixelFormat = pf24bit; TempBitmap->Width = data->Bitmap->Width * WidthRes / ZoomOut; TempBitmap->Height = data->Bitmap->Height * HeightRes / ZoomOut; TempBitmap->HandleType = bmDIB; StretchBlt(TempBitmap->Canvas->Handle,0,0,TempBitmap->Width,TempBitmap->Height, data->Bitmap->Canvas->Handle,0,0,data->Bitmap->Width,data->Bitmap->Height,SRCCOPY); hBrush = CreatePatternBrush(TempBitmap->Handle); hOldBrush = SelectObject(dcDst, hBrush); } }else if (data->bFill) { // ColorFill À϶§ hBrush = CreateBrushIndirect(&logbrush); hOldBrush = SelectObject(dcDst, hBrush); }else { // Fill X hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); } if (data->bWinding) SetPolyFillMode(dcDst, WINDING); // ä¿ì±â ¸ðµå ¼±Åà else SetPolyFillMode(dcDst, ALTERNATE); logbrush.lbColor = data->Color; // ÆæÀÇ color¸¦ À§Çؼ­... switch (data->PenStyle) { case 0: nPenStyle = int (PS_SOLID); break; case 1: nPenStyle = int (PS_DASH); break; case 2: nPenStyle = int (PS_DOT); break; case 3: nPenStyle = int (PS_DASHDOT); break; case 4: nPenStyle = int (PS_DASHDOTDOT);break; } if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, data->PenThick* WidthRes / ZoomOut, data->Color); }else { if (data->bRound) // win 2000, NT¿¡¼­¸¸ Á¦´ë·Î ÀÛµ¿ÇÑ´Ù hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_ROUND | PS_JOIN_ROUND, data->PenThick* WidthRes/ZoomOut +0.5, &logbrush, 0, NULL ); else hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_FLAT | PS_JOIN_MITER, data->PenThick* WidthRes/ZoomOut +0.5, &logbrush, 0, NULL ); } hOldPen = SelectObject(dcDst, hPen); }else { nTemp = data->Font.lfHeight; data->Font.lfHeight = data->Font.lfHeight *WidthRes / ZoomOut+0.5; if (data->Font.lfHeight == 0) data->Font.lfHeight = 1; } PAINT_VECTOR; if (data->Kind != V_TEXT) { SelectObject(dcDst, hOldBrush); SelectObject(dcDst, hOldPen); } if (hBrush) DeleteObject(hBrush); if (hPen) DeleteObject(hPen); hOldPen = NULL; hOldBrush = NULL; hPen = NULL; hBrush = NULL; if (TempBitmap) { delete TempBitmap; TempBitmap = NULL; } } return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::FullViewDraw (HDC dcDst, int px, int py, int vw, int vh) // convert by celberus { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL, hBrush = NULL; LOGBRUSH logbrush; int nDrawMode, nFillMode, nTemp, nPenStyle; RGBQUAD rgb; POINT pTemp[1024]; HFONT font=NULL, oldfont=NULL; double rx = (double) vw / MainImageForm->iMainImage->uBitmap->Width; double ry = (double) vh / MainImageForm->iMainImage->uBitmap->Height; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; int FirstX = data->First.x * rx -px; // int FirstY = data->First.y * ry -py; // int SecondX = data->Second.x * rx -px; // int SecondY = data->Second.y * ry -py; // convert by celberus int pw = data->PenThick/2; int resizedPenThick = max(1.0, data->PenThick * min(rx, ry)); // convert by celberus if (!data->Equal(MainImageForm->Number)) continue; if (bMergeMode && data->bSelected) { // Merge Mode¿¡¼­ ¼±ÅÃµÈ ¿ÀºêÁ§Æ®ÀÇ ¸¶¿ì½º À̵¿¿¡ µû¸¥ ÁÂÇ¥ º¯°æ px += MergeX; py += MergeY; } if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = data->pList[i].x * rx -px; // pTemp[i].y = data->pList[i].y * ry -py; // convert by celberus } } //////// Closed Path last point and for nicer close if (data->bClosed && data->PenStyle == P_SOLID) { pTemp[data->nCount*3] = pTemp[0]; pTemp[data->nCount*3+1] = pTemp[1]; pTemp[data->nCount*3+2] = pTemp[2]; pTemp[data->nCount*3+3] = pTemp[3]; } //////// nDrawMode = GetROP2(dcDst); nFillMode = GetPolyFillMode(dcDst); if (data->Kind != V_TEXT) { // Text´Â Pen°ú Brush°¡ ÇÊ¿ä ¾ø´Ù logbrush.lbStyle = BS_SOLID; logbrush.lbColor = data->Brush; logbrush.lbHatch = 0; if (data->bPatternFill) { // PatternFill À϶§ FullView¿¡¼­´Â Ä¥ÇÏÁö ¾Ê´Â´Ù(¼Óµµ¹®Á¦) hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); }else if (data->bFill) { // ColorFill À϶§ hBrush = CreateBrushIndirect(&logbrush); hOldBrush = SelectObject(dcDst, hBrush); }else { // Fill X hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); } if (data->bWinding) SetPolyFillMode(dcDst, WINDING); // ä¿ì±â ¸ðµå ¼±Åà else SetPolyFillMode(dcDst, ALTERNATE); logbrush.lbColor = data->Color; // ÆæÀÇ color¸¦ À§Çؼ­... switch (data->PenStyle) { case 0: nPenStyle = int (PS_SOLID); break; case 1: nPenStyle = int (PS_DASH); break; case 2: nPenStyle = int (PS_DOT); break; case 3: nPenStyle = int (PS_DASHDOT); break; case 4: nPenStyle = int (PS_DASHDOTDOT);break; } if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, resizedPenThick, data->Color); //data->PenThick -> resized convert by celberus }else { if (data->bRound) // win 2000, NT¿¡¼­¸¸ Á¦´ë·Î ÀÛµ¿ÇÑ´Ù hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_ROUND | PS_JOIN_ROUND, resizedPenThick, &logbrush, 0, NULL ); //data->PenThick -> resized convert by celberus else hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_FLAT | PS_JOIN_MITER, resizedPenThick, &logbrush, 0, NULL ); //data->PenThick -> resized convert by celberus } hOldPen = SelectObject(dcDst, hPen); }else { nTemp = data->Font.lfHeight; data->Font.lfHeight = data->Font.lfHeight * min(rx, ry); // convert by celberus if(data->Font.lfHeight < 6) data->Font.lfHeight = 0; // ÅØ½ºÆ®´Â »çÀÌÁî°¡ ÃÖ¼Ò »çÀÌÁ´Ù ÀÛÀ¸¸é Ç×»ó ÃÖ¼Ò »çÀÌÁî·Î ±×¸®±â ¶§¹®¿¡ by celberus } if (data->Kind != V_TEXT || data->Font.lfHeight!=0) { PAINT_VECTOR; } else { data->Font.lfHeight = nTemp; } if (data->Kind != V_TEXT) { SelectObject(dcDst, hOldBrush); SelectObject(dcDst, hOldPen); } if (hBrush) DeleteObject(hBrush); if (hPen) DeleteObject(hPen); hOldPen = NULL; hOldBrush = NULL; hPen = NULL; hBrush = NULL; } return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::TagDraw (HDC dcDst, TRect src, int method) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL, hBrush = NULL; int nDrawMode, nFillMode, nTemp, nPenStyle;; RGBQUAD rgb; POINT pTemp[1024]; HFONT font = NULL, oldfont = NULL; LOGBRUSH logbrush; Graphics::TBitmap *TempBitmap = NULL; int PositionX = src.Left; int PositionY = src.Top; int px = 0, py = 0, w ,h; double rx, ry, Zoom; rx = 80.0/(src.Right-src.Left); ry = 100.0/(src.Bottom-src.Top); if (rx>ry) { w = (src.Right-src.Left)*ry; h = (src.Bottom-src.Top)*ry; Zoom = double(h) / double(src.Bottom-src.top); }else { w = (src.Right-src.Left)*rx; h = (src.Bottom-src.Top)*rx; Zoom = double(w) / double(src.Right-src.Left); } for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; int FirstX = (data->First.x - PositionX) * Zoom -px; int FirstY = (data->First.y - PositionY) * Zoom -py; int SecondX = (data->Second.x - PositionX) * Zoom -px; int SecondY = (data->Second.y - PositionY) * Zoom -py; int pw = data->PenThick/2; if (!data->Equal(MainImageForm->Number)) continue; if (method == 4 && !data->bSelected) continue; // 4: ¼±ÅÃµÈ ¿ÀºêÁ§Æ®¸¸ ±×·ÁÁÜ if (MainImageForm->WorkArea->Mask) { // ÀÛ¾÷±¸¿ª ¹Ù±ù °´Ã¼´Â °É·¯ÁÜ TRect Src = MainImageForm->WorkArea->Range; bool bRange = true; INRECTMETHOD; // ¿µ¿ª ¾È¿¡ ¾ø´Â°ÍÀº °É·¯³»´Â define } if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = (data->pList[i].x - PositionX) * Zoom -px; pTemp[i].y = (data->pList[i].y - PositionY) * Zoom -py; } } //////// Closed Path last point and for nicer close if (data->bClosed && data->PenStyle == P_SOLID) { pTemp[data->nCount*3] = pTemp[0]; pTemp[data->nCount*3+1] = pTemp[1]; pTemp[data->nCount*3+2] = pTemp[2]; pTemp[data->nCount*3+3] = pTemp[3]; } //////// nDrawMode = GetROP2(dcDst); nFillMode = GetPolyFillMode(dcDst); if (data->Kind != V_TEXT) { // Text´Â Pen°ú Brush°¡ ÇÊ¿ä ¾ø´Ù logbrush.lbStyle = BS_SOLID; logbrush.lbColor = data->Brush; logbrush.lbHatch = 0; if (data->bPatternFill) { // PatternFill À϶§ TempBitmap = new Graphics::TBitmap; TempBitmap->PixelFormat = pf24bit; TempBitmap->Width = data->Bitmap->Width * Zoom; TempBitmap->Height = data->Bitmap->Height * Zoom; StretchBlt(TempBitmap->Canvas->Handle,0,0,TempBitmap->Width,TempBitmap->Height, data->Bitmap->Canvas->Handle,0,0,data->Bitmap->Width,data->Bitmap->Height,SRCCOPY); SetBrushOrgEx(dcDst, FirstX, FirstY, NULL); hBrush = CreatePatternBrush(TempBitmap->Handle); hOldBrush = SelectObject(dcDst, hBrush); }else if (data->bFill) { // ColorFill À϶§ hBrush = CreateBrushIndirect(&logbrush); hOldBrush = SelectObject(dcDst, hBrush); }else { // Fill X hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); } if (data->bWinding) SetPolyFillMode(dcDst, WINDING); // ä¿ì±â ¸ðµå ¼±Åà else SetPolyFillMode(dcDst, ALTERNATE); logbrush.lbColor = data->Color; // ÆæÀÇ color¸¦ À§Çؼ­... switch (data->PenStyle) { case 0: nPenStyle = int (PS_SOLID); break; case 1: nPenStyle = int (PS_DASH); break; case 2: nPenStyle = int (PS_DOT); break; case 3: nPenStyle = int (PS_DASHDOT); break; case 4: nPenStyle = int (PS_DASHDOTDOT);break; } if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, data->PenThick* Zoom, data->Color); }else { if (data->bRound) // win 2000, NT¿¡¼­¸¸ Á¦´ë·Î ÀÛµ¿ÇÑ´Ù hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_ROUND | PS_JOIN_ROUND, data->PenThick* Zoom, &logbrush, 0, NULL ); else hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_FLAT | PS_JOIN_MITER, data->PenThick* Zoom, &logbrush, 0, NULL ); } hOldPen = SelectObject(dcDst, hPen); }else { nTemp = data->Font.lfHeight; // FontÀÇ Å©±â Àӽà ÀúÀå data->Font.lfHeight = data->Font.lfHeight *Zoom + 0.5; if (data->Font.lfHeight == 0) data->Font.lfHeight = 1; } PAINT_VECTOR; if (data->Kind != V_TEXT) { SelectObject(dcDst, hOldBrush); SelectObject(dcDst, hOldPen); } if (hBrush) DeleteObject(hBrush); if (hPen) DeleteObject(hPen); hOldPen = NULL; hOldBrush = NULL; hPen = NULL; hBrush = NULL; if (TempBitmap) { delete TempBitmap; TempBitmap = NULL; } } return; fail: delete data; data = NULL; } //--------------------------------------------------------------------------- TPException __fastcall TVecDraw::SaveVectorTag(HANDLE fh, TPalette *pPalette, TEXPIAFILEHEADER &tpfh){ DWORD dwWrite; TPException ec = EC_NONE; TRect src; src.Left = 0; src.Top = 0; src.Right = MainImageForm->iMainImage->Width; src.Bottom = MainImageForm->iMainImage->Height; TTexpiaBitmap *tag = NULL, *tb = NULL; HDC dcTmp = NULL, dcTmp2 = NULL; WORD bpp; RGBQUAD rgb[256]; int Version=100; ///////////////////////////////// Start of Standard Tag Format if ((tb = new TTexpiaBitmap)==NULL) { ec = EC_MEMORY_LACK; goto fail; } if (MainImageForm->iMainImage->Bitmap->BitsPerPixel == 8) { MainImageForm->iMainImage->Bitmap->GetColors(0, 256, rgb); if (!tb->Create(MainImageForm->iMainImage->Bitmap->Width, MainImageForm->iMainImage->Bitmap->Height, 8, rgb)) { ec = EC_MEMORY_LACK; goto fail; } } else { if (!tb->Create(MainImageForm->iMainImage->Bitmap->Width, MainImageForm->iMainImage->Bitmap->Height, 24)) { ec = EC_MEMORY_LACK; goto fail; } } // if ((dcTmp = tb->CreateDC()) == NULL) { ec = EC_MEMORY_LACK; goto fail; } tb->FillRect(Rect(0, 0, MainImageForm->iMainImage->Bitmap->Width, MainImageForm->iMainImage->Bitmap->Height), clWhite); // iMainImage->FullViewPaint(dcTmp, 1, 1); // tb->DeleteDC(dcTmp); dcTmp = NULL; if ((tag = new TTexpiaBitmap)==NULL) { ec = EC_MEMORY_LACK; goto fail; } MakeTexpiaTag(tag, tb, src, 0); delete tb; ///// if ((dcTmp2 = tag->CreateDC())==NULL) { ec = EC_MEMORY_LACK; goto fail; } TagDraw(dcTmp2, src, 1); tag->DeleteDC(dcTmp2); dcTmp2 = NULL; ///// if (!WriteFile(fh, &tpfh, sizeof(TEXPIAFILEHEADER), &dwWrite, NULL)) return false; if (!WriteFile(fh, &pPalette->UseColor, sizeof(Word), &dwWrite, NULL)) return false; pPalette->SaveToFileHandle((int)fh); bpp = tag->BitsPerPixel; if (!WriteFile(fh, &bpp, sizeof(WORD), &dwWrite, NULL)) return false; if (!tag->SaveToTexpiaFile(fh, cmNone)) return false; delete tag; ///////////////////////////////// End of Standard Tag Format if(!WriteFile(fh, &Version, sizeof(int), &dwWrite, NULL)) { ec = EC_FILE_NOT_WRITE; goto fail; } // bmSim->SaveToTexpiaFile(fh, tpfh.Compress); // bmBot->SaveToTexpiaFile(fh, tpfh.Compress); // if ((ec = SaveDataToFile(fh))!=EC_NONE) goto fail; return EC_NONE; fail: if(tag) delete tag; if (fh!=INVALID_HANDLE_VALUE) CloseHandle(fh); return ec; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ConvertToBitmap(TObject *Sender, HDC dcDst, int px, int py, bool isFinished) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL, hBrush = NULL; LOGBRUSH logbrush; int nDrawMode, nFillMode, nTemp, nPenStyle; POINT pTemp[1024]; HFONT font=NULL, oldfont=NULL; bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; int FirstX = data->First.x -px; int FirstY = data->First.y -py; int SecondX = data->Second.x -px; int SecondY = data->Second.y -py; int pw = data->PenThick/2; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = data->pList[i].x -px; pTemp[i].y = data->pList[i].y -py; } } //////// Closed Path last point and for nicer close if (data->bClosed && data->PenStyle == P_SOLID) { pTemp[data->nCount*3] = pTemp[0]; pTemp[data->nCount*3+1] = pTemp[1]; pTemp[data->nCount*3+2] = pTemp[2]; pTemp[data->nCount*3+3] = pTemp[3]; } //////// nDrawMode = GetROP2(dcDst); nFillMode = GetPolyFillMode(dcDst); if (data->Kind != V_TEXT) { // Text´Â Pen°ú Brush°¡ ÇÊ¿ä ¾ø´Ù logbrush.lbStyle = BS_SOLID; logbrush.lbColor = data->Brush; logbrush.lbHatch = 0; if (data->bPatternFill) { // PatternFill À϶§ hBrush = CreatePatternBrush(data->Bitmap->Handle); SetBrushOrgEx(dcDst, FirstX, FirstY, NULL); hOldBrush = SelectObject(dcDst, hBrush); }else if (data->bFill) { // ColorFill À϶§ hBrush = CreateBrushIndirect(&logbrush); hOldBrush = SelectObject(dcDst, hBrush); }else { // Fill X hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); } if (data->bWinding) SetPolyFillMode(dcDst, WINDING); // ä¿ì±â ¸ðµå ¼±Åà else SetPolyFillMode(dcDst, ALTERNATE); logbrush.lbColor = data->Color; // ÆæÀÇ color¸¦ À§Çؼ­... switch (data->PenStyle) { case 0: nPenStyle = int (PS_SOLID); break; case 1: nPenStyle = int (PS_DASH); break; case 2: nPenStyle = int (PS_DOT); break; case 3: nPenStyle = int (PS_DASHDOT); break; case 4: nPenStyle = int (PS_DASHDOTDOT);break; } if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, data->PenThick, data->Color); }else { if (data->bRound) // win 2000, NT¿¡¼­¸¸ Á¦´ë·Î ÀÛµ¿ÇÑ´Ù hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_ROUND | PS_JOIN_ROUND , data->PenThick, &logbrush, 0, NULL ); else hPen = ExtCreatePen(PS_GEOMETRIC | nPenStyle | PS_ENDCAP_FLAT | PS_JOIN_MITER, data->PenThick, &logbrush, 0, NULL ); } hOldPen = SelectObject(dcDst, hPen); }else { nTemp = data->Font.lfHeight; data->Font.lfHeight = data->Font.lfHeight; } PAINT_VECTOR; if (data->Kind != V_TEXT) { SelectObject(dcDst, hOldBrush); SelectObject(dcDst, hOldPen); } if (hBrush) DeleteObject(hBrush); if (hPen) DeleteObject(hPen); hOldPen = NULL; hOldBrush = NULL; hPen = NULL; hBrush = NULL; UndoSave(VU_DELETE, i, sw); sw = false; if(isFinished) { // convert by celberus DataList->Delete(i); if (data->Bitmap) { delete data->Bitmap; data->Bitmap = NULL;} delete data; data = NULL; i--; } } // MainImageForm->iMainImage->Repaint(); convert by celberus return; fail: if (dcDst) MainImageForm->iMainImage->uBitmap->DeleteDC(dcDst); delete data; data = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DrawVCurve (POINT pFst, POINT pScd, POINT pCrt) { if (!bFirst) DrawCurrentCurve(pFst, pScd, pBak); DrawCurrentCurve(pFst, pScd, pCrt); pBak = pCrt; bFirst = false; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DrawCurrentCurve(POINT pFst, POINT pScd, POINT pCrt) { HDC formDC = MainImageForm->iMainImage->Canvas->Handle; HPEN hOldPen = NULL , hPen = NULL; // HBRUSH hOldBrush=NULL, hBrush=NULL; int nDrawMode; RGBQUAD rgb; POINT pTan1, pTan2; int ZoomIn = MainImageForm->iMainImage->ZoomIn; int ZoomOut = MainImageForm->iMainImage->ZoomOut; int PositionX = MainImageForm->sbHorz->Position; int PositionY = MainImageForm->sbVert->Position; if (!bFstLine) { data = (TVecData *)DataList->Items[DataList->Count-1]; if (data->Color != PenManagerForm->PenShape->Pen->Color || data->bRound == PenManagerForm->Pen->Shape || data->PenThick != PenManagerForm->Pen->Thick) bFstLine = true; } if (bFstLine) pTan1 = pFst; else { pTan1.x = data->pList[data->nCount*3].x *2 - data->pList[data->nCount*3 -1].x; pTan1.y = data->pList[data->nCount*3].y *2 - data->pList[data->nCount*3 -1].y; } pTan2.x = pScd.x *2 - pCrt.x; pTan2.y = pScd.y *2 - pCrt.y; pFst.x = (pFst.x - PositionX) * ZoomIn / ZoomOut; pFst.y = (pFst.y - PositionY) * ZoomIn / ZoomOut; pTan1.x = (pTan1.x - PositionX) * ZoomIn / ZoomOut; pTan1.y = (pTan1.y - PositionY) * ZoomIn / ZoomOut; pTan2.x = (pTan2.x - PositionX) * ZoomIn / ZoomOut; pTan2.y = (pTan2.y - PositionY) * ZoomIn / ZoomOut; pCrt.x = (pCrt.x - PositionX) * ZoomIn / ZoomOut; pCrt.y = (pCrt.y - PositionY) * ZoomIn / ZoomOut; pScd.x = (pScd.x - PositionX) * ZoomIn / ZoomOut; pScd.y = (pScd.y - PositionY) * ZoomIn / ZoomOut; POINT pts[] = {{pFst.x ,pFst.y}, {pTan1.x, pTan1.y}, {pTan2.x, pTan2.y}, {pScd.x, pScd.y}}; hPen = CreatePen(psSolid , 1, clBlack); hOldPen = SelectObject(formDC, hPen); nDrawMode = GetROP2(formDC); SetROP2(formDC, R2_NOT); PolyBezier (formDC, pts, 4); MoveToEx(formDC, pFst.x, pFst.y, NULL); LineTo(formDC, pTan1.x, pTan1.y); MoveToEx(formDC, pCrt.x, pCrt.y, NULL); LineTo(formDC, pTan2.x, pTan2.y); if(!bFstLine) Rectangle(formDC, pFst.x-2, pFst.y-2, pFst.x+2, pFst.y+2); Rectangle(formDC, pTan1.x-2, pTan1.y-2, pTan1.x+2, pTan1.y+2); Rectangle(formDC, pTan2.x-2, pTan2.y-2, pTan2.x+2, pTan2.y+2); Rectangle(formDC, pCrt.x-2, pCrt.y-2, pCrt.x+2, pCrt.y+2); Rectangle(formDC, pScd.x-2, pScd.y-2, pScd.x+2, pScd.y+2); SetROP2(formDC, nDrawMode); SelectObject(formDC, hOldPen); DeleteObject(hPen); hPen = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DrawCurrentObject(HDC dcDst, int px, int py) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush = NULL; int nDrawMode; LOGBRUSH logbrush; int ZoomIn = MainImageForm->iMainImage->ZoomIn; int ZoomOut = MainImageForm->iMainImage->ZoomOut; int PositionX = MainImageForm->sbHorz->Position; int PositionY = MainImageForm->sbVert->Position; int Lex = (VectorForm->Lex - PositionX) * ZoomIn / ZoomOut -px; int Ley = (VectorForm->Ley - PositionY) * ZoomIn / ZoomOut -py; int Lsx = (VectorForm->Lsx - PositionX) * ZoomIn / ZoomOut -px; int Lsy = (VectorForm->Lsy - PositionY) * ZoomIn / ZoomOut -py; // int Csx = (VectorForm->Csx - PositionX) * ZoomIn / ZoomOut -px; // int Csy = (VectorForm->Csy - PositionY) * ZoomIn / ZoomOut -py; int Cux = (VectorForm->Cux - PositionX) * ZoomIn / ZoomOut -px; int Cuy = (VectorForm->Cuy - PositionY) * ZoomIn / ZoomOut -py; nDrawMode = GetROP2(dcDst); logbrush.lbStyle = BS_SOLID; logbrush.lbColor = PenManagerForm->PenShape->Pen->Color; logbrush.lbHatch = 0; if (osVERSION < 2) { // 3.1, 95, 98 hPen = CreatePen(psSolid, PenManagerForm->Pen->Thick* ZoomIn/ZoomOut, PenManagerForm->PenShape->Pen->Color); }else { if (!PenManagerForm->Pen->Shape) hPen = ExtCreatePen(PS_GEOMETRIC | P_SOLID | PS_JOIN_ROUND , PenManagerForm->Pen->Thick*ZoomIn/ZoomOut, &logbrush, 0, NULL ); else hPen = ExtCreatePen(PS_GEOMETRIC | P_SOLID | PS_ENDCAP_FLAT , PenManagerForm->Pen->Thick*ZoomIn/ZoomOut, &logbrush, 0, NULL ); } hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); hOldPen = SelectObject(dcDst, hPen); SetROP2(dcDst, R2_COPYPEN); switch (VectorForm->Item) { case 1: // Line if (step == 1) { if (VectorForm->bZKey) { // ¼öÁ÷/¼öÆò ±×¸®±â if (abs(Cux-Lsx)>abs(Cuy-Lsy)) Cuy = Lsy; else Cux = Lsx; } MoveToEx(dcDst, Lsx, Lsy, NULL); LineTo(dcDst, Cux, Cuy); //============= RECT tr = Rect(VectorForm->Cux-3, VectorForm->Cuy-3, VectorForm->Cux+3, VectorForm->Cuy+3); if (!bFstLine) { if (PtInRect(&tr, data->pList[0].P()) && bAltState && !CheckFirstLine()) { MainImageForm->iMainImage->Cursor = crHandPoint; bClosedState = true; }else { MainImageForm->iMainImage->Cursor = crDefault; bClosedState = false; } } //============= } break; case 2: // Curve if (step == 1) { if (VectorForm->bZKey) { // ¼öÁ÷/¼öÆò ±×¸®±â if (abs(Cux-Lsx)>abs(Cuy-Lsy)) Cuy = Lsy; else Cux = Lsx; } MoveToEx(dcDst, Lsx, Lsy, NULL); LineTo(dcDst, Cux, Cuy); //============= RECT tr = Rect(VectorForm->Cux-3, VectorForm->Cuy-3, VectorForm->Cux+3, VectorForm->Cuy+3); if (!bFstLine) { if (PtInRect(&tr, data->pList[0].P()) && bAltState) { MainImageForm->iMainImage->Cursor = crHandPoint; bClosedState = true; }else { MainImageForm->iMainImage->Cursor = crDefault; bClosedState = false; } } //============= }else if (step == 2) { POINT pTan1, pTan2; if (VectorForm->LineType == 1 || VectorForm->LineType == 2) { pTan1.x = Lsx; pTan1.y = Lsy; pTan2.x = Lex *2 - Cux; pTan2.y = Ley *2 - Cuy; }else if (VectorForm->LineType == 3) { if (bFstLine) { pTan1.x = Lsx; pTan1.y = Lsy; }else { pTan1.x = (pTan.x - PositionX) * ZoomIn / ZoomOut -px; pTan1.y = (pTan.y - PositionY) * ZoomIn / ZoomOut -py; } pTan2.x = Lex *2 - Cux; pTan2.y = Ley *2 - Cuy; } POINT pts[] = {{Lsx ,Lsy}, {pTan1.x, pTan1.y}, {pTan2.x, pTan2.y}, {Lex, Ley}}; PolyBezier (dcDst, pts, 4); DeleteObject(SelectObject(dcDst, hOldPen)); hPen = NULL; // hPen = CreatePen(psSolid , 1, clBlack); hPen = CreatePen(psSolid , 1, PathColor); hOldPen = SelectObject(dcDst, hPen); SetROP2(dcDst, R2_COPYPEN); MoveToEx(dcDst, pTan2.x, pTan2.y, NULL); LineTo(dcDst, Cux, Cuy); SmallRect(dcDst, pTan2); SmallRect(dcDst, Point(Cux, Cuy)); } break; case 3: // Square if (step == 1) { int vmin = min(abs(Lsx-Cux), abs(Ley-Cuy)); if (Cux > Lsx) Cux = Lsx + vmin; else Cux = Lsx - vmin; if (Cuy > Ley) Cuy = Ley + vmin; else Cuy = Ley - vmin; Rectangle(dcDst, Lsx, Ley, Cux, Cuy); } break; case 4: // Rectangle if (step == 1) { Rectangle(dcDst, Lsx, Lsy, Cux, Cuy); } break; case 5: // Circle if (step == 1) { int ra = sqrt((Cux-Lsx)*(Cux-Lsx)+(Cuy-Lsy)*(Cuy-Lsy)); Ellipse(dcDst, Lsx-ra, Lsy-ra, Lsx+ra, Lsy+ra); } break; case 6: // Ellipse if (step == 1) { Ellipse(dcDst, Lsx-abs(Lsx-Cux), Lsy-abs(Lsy-Cuy), Lsx+abs(Lsx-Cux), Lsy+abs(Lsy-Cuy)); } break; } SetROP2(dcDst, nDrawMode); SelectObject(dcDst, hOldPen); SelectObject(dcDst, hOldBrush); DeleteObject(hPen); hPen = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ObjectSelect(TShiftState Shift, int X, int Y, bool bPoint) { POINT pTemp[1024]; int MinDist = 29999, MinIndex = -1; int FirstX, FirstY, SecondX, SecondY; nSelPos = 0; ptNumber = -1; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->bLocked) {data->bSelected = false; continue;} if (data->Kind == V_TEXT) { FirstY = min(data->First.y, data->Second.y); SecondY = max(data->First.y, data->Second.y); FirstX = min(data->First.x, data->Second.x); SecondX = max(data->First.x, data->Second.x); }else { FirstX = data->First.x - data->PenThick; FirstY = data->First.y - data->PenThick; SecondX = data->Second.x + data->PenThick; SecondY = data->Second.y + data->PenThick; } if (!Shift.Contains(ssShift) && !Shift.Contains(ssAlt)) data->bSelected = false; /* if (data->Kind == V_CURVE && data->nCount == 1){ double x, y, a, b, dx, dy, r; if (X < FirstX-5 || X > SecondX+5 || Y < FirstY-5 || Y > SecondY+5) continue; x = double(data->pList[0].x); y = double(data->pList[0].y); a = double(data->pList[3].x); b = double(data->pList[3].y); dx = x - a; dy = y - b; if (dx != 0) r = abs(dy/dx*X - Y - dy/dx*x + y)/sqrt((dy*dy)/(dx*dx) + 1); else r = abs(x - X); if (r <= data->PenThick) { MinIndex = i; MinDist = 0; // ¹«Á¶°Ç Á÷¼±À¸·Î Àâ¾ÆÁØ´Ù continue; } } */ if (X < FirstX || X > SecondX || Y < FirstY || Y > SecondY) continue; // »ç°¢Çü ¾È¿¡ ÀÖ´ÂÁö °Ë»ç if (data->Kind == V_LINE || data->Kind == V_CURVE){ // Á÷¼±, °î¼±¾ÈÀÇ ¿µ¿ª¿¡ ÀÖ´ÂÁö °Ë»ç if (!PointOnCurvePath(data, X, Y)) continue; } if (MinDist > sqrt(pow((X-(FirstX+SecondX)/2),2)+pow((Y-(FirstY+SecondY)/2),2))){ MinDist = sqrt(pow((X-(FirstX+SecondX)/2),2)+pow((Y-(FirstY+SecondY)/2),2)); MinIndex = i; } memset(data->pMask, 0, 128);; // Point MaskÃʱâÈ­ } if (MinIndex == -1) { bSelected = false; return; } // ÇØ´çÇÏ´Â object°¡ ¾øÀ½ success: data = (TVecData *)DataList->Items[MinIndex]; if (Shift.Contains(ssAlt)) { data->bSelected = false; // ¾ËÆ®¸¦ ´©¸£°í ¼±ÅÃÇÏ¸é ¼±ÅÃÀÌ ÇØÁ¦µÈ´Ù if ((data->GroupIndex & 0xfffffe00) && !bPoint) ModifyGroup(data, false); }else { data->bSelected = true; if ((data->GroupIndex & 0xfffffe00 && !bPoint)) ModifyGroup(data, true); } bSelected = true; Index = MinIndex; nSelPos = 5; // ´©¸£ÀÚ ¸¶ÀÚ À̵¿½Ãų ¼ö ÀÖÀ½ } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DrawSelectedLine(HDC dcDst, int px, int py, TMainImageForm *form) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush=NULL; POINT pTemp[1024]; int nDrawMode; int ZoomIn = form->iMainImage->ZoomIn; int ZoomOut = form->iMainImage->ZoomOut; int PositionX = form->sbHorz->Position; int PositionY = form->sbVert->Position; // hPen = CreatePen(psSolid , 1, clBlack); hPen = CreatePen(psSolid , 1, PathColor); hOldPen = SelectObject(dcDst, hPen); nDrawMode = GetROP2(dcDst); SetROP2(dcDst, R2_COPYPEN); // SetROP2(dcDst, R2_NOT); hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; int FirstX = (data->First.x - PositionX) * ZoomIn / ZoomOut -px; int FirstY = (data->First.y - PositionY) * ZoomIn / ZoomOut -py; int SecondX = (data->Second.x - PositionX) * ZoomIn / ZoomOut -px; int SecondY = (data->Second.y - PositionY) * ZoomIn / ZoomOut -py; if (!data->bSelected) continue; if (!data->Equal(form->Number)) continue; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = (data->pList[i].x - PositionX) * ZoomIn / ZoomOut -px; pTemp[i].y = (data->pList[i].y - PositionY) * ZoomIn / ZoomOut -py; } } //////// Closed Path if (data->bClosed) pTemp[data->nCount*3] = pTemp[0]; //////// if (data->Kind == V_TEXT) { int height = data->Font.lfHeight * ZoomIn / ZoomOut; double angle = 2*M_PI*data->Font.lfEscapement/10/360; if (angle M_PI && angleKind) { case V_LINE: for (int i = 0; i < data->nCount+1; i++) { SmallRect(dcDst, pTemp[i]); if ((data->pMask[i/8] >> i%8) & 0x01) SmallRect2(dcDst, pTemp[i]); } Polyline(dcDst, pTemp, data->nCount +1); SmallRect(dcDst, Point((FirstX+SecondX)/2, (FirstY+SecondY)/2)); break; case V_CURVE: PolyBezier (dcDst, pTemp, data->nCount*3 +1); SmallRect(dcDst, Point((FirstX+SecondX)/2, (FirstY+SecondY)/2)); for (int j = 0; j < data->nCount*3 + (!data->bClosed); j+=3) { SmallRect(dcDst, pTemp[j]); if ((data->pMask[j/8] >> j%8) & 0x01) { SmallRect2(dcDst, pTemp[j]); } } for (int j = 0; j < data->nCount*3 + (!data->bClosed); j++) { if ((data->pMask[j/8] >> j%8) & 0x01) { switch (j%3) { case 0: // ½ÇÁ¦ Á¡ if (j == data->nCount*3){ // ¸¶Áö¸· Á¡Àΰæ¿ì!~ SmallRect(dcDst, pTemp[j-1]); MoveToEx(dcDst, pTemp[j-1].x, pTemp[j-1].y, NULL); LineTo(dcDst, pTemp[j].x, pTemp[j].y); }else { if (j == 0) { if (data->bClosed) { // for Closed path SmallRect(dcDst, pTemp[data->nCount*3-1]); SmallRect(dcDst, pTemp[j+1]); MoveToEx(dcDst, pTemp[data->nCount*3-1].x, pTemp[data->nCount*3-1].y, NULL); LineTo(dcDst, pTemp[j].x, pTemp[j].y); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); }else { // when j equal zero SmallRect(dcDst, pTemp[j+1]); MoveToEx(dcDst, pTemp[j].x, pTemp[j].y, NULL); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); } }else { // ordinary SmallRect(dcDst, pTemp[j-1]); SmallRect(dcDst, pTemp[j+1]); MoveToEx(dcDst, pTemp[j-1].x, pTemp[j-1].y, NULL); LineTo(dcDst, pTemp[j].x, pTemp[j].y); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); } } break; case 1: if (j == 1) { if (data->bClosed) { SmallRect(dcDst, pTemp[data->nCount*3-1]); SmallRect(dcDst, pTemp[j]); MoveToEx(dcDst, pTemp[data->nCount*3-1].x, pTemp[data->nCount*3-1].y, NULL); LineTo(dcDst, pTemp[j-1].x, pTemp[j-1].y); LineTo(dcDst, pTemp[j].x, pTemp[j].y); }else { SmallRect(dcDst, pTemp[j]); MoveToEx(dcDst, pTemp[j-1].x, pTemp[j-1].y, NULL); LineTo(dcDst, pTemp[j].x, pTemp[j].y); } }else { SmallRect(dcDst, pTemp[j-2]); SmallRect(dcDst, pTemp[j]); MoveToEx(dcDst, pTemp[j-2].x, pTemp[j-2].y, NULL); LineTo(dcDst, pTemp[j-1].x, pTemp[j-1].y); LineTo(dcDst, pTemp[j].x, pTemp[j].y); } break; case 2: if (j == data->nCount*3-1){ // ¸¶Áö¸· Á¶ÀýÁ¡Àΰæ¿ì!~ if (data->bClosed) { SmallRect(dcDst, pTemp[j]); SmallRect(dcDst, pTemp[1]); MoveToEx(dcDst, pTemp[j].x, pTemp[j].y, NULL); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); LineTo(dcDst, pTemp[1].x, pTemp[1].y); }else { SmallRect(dcDst, pTemp[j]); MoveToEx(dcDst, pTemp[j].x, pTemp[j].y, NULL); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); } }else { SmallRect(dcDst, pTemp[j]); SmallRect(dcDst, pTemp[j+2]); MoveToEx(dcDst, pTemp[j].x, pTemp[j].y, NULL); LineTo(dcDst, pTemp[j+1].x, pTemp[j+1].y); LineTo(dcDst, pTemp[j+2].x, pTemp[j+2].y); } break; } } } break; default: Rectangle(dcDst, FirstX, FirstY, SecondX, SecondY); SmallRect(dcDst, Point(FirstX, FirstY)); SmallRect(dcDst, Point(SecondX, SecondY)); SmallRect(dcDst, Point(FirstX, SecondY)); SmallRect(dcDst, Point(SecondX, FirstY)); SmallRect(dcDst, Point((FirstX+SecondX)/2,(FirstY+SecondY)/2)); break; } } SetROP2(dcDst, nDrawMode); SelectObject(dcDst, hOldPen); SelectObject(dcDst, hOldBrush); DeleteObject(hPen); hPen = NULL; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DrawRotationLine(HDC dcDst, int px, int py) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush=NULL; POINT pTemp[1024]; int nDrawMode; int ZoomIn = MainImageForm->iMainImage->ZoomIn; int ZoomOut = MainImageForm->iMainImage->ZoomOut; int PositionX = MainImageForm->sbHorz->Position; int PositionY = MainImageForm->sbVert->Position; int cx = (sx+ex)/2, cy = (sy+ey)/2; // rotation objectµéÀÇ centerÁ¡µé hPen = CreatePen(psSolid , 2, PathColor); hOldPen = SelectObject(dcDst, hPen); nDrawMode = GetROP2(dcDst); SetROP2(dcDst, R2_COPYPEN); hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->bSelected) continue; if (!data->Equal(MainImageForm->Number)) continue; if (data->Kind == V_TEXT) { data->bSelected = false; continue; } for (int i = 0; i < data->nCount*3 +1; i++) pTemp[i] = data->pList[i].P(); for (int j = 0; j < data->nCount*3 +1; j++) { int tx = pTemp[j].x - cx; int ty = cy - pTemp[j].y; pTemp[j].x = tx*cos(-RotationAngle) + ty*sin(-RotationAngle) + cx; pTemp[j].y = cy - (-tx*sin(-RotationAngle) + ty*cos(-RotationAngle)); } if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { pTemp[i].x = (pTemp[i].x - PositionX) * ZoomIn / ZoomOut -px; pTemp[i].y = (pTemp[i].y - PositionY) * ZoomIn / ZoomOut -py; } } if (data->bClosed) pTemp[data->nCount*3] = pTemp[0]; switch (data->Kind) { case V_LINE: // for (int i = 0; i < data->nCount+1; i++) { // SmallRect(dcDst, pTemp[i]); // if ((data->pMask[i/8] >> i%8) & 0x01) SmallRect2(dcDst, pTemp[i]); // } Polyline(dcDst, pTemp, data->nCount +1); break; case V_CURVE: PolyBezier (dcDst, pTemp, data->nCount*3 +1); // SmallRect(dcDst, Point(cx, cy); // for (int j = 0; j < data->nCount*3 + (!data->bClosed); j+=3) { // SmallRect(dcDst, pTemp[j]); // if ((data->pMask[j/8] >> j%8) & 0x01) { // SmallRect2(dcDst, pTemp[j]); // } // } break; } } SetROP2(dcDst, nDrawMode); SelectObject(dcDst, hOldPen); SelectObject(dcDst, hOldBrush); DeleteObject(hPen); hPen = NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Mouse Handling Part //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseMove(int X, int Y) { int FirstX, FirstY, SecondX, SecondY; nSelPos = 0; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind == V_TEXT) { FirstY = min(data->First.y, data->Second.y); SecondY = max(data->First.y, data->Second.y); FirstX = min(data->First.x, data->Second.x); SecondX = max(data->First.x, data->Second.x); }else { FirstX = data->First.x - data->PenThick; FirstY = data->First.y - data->PenThick; SecondX = data->Second.x + data->PenThick; SecondY = data->Second.y + data->PenThick; } if (X < FirstX || X > SecondX || Y < FirstY || Y > SecondY) continue; if (data->Kind == V_LINE || data->Kind == V_CURVE) { if (PointOnCurvePath(data, X, Y)) { nSelPos = 5; break; } }else {nSelPos = 5; break; } // ¿µ¿ª ¾È¿¡¸¸ À־ À̵¿ °¡´É if (data->Kind == V_LINE || data->Kind == V_CURVE) continue; // Line°ú curve´Â ¸ð¼­¸®Á¡ Ŭ¸¯ ¾ø´Ù if (abs(X - data->First.x) < 3 && abs(Y - data->First.y) < 3) { nSelPos = 1; break; } if (abs(X - data->Second.x) < 3 && abs(Y - data->First.y) < 3) { nSelPos = 2; break; } if (abs(X - data->First.x) < 3 && abs(Y - data->Second.y) < 3) { nSelPos = 3; break; } if (abs(X - data->Second.x) < 3 && abs(Y - data->Second.y) < 3) { nSelPos = 4; break; } if (abs(X - (data->First.x + data->Second.x)/2) < 3 && abs(Y - (data->First.y + data->Second.y)/2) < 3) { nSelPos = 5; break; } } switch (nSelPos){ // Ä¿¼­ÀÇ À§Ä¡¿¡ µû¸¥ Ä¿¼­ ¸ð¾ç º¯È­ case 1: case 4: MainImageForm->iMainImage->Cursor = crSizeNWSE; break; case 2: case 3: MainImageForm->iMainImage->Cursor = crSizeNESW; break; case 5: MainImageForm->iMainImage->Cursor = crSizeAll; break; case 0: MainImageForm->iMainImage->Cursor = crDefault; break; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMousePointMove(int X, int Y) { nSelPos = 0; RECT rc; int rg; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É //rg = data->PenThick > 3 ? 3 : data->PenThick; rg = 3; rc = Rect(X-rg, Y-rg, X+rg, Y+rg); if (PointOnCurvePath(data, X, Y)) { nSelPos = 5; } for (int i = 0; i < data->nCount*3+1; i++) { if (PtInRect(&rc, data->pList[i].P())) { nSelPos = 10; // Á¡À§¿¡ ÀÖ°ÔµÇ¸é °ªÀº 10ÀÌ´Ù ptNumber = i; if (ptNumber % 3 == 0) goto next; // Á¶ÀýÁ¡ º¸´Ù´Â ½ÇÁ¦ Á¡ÀÌ ¿ì¼±Çϵµ·Ï ÇÑ´Ù } } if (nSelPos) break; } next: switch (nSelPos){ // Ä¿¼­ÀÇ À§Ä¡¿¡ µû¸¥ Ä¿¼­ ¸ð¾ç º¯È­ case 10: MainImageForm->iMainImage->Cursor = crDrag; break; case 0: MainImageForm->iMainImage->Cursor = crDefault; break; } } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::OnMouseDrawMove(int X, int Y) { nSelPos = 0; RECT rc; int rg; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É if (data->bClosed) continue; rg = data->PenThick > 5 ? 5 : data->PenThick; rc = Rect(X-rg, Y-rg, X+rg, Y+rg); if (PtInRect(&rc, data->pList[0].P())) { nSelPos = 10; // Á¡À§¿¡ ÀÖ°ÔµÇ¸é °ªÀº 10ÀÌ´Ù bExtendFirst = true; Index = i; goto success; }else if (PtInRect(&rc, data->pList[data->nCount*3].P())) { nSelPos = 10; // Á¡À§¿¡ ÀÖ°ÔµÇ¸é °ªÀº 10ÀÌ´Ù bExtendFirst = false; Index = i; goto success; } } MainImageForm->iMainImage->Cursor = crDefault; return false; success: MainImageForm->iMainImage->Cursor = crDrag; return true; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseDrag(int &Lsx, int &Lsy, int X, int Y) { RECT rc, rc2 = Rect(MainImageForm->iMainImage->uBitmap->Width, MainImageForm->iMainImage->uBitmap->Height, 0, 0); int MoveX = X - Lsx; int MoveY = Y - Lsy; Lsx = X; Lsy = Y; bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (bUndosw && (MoveX || MoveY)) UndoSave(VU_MODIFY, i, sw); sw = false; data->First.x += MoveX; data->First.y += MoveY; data->Second.x += MoveX; data->Second.y += MoveY; switch (data->Kind) { case V_LINE: for (int i = 0; i < data->nCount+1; i++) { data->pList[i].x += MoveX; data->pList[i].y += MoveY; } break; case V_CURVE: for (int i = 0; i < data->nCount*3+1; i++) { data->pList[i].x += MoveX; data->pList[i].y += MoveY; } break; default: break; } if (data->Kind == V_CURVE) { POINT Temp1, Temp2; Temp1.x = 19999; Temp1.y = 19999; Temp2.y = 0; Temp2.y = 0; for (int i = 0; i < data->nCount*3+1; i++) { if (Temp1.x > data->pList[i].x) Temp1.x = data->pList[i].x; if (Temp1.y > data->pList[i].y) Temp1.y = data->pList[i].y; if (Temp2.x < data->pList[i].x) Temp2.x = data->pList[i].x; if (Temp2.y < data->pList[i].y) Temp2.y = data->pList[i].y; } rc.top = MoveY > 0 ? Temp1.y - MoveY - data->PenThick - 5: Temp1.y - data->PenThick - 5; rc.bottom = MoveY > 0 ? Temp2.y + data->PenThick + 5: Temp2.y - MoveY + data->PenThick + 5; rc.left = MoveX > 0 ? Temp1.x - MoveX - data->PenThick - 5: Temp1.x - data->PenThick - 5; rc.right = MoveX > 0 ? Temp2.x + data->PenThick + 5: Temp2.x - MoveX + data->PenThick + 5; }else if (data->Kind == V_TEXT) { POINT fst,snd; fst.x = min(data->First.x, data->Second.x) - data->Font.lfHeight; fst.y = min(data->First.y, data->Second.y) - data->Font.lfHeight; snd.x = max(data->First.x, data->Second.x) + data->Font.lfHeight; snd.y = max(data->First.y, data->Second.y) + data->Font.lfHeight; rc.top = MoveY > 0 ? fst.y - MoveY : fst.y; rc.bottom = MoveY > 0 ? snd.y : snd.y - MoveY; rc.left = MoveX > 0 ? fst.x - MoveX : fst.x; rc.right = MoveX > 0 ? snd.x : snd.x - MoveX; }else { rc.top = MoveY > 0 ? data->First.y - MoveY - data->PenThick - 20: data->First.y - data->PenThick - 20; rc.bottom = MoveY > 0 ? data->Second.y + data->PenThick + 20: data->Second.y - MoveY + data->PenThick + 20; rc.left = MoveX > 0 ? data->First.x - MoveX - data->PenThick - 20: data->First.x - data->PenThick - 20; rc.right = MoveX > 0 ? data->Second.x + data->PenThick + 20: data->Second.x - MoveX + data->PenThick + 20; } rc2.top = min(rc2.top, rc.top); // ÃÖÀûÀÇ »ç°¢Çü ¸¸µé±â (ÇѹøÀÇ rectpaint¸¸ Çϵµ·Ï) rc2.bottom = max(rc2.bottom, rc.bottom); rc2.left = min(rc2.left, rc.left); rc2.right = max(rc2.right, rc.right); } MainImageForm->iMainImage->RectPaint(rc2); if (MoveX || MoveY) bUndosw = false; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMousePointDrag(int &Lsx, int &Lsy, int X, int Y) { RECT rc1, rc2, rc3; int MoveX = X - Lsx; int MoveY = Y - Lsy; Lsx = X; Lsy = Y; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (bUndosw && (MoveX || MoveY)) UndoSave(VU_MODIFY, i); for (int j = 0; j < data->nCount*3+1; j++) { if (((data->pMask[j/8] >> j%8) & 0x01)) { data->pList[j].x += MoveX; data->pList[j].y += MoveY; switch (j%3) { double vx,vy,d; case 0: if (j == 0) { if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[data->nCount*3-1].x += MoveX; data->pList[data->nCount*3-1].y += MoveY; data->pList[data->nCount*3] = data->pList[j]; } data->pList[j+1].x += MoveX; data->pList[j+1].y += MoveY; }else if (j == data->nCount*3) { if (data->bClosed) { }else { data->pList[j-1].x += MoveX; data->pList[j-1].y += MoveY; } }else { data->pList[j-1].x += MoveX; data->pList[j-1].y += MoveY; data->pList[j+1].x += MoveX; data->pList[j+1].y += MoveY; } break; case 1: vx = data->pList[j].x - data->pList[j-1].x; vy = data->pList[j].y - data->pList[j-1].y; d = sqrt(vx*vx + vy*vy); if (d == 0) break; vx = vx / d * (-1); vy = vy / d * (-1); if (j == 1) { d = sqrt(pow(data->pList[data->nCount*3-1].x - data->pList[j-1].x ,2)+ pow(data->pList[data->nCount*3-1].y - data->pList[j-1].y ,2) ); if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[data->nCount*3-1].x = data->pList[j-1].x + vx * d; data->pList[data->nCount*3-1].y = data->pList[j-1].y + vy * d; } }else { d = sqrt(pow(data->pList[j-2].x - data->pList[j-1].x ,2)+ pow(data->pList[j-2].y - data->pList[j-1].y ,2) ); data->pList[j-2].x = data->pList[j-1].x + vx * d; data->pList[j-2].y = data->pList[j-1].y + vy * d; } break; case 2: if (j == data->nCount*3 -1) { vx = data->pList[j].x - data->pList[0].x; vy = data->pList[j].y - data->pList[0].y; d = sqrt(vx*vx + vy*vy); if (d == 0) break; vx = vx / d * (-1); vy = vy / d * (-1); d = sqrt(pow(data->pList[1].x - data->pList[0].x ,2)+ pow(data->pList[1].y - data->pList[0].y ,2) ); if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[1].x = data->pList[0].x + vx * d; data->pList[1].y = data->pList[0].y + vy * d; } }else { vx = data->pList[j].x - data->pList[j+1].x; vy = data->pList[j].y - data->pList[j+1].y; d = sqrt(vx*vx + vy*vy); if (d == 0) break; vx = vx / d * (-1); vy = vy / d * (-1); d = sqrt(pow(data->pList[j+2].x - data->pList[j+1].x ,2)+ pow(data->pList[j+2].y - data->pList[j+1].y ,2) ); data->pList[j+2].x = data->pList[j+1].x + vx * d; data->pList[j+2].y = data->pList[j+1].y + vy * d; } break; } } } // data->pList[ptNumber].x += MoveX; // data->pList[ptNumber].y += MoveY; //============ Point Drag·Î Alt ´©¸£°í Closed path ¸¸µé±â if (ptNumber == data->nCount*3 && bAltState && !data->bClosed) { RECT rt = Rect(X-3, Y-3, X+3, Y+3); if (PtInRect(&rt, data->pList[0].P())) { data->bClosed = true; data->pList[data->nCount*3-1].x += data->pList[0].x - data->pList[data->nCount*3].x; data->pList[data->nCount*3-1].y += data->pList[0].y - data->pList[data->nCount*3].y; ptNumber = 0; MoveX = 0; MoveY = 0; } }else if (ptNumber == 0 && bAltState && !data->bClosed) { RECT rt = Rect(X-3, Y-3, X+3, Y+3); if (PtInRect(&rt, data->pList[data->nCount*3].P())) { data->bClosed = true; data->pList[data->nCount*3-1].x += data->pList[0].x - data->pList[data->nCount*3].x; data->pList[data->nCount*3-1].y += data->pList[0].y - data->pList[data->nCount*3].y; ptNumber = 0; MoveX = 0; MoveY = 0; } } //============ /* if (ptNumber == data->nCount*3 && !data->bClosed) { RECT rt = Rect(X-3, Y-3, X+3, Y+3); if (PtInRect(&rt, data->pList[0])) { MainImageForm->iMainImage->Cursor = crHandPoint; Application->ProcessMessages(); // MoveX = 0; MoveY = 0; } }else if (ptNumber == 0 && !data->bClosed) { RECT rt = Rect(X-3, Y-3, X+3, Y+3); if (PtInRect(&rt, data->pList[data->nCount*3])) { MainImageForm->iMainImage->Cursor = crHandPoint; Application->ProcessMessages(); // MoveX = 0; MoveY = 0; } }*/ ///////////////////////»õ·Î¿î ¹æ½Ä next: rc1.top = data->First.y - data->PenThick*2 -10; rc1.bottom = data->Second.y + data->PenThick*2 +10; rc1.left = data->First.x - data->PenThick*2 -10; rc1.right = data->Second.x + data->PenThick*2 +10; SET_RECT; rc2.top = data->First.y - data->PenThick*2 -10; rc2.bottom = data->Second.y + data->PenThick*2 +10; rc2.left = data->First.x - data->PenThick*2 -10; rc2.right = data->Second.x + data->PenThick*2 +10; UnionRect(&rc3, &rc1, &rc2); // µÎ rect¸¦ Æ÷ÇÔÇÏ´Â °¡Àå ÀÛÀº rect rc3 MainImageForm->iMainImage->RectPaint(rc3); break; } if (MoveX || MoveY) bUndosw = false; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseConvertDown(int &Lsx, int &Lsy, int X, int Y) { RECT rc1, rc2, rc3, rt = Rect(X-3, Y-3, X+3, Y+3); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; for (int j = 0; j < data->nCount*3+1; j+=3) { // ½ÇÁ¦ Á¡ ¸ÕÀú if (PtInRect(&rt, data->pList[j].P())) { memset(data->pMask, 0, 128);; data->pMask[j/8] |= (0x01<<(j%8)); UndoSave(VU_MODIFY, i); if (j == 0) { if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[data->nCount*3-1] = data->pList[j]; } data->pList[j+1] = data->pList[j]; }else if (j == data->nCount*3) { data->pList[j-1] = data->pList[j]; }else { data->pList[j+1] = data->pList[j]; data->pList[j-1] = data->pList[j]; } rc1.top = data->First.y - data->PenThick -5; rc1.bottom = data->Second.y + data->PenThick +5; rc1.left = data->First.x - data->PenThick -5; rc1.right = data->Second.x + data->PenThick +5; SET_RECT; rc2.top = data->First.y - data->PenThick -5; rc2.bottom = data->Second.y + data->PenThick +5; rc2.left = data->First.x - data->PenThick -5; rc2.right = data->Second.x + data->PenThick +5; UnionRect(&rc3, &rc1, &rc2); // µÎ rect¸¦ Æ÷ÇÔÇÏ´Â °¡Àå ÀÛÀº rect rc3 MainImageForm->iMainImage->RectPaint(rc3); bUndosw = false; goto success; } } for (int j = 0; j < data->nCount*3+1; j++) { if (PtInRect(&rt, data->pList[j].P())) { memset(data->pMask, 0, 128);; data->pMask[j/8] |= (0x01<<(j%8)); } } } success: return; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseConvert(int &Lsx, int &Lsy, int X, int Y) { RECT rc1, rc2, rc3, tp; int MoveX = X - Lsx; int MoveY = Y - Lsy; Lsx = X; Lsy = Y; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; // if (bUndosw && (MoveX || MoveY)) UndoSave(VU_MODIFY, i); if (bUndosw) UndoSave(VU_MODIFY, i); for (int j = 0; j < data->nCount*3 + (!data->bClosed); j++) { if ((data->pMask[j/8] >> j%8) & 0x01) { switch (j%3) { case 0: tp = Rect(X-3, Y-3, X+3, Y+3); if (PtInRect(&tp, data->pList[j].P())) { // ¿òÁ÷ÀÓÀÌ ¾ø´Â°æ¿ì if (j == 0) { if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[data->nCount*3-1] = data->pList[j]; } data->pList[j+1] = data->pList[j]; }else if (j == data->nCount*3) { data->pList[j-1] = data->pList[j]; }else { data->pList[j+1] = data->pList[j]; data->pList[j-1] = data->pList[j]; } }else { if (j == 0) { if (data->bClosed) { // closed path¿¡¼­ÀÇ Ã³¸® data->pList[data->nCount*3-1].DPoint(data->pList[j].x*2 - data->pList[j+1].x, data->pList[j].y*2 - data->pList[j+1].y); } data->pList[j+1].DPoint(X, Y); }else if (j == data->nCount*3) { data->pList[j-1].DPoint(data->pList[j].x*2 - X, data->pList[j].y*2 - Y); }else { data->pList[j+1].DPoint(X, Y); data->pList[j-1].DPoint(data->pList[j].x*2 - data->pList[j+1].x, data->pList[j].y*2 - data->pList[j+1].y); } } break; case 1: data->pList[j].DPoint(X, Y); break; case 2: data->pList[j].DPoint(X, Y); break; } break; } } rc1.top = data->First.y - data->PenThick -5; rc1.bottom = data->Second.y + data->PenThick +5; rc1.left = data->First.x - data->PenThick -5; rc1.right = data->Second.x + data->PenThick +5; SET_RECT; rc2.top = data->First.y - data->PenThick -5; rc2.bottom = data->Second.y + data->PenThick +5; rc2.left = data->First.x - data->PenThick -5; rc2.right = data->Second.x + data->PenThick +5; UnionRect(&rc3, &rc1, &rc2); // µÎ rect¸¦ Æ÷ÇÔÇÏ´Â °¡Àå ÀÛÀº rect rc3 MainImageForm->iMainImage->RectPaint(rc3); break; } // if (MoveX || MoveY) bUndosw = false; bUndosw = false; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseRepro(int &Lsx, int &Lsy, int X, int Y) { RECT rc; int MoveX = X - Lsx; int MoveY = Y - Lsy; Lsx = X; Lsy = Y; bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; switch (nSelPos) { case 1: data->First.x += MoveX; data->First.y += MoveY; break; case 2: data->Second.x += MoveX; data->First.y += MoveY; break; case 3: data->First.x += MoveX; data->Second.y += MoveY; break; case 4: data->Second.x += MoveX; data->Second.y += MoveY; break; } rc.top = MoveY > 0 ? data->First.y - MoveY - data->PenThick: data->First.y - data->PenThick; rc.bottom = MoveY > 0 ? data->Second.y + data->PenThick: data->Second.y - MoveY + data->PenThick; rc.left = MoveX > 0 ? data->First.x - MoveX - data->PenThick: data->First.x - data->PenThick; rc.right = MoveX > 0 ? data->Second.x + data->PenThick: data->Second.x - MoveX + data->PenThick; MainImageForm->iMainImage->RectPaint(rc); } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseSelectDrag(int Lex, int Ley, int X, int Y) { HPEN hOldPen = NULL , hPen = NULL; HBRUSH hOldBrush=NULL; int nDrawMode; HDC dcDst = MainImageForm->iMainImage->Canvas->Handle; int ZoomIn = MainImageForm->iMainImage->ZoomIn; int ZoomOut = MainImageForm->iMainImage->ZoomOut; int PositionX = MainImageForm->sbHorz->Position; int PositionY = MainImageForm->sbVert->Position; int FirstX = (Lex - PositionX) * ZoomIn / ZoomOut; int FirstY = (Ley - PositionY) * ZoomIn / ZoomOut; int SecondX = (X - PositionX) * ZoomIn / ZoomOut; int SecondY = (Y - PositionY) * ZoomIn / ZoomOut; int TempX = (pBak.x - PositionX) * ZoomIn / ZoomOut; int TempY = (pBak.y - PositionY) * ZoomIn / ZoomOut; hPen = CreatePen(psDash, 1, clBlue); hOldPen = SelectObject(dcDst, hPen); nDrawMode = GetROP2(dcDst); SetROP2(dcDst, R2_NOT); hOldBrush = SelectObject(dcDst, GetStockObject(NULL_BRUSH)); if (!bFirstMove) Rectangle(dcDst, FirstX, FirstY, TempX, TempY); //ÀÜ»ó¾ø¿¡±â Rectangle(dcDst, FirstX, FirstY, SecondX, SecondY); SetROP2(dcDst, nDrawMode); SelectObject(dcDst, hOldPen); SelectObject(dcDst, hOldBrush); DeleteObject(hPen); hPen = NULL; pBak = Point(X, Y); } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::MouseDragUp(TShiftState Shift, RECT Area, bool bPoint) { POINT Third, Forth; bool Success = false, sw = false; bool bShift = Shift.Contains(ssShift), bAlt = Shift.Contains(ssAlt); int group = 0; // ÀÌ¹Ì ¼±ÅÃÇÑ groupÀ» ´Ù½Ã ¼±ÅÃÇÏÁö ¾Êµµ·Ï for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->bLocked) {data->bSelected = false; continue;} if ((data->GroupIndex & group) && !bPoint) continue; if (!bShift && !bAlt) data->bSelected = false; if (data->Kind == V_LINE || data->Kind == V_CURVE) { // ¶óÀΰú Ä¿ºê´Â °¢°¢ÀÇ Á¡µéÀ» ´Ù Ã¼Å©ÇØº»´Ù if (!bPoint || (!bShift && !bAlt)) memset(data->pMask, 0, 128);; // Point MaskÃʱâÈ­ for (int j = 0; j < data->nCount*3+1; j+=3) { if (PtInRect(&Area, data->pList[j].P())) { sw = true; if (!bPoint) break; // object editÀÎ °æ¿ì °É¸®¸é ³Ñ¾î°¡±â else { // point editÀÎ °æ¿ì if (bAlt) data->pMask[j/8] &= ~(0x01<<(j%8)); else data->pMask[j/8] |= (0x01<<(j%8)); } } } }else if (!bPoint) { // ±âŸµîµî (Point Edit menu¿¡¼­´Â ºÒ°¡) Third = Point(data->First.x, data->Second.y); Forth = Point(data->Second.x, data->First.y); if (PtInRect(&Area, data->First) || PtInRect(&Area, data->Second) || PtInRect(&Area, Third) || PtInRect(&Area, Forth)) { sw = true; } } if (sw) { if (data->bSelected) { if (!bShift && !bPoint) { // AltŰ ´©¸¥ °æ¿ì data->bSelected = false; if (data->GroupIndex & 0xfffffe00) { group |= data->GroupIndex; // ¼±ÅÃÇÑ groupÀº ÀúÀåÇØ¼­ ´Ù½Ã ¼±ÅõÇÁö ¾Êµµ·Ï ÇÔ ModifyGroup(data, false); } } }else { // ¾È´©¸£°Å³ª Shift´©¸¥ °æ¿ì if(!bAlt) { data->bSelected = true; if ((data->GroupIndex & 0xfffffe00) && !bPoint) { group |= data->GroupIndex; ModifyGroup(data, true); } } Index = i; } bSelected = true; Success = true; sw = false; } } return Success; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ProportionMouseMove(int &X, int &Y) { RECT rc; static int tempX = X, tempY = Y; // rectpaint½ÃÀÇ ±¸¿ªÀ» Àâ±â À§ÇØ(ÀÌÀü Á¡À» ÀúÀå) ratiox = double(X-sx) / (double(ex-sx) ? double(ex-sx) : 1); ratioy = double(Y-sy) / (double(ey-sy) ? double(ey-sy) : 1); rc.top = min(int(sy), min(Y, tempY)) - thick; rc.bottom = max(int(ey*2-Y), max(Y, tempY)) + thick; rc.left = min(int(sx), min(X, tempX)) - thick; rc.right = max(int(ex*2-X), max(X, tempX)) + thick; tempX = X; tempY = Y; MainImageForm->iMainImage->RectPaint(rc); X = ratiox * 100; // ºñÀ²À» µ¹·ÁÁØ´Ù(¼ýÀÚ·Î º¸¿©ÁÖ±â À§ÇØ) Y = ratioy * 100; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::OnMouseDirectDown(TShiftState Shift, int X, int Y) { RECT rc, rt = Rect(X-3, Y-3, X+3, Y+3); bool bresult = false; if (bAltState) { // AltŰ ´©¸£°í Ŭ¸¯ÇÏ¿© ÆÐ½º ¿­±â if ((ptNumber%3)!= 0) return; data = (TVecData *)DataList->Items[Index]; if (data->Kind != V_LINE && data->Kind != V_CURVE) return; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É if (!data->bClosed) return; if (!PtInRect(&rt, data->pList[ptNumber].P())) return; UndoSave(VU_MODIFY, Index); POINT temp[1024]; for (int i = 0; i < data->nCount*3 - ptNumber; i++) temp[i] = data->pList[ptNumber+i].P(); for (int i = data->nCount*3 - ptNumber; i < data->nCount*3+1; i++) temp[i] = data->pList[i-data->nCount*3+ptNumber].P(); for (int i = 0; i < data->nCount*3 +1; i++) data->pList[i].DPoint(temp[i]); data->bClosed = false; ptNumber = 0; }else { for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É for (int j = 0; j < data->nCount*3+1; j+=3) { // ½ÇÁ¦ Á¡ºÎÅÍ Ã£±â if (PtInRect(&rt, data->pList[j].P())) { if (!Shift.Contains(ssShift)) { if (!((data->pMask[j/8] >> j%8) & 0x01)) { // ¼±Åà µÇ¾îÀÖ´Â°É ´©¸£¸é Åë°ú memset(data->pMask, 0, 128);; data->pMask[j/8] |= (0x01<<(j%8)); } }else { // shift´Â Ãß°¡ data->pMask[j/8] ^= (0x01<<(j%8)); } bresult = true; break; } } for (int j = 0; j < data->nCount*3+1 && !bresult; j++) { // Á¶ÀýÁ¡ ã±â if (PtInRect(&rt, data->pList[j].P())) { memset(data->pMask, 0, 128);; data->pMask[j/8] |= (0x01<<(j%8)); bresult = true; break; } } if (bresult) break; } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Object Edit Part //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeObjectColor(bool bFill) { RECT rc; bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; if (bFill) { // »ö±ò·Î ä¿ì±â data->bPatternFill = false; if (data->Bitmap) { delete data->Bitmap; data->Bitmap = NULL; } if (PaletteForm->DIB256Palette->ChoiceIndex == 1) { // ¼±ÅÃµÈ color°¡ ¹ÙÅÁ»öÀ̸é NULL Brush·Î~ // data->Brush = 0; data->bFill = false; }else { if (data->bFill && data->Brush==PenManagerForm->PenShape->Pen->Color) { if (data->bWinding) data->bWinding = false; else data->bWinding = true; }else { data->Brush = PenManagerForm->PenShape->Pen->Color; data->bFill = true; data->bWinding = false; } } }else { // Ææ»ö±ò ¹Ù²Ù±â data->Color = PenManagerForm->PenShape->Pen->Color; } if (data->Kind == V_TEXT) { rc.top = min(data->First.y, data->Second.y) - data->Font.lfHeight; rc.bottom = max(data->First.y, data->Second.y) + data->Font.lfHeight; rc.left = min(data->First.x, data->Second.x) - data->Font.lfHeight; rc.right = max(data->First.x, data->Second.x) + data->Font.lfHeight; }else { rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; } MainImageForm->iMainImage->RectPaint(rc); } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeObjectOrder(bool bFront, bool bOne) { RECT rc; bool sw = true; for (int i = 0; i < DataList->Count; i++) { if (bFront && bOne) // ¾ÕÀ¸·Î ÇÑÄ­ º¸³»±â¿¡¼­´Â µÚ¿¡¼­ºÎÅÍ °Ë»öÇØ¾ßÇÔ data = (TVecData *)DataList->Items[DataList->Count-i-1]; else data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (bFront) { // ¾ÕÀ¸·Î º¸³¿ if (bOne) { if (i == 0) continue; // ¸Ç ¾Õ¿¡°Å´Â ¸øº¸³¿~ UndoSave(VU_ORDERF, DataList->Count-i-1, sw, DataList->Count-i); DataList->Move(DataList->Count-i-1,DataList->Count-i); Index = DataList->Count-i; }else { UndoSave(VU_ORDERF, i, sw); DataList->Move(i,DataList->Count-1); Index = DataList->Count-1; } }else { // µÚ·Î º¸³¿ if (bOne) { if (i == 0) continue; // ¸Ç µÚ¿¡°Å´Â ¸øº¸³¿~ UndoSave(VU_ORDERB, i, sw, i-1); DataList->Move(i,i-1); Index = i-1; }else { UndoSave(VU_ORDERB, i, sw); DataList->Move(i,0); Index = 0; } } sw = false; if (data->Kind == V_TEXT) { rc.top = min(data->First.y, data->Second.y) - data->Font.lfHeight; rc.bottom = max(data->First.y, data->Second.y) + data->Font.lfHeight; rc.left = min(data->First.x, data->Second.x) - data->Font.lfHeight; rc.right = max(data->First.x, data->Second.x) + data->Font.lfHeight; }else { rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; } MainImageForm->iMainImage->RectPaint(rc); } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DeleteVectorObject(bool bUndo) { RECT rc = Rect(0, 0, MainImageForm->iMainImage->uBitmap->Width, MainImageForm->iMainImage->uBitmap->Height); bool sw = true; if (!bSelected) return; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (bUndo) UndoSave(VU_DELETE, i, sw); sw = false; if (data->Bitmap) { delete data->Bitmap; data->Bitmap = NULL;} DataList->Delete(i); delete data; data = NULL; i--; } nSelPos = 0; bSelected = false; MainImageForm->iMainImage->Cursor = crDefault; MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::DeleteEmptyObject() { TVecData *tdata; for (int i = 0; i < DataList->Count; i++) { tdata = (TVecData *)DataList->Items[i]; if (!tdata->Equal(MainImageForm->Number)) continue; if (tdata->nCount) continue; DataList->Delete(i); tdata = NULL; i--; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::CopyVectorObject() { RECT rc = Rect(0, 0, MainImageForm->iMainImage->uBitmap->Width, MainImageForm->iMainImage->uBitmap->Height); int x = 50000, y = 50000, count = DataList->Count; bool sw = true; if (!bSelected) return; for (int i = 0; i < count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; x = min(int(min(data->First.x, data->Second.x)), x); y = min(int(min(data->First.y, data->Second.y)), y); } for (int i = 0; i < count; i++) { TVecData *temp=NULL; data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; temp = new TVecData(MainImageForm->Number); temp->Copy(data); temp->GroupIndex = 0; // GroupIndex´Â copy¾ÈµÇ°Ô.. //======== ÇöÀç´Â ¸Ç À§ÂÊ¿¡ »ý¼ºµÇµµ·Ï... temp->First.x -= x; temp->First.y -= y; temp->Second.x -= x; temp->Second.y -= y; if (data->Kind == V_LINE || data->Kind == V_CURVE) for (int j = 0; j < data->nCount*3+1; j++) { temp->pList[j].x -= x; temp->pList[j].y -= y; } //======== if (data->bPatternFill) { temp->Bitmap = new Graphics::TBitmap; temp->Bitmap->PixelFormat = pf24bit; temp->Bitmap->Width = data->Bitmap->Width; temp->Bitmap->Height = data->Bitmap->Height; BitBlt(temp->Bitmap->Canvas->Handle,0,0,temp->Bitmap->Width,temp->Bitmap->Height, data->Bitmap->Canvas->Handle,0,0,SRCCOPY); } DataList->Add(temp); UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeObjectThick(int Thick, bool multi) { RECT rc = Rect(50000, 50000, 0, 0); bool sw = true; if (multi) { // ¿©·¯°³ µ¿½Ã¿¡ for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->PenThick += Thick; if (data->PenThick == 0) data->PenThick = 1; rc.top = min(rc.top, data->First.y - data->PenThick); rc.bottom = max(rc.bottom, data->Second.y + data->PenThick); rc.left = min(rc.left, data->First.x - data->PenThick); rc.right = max(rc.right, data->Second.x + data->PenThick); } }else { // Çϳª¸¸¹Ù²Ù±â data = (TVecData *)DataList->Items[Index]; UndoSave(VU_MODIFY, Index); data->PenThick = Thick; rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; } MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeObjectPenStyle(int Style) { RECT rc = Rect(50000, 50000, 0, 0); bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->PenStyle = EPenStyle(Style); rc.top = min(rc.top, data->First.y - data->PenThick); rc.bottom = max(rc.bottom, data->Second.y + data->PenThick); rc.left = min(rc.left, data->First.x - data->PenThick); rc.right = max(rc.right, data->Second.x + data->PenThick); } MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ObjectPatternFill(int Width, int Height, HDC dcSrc) { RECT rc; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; data->Bitmap = new Graphics::TBitmap; data->Bitmap->PixelFormat = pf24bit; // data->Bitmap->IgnorePalette = true; data->Bitmap->Width = Width; data->Bitmap->Height = Height; data->bPatternFill = true; data->bFill = true; data->bWinding = true; if (data->Bitmap->Empty) goto next; BitBlt(data->Bitmap->Canvas->Handle,0,0,Width,Height,dcSrc,0,0,SRCCOPY); rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; MainImageForm->iMainImage->RectPaint(rc); next: } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitProportion() { sx = 0; sy = 0; ex = 0; ey = 0; thick = 0; // sxy: x,yÀÇ ÃÖ¼ÒÁ¡ exy: ÃÖ´ëÁ¡ for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_TEXT) { if (sx == 0) sx = data->First.x; else sx = min(sx, double(data->First.x)); if (sy == 0) sy = data->First.y; else sy = min(sy, double(data->First.y)); ex = max(ex, double(data->Second.x)); ey = max(ey, double(data->Second.y)); thick = max(thick, data->PenThick); }else { double FirstX, FirstY, SecondX, SecondY; double angle = 2*M_PI*data->Font.lfEscapement/10/360; int height = data->Font.lfHeight; if (angle M_PI && angleFirst.x - height*sin(angle); SecondX = data->Second.x + height*sin(angle); FirstY = data->First.y; SecondY = data->Second.y; }else { // 2, 4»çºÐ¸é¿¡¼­ FirstY = data->First.y - height*cos(angle); SecondY = data->Second.y + height*cos(angle); FirstX = data->First.x; SecondX = data->Second.x; } if (sx == 0) sx = min(FirstX, SecondX); else sx = min(sx, min(FirstX, SecondX)); if (sy == 0) sy = min(FirstY, SecondY); else sy = min(sy, min(FirstY, SecondY)); ex = max(ex, max(FirstX, SecondX)); ey = max(ey, max(FirstY, SecondY)); } } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ProportionTransform() { Temp1 = data->First; Temp2 = data->Second; switch (data->Kind) { case V_CURVE: case V_LINE: for (int i = 0; i < data->nCount*3 +1; i++) { Temp[i].x = data->pList[i].x; Temp[i].y = data->pList[i].y; data->pList[i].x = (data->pList[i].x - sx)*ratiox + sx; data->pList[i].y = (data->pList[i].y - sy)*ratioy + sy; } case V_RECT: case V_ELLIPSE: data->First.x = (data->First.x - sx)*ratiox + sx; data->First.y = (data->First.y - sy)*ratioy + sy; data->Second.x = (data->Second.x - sx)*ratiox + sx; data->Second.y = (data->Second.y - sy)*ratioy + sy; break; case V_TEXT: data->First.x = (data->First.x - sx)*min(fabs(ratiox),fabs(ratioy)) + sx; data->First.y = (data->First.y - sy)*min(fabs(ratiox),fabs(ratioy)) + sy; data->Second.x = (data->Second.x - sx)*min(fabs(ratiox),fabs(ratioy)) + sx; data->Second.y = (data->Second.y - sy)*min(fabs(ratiox),fabs(ratioy)) + sy; fontsize = data->Font.lfHeight; // Àӽà ÀúÀå data->Font.lfHeight *= min(fabs(ratiox),fabs(ratioy)); if (data->Font.lfHeight < 1) data->Font.lfHeight = 1; break; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ProportionInverseTransform() { data->First = Temp1; data->Second = Temp2; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { data->pList[i].x = Temp[i].x; data->pList[i].y = Temp[i].y; } } if (data->Kind == V_TEXT) { data->Font.lfHeight = fontsize; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ObjectProportion(int x, int y) { RECT rc; double ratiox = x / 100.0, ratioy = y / 100.0; int x1,x2,y1,y2; bool sw = true; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; switch (data->Kind) { case V_LINE: case V_CURVE: for (int i = 0; i < data->nCount*3 +1; i++) { data->pList[i].x = (data->pList[i].x - sx)*ratiox + sx; data->pList[i].y = (data->pList[i].y - sy)*ratioy + sy; } SET_RECT; break; case V_RECT: case V_ELLIPSE: data->First.x = (data->First.x - sx)*ratiox + sx; data->First.y = (data->First.y - sy)*ratioy + sy; data->Second.x = (data->Second.x - sx)*ratiox + sx; data->Second.y = (data->Second.y - sy)*ratioy + sy; x1 = min(data->First.x, data->Second.x); x2 = max(data->First.x, data->Second.x); y1 = min(data->First.y, data->Second.y); y2 = max(data->First.y, data->Second.y); data->First.x = x1; data->First.y = y1; data->Second.x = x2; data->Second.y = y2; break; case V_TEXT: // Text´Â ÀÛÀº ºñÀ²·Î¸¸ È®´ë Ãà¼Ò°¡ µÈ´Ù (ÇöÀç·Î¼­ °¡·Î, ¼¼·Î ´Ù¸¥ºñÀ² º¯È­´Â ºÒ°¡´É) data->First.x = (data->First.x - sx)*min(fabs(ratiox),fabs(ratioy)) + sx; data->First.y = (data->First.y - sy)*min(fabs(ratiox),fabs(ratioy)) + sy; data->Second.x = (data->Second.x - sx)*min(fabs(ratiox),fabs(ratioy)) + sx; data->Second.y = (data->Second.y - sy)*min(fabs(ratiox),fabs(ratioy)) + sy; data->Font.lfHeight *= min(fabs(ratiox),fabs(ratioy)); if (data->Font.lfHeight < 1) data->Font.lfHeight = 1; break; } if (data->bPatternFill) { // ÆÐÅÏÀÇ È®´ë Ãà¼Ò Graphics::TBitmap *temp = NULL; temp = new Graphics::TBitmap; temp->PixelFormat = pf24bit; temp->Width = data->Bitmap->Width * fabs(ratiox); temp->Height = data->Bitmap->Height * fabs(ratioy); StretchBlt(temp->Canvas->Handle,0,0,temp->Width,temp->Height, data->Bitmap->Canvas->Handle,0,0,data->Bitmap->Width,data->Bitmap->Height,SRCCOPY); data->Bitmap->Width = temp->Width; data->Bitmap->Height = temp->Height; BitBlt(data->Bitmap->Canvas->Handle,0,0,temp->Width,temp->Height,temp->Canvas->Handle,0,0,SRCCOPY); delete temp; temp = NULL; } } bProportion = false; // ÀÌÁ¦ È®´ëÃà¼Ò¸ðµå´Â ³¡~ rc.top = sy - thick; rc.bottom = sy + (ey-sy)*max(1.0, ratioy) + thick; rc.left = sx - thick; rc.right = sx + (ex-sx)*max(1.0, ratiox) + thick; MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- int __fastcall TVecDraw::RotationMouseMove(int X, int Y) { RECT rc; double dx = X - (sx+ex)/2, dy = (sy+ey)/2 -Y; RotationAngle = ArcTan2(dy, dx); double maxl = sqrt(((ex-sx)/2)*((ex-sx)/2) + ((ey-sy)/2)*((ey-sy)/2)); rc.top = (sy+ey)/2 - maxl - thick; rc.bottom = (sy+ey)/2 + maxl + thick; rc.left = (sx+ex)/2 - maxl - thick; rc.right = (sx+ex)/2 + maxl + thick; MainImageForm->iMainImage->RectPaint(rc); return int(RotationAngle > 0 ? RotationAngle*180/M_PI : 360+RotationAngle*180/M_PI); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ObjectRotation(bool box, double angle) { RECT rc; bool sw = true; double cx = (sx+ex)/2, cy = (sy+ey)/2; // rotation objectµéÀÇ centerÁ¡µé double maxl = sqrt(((ex-sx)/2)*((ex-sx)/2) + ((ey-sy)/2)*((ey-sy)/2)); bRotation = false; if (box) RotationAngle = angle / 180 * M_PI; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; for (int i = 0; i < data->nCount*3 +1; i++) { double tx = data->pList[i].x - cx; double ty = cy - data->pList[i].y; data->pList[i].x = tx*cos(-RotationAngle) + ty*sin(-RotationAngle) + cx; data->pList[i].y = cy - (-tx*sin(-RotationAngle) + ty*cos(-RotationAngle)); } SET_RECT; } rc.top = (sy+ey)/2 - maxl - thick; rc.bottom = (sy+ey)/2 + maxl + thick; rc.left = (sx+ex)/2 - maxl - thick; rc.right = (sx+ex)/2 + maxl + thick; MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeTextFont(TFont* font) { int height, widthsum; double angle; AnsiString Text; HFONT font2, oldfont; char *tempstr = ""; HDC hdc = MainImageForm->iMainImage->Canvas->Handle; SIZE sz; data = (TVecData *)DataList->Items[Index]; UndoSave(VU_MODIFY, Index); strcpy(data->Font.lfFaceName, font->Name.c_str()); data->Font.lfHeight = font->Size; data->Font.lfItalic = font->Style.Contains(fsItalic); data->Font.lfUnderline = font->Style.Contains(fsUnderline); if (font->Style.Contains(fsBold)) data->Font.lfWeight = FW_BOLD; else data->Font.lfWeight = FW_NORMAL; data->Font.lfStrikeOut = font->Style.Contains(fsStrikeOut); Text = data->TextString; for (int k = 0; k < data->nCount; k++) tempstr[k] = char(data->TextString[k+1]); font2 = CreateFontIndirect(&data->Font); oldfont = SelectObject(hdc, font2); SelectObject(hdc, font2); GetTextExtentPoint32(hdc, tempstr, Text.Length(), &sz); widthsum = sz.cx; SelectObject(hdc, oldfont); DeleteObject(font2); font = NULL; height = data->Font.lfHeight; angle = 2*M_PI*data->Font.lfEscapement/10/360; data->Second.x = data->First.x + widthsum*cos(angle) - height*sin(angle); data->Second.y = data->First.y - widthsum*sin(angle) - height*cos(angle); MainImageForm->iMainImage->Repaint(); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ChangeTextData(AnsiString Text, int textangle) { // RECT rc; int height, widthsum; double angle; AnsiString text; HFONT font, oldfont; char *tempstr = ""; HDC hdc = MainImageForm->iMainImage->Canvas->Handle; SIZE sz; data = (TVecData *)DataList->Items[Index]; UndoSave(VU_MODIFY, Index); data->nCount = Text.Length(); data->Font.lfEscapement = textangle * 10; data->TextString = Text; text = data->TextString; MainImageForm->iMainImage->Canvas->Font->Size = data->Font.lfHeight; for (int k = 0; k < data->nCount; k++) tempstr[k] = char(data->TextString[k+1]); font = CreateFontIndirect(&data->Font); oldfont = SelectObject(hdc, font); SelectObject(hdc, font); GetTextExtentPoint32(hdc, tempstr, Text.Length(), &sz); widthsum = sz.cx; SelectObject(hdc, oldfont); DeleteObject(font); font = NULL; height = data->Font.lfHeight; angle = 2*M_PI*data->Font.lfEscapement/10/360; data->Second.x = data->First.x + widthsum*cos(angle) - height*sin(angle); data->Second.y = data->First.y - widthsum*sin(angle) - height*cos(angle); // rc.top = min(data->First.y, data->Second.y) - data->Font.lfHeight; // rc.bottom = max(data->First.y, data->Second.y) + data->Font.lfHeight; // rc.left = min(data->First.x, data->Second.x) - data->Font.lfHeight; // rc.right = max(data->First.x, data->Second.x) + data->Font.lfHeight; // MainImageForm->iMainImage->RectPaint(rc); MainImageForm->iMainImage->Repaint(); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ArrowObjectMove(int Key, bool bPoint) { bool sw = true; RECT rc; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; if (data->Kind == V_TEXT) { switch (Key) { case 37: data->First.x--; data->Second.x--; break; case 38: data->First.y--; data->Second.y--; break; case 39: data->First.x++; data->Second.x++; break; case 40: data->First.y++; data->Second.y++; break; } }else { switch (Key) { case 37: // left for (int j = 0; j < data->nCount*3 +1; j++) { if (!bPoint) data->pList[j].x--; // Object EditÀÎ °æ¿ì else if ((data->pMask[j/8] >> j%8) & 0x01) data->pList[j].x--; // Point Edit ÀÎ °æ¿ì } break; case 38: // up for (int j = 0; j < data->nCount*3 +1; j++) { if (!bPoint) data->pList[j].y--; else if ((data->pMask[j/8] >> j%8) & 0x01) data->pList[j].y--; } break; case 39: // right for (int j = 0; j < data->nCount*3 +1; j++) { if (!bPoint) data->pList[j].x++; else if ((data->pMask[j/8] >> j%8) & 0x01) data->pList[j].x++; } break; case 40: // down for (int j = 0; j < data->nCount*3 +1; j++) { if (!bPoint) data->pList[j].y++; else if ((data->pMask[j/8] >> j%8) & 0x01) data->pList[j].y++; } break; } SET_RECT; } rc.top = data->First.y - data->PenThick*2 -15; rc.bottom = data->Second.y + data->PenThick*2 +15; rc.left = data->First.x - data->PenThick*2 -15; rc.right = data->Second.x + data->PenThick*2 +15; MainImageForm->iMainImage->RectPaint(rc); } } //--------------------------------------------------------------------------- int __fastcall TVecDraw::SelectedObjectCount() { int count = 0, index; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->bSelected){ count++; index = i; } } if (count) bSelected = true; else bSelected = false; if (count == 1) Index = index; // 1°³ÀÇ °æ¿ìÀÇ index¸¦ º¸³»Áà~ return count; } //--------------------------------------------------------------------------- TRect __fastcall TVecDraw::GetObjectRect() { long minx = 59999, miny = 59999, maxx = 0, maxy = 0; int maxthick = 0; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; minx = min(minx, data->First.x); minx = min(minx, data->Second.x); maxx = max(maxx, data->First.x); maxx = max(maxx, data->Second.x); miny = min(miny, data->First.y); miny = min(miny, data->Second.y); maxy = max(maxy, data->First.y); maxy = max(maxy, data->Second.y); maxthick = max(maxthick, data->PenThick); } return Rect(minx-maxthick, miny-maxthick, maxx+maxthick, maxy+maxthick); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::GetSingleObjectData(int &PenThick, int &PenStyle, EVecKind &kind, AnsiString &text) { text = ""; data = (TVecData *)DataList->Items[Index]; kind = data->Kind; if (kind != V_TEXT) { PenThick = data->PenThick; PenStyle = data->PenStyle; }else { // TextÀÇ °æ¿ì¿¡´Â Penthick´ë½Å¿¡ °¢µµ¸¦ ¹ÝȯÇÑ´Ù PenThick = data->Font.lfEscapement/10; text = data->TextString; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::SelectAll() { for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; data->bSelected = true; } bSelected = true; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::deSelect() { for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; data->bSelected = false; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::PointBack(int &Lsx, int &Lsy) { RECT rc1; if (bExtend) data = (TVecData *)DataList->Items[Index]; if (step == 2) { // °î¼± ±â¿ï±â ±×¸®°í ÀÖ´Â µµÁß step = 1; rc1.top = 0; rc1.left = 0; }else if (step == 1 && bFstLine) { rc1.top = data->First.y - data->PenThick -5; rc1.left = data->First.x - data->PenThick -5; goto next; }else { if (data->nCount == 0) return; rc1.top = data->First.y - data->PenThick -5; rc1.left = data->First.x - data->PenThick -5; data->nCount--; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); Lsx = data->pList[data->nCount*3].x; Lsy = data->pList[data->nCount*3].y; } if (data) { if (data->nCount >0) { // ±â¿ï±â À̾îÁø ¼±À» À§ÇØ pTan.x = data->pList[data->nCount*3].x*2 - data->pList[data->nCount*3-1].x; pTan.y = data->pList[data->nCount*3].y*2 - data->pList[data->nCount*3-1].y; } SET_RECT; } next: rc1.bottom = MainImageForm->iMainImage->uBitmap->Height; rc1.right = MainImageForm->iMainImage->uBitmap->Width; MainImageForm->iMainImage->RectPaint(rc1); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Group Handling //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TVecDraw::MakeGroup(int number) { // GroupÀ» Number·Î ±¸ºÐÇÏ¿© Á÷Á¢ ¼±Åà (Popupmenu¾È¿¡ ÀÖÀ½) for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->GroupIndex & (1<GroupIndex -= 1<bSelected) continue; if (!(data->GroupIndex & (1<GroupIndex += 1<Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->GroupIndex) continue; index |= data->GroupIndex; } for (int i = 10; i < 32; i++) { if (index & (1 << i)) continue; index = i; break; } //== Group Index´Â 1~9±îÁö´Â ¹øÈ£ÁöÁ¤ ±×·ì, ±× ÀÌ»óÀº ¹ÌÁöÁ¤ ±×·ìÀ¸·Î ÇÑ´Ù. for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->GroupIndex & (1<GroupIndex -= 1<bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->GroupIndex &= 0x000001ff; if (!(data->GroupIndex & (1<GroupIndex += 1<Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->GroupIndex &= 0x000001ff; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ModifyGroup(TVecData *data, bool select) { TVecData *temp; for (int i = 0; i < DataList->Count; i++) { temp = (TVecData *)DataList->Items[i]; if (!temp->Equal(MainImageForm->Number)) continue; if (!temp->GroupIndex) continue; if ((temp->GroupIndex & 0xfffffe00) == (data->GroupIndex & 0xfffffe00)) temp->bSelected = select; } } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::GroupUpdate() { int index = 0; if (!bSelected) return false; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (!(data->GroupIndex & 0xfffffe00)) return false; if (index && (~index & (data->GroupIndex & 0xfffffe00))) return false; index |= (data->GroupIndex & 0xfffffe00); } return true; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::CheckFirstLine() { if (data->Color != PenManagerForm->PenShape->Pen->Color || data->bRound == PenManagerForm->Pen->Shape || data->PenThick != PenManagerForm->Pen->Thick || (data->Kind != V_LINE && data->Kind !=V_CURVE)) bFstLine = true; if (!data->Equal(MainImageForm->Number)) bFstLine = true; return bFstLine; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::SelectGroup(int number) { for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; data->bSelected = false; if (data->GroupIndex & (1<bSelected = true; bSelected = true; } } MainImageForm->iMainImage->Repaint(); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ObjectLock(bool unlock) { bool sw = true; if (!unlock) { // lockÀ» °Å´Â °æ¿ì for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->bLocked = true; data->bSelected = false; } bSelected = false; bLocked = true; }else { // lock À» ÇØÁ¦ÇÏ´Â °æ¿ì for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bLocked) continue; UndoSave(VU_MODIFY, i, sw); sw = false; data->bLocked = false; } bLocked = false; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //------- Merge Function Part ----------------------------------------- //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitMerge(HANDLE fh, int width, bool mirror, bool bLib) { if (bMergeMode) DeleteVectorObject(false); deSelect(); bMergeMode = true; bSelected = true; LoadFromFile(fh); PasteRange = Rect(50000, 50000, 0, 0); MaxThick = 0; if (bLib) { // Style Lib ¿¡¼­´Â º¤ÅÍ ¿ÀºêÁ§Æ®¸¸ÀÇ ¹üÀ§¸¦ ¼³Á¤ÇØ ÁÖ¾î¾ß ÇÑ´Ù for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; MaxThick = max(MaxThick, data->PenThick); PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)); } for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; data->First.x -= PasteRange.left; data->Second.x -= PasteRange.left; data->First.y -= PasteRange.top; data->Second.y -= PasteRange.top; if (data->Kind == V_LINE || data->Kind == V_CURVE) for (int j = 0; j < data->nCount*3+1; j++) { data->pList[j].x -= PasteRange.left; data->pList[j].y -= PasteRange.top; } } width = PasteRange.right - PasteRange.left; } if (mirror) { for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; int tempx = data->First.x; data->First.x = width - data->Second.x; data->Second.x = width - tempx; if (data->Kind == V_CURVE || data->Kind == V_LINE) for (int i = 0; i < data->nCount*3 +1; i++) data->pList[i].x = width - data->pList[i].x; } } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::ExitMerge() { if (!bMergeMode) return; DeleteVectorObject(false); deSelect(); bMergeMode = false; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::SetMergePosition(int X, int Y, RECT range, bool paint) { // paint°¡ falseÀÌ¸é ³¡ÀÌ´Ù if (!bMergeMode) return; int width = range.right - range.left, height = range.bottom - range.top; MergeX = X - width/2; MergeY = Y - height/2; if (MergeX < 0) MergeX = 0; if (MergeY < 0) MergeY = 0; if (MergeX > MainImageForm->iMainImage->uBitmap->Width - width) MergeX = MainImageForm->iMainImage->uBitmap->Width - width; if (MergeY > MainImageForm->iMainImage->uBitmap->Height - height) MergeY = MainImageForm->iMainImage->uBitmap->Height - height; if (!paint) { // Merge Mode ³¡³»±â for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; data->First.x += MergeX; data->First.y += MergeY; data->Second.x += MergeX; data->Second.y += MergeY; if (data->Kind == V_CURVE || data->Kind == V_LINE) { for (int i = 0; i < data->nCount*3 +1; i++) { data->pList[i].x += MergeX; data->pList[i].y += MergeY; } } } bMergeMode = false; MergeX = 0; MergeY = 0; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitCopy(bool isCut) { TVecData *cdata = NULL; int CopyCount = 0; int Allocatesize = 0; Byte *lpData; PasteRange = Rect(50000, 50000, 0, 0); MaxThick = 0; HGLOBAL hMem = NULL; TPException ec = EC_NONE; // UINT VectorFormat = RegisterClipboardFormat("Vector"); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; CopyCount++; PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)-data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)+data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)-data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)+data->PenThick*2); switch (data->Kind) { case V_LINE: case V_CURVE: Allocatesize += (sizeof(EPenStyle) + 3*sizeof(int) + 5*sizeof(bool) + 2*sizeof(TColor) + sizeof(DPOINT)*(data->nCount*3+1)); break; case V_TEXT: Allocatesize += (sizeof(LOGFONT) + sizeof(int) + sizeof(TColor) + sizeof(char)*data->nCount); break; } } if (CopyCount == 0) return; Allocatesize += (CopyCount*(sizeof(int) + sizeof(EVecKind) + sizeof(EDataCode) + 2*sizeof(POINT))); hMem = GlobalAlloc(GHND, Allocatesize); lpData = (Byte *)GlobalLock(hMem); memcpy(lpData, &CopyCount, sizeof(int)); lpData += sizeof(int); memcpy(lpData, &DataCode, sizeof(EDataCode)); lpData += sizeof(EDataCode); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; cdata = new TVecData(MainImageForm->Number); cdata->Copy(data); cdata->First.x -= PasteRange.left; cdata->Second.x -= PasteRange.left; cdata->First.y -= PasteRange.top; cdata->Second.y -= PasteRange.top; cdata->GroupIndex = 0; // GroupIndex´Â copy¾ÈµÇ°Ô.. if (cdata->Kind == V_LINE || cdata->Kind == V_CURVE) { for (int j = 0; j < cdata->nCount*3+1; j++) { cdata->pList[j].x -= PasteRange.left; cdata->pList[j].y -= PasteRange.top; } } memcpy(lpData, &cdata->Kind, sizeof(EVecKind)); lpData += sizeof(EVecKind); memcpy(lpData, &cdata->First, sizeof(POINT)); lpData += sizeof(POINT); memcpy(lpData, &cdata->Second, sizeof(POINT)); lpData += sizeof(POINT); switch (cdata->Kind) { case V_LINE: case V_CURVE: *(EPenStyle *)lpData = cdata->PenStyle; lpData += sizeof(EPenStyle); *(int *)lpData = cdata->PenThick; lpData += sizeof(int); *(int *)lpData = cdata->nCount; lpData += sizeof(int); *(bool *)lpData = cdata->bRound; lpData += sizeof(bool); *(bool *)lpData = cdata->bFill; lpData += sizeof(bool); *(bool *)lpData = cdata->bWinding; lpData += sizeof(bool); *(TColor *)lpData = cdata->Color; lpData += sizeof(TColor); *(TColor *)lpData = cdata->Brush; lpData += sizeof(TColor); *(bool *)lpData = cdata->bClosed; lpData += sizeof(bool); *(int *)lpData = cdata->GroupIndex; lpData += sizeof(int); memcpy(lpData, cdata->pList, sizeof(DPOINT)*(cdata->nCount*3+1)); lpData += (sizeof(DPOINT)*(cdata->nCount*3+1)); *(bool *)lpData = cdata->bPatternFill; lpData += sizeof(bool); /* *(int *)lpData = cdata->LayerIndex; lpData += sizeof(int); *(int *)lpData = cdata->top; lpData += sizeof(int); *(int *)lpData = cdata->bottom; lpData += sizeof(int); memcpy(lpData, cdata->GridIndex, sizeof(int)*8); lpData += (sizeof(int)*8); *(int *)lpData = cdata->GridCount; lpData += sizeof(int); */ break; case V_TEXT: *(TColor *)lpData = cdata->Color; lpData += sizeof(TColor); *(LOGFONT *)lpData = cdata->Font; lpData += sizeof(LOGFONT); *(int *)lpData = cdata->nCount; lpData += sizeof(int); /* *(int *)lpData = cdata->top; lpData += sizeof(int); *(int *)lpData = cdata->bottom; lpData += sizeof(int); */ memcpy(lpData, cdata->TextString.c_str(), sizeof(char)*cdata->nCount); lpData += (sizeof(char)*cdata->nCount); break; } // delete cdata->pList; // cdata->pList = NULL; delete cdata; cdata = NULL; } GlobalUnlock(hMem); OpenClipboard(MainImageForm->Handle); EmptyClipboard(); SetClipboardData(CF_SYLK, hMem); // SetClipboardData(VectorFormat, hMem); CloseClipboard(); /* TVecData *cdata = NULL; int CopyCount = 0; PasteRange = Rect(50000, 50000, 0, 0); Byte *lpData; HGLOBAL hMem = NULL; TPException ec = EC_NONE; UINT VectorFormat = RegisterClipboardFormat("Vector"); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; CopyCount++; PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)-data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)+data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)-data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)+data->PenThick*2); } hMem = GlobalAlloc(GHND, sizeof(int)+sizeof(TVecData)*CopyCount); lpData = (Byte *)GlobalLock(hMem); memcpy(lpData, &CopyCount, sizeof(int)); lpData += sizeof(int); while (CopyList->Count) { cdata = (TVecData *)CopyList->First(); delete cdata; CopyList->Remove(cdata); } for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; cdata = new TVecData(MainImageForm->Number); cdata->Copy(data); cdata->First.x -= PasteRange.left; cdata->Second.x -= PasteRange.left; cdata->First.y -= PasteRange.top; cdata->Second.y -= PasteRange.top; cdata->GroupIndex = 0; // GroupIndex´Â copy¾ÈµÇ°Ô.. if (cdata->Kind == V_LINE || cdata->Kind == V_CURVE) { for (int j = 0; j < cdata->nCount*3+1; j++) { cdata->pList[j].x -= PasteRange.left; cdata->pList[j].y -= PasteRange.top; } } CopyList->Add(cdata); memcpy(lpData, cdata, sizeof(TVecData)); lpData += sizeof(TVecData); } GlobalUnlock(hMem); OpenClipboard(MainImageForm->Handle); EmptyClipboard(); SetClipboardData(VectorFormat, hMem); CloseClipboard(); */ if (isCut) DeleteVectorObject(); } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitPaste() { Byte *lpData; bool sw = true; HGLOBAL hMem = NULL; int CopyCount = 0; EDataCode Code; // UINT VectorFormat = RegisterClipboardFormat("Vector"); // if (IsClipboardFormatAvailable(VectorFormat)) { if (IsClipboardFormatAvailable(CF_SYLK)) { deSelect(); bMergeMode = true; bSelected = true; OpenClipboard(MainImageForm->Handle); hMem = GetClipboardData(CF_SYLK); //hMem = GetClipboardData(VectorFormat); lpData = (Byte *)GlobalLock(hMem); CopyCount = *(int *)lpData; lpData += sizeof(int); Code = *(EDataCode *)lpData; lpData += sizeof(EDataCode); for (int i = 0; i < CopyCount; i++) { data = new TVecData(MainImageForm->Number); data->Kind = *(EVecKind *)lpData; lpData += sizeof(EVecKind); data->First = *(POINT *)lpData; lpData += sizeof(POINT); data->Second = *(POINT *)lpData; lpData += sizeof(POINT); switch (data->Kind) { case V_LINE: case V_CURVE: data->PenStyle = *(EPenStyle *)lpData; lpData += sizeof(EPenStyle); data->PenThick = *(int *)lpData; lpData += sizeof(int); data->nCount = *(int *)lpData; lpData += sizeof(int); data->bRound = *(bool *)lpData; lpData += sizeof(bool); data->bFill = *(bool *)lpData; lpData += sizeof(bool); data->bWinding = *(bool *)lpData; lpData += sizeof(bool); data->Color = *(TColor *)lpData; lpData += sizeof(TColor); data->Brush = *(TColor *)lpData; lpData += sizeof(TColor); data->bClosed = *(bool *)lpData; lpData += sizeof(bool); data->GroupIndex = *(int *)lpData; lpData += sizeof(int); data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); memcpy(data->pList, lpData, sizeof(DPOINT)*(data->nCount*3+1)); lpData += (sizeof(DPOINT)*(data->nCount*3+1)); data->bPatternFill = *(bool *)lpData; lpData += sizeof(bool); /* data->LayerIndex = *(int *)lpData; lpData += sizeof(int); data->top = *(int *)lpData; lpData += sizeof(int); data->bottom = *(int *)lpData; lpData += sizeof(int); memcpy(data->GridIndex, lpData, sizeof(int)*8); lpData += (sizeof(int)*8); data->GridCount = *(int *)lpData; lpData += sizeof(int); */ break; case V_TEXT: data->Color = *(TColor *)lpData; lpData += sizeof(TColor); data->Font = *(LOGFONT *)lpData; lpData += sizeof(LOGFONT); data->nCount = *(int *)lpData; lpData += sizeof(int); /* data->top = *(int *)lpData; lpData += sizeof(int); data->bottom = *(int *)lpData; lpData += sizeof(int); */ char tempchar; for (int k = 0; k < data->nCount; k++) { tempchar = *(char *)lpData; data->TextString += tempchar; lpData += sizeof(char); } break; } data->bSelected = true; if (Code == T_TEX3D) { if (data->bClosed) data->bFill = true; } DataList->Add(data); UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } } GlobalUnlock(hMem); CloseClipboard(); PasteRange = Rect(50000, 50000, 0, 0); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)-data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)+data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)-data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)+data->PenThick*2); } /* TVecData *cdata = NULL; bool sw = true; deSelect(); bMergeMode = true; bSelected = true; for (int i = 0; i < CopyList->Count; i++) { cdata = (TVecData *)CopyList->Items[i]; data = new TVecData(MainImageForm->Number); data->Copy(cdata); data->bSelected = true; DataList->Add(data); UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } */ } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitReverse() { TVecData *cdata = NULL; PasteRange = Rect(50000, 50000, 0, 0); int nVCenter; // ¼öÁ÷ Áß½ÉÁÂÇ¥ bool sw = true; //========== ÀúÀåµÇ¾ú´ø copydataÁö¿ò while (CopyList->Count) { cdata = (TVecData *)CopyList->First(); delete cdata; CopyList->Remove(cdata); } //========== ¿Ü°¢ µÑ·¹ ±¸ÇÏ´Â ºÎºÐ for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind !=V_CURVE) continue; // Text´Â ¹ÝÀüº¹»ç ¸øÇØ¿ä... PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x) - data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x) + data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y) - data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y) + data->PenThick*2); } nVCenter = (PasteRange.left + PasteRange.right) /2; //========== ¹ÝÀüº¹»ç ÇÏ´Â ºÎºÐ for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind !=V_CURVE) continue; // Text´Â ¹ÝÀüº¹»ç ¸øÇØ¿ä... cdata = new TVecData(MainImageForm->Number); cdata->Copy(data); if (cdata->Kind == V_LINE || cdata->Kind == V_CURVE) for (int j = 0; j < cdata->nCount*3+1; j++) { cdata->pList[j].x = 2*nVCenter - cdata->pList[j].x - PasteRange.left; cdata->pList[j].y -= PasteRange.top; } int tempx = cdata->First.x; cdata->First.x = 2*nVCenter - cdata->Second.x - PasteRange.left; cdata->Second.x = 2*nVCenter - tempx - PasteRange.left; cdata->First.y -= PasteRange.top; cdata->Second.y -= PasteRange.top; cdata->GroupIndex = 0; // GroupIndex´Â copy¾ÈµÇ°Ô.. CopyList->Add(cdata); } //==========ºÙÀÌ´Â ºÎºÐ deSelect(); bMergeMode = true; bSelected = true; for (int i = 0; i < CopyList->Count; i++) { cdata = (TVecData *)CopyList->Items[i]; data = new TVecData(MainImageForm->Number); data->Copy(cdata); data->bSelected = true; DataList->Add(data); UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitJoin() { int count = 0, pcount = 0, tempcount; bool success, first1, first2, sw = true; // TVecData *data1 = NULL, *data2 = NULL; DPOINT temp1[1024], temp2[1024]; RECT rc; for (int i = 0; i < DataList->Count; i++) { // JoinÀÌ °¡´ÉÇÑÁö ÆÇ´Ü data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->bClosed) goto fail; if (++count > 2) goto fail; // 2°³ ÃʰúÀÇ object°¡ ¼±ÅÃµÈ °æ¿ì for (int j = 0; j < data->nCount*3+1; j+=3) { if ((data->pMask[j/8] >> j%8) & 0x01) { if (j != 0 && j != data->nCount*3) goto fail; // ³¡Á¡ÀÌ ¾Æ´Ñ°æ¿ì if (++pcount > 2) goto fail; // 2°³ ÃʰúÀÇ Á¡ÀÌ ¼±ÅÃµÈ °æ¿ì if (pcount == 1) first1 = j==0 ? true : false; // ù¹øÂ° Á¡ÀÌ³Ä ¸¶Á÷¸· Á¡ÀÌ³Ä if (pcount == 2) first2 = j==0 ? true : false; } } } if (!pcount || pcount == 1 || !count) goto fail; for (int i = 0; i < DataList->Count; i++) { // Join ¼öÇà data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (count == 1) { // ÇÑ ¿ÀºêÁ§Æ®ÀÇ ¾ç ³¡Á¡ÀÌ ¼±ÅÃµÈ °æ¿ì if ((data->pMask[0] & 0x01) && (data->pMask[data->nCount*3/8] >> data->nCount*3%8) & 0x01) { UndoSave(VU_MODIFY, i); data->bClosed = true; if (pEqual(data->pList[0].P(), data->pList[data->nCount*3].P())) { // Join Point°¡ °°Àº °æ¿ì (°ãÄ¡´Â Á¡Àΰæ¿ì) }else { // ¾Æ´Ñ°æ¿ì data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); data->pList[data->nCount*3-2] = data->pList[data->nCount*3-3]; data->pList[data->nCount*3-1] = data->pList[0]; data->pList[data->nCount*3] = data->pList[0]; } SET_RECT; rc.top = data->First.y - data->PenThick*2 -15; rc.bottom = data->Second.y + data->PenThick*2 +15; rc.left = data->First.x - data->PenThick*2 -15; rc.right = data->Second.x + data->PenThick*2 +15; goto success; }else goto fail; // ³¡Á¡µÎ°³°¡ ¾Æ´Ñ°æ¿ì }else if (count == 2) { if (sw) { // ù´Ü°è for (int j = 0; j < data->nCount*3 +1; j++) temp1[j] = data->pList[j]; tempcount = data->nCount; sw = false; UndoSave(VU_DELETE, i, true); if (data->Bitmap) { delete data->Bitmap; data->Bitmap = NULL;} DataList->Delete(i--); delete data; data = NULL; }else { // µÎ¹øÂ° bool equal = false; for (int j = 0; j < data->nCount*3 +1; j++) temp2[j] = data->pList[j]; UndoSave(VU_MODIFY, i, false); data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*((data->nCount+tempcount+1)*3+1)); HeapCompact(GetProcessHeap(), 0); if (first1) { if (first2) { // µÑ´Ù ùÁ¡ÀÎ °æ¿ì for (int j = 0; j < tempcount*3+1; j++) { data->pList[j] = temp1[tempcount*3-j]; } equal = pEqual(temp1[0].P(),temp2[0].P()); if (equal) { data->pList[tempcount*3+1] = temp2[1]; data->pList[tempcount*3+2] = temp2[2]; }else { data->pList[tempcount*3+1] = temp1[0]; data->pList[tempcount*3+2] = temp2[0]; } for (int j = 0; j < data->nCount*3+1; j++) { // µÎ Á¢ÇÕÁ¡ÀÌ °°À¸¸é Á¡Àº Çϳª »ý·« data->pList[j+(tempcount+1)*3] = temp2[j + 3*equal]; } }else { for (int j = 0; j < tempcount*3+1; j++) { data->pList[j] = temp1[tempcount*3-j]; } equal = pEqual(temp1[0].P(),temp2[data->nCount*3].P()); if (equal) { data->pList[tempcount*3+1] = temp2[data->nCount*3-1]; data->pList[tempcount*3+2] = temp2[data->nCount*3-2]; }else { data->pList[tempcount*3+1] = temp1[0]; data->pList[tempcount*3+2] = temp2[data->nCount*3]; } for (int j = 0; j < data->nCount*3+1; j++) { data->pList[j+(tempcount+1)*3] = temp2[data->nCount*3 -j - 3*equal]; } } }else { if (first2) { for (int j = 0; j < tempcount*3+1; j++) { data->pList[j] = temp1[j]; } equal = pEqual(temp1[tempcount*3].P(),temp2[0].P()); if (equal) { data->pList[tempcount*3+1] = temp2[1]; data->pList[tempcount*3+2] = temp2[2]; }else { data->pList[tempcount*3+1] = temp1[tempcount*3]; data->pList[tempcount*3+2] = temp2[0]; } for (int j = 0; j < data->nCount*3+1; j++) { data->pList[j+(tempcount+1)*3] = temp2[j+ 3*equal]; } }else { // µÑ´Ù ³¡Á¡ for (int j = 0; j < tempcount*3+1; j++) { data->pList[j] = temp1[j]; } equal = pEqual(temp1[tempcount*3].P(),temp2[data->nCount*3].P()); if (equal) { data->pList[tempcount*3+1] = temp2[data->nCount*3-1]; data->pList[tempcount*3+2] = temp2[data->nCount*3-2]; }else { data->pList[tempcount*3+1] = temp1[tempcount*3]; data->pList[tempcount*3+2] = temp2[data->nCount*3]; } for (int j = 0; j < data->nCount*3+1; j++) { data->pList[j+(tempcount+1)*3] = temp2[data->nCount*3 -j - 3*equal]; } } } data->nCount += (tempcount+1-equal); SET_RECT; rc.top = data->First.y - data->PenThick*2 -15; rc.bottom = data->Second.y + data->PenThick*2 +15; rc.left = data->First.x - data->PenThick*2 -15; rc.right = data->Second.x + data->PenThick*2 +15; } } } success: MainImageForm->iMainImage->RectPaint(rc); return; fail: ShowMessage("Choose a couple of edge points"); return; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::InitAverage(bool bVert, bool bHorz) { int vert = 0, horz = 0, number = 0; RECT rc1, rc2, rc3; bool sw = true; if (!bSelected) goto fail; //======= ¼±ÅÃµÈ ¿ÀºêÁ§Æ®ÀÇ ¼±ÅÃµÈ Á¡µéÀÇ Æò±Õ ³»±â for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; for (int j = 0; j < data->nCount*3+1; j+=3) { if ((data->pMask[j/8] >> j%8) & 0x01) { if (data->bClosed && j == data->nCount*3) continue; // closed path´Â ÁßøÁ¡ °è»ê¿¡ ¾È³ÖÀ½ horz += data->pList[j].x; vert += data->pList[j].y; number++; } } } if (number < 2) goto fail; horz /= number; vert /= number; //======== ´Ù½Ã ã¾Æ¼­ Æò±ÕÀ» ´ëÀÔ for (int i = 0; i < DataList->Count; i++) { bool paint = false; data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; UndoSave(VU_MODIFY, i, sw); sw = false; for (int j = 0; j < data->nCount*3+1; j+=3) { if ((data->pMask[j/8] >> j%8) & 0x01) { if (bHorz) { if (j != 0) data->pList[j-1].x += horz - data->pList[j].x; if (j != data->nCount*3) data->pList[j+1].x += horz - data->pList[j].x; data->pList[j].x = horz; } if (bVert) { if (j != 0) data->pList[j-1].y += vert - data->pList[j].y; if (j != data->nCount*3) data->pList[j+1].y += vert - data->pList[j].y; data->pList[j].y = vert; } paint = true; } } if (!paint) continue; rc1.top = data->First.y - data->PenThick*2 -10; rc1.bottom = data->Second.y + data->PenThick*2 +10; rc1.left = data->First.x - data->PenThick*2 -10; rc1.right = data->Second.x + data->PenThick*2 +10; SET_RECT; rc2.top = data->First.y - data->PenThick*2 -10; rc2.bottom = data->Second.y + data->PenThick*2 +10; rc2.left = data->First.x - data->PenThick*2 -10; rc2.right = data->Second.x + data->PenThick*2 +10; UnionRect(&rc3, &rc1, &rc2); // µÎ rect¸¦ Æ÷ÇÔÇÏ´Â °¡Àå ÀÛÀº rect rc3 MainImageForm->iMainImage->RectPaint(rc3); } success: return; fail: ShowMessage("You must select above two points"); return; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //------- Point Editing Part ----------------------------------------- //--------------------------------------------------------------------------- void __fastcall TVecDraw::DeletePoint() { RECT rc; if ((ptNumber%3)!= 0) return; // Á¶ÀýÁ¡ÀÌ ¾Æ´Ñ ½ÇÁ¦ Á¡À» Áö¿ì´Â°Í~! for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É if (data->nCount == 1) continue; // 1°³¸¸ ³²¾ÒÀ»¶§´Â Áö¿ìÁö ¸»ÀÚ UndoSave(VU_MODIFY, i); if (ptNumber == 0) { // ùÁ¡À» Áö¿ï°æ¿ì if (data->bClosed) { data->pList[data->nCount*3-1] = data->pList[2]; for (int i = 0; i < data->nCount*3 -2; i++) data->pList[i] = data->pList[i+3]; }else { for (int i = 0; i < data->nCount*3 -2; i++) data->pList[i] = data->pList[i+3]; // ÇÑÁ¡ÀÌ Áö¿öÁö¹Ç·Î Á¶ÀýÁ¡2°³¿Í Á¡1°³¸¦ ¶¯±ä´Ù } }else { // ³ª¸ÓÁö °æ¿ì for (int i = ptNumber-1; i < data->nCount*3 -2; i++) { data->pList[i] = data->pList[i+3]; // ÇÑÁ¡ÀÌ Áö¿öÁö¹Ç·Î Á¶ÀýÁ¡2°³¿Í Á¡1°³¸¦ ¶¯±ä´Ù } } data->nCount--; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; MainImageForm->iMainImage->RectPaint(rc); SET_RECT; } ptNumber = -1; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::AddPoint(int X, int Y) { RECT rc; HRGN rgn = NULL; HPEN hPen, hOldPen; HDC dcDst = MainImageForm->iMainImage->Canvas->Handle; bool bResult = false; int CurveNumber, seg1, seg2; // ÇÑ Object¾ÈÀÇ ¸î¹øÂ° curveÀÎÁö.. POINT ptemp[4], pdiv[11]; // pdiv : 10°³¾¿À¸·Î ³ª´©´Â Á¡µé double distance[11], tempdist, t; int nFillMode; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É if (!PointOnCurvePath(data, X, Y)) goto fail; // ¿ì¼± ÂïÀº Á¡ÀÌ curveÀ§¿¡ ÀÖ´ÂÁö.. UndoSave(VU_MODIFY, i); nFillMode = GetPolyFillMode(dcDst); SetPolyFillMode(dcDst, WINDING); hPen = CreatePen(PS_SOLID, data->PenThick>5 ? data->PenThick : 5, RGB(0,0,0)); hOldPen = SelectObject(dcDst, hPen); for (int j = 0; j < data->nCount; j++) { // ¸î¹ø¤Š curve¿¡ ¼ÓÇÑ Á¡ÀÎÁö¸¦ ã´Â °úÁ¤ ptemp[0] = data->pList[j*3].P(); ptemp[1] = data->pList[j*3+1].P(); ptemp[2] = data->pList[j*3+2].P(); ptemp[3] = data->pList[j*3+3].P(); BeginPath(dcDst); PolyBezier (dcDst, ptemp, 4); EndPath(dcDst); WidenPath(dcDst); rgn = PathToRegion(dcDst); if (PtInRegion(rgn, X, Y)) { bResult = true; CurveNumber = j; } DeleteObject(rgn); rgn = NULL; if (bResult) break; } SetPolyFillMode(dcDst, nFillMode); DeleteObject(SelectObject(dcDst, hOldPen)); hPen = NULL; hOldPen = NULL; if (!bResult) goto fail; for (int k = 0; k <= 10; k++) { t = double(k) / 10; pdiv[k].x = (1-t)*(1-t)*(1-t)*ptemp[0].x + 3*(1-t)*(1-t)*t*ptemp[1].x + 3*(1-t)*t*t*ptemp[2].x + t*t*t*ptemp[3].x; pdiv[k].y = (1-t)*(1-t)*(1-t)*ptemp[0].y + 3*(1-t)*(1-t)*t*ptemp[1].y + 3*(1-t)*t*t*ptemp[2].y + t*t*t*ptemp[3].y; distance[k] = sqrt((pdiv[k].x-X)*(pdiv[k].x-X) + (pdiv[k].y-Y)*(pdiv[k].y-Y)); if (k == 0) { tempdist = distance[k]; seg1 = k; } else { // °Å¸®°¡ ÃÖ¼ÒÀÎÁ¡À» ã´Â´Ù if (tempdist > distance[k]) { tempdist = distance[k]; seg1 = k; } } } if (seg1 != 0 && seg1 != 10) { // P------O--P---------P ÀÌ·¸°Ô ÀÖ´ÂÁö if (distance[seg1-1] < distance[seg1+1] ) { // P---------P---O-----P ÀÌ·¸°Ô ÀÖ´ÂÁö ÆÇ´Ü seg1--; // ÀüÀÚÀ̸é ÀÌÀü Á¡À» ¼±ÅÃÇØ ÁØ´Ù(Á¤È®ÇÑ t°ªÀ» ÆÇ´ÜÇϱâ À§ÇØ) } }else if (seg1 == 10) seg1--; for (int k = 0; k <= 10; k++) { t = (double(seg1) / 10) + (double(k) / 100); pdiv[k].x = (1-t)*(1-t)*(1-t)*ptemp[0].x + 3*(1-t)*(1-t)*t*ptemp[1].x + 3*(1-t)*t*t*ptemp[2].x + t*t*t*ptemp[3].x; pdiv[k].y = (1-t)*(1-t)*(1-t)*ptemp[0].y + 3*(1-t)*(1-t)*t*ptemp[1].y + 3*(1-t)*t*t*ptemp[2].y + t*t*t*ptemp[3].y; distance[k] = sqrt((pdiv[k].x-X)*(pdiv[k].x-X) + (pdiv[k].y-Y)*(pdiv[k].y-Y)); if (k == 0) { tempdist = distance[k]; seg2 = k; } else { // °Å¸®°¡ ÃÖ¼ÒÀÎÁ¡À» ã´Â´Ù if (tempdist > distance[k]) { tempdist = distance[k]; seg2 = k; } } } t = double(seg1)/10 + double(seg2)/100; // ÃÖÁ¾ÀûÀÎ °ª data->nCount++; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); for (int l = data->nCount*3 -3; l > CurveNumber*3+1; l--) { data->pList[l+3] = data->pList[l]; } if (ptemp[0].x == ptemp[1].x && ptemp[0].y == ptemp[1].y && ptemp[2].x == ptemp[3].x && ptemp[2].y == ptemp[3].y) { // ÀâÈù ¼±ÀÌ Á÷¼±ÀÎ °æ¿ì data->pList[CurveNumber*3+3].x = (1-t)*(1-t)*(1-t)*ptemp[0].x + 3*(1-t)*(1-t)*t*ptemp[1].x + 3*(1-t)*t*t*ptemp[2].x + t*t*t*ptemp[3].x; data->pList[CurveNumber*3+3].y = (1-t)*(1-t)*(1-t)*ptemp[0].y + 3*(1-t)*(1-t)*t*ptemp[1].y + 3*(1-t)*t*t*ptemp[2].y + t*t*t*ptemp[3].y; data->pList[CurveNumber*3+2].x = data->pList[CurveNumber*3+3].x; data->pList[CurveNumber*3+2].y = data->pList[CurveNumber*3+3].y; data->pList[CurveNumber*3+4].x = data->pList[CurveNumber*3+3].x; data->pList[CurveNumber*3+4].y = data->pList[CurveNumber*3+3].y; }else { // °î¼±ÀÎ °æ¿ì // »õ·Î »ý±â´Â Á¡ data->pList[CurveNumber*3+3].x = (1-t)*(1-t)*(1-t)*ptemp[0].x + 3*(1-t)*(1-t)*t*ptemp[1].x + 3*(1-t)*t*t*ptemp[2].x + t*t*t*ptemp[3].x; data->pList[CurveNumber*3+3].y = (1-t)*(1-t)*(1-t)*ptemp[0].y + 3*(1-t)*(1-t)*t*ptemp[1].y + 3*(1-t)*t*t*ptemp[2].y + t*t*t*ptemp[3].y; // »õ·Î »ý±â´Â Á¡ÀÇ Á¶ÀýÁ¡ 2°³ data->pList[CurveNumber*3+2].x = (1-t)*(1-t)*ptemp[0].x + 2*t*(1-t)*ptemp[1].x + t*t*ptemp[2].x; data->pList[CurveNumber*3+2].y = (1-t)*(1-t)*ptemp[0].y + 2*t*(1-t)*ptemp[1].y + t*t*ptemp[2].y; data->pList[CurveNumber*3+4].x = (1-t)*(1-t)*ptemp[1].x + 2*t*(1-t)*ptemp[2].x + t*t*ptemp[3].x; data->pList[CurveNumber*3+4].y = (1-t)*(1-t)*ptemp[1].y + 2*t*(1-t)*ptemp[2].y + t*t*ptemp[3].y; // ¾ç¿·ÀÇ Á¶ÀýÁ¡ÀÇ º¯È­ data->pList[CurveNumber*3+1].x = (1-t)*ptemp[0].x + t*ptemp[1].x; data->pList[CurveNumber*3+1].y = (1-t)*ptemp[0].y + t*ptemp[1].y; data->pList[CurveNumber*3+5].x = (1-t)*ptemp[2].x + t*ptemp[3].x; data->pList[CurveNumber*3+5].y = (1-t)*ptemp[2].y + t*ptemp[3].y; } memset(data->pMask, 0, 128);; // »õ·Î »ý±ä Á¡ÀÇ Á¶ÀýÁ¡À» º¸¿©ÁÖµµ·Ï (DrawSelectedLine¿¡¼­) data->pMask[(CurveNumber*3+3)/8] |= (0x01<<((CurveNumber*3+3)%8)); rc.top = data->First.y - data->PenThick; rc.bottom = data->Second.y + data->PenThick; rc.left = data->First.x - data->PenThick; rc.right = data->Second.x + data->PenThick; MainImageForm->iMainImage->RectPaint(rc); return; } fail: return; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::Knife(int X, int Y) { // RECT rc; if ((ptNumber%3)!= 0) return; // Á¶ÀýÁ¡ÀÌ ¾Æ´Ñ ½ÇÁ¦ Á¡À» Áö¿ì´Â°Í~! for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; if (data->Kind != V_LINE && data->Kind != V_CURVE) continue; // Line°ú curve¿¡¼­¸¸ Point Edit °¡´É if (data->bClosed) { DPOINT temp[1024]; UndoSave(VU_MODIFY, i); for (int i = 0; i < data->nCount*3 - ptNumber; i++) temp[i] = data->pList[ptNumber+i]; for (int i = data->nCount*3 - ptNumber; i < data->nCount*3+1; i++) temp[i] = data->pList[i-data->nCount*3+ptNumber]; for (int i = 0; i < data->nCount*3 +1; i++) data->pList[i] = temp[i]; data->bClosed = false; ptNumber = 0; memset(data->pMask, 0, 128);; // Point MaskÃʱâÈ­ data->pMask[0] |= 0x01;// ù¹øÂ° point¸¦ Ȱ¼ºÈ­½ÃÄÑÁÜ break; }else { if (ptNumber == 0 || ptNumber == data->nCount*3) { // open path¿¡¼­ ùÁ¡°ú ³¡Á¡Àº ¾ÈµÇ~ ShowMessage("Select neither First nor Last Point"); break; } TVecData *temp = NULL; temp = new TVecData(MainImageForm->Number); UndoSave(VU_MODIFY, i, true); temp->Copy(data); temp->GroupIndex &= 0xfffffe00; // ¹øÈ£ ÁöÁ¤ GroupIndex´Â copy¾ÈµÇ°Ô.. temp->nCount = data->nCount - ptNumber/3; for (int j = 0; j < temp->nCount*3+1; j++) { temp->pList[j] = temp->pList[j+ptNumber]; } temp->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, temp->pList, sizeof(DPOINT)*(temp->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); temp->First.x = 59999; temp->First.y = 59999; \ temp->Second.x = 0; temp->Second.y = 0; \ for (int i = 0; i < temp->nCount*3+1; i++) { \ if (temp->First.x > temp->pList[i].x) temp->First.x = temp->pList[i].x; \ if (temp->First.y > temp->pList[i].y) temp->First.y = temp->pList[i].y; \ if (temp->Second.x < temp->pList[i].x) temp->Second.x = temp->pList[i].x; \ if (temp->Second.y < temp->pList[i].y) temp->Second.y = temp->pList[i].y; \ } \ data->nCount = ptNumber/3; data->pList = (DPOINT *)HeapReAlloc(GetProcessHeap(), 0, data->pList, sizeof(DPOINT)*(data->nCount*3+1)); HeapCompact(GetProcessHeap(), 0); SET_RECT; DataList->Insert(i+1, temp); UndoSave(VU_CREATE, i+1, false); break; } } // MainImageForm->iMainImage->RectPaint(rc); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //------- File Handle Part -------------------------------------------- //--------------------------------------------------------------------------- bool __fastcall TVecDraw::LoadFromFile(HANDLE fh) { int Version, count; int existindex = 0, index = 0, existcount; // ±âÁ¸¿¡ Á¸ÀçÇÏ´Â indexÆÇº°, »ðÀÔÇÒ index number, ±âÁ¸ÀÇ objectÀÇ °¹¼ö DWORD dwRead; bool sw = true; if (!ReadFile(fh, &Version, sizeof(int), &dwRead, NULL)) goto fail; if (Version != 100 && Version != 110 && Version != 120 ) goto fail; if (!ReadFile(fh, &count, sizeof(int), &dwRead, NULL)) goto fail; existcount = DataList->Count; for (int i = 0; i < count; i++) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; if (!ReadFile(fh, &data->Kind, sizeof(EVecKind), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->First, sizeof(POINT), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Second, sizeof(POINT), &dwRead, NULL)) goto fail; switch (data->Kind) { case V_LINE: case V_CURVE: if (!ReadFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->PenThick, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->nCount, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bRound, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bFill, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bWinding, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Brush, sizeof(TColor), &dwRead, NULL)) goto fail; //===7.41, Version 110 Ãß°¡ if (Version >= 110) { if (!ReadFile(fh, &data->bClosed, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->GroupIndex, sizeof(int), &dwRead, NULL)) goto fail; } //========================= data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (Version <= 110) { // 7.41ÀÌÇÏ¿¡¼­´Â DPOINT¸¦ »ç¿ëÇÏÁö ¾Ê¾Ò´Ù POINT temp[1024]; if (!ReadFile(fh, temp, sizeof(POINT)*(data->nCount*3+1), &dwRead, NULL)) goto fail; for (int j = 0; j < data->nCount*3+1; j++) data->pList[j].DPoint(temp[j]); }else { if (!ReadFile(fh, data->pList, sizeof(DPOINT)*(data->nCount*3+1), &dwRead, NULL)) goto fail; } if (!ReadFile(fh, &data->bPatternFill, sizeof(bool), &dwRead, NULL)) goto fail; if (data->bPatternFill) LoadObjectBitmap(fh); break; case V_RECT: case V_ELLIPSE: if (!ReadFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->PenThick, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bRound, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bFill, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bWinding, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Brush, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bPatternFill, sizeof(bool), &dwRead, NULL)) goto fail; if (data->bPatternFill) LoadObjectBitmap(fh); break; case V_TEXT: char tempchar; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Font, sizeof(LOGFONT), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->nCount, sizeof(int), &dwRead, NULL)) goto fail; for (int k = 0; k < data->nCount; k++) { if (!ReadFile(fh, &tempchar, sizeof(char), &dwRead, NULL)) goto fail; data->TextString += tempchar; } break; } DataList->Add(data); if (bMergeMode) { // MergeÀÎ °æ¿ì¸¸ Undo save¸¦ ÇÑ´Ù UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } } //=========== Group Index¸¦ ÀçÁöÁ¤ÇØÁÖ´Â ºÎºÐ //===========±âÁ¸ objectµéÀÇ indexÃ߸®±â for (int i = 0; i < existcount; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->GroupIndex) continue; existindex |= data->GroupIndex; } //========= Group Index ÁöÁ¤ (»õ·Î¿î index·Î »ðÀÔ) for (int k = 10; k < 32; k++) { // µé¾î°¥ GroupindexÁöÁ¤ for (int i = 10; i < 32; i++) { if (existindex & (1 << i)) continue; index = i; break; } for (int i = existcount; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->bSelected) continue; // ÀÌ¹Ì Çѹø ÁöÁ¤µÇ¾îÀÖ´Â °æ¿ì´Â º¸³½´Ù if (!(data->GroupIndex & (1<GroupIndex &= 0x000001ff; data->GroupIndex += 1<bSelected = true; existindex |= 1<Count; i++) { data = (TVecData *)DataList->Items[i]; data->bSelected = bMergeMode; // MergeÀΰæ¿ì´Â ¼±ÅÃÀÌ µÈ»óÅ·Π»ý¼º } return true; fail: return false; } //--------------------------------------------------------------------------- TPException __fastcall TVecDraw::LoadVector(HANDLE fh, TPalette *pPalette, TEXPIAFILEHEADER &tpfh) { WORD BitCount; TPException ec = EC_NONE; DWORD dwRead; int Version; // plata0 : C++ Builder 6 ´À·ÁÁö´Â ¹®Á¦ ÃßÀûÁß // ¿©±â±îÁö´Â ´À·ÁÁöÁö ¾ÊÀ½ ///////////////////////////////// Start of Standard Tag Format if (!ReadFile(fh, &tpfh, sizeof(TEXPIAFILEHEADER), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &pPalette->UseColor, sizeof(Word), &dwRead, NULL)) goto fail; pPalette->LoadFromFileHandle((int)fh, 1); if (!ReadFile(fh, &BitCount, sizeof(WORD), &dwRead, NULL)) goto fail; if (SetFilePointer(fh, BitCount==8 ? 8000 : 24000, NULL, FILE_CURRENT)== 0xFFFFFFFF) goto fail; ///////////////////////////////// End of Standard Tag Format //////////////free and realloc //Create(tpfh.CanvasInfor.Width,tpfh.CanvasInfor.Height); ////////////// if(!ReadFile(fh, &Version, sizeof(int), &dwRead, NULL)) { ec = EC_FILE_NOT_READ; goto fail; } if(Version<100) { // ec = EC_FILE_OLD_VERSION; goto fail; ec = EC_FILE_NOT_READ; goto fail; } else { //if ((ec = LoadDataFromFile(fh))!=EC_NONE) goto fail; } return EC_NONE; fail: if (fh!=INVALID_HANDLE_VALUE) CloseHandle(fh); return ec; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::LoadVectorFromFile(HANDLE fh) { int Version, count; int existindex = 0, index = 0, existcount; // ±âÁ¸¿¡ Á¸ÀçÇÏ´Â indexÆÇº°, »ðÀÔÇÒ index number, ±âÁ¸ÀÇ objectÀÇ °¹¼ö DWORD dwRead; bool sw = true; EDataCode Code; if (!ReadFile(fh, &Code, sizeof(EDataCode), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &Version, sizeof(int), &dwRead, NULL)) goto fail; if (Version != 100 && Version != 110 && Version != 120 ) goto fail; if (!ReadFile(fh, &count, sizeof(int), &dwRead, NULL)) goto fail; existcount = DataList->Count; if (count) { deSelect(); bSelected = true; PasteRange = Rect(50000, 50000, 0, 0); } for (int i = 0; i < count; i++) { if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; if (!ReadFile(fh, &data->Kind, sizeof(EVecKind), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->First, sizeof(POINT), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Second, sizeof(POINT), &dwRead, NULL)) goto fail; switch (data->Kind) { case V_LINE: case V_CURVE: if (!ReadFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->PenThick, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->nCount, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bRound, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bFill, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bWinding, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Brush, sizeof(TColor), &dwRead, NULL)) goto fail; //===7.41, Version 110 Ãß°¡ if (Version >= 110) { if (!ReadFile(fh, &data->bClosed, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->GroupIndex, sizeof(int), &dwRead, NULL)) goto fail; } //========================= data->pList = (DPOINT *)HeapAlloc(GetProcessHeap(), 0, sizeof(DPOINT)*(data->nCount*3+1)); if (Version <= 110) { // 7.41ÀÌÇÏ¿¡¼­´Â DPOINT¸¦ »ç¿ëÇÏÁö ¾Ê¾Ò´Ù POINT temp[1024]; if (!ReadFile(fh, temp, sizeof(POINT)*(data->nCount*3+1), &dwRead, NULL)) goto fail; for (int j = 0; j < data->nCount*3+1; j++) data->pList[j].DPoint(temp[j]); }else { if (!ReadFile(fh, data->pList, sizeof(DPOINT)*(data->nCount*3+1), &dwRead, NULL)) goto fail; } if (!ReadFile(fh, &data->bPatternFill, sizeof(bool), &dwRead, NULL)) goto fail; if (data->bPatternFill) LoadObjectBitmap(fh); //========================= N3D ¿¡¼­ Ãß°¡ - LayerIndex, GridIIndex //if (!ReadFile(fh, &data->LayerIndex, sizeof(int), &dwRead, NULL)) goto fail; //if (bLoadVectorMergeMode) //if (!ReadFile(fh, data->GridIndex, sizeof(int)*8, &dwRead, NULL)) goto fail; //if (!ReadFile(fh, &data->GridCount, sizeof(int), &dwRead, NULL)) goto fail; //if (!ReadFile(fh, &data->top, sizeof(int), &dwRead, NULL)) goto fail; //if (!ReadFile(fh, &data->bottom, sizeof(int), &dwRead, NULL)) goto fail; //data->GridCount = 0; //data->bSelected = true; if (data->bClosed && DataCode == T_TEX3D) data->bFill = true; PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)-data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)+data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)-data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)+data->PenThick*2); break; case V_RECT: case V_ELLIPSE: if (!ReadFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->PenThick, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bRound, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bFill, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bWinding, sizeof(bool), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Brush, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->bPatternFill, sizeof(bool), &dwRead, NULL)) goto fail; if (data->bPatternFill) LoadObjectBitmap(fh); break; case V_TEXT: char tempchar; if (!ReadFile(fh, &data->Color, sizeof(TColor), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->Font, sizeof(LOGFONT), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &data->nCount, sizeof(int), &dwRead, NULL)) goto fail; for (int k = 0; k < data->nCount; k++) { if (!ReadFile(fh, &tempchar, sizeof(char), &dwRead, NULL)) goto fail; data->TextString += tempchar; } break; } DataList->Add(data); UndoSave(VU_CREATE, DataList->Count-1, sw); sw = false; } //=========== Group Index¸¦ ÀçÁöÁ¤ÇØÁÖ´Â ºÎºÐ //===========±âÁ¸ objectµéÀÇ indexÃ߸®±â for (int i = 0; i < existcount; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->GroupIndex) continue; existindex |= data->GroupIndex; } //========= Group Index ÁöÁ¤ (»õ·Î¿î index·Î »ðÀÔ) for (int k = 10; k < 32; k++) { // µé¾î°¥ GroupindexÁöÁ¤ for (int i = 10; i < 32; i++) { if (existindex & (1 << i)) continue; index = i; break; } for (int i = existcount; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (data->bSelected) continue; // ÀÌ¹Ì Çѹø ÁöÁ¤µÇ¾îÀÖ´Â °æ¿ì´Â º¸³½´Ù if (!(data->GroupIndex & (1<GroupIndex &= 0x000001ff; data->GroupIndex += 1<bSelected = true; existindex |= 1<Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; data->bSelected = true; } //================== for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; data->First.x -= PasteRange.left; data->Second.x -= PasteRange.left; data->First.y -= PasteRange.top; data->Second.y -= PasteRange.top; if (data->Kind == V_LINE || data->Kind == V_CURVE) { for (int j = 0; j < data->nCount*3+1; j++) { data->pList[j].x -= PasteRange.left; data->pList[j].y -= PasteRange.top; } } } PasteRange = Rect(50000, 50000, 0, 0); for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (!data->bSelected) continue; PasteRange.left = min(PasteRange.left, min(data->First.x, data->Second.x)-data->PenThick*2); PasteRange.right = max(PasteRange.right, max(data->First.x, data->Second.x)+data->PenThick*2); PasteRange.top = min(PasteRange.top, min(data->First.y, data->Second.y)-data->PenThick*2); PasteRange.bottom = max(PasteRange.bottom, max(data->First.y, data->Second.y)+data->PenThick*2); } if (count) bMergeMode = true; return true; fail: return false; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::SaveToFile(HANDLE fh, int method) { // Method 2 : ÇÑ Á¡ÀÌ¶óµµ Area¾È¿¡ Àִ°æ¿ì ÀúÀå // 3 : ÇÑ Á¡ÀÌ¶óµµ Area¹Û¿¡ ÀÖÀ¸¸é ÀúÀåÇÏÁö ¾ÊÀ½ // 4 : ¼±ÅÃµÈ Object¸¸ ÀúÀåµÊ int Version = 120, count = 0; // Version 7.4 : 100, 7.41 : 110, 7.42 : 120 bool isVector, bRange = false; DWORD dwWrite; TRect Src; if (MainImageForm->WorkArea->Mask) { // ÀÛ¾÷±¸¿ªÀÌ ÀÖ´Â °æ¿ì¿¡´Â ¿µ¿ªÀÇ »çÀÌÁî¿¡ ¸ÂÃß¾î shift~ bRange = true; Src = MainImageForm->WorkArea->Range; } for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (method == 4 && !data->bSelected) continue; INRECTMETHOD; count++; } if (count > 0) isVector = true; else isVector = false; if (!WriteFile(fh, &isVector, sizeof(bool), &dwWrite, NULL)) goto fail; if (!isVector) return true; if (!WriteFile(fh, &Version, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &count, sizeof(int), &dwWrite, NULL)) goto fail; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; if (method == 4 && !data->bSelected) continue; INRECTMETHOD; if (!WriteFile(fh, &data->Kind, sizeof(EVecKind), &dwWrite, NULL)) goto fail; if (bRange){ POINT TempFirst, TempSecond; TempFirst.x = data->First.x - Src.Left; TempFirst.y = data->First.y - Src.Top; TempSecond.x = data->Second.x - Src.Left; TempSecond.y = data->Second.y - Src.Top; if (!WriteFile(fh, &TempFirst, sizeof(POINT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &TempSecond, sizeof(POINT), &dwWrite, NULL)) goto fail; }else { if (!WriteFile(fh, &data->First, sizeof(POINT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Second, sizeof(POINT), &dwWrite, NULL)) goto fail; } switch (data->Kind) { case V_LINE: case V_CURVE: if (!WriteFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->PenThick, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->nCount, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bRound, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bWinding, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Brush, sizeof(TColor), &dwWrite, NULL)) goto fail; //===7.41, Version 110 Ãß°¡ if (!WriteFile(fh, &data->bClosed, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->GroupIndex, sizeof(int), &dwWrite, NULL)) goto fail; //========================= if (bRange){ DPOINT TempList[1024]; for (int i = 0; i < data->nCount*3+1; i++) { TempList[i].x = data->pList[i].x - Src.Left; TempList[i].y = data->pList[i].y - Src.Top; } if (!WriteFile(fh, TempList, sizeof(DPOINT)*(data->nCount*3+1), &dwWrite, NULL)) goto fail; }else { if (!WriteFile(fh, data->pList, sizeof(DPOINT)*(data->nCount*3+1), &dwWrite, NULL)) goto fail; } if (!WriteFile(fh, &data->bPatternFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (data->bPatternFill) SaveObjectBitmap(fh); break; case V_RECT: case V_ELLIPSE: if (!WriteFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->PenThick, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bRound, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bWinding, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Brush, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bPatternFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (data->bPatternFill) SaveObjectBitmap(fh); break; case V_TEXT: // char *tempstr = ""; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Font, sizeof(LOGFONT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->nCount, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, data->TextString.c_str(), sizeof(char)*data->nCount, &dwWrite, NULL)) goto fail; // for (int k = 0; k < data->nCount; k++) tempstr[k] = data->TextString[k+1]; // if (!WriteFile(fh, tempstr, sizeof(char)*data->nCount, &dwWrite, NULL)) goto fail; break; } } return true; fail: return false; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::SaveVectorToFile(HANDLE fh, int method) { // Method 2 : ÇÑ Á¡ÀÌ¶óµµ Area¾È¿¡ Àִ°æ¿ì ÀúÀå // 3 : ÇÑ Á¡ÀÌ¶óµµ Area¹Û¿¡ ÀÖÀ¸¸é ÀúÀåÇÏÁö ¾ÊÀ½ // 4 : ¼±ÅÃµÈ Object¸¸ ÀúÀåµÊ int Version = 120, count = 0; // Version 7.4 : 100, 7.41 : 110, 7.42 : 120 bool isVector, bRange = false; DWORD dwWrite; TRect Src; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; //if (method == 4 && !data->bSelected) continue; INRECTMETHOD; count++; } //if (count > 0) isVector = true; else isVector = false; //if (!WriteFile(fh, &isVector, sizeof(bool), &dwWrite, NULL)) goto fail; //if (!isVector) return true; if (!WriteFile(fh, &DataCode, sizeof(EDataCode), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &Version, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &count, sizeof(int), &dwWrite, NULL)) goto fail; for (int i = 0; i < DataList->Count; i++) { data = (TVecData *)DataList->Items[i]; if (!data->Equal(MainImageForm->Number)) continue; //if (method == 4 && !data->bSelected) continue; INRECTMETHOD; if (!WriteFile(fh, &data->Kind, sizeof(EVecKind), &dwWrite, NULL)) goto fail; if (bRange){ POINT TempFirst, TempSecond; TempFirst.x = data->First.x - Src.Left; TempFirst.y = data->First.y - Src.Top; TempSecond.x = data->Second.x - Src.Left; TempSecond.y = data->Second.y - Src.Top; if (!WriteFile(fh, &TempFirst, sizeof(POINT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &TempSecond, sizeof(POINT), &dwWrite, NULL)) goto fail; }else { if (!WriteFile(fh, &data->First, sizeof(POINT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Second, sizeof(POINT), &dwWrite, NULL)) goto fail; } switch (data->Kind) { case V_LINE: case V_CURVE: if (!WriteFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->PenThick, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->nCount, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bRound, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bWinding, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Brush, sizeof(TColor), &dwWrite, NULL)) goto fail; //===7.41, Version 110 Ãß°¡ if (!WriteFile(fh, &data->bClosed, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->GroupIndex, sizeof(int), &dwWrite, NULL)) goto fail; //========================= if (bRange){ DPOINT TempList[1024]; for (int i = 0; i < data->nCount*3+1; i++) { TempList[i].x = data->pList[i].x - Src.Left; TempList[i].y = data->pList[i].y - Src.Top; } if (!WriteFile(fh, TempList, sizeof(DPOINT)*(data->nCount*3+1), &dwWrite, NULL)) goto fail; }else { if (!WriteFile(fh, data->pList, sizeof(DPOINT)*(data->nCount*3+1), &dwWrite, NULL)) goto fail; } if (!WriteFile(fh, &data->bPatternFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (data->bPatternFill) SaveObjectBitmap(fh); //========================= N3D ¿¡¼­ Ãß°¡ - LayerIndex, GridIIndex //if (!WriteFile(fh, &data->LayerIndex, sizeof(int), &dwWrite, NULL)) goto fail; //if (!WriteFile(fh, data->GridIndex, sizeof(int)*8, &dwWrite, NULL)) goto fail; //if (!WriteFile(fh, &data->GridCount, sizeof(int), &dwWrite, NULL)) goto fail; //if (!WriteFile(fh, &data->top, sizeof(int), &dwWrite, NULL)) goto fail; //if (!WriteFile(fh, &data->bottom, sizeof(int), &dwWrite, NULL)) goto fail; break; case V_RECT: case V_ELLIPSE: if (!WriteFile(fh, &data->PenStyle, sizeof(EPenStyle), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->PenThick, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bRound, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bWinding, sizeof(bool), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Brush, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->bPatternFill, sizeof(bool), &dwWrite, NULL)) goto fail; if (data->bPatternFill) SaveObjectBitmap(fh); break; case V_TEXT: // char *tempstr = ""; if (!WriteFile(fh, &data->Color, sizeof(TColor), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->Font, sizeof(LOGFONT), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &data->nCount, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, data->TextString.c_str(), sizeof(char)*data->nCount, &dwWrite, NULL)) goto fail; // for (int k = 0; k < data->nCount; k++) tempstr[k] = data->TextString[k+1]; // if (!WriteFile(fh, tempstr, sizeof(char)*data->nCount, &dwWrite, NULL)) goto fail; break; } } return true; fail: return false; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::SaveObjectBitmap(HANDLE fh) { BYTE *pMem = NULL; BYTE *ptr=NULL; DWORD dwWrite; int w = data->Bitmap->Width, h = data->Bitmap->Height; if (!WriteFile(fh, &w, sizeof(int), &dwWrite, NULL)) goto fail; if (!WriteFile(fh, &h, sizeof(int), &dwWrite, NULL)) goto fail; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, w*h*3))==NULL) goto fail; for (int y = 0; y < h; y++) { ptr = (Byte *)data->Bitmap->ScanLine[y]; memcpy(pMem+w*3*y, ptr, w*3); } if (!WriteFile(fh, pMem, w*h*3, &dwWrite, NULL)) goto fail; HeapFree(GetProcessHeap(), 0, pMem); return true; fail: return false; } //--------------------------------------------------------------------------- bool __fastcall TVecDraw::LoadObjectBitmap(HANDLE fh) { BYTE *pMem = NULL; BYTE *ptr=NULL; DWORD dwRead; int w, h; if (!ReadFile(fh, &w, sizeof(int), &dwRead, NULL)) goto fail; if (!ReadFile(fh, &h, sizeof(int), &dwRead, NULL)) goto fail; if ((pMem = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, w*h*3))==NULL) goto fail; data->Bitmap = new Graphics::TBitmap; data->Bitmap->PixelFormat = pf24bit; data->Bitmap->Width = w; data->Bitmap->Height = h; if (!ReadFile(fh, pMem, w*h*3, &dwRead, NULL)) goto fail; for (int y = 0; y < h; y++) { ptr = (Byte *)data->Bitmap->ScanLine[y]; memcpy(ptr, pMem+y*w*3, w*3); } HeapFree(GetProcessHeap(), 0, pMem); return true; fail: return false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //-------- Undo Handling --------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TVecDraw::UndoSave(int kind, int index, bool sw, int nDest) { if ((udata = new TVUndoData(MainImageForm->Number))==NULL) goto fail; switch (kind) { case VU_ALL: udata->Kind = VU_ALL; break; case VU_CREATE: udata->Kind = VU_CREATE; udata->IndexNumber = index; udata->VUndoData = NULL; udata->bFirst = sw; break; case VU_DELETE: udata->Kind = VU_DELETE; udata->IndexNumber = index; udata->VUndoData = new TVecData(MainImageForm->Number); udata->VUndoData->Copy((TVecData *)DataList->Items[index]); udata->bFirst = sw; break; case VU_MODIFY: udata->Kind = VU_MODIFY; udata->IndexNumber = index; udata->VUndoData = new TVecData(MainImageForm->Number); udata->VUndoData->Copy((TVecData *)DataList->Items[index]); udata->bFirst = sw; break; case VU_ORDERF: udata->Kind = VU_ORDERF; udata->IndexNumber = index; if (nDest) udata->DstNumber = nDest; else udata->DstNumber = DataList->Count-1; udata->VUndoData = NULL; udata->bFirst = sw; break; case VU_ORDERB: udata->Kind = VU_ORDERB; udata->IndexNumber = index; udata->DstNumber = nDest; udata->VUndoData = NULL; udata->bFirst = sw; break; } UndoList->Insert(0, udata); if (UndoList->Count > MAX_UNDO) { udata = (TVUndoData *)UndoList->Items[MAX_UNDO]; UndoList->Delete(MAX_UNDO); if (udata->VUndoData) {delete udata->VUndoData; udata->VUndoData = NULL; } delete udata; udata = NULL; } while (RedoList->Count) { rdata = (TVUndoData *)RedoList->First(); RedoList->Delete(0); if (rdata->VUndoData) {delete rdata->VUndoData; rdata->VUndoData = NULL; } delete rdata; rdata = NULL; } MainImageForm->Modify = true; return; fail: return; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::UndoRead() { RECT rc = Rect(0, 0, MainImageForm->iMainImage->uBitmap->Width, MainImageForm->iMainImage->uBitmap->Height); if (UndoList->Count == 0) return; for (int i = 0; i < UndoList->Count; i++) { udata = (TVUndoData *)UndoList->Items[i]; if (!udata->Equal(MainImageForm->Number)) continue; if ((rdata = new TVUndoData(MainImageForm->Number))==NULL) goto fail; switch (udata->Kind) { case VU_ALL: break; case VU_CREATE: data = (TVecData *)DataList->Items[udata->IndexNumber]; rdata->Kind = VU_DELETE; rdata->IndexNumber = udata->IndexNumber; rdata->VUndoData = new TVecData(MainImageForm->Number); rdata->VUndoData->Copy(data); rdata->bFirst = udata->bFirst; DataList->Delete(udata->IndexNumber); delete data; data = NULL; // if (udata->IndexNumber == Index) deSelect(); // Áö¿öÁö´Â°æ¿ì¿¡ Select°¡ µÇ¸é ¾ÈµÇ´Ï±î UndoList->Delete(i); i--; delete udata->VUndoData; udata->VUndoData = NULL; break; case VU_DELETE: rdata->Kind = VU_CREATE; rdata->IndexNumber = udata->IndexNumber; rdata->VUndoData = NULL; rdata->bFirst = udata->bFirst; if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Copy(udata->VUndoData); DataList->Insert(udata->IndexNumber, data); UndoList->Delete(i); i--; delete udata->VUndoData; udata->VUndoData = NULL; break; case VU_MODIFY: data = (TVecData *)DataList->Items[udata->IndexNumber]; rdata->Kind = VU_MODIFY; rdata->IndexNumber = udata->IndexNumber; rdata->VUndoData = new TVecData(MainImageForm->Number); rdata->VUndoData->Copy(data); rdata->bFirst = udata->bFirst; data->Copy(udata->VUndoData); // data->bSelected = false; // bSelected = false; UndoList->Delete(i); i--; delete udata->VUndoData; udata->VUndoData = NULL; break; case VU_ORDERF: DataList->Move(udata->DstNumber, udata->IndexNumber); rdata->Kind = VU_ORDERB; rdata->IndexNumber = udata->DstNumber; rdata->DstNumber = udata->IndexNumber; rdata->VUndoData = NULL; rdata->bFirst = udata->bFirst; UndoList->Delete(i); i--; delete udata->VUndoData; udata->VUndoData = NULL; deSelect(); // orderÀÇ index°¡ ¼¯À̹ǷΠ¸ðµç ¼±ÅÃÀ» ÇØÁ¦½ÃŲ´Ù break; case VU_ORDERB: DataList->Move(udata->DstNumber, udata->IndexNumber); rdata->Kind = VU_ORDERF; rdata->IndexNumber = udata->DstNumber; rdata->DstNumber = udata->IndexNumber; rdata->VUndoData = NULL; rdata->bFirst = udata->bFirst; UndoList->Delete(i); i--; delete udata->VUndoData; udata->VUndoData = NULL; deSelect(); // orderÀÇ index°¡ ¼¯À̹ǷΠ¸ðµç ¼±ÅÃÀ» ÇØÁ¦½ÃŲ´Ù break; } RedoList->Insert(0, rdata); if (udata->bFirst) { delete udata; udata = NULL; break; }else { delete udata; udata = NULL; } } MainImageForm->iMainImage->Cursor = crDefault; MainImageForm->iMainImage->RectPaint(rc); return; fail: return; } //--------------------------------------------------------------------------- void __fastcall TVecDraw::RedoRead() { RECT rc = Rect(0, 0, MainImageForm->iMainImage->uBitmap->Width, MainImageForm->iMainImage->uBitmap->Height); if (RedoList->Count == 0) return; for (int i = 0; i < RedoList->Count; i++) { rdata = (TVUndoData *)RedoList->Items[i]; if (!rdata->Equal(MainImageForm->Number)) continue; if ((udata = new TVUndoData(MainImageForm->Number))==NULL) goto fail; switch (rdata->Kind) { case VU_ALL: break; case VU_CREATE: data = (TVecData *)DataList->Items[rdata->IndexNumber]; udata->Kind = VU_DELETE; udata->IndexNumber = rdata->IndexNumber; udata->VUndoData = new TVecData(MainImageForm->Number); udata->VUndoData->Copy(data); udata->bFirst = rdata->bFirst; DataList->Delete(rdata->IndexNumber); delete data; data = NULL; RedoList->Delete(i); i--; delete rdata->VUndoData; rdata->VUndoData = NULL; break; case VU_DELETE: udata->Kind = VU_CREATE; udata->IndexNumber = rdata->IndexNumber; udata->VUndoData = NULL; udata->bFirst = rdata->bFirst; if ((data = new TVecData(MainImageForm->Number))==NULL) goto fail; data->Copy(rdata->VUndoData); DataList->Insert(rdata->IndexNumber, data); RedoList->Delete(i); i--; delete rdata->VUndoData; rdata->VUndoData = NULL; break; case VU_MODIFY: data = (TVecData *)DataList->Items[rdata->IndexNumber]; udata->Kind = VU_MODIFY; udata->IndexNumber = rdata->IndexNumber; udata->VUndoData = new TVecData(MainImageForm->Number); udata->VUndoData->Copy(data); udata->bFirst = rdata->bFirst; data->Copy(rdata->VUndoData); RedoList->Delete(i); i--; delete rdata->VUndoData; rdata->VUndoData = NULL; break; case VU_ORDERF: DataList->Move(rdata->DstNumber, rdata->IndexNumber); udata->Kind = VU_ORDERB; udata->IndexNumber = rdata->DstNumber; udata->DstNumber = rdata->IndexNumber; udata->VUndoData = NULL; udata->bFirst = rdata->bFirst; RedoList->Delete(i); i--; delete rdata->VUndoData; rdata->VUndoData = NULL; deSelect(); // orderÀÇ index°¡ ¼¯À̹ǷΠ¸ðµç ¼±ÅÃÀ» ÇØÁ¦½ÃŲ´Ù break; case VU_ORDERB: DataList->Move(rdata->DstNumber, rdata->IndexNumber); udata->Kind = VU_ORDERF; udata->IndexNumber = rdata->DstNumber; udata->DstNumber = rdata->IndexNumber; udata->VUndoData = NULL; udata->bFirst = rdata->bFirst; RedoList->Delete(i); i--; delete rdata->VUndoData; rdata->VUndoData = NULL; deSelect(); // orderÀÇ index°¡ ¼¯À̹ǷΠ¸ðµç ¼±ÅÃÀ» ÇØÁ¦½ÃŲ´Ù break; } UndoList->Insert(0, udata); delete rdata; rdata = NULL; if (RedoList->Count == 0) break; rdata = (TVUndoData *)RedoList->First(); if (rdata->bFirst) break; } MainImageForm->iMainImage->Cursor = crDefault; MainImageForm->iMainImage->RectPaint(rc); return; fail: return; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //-------- Library Part --------------------------------------------- //--------------------------------------------------------------------------- bool __fastcall TVecDraw::PointOnCurvePath(TVecData *dt, int X, int Y) { HRGN rgn = NULL; // Á¤È®ÇÑ ¿µ¿ªÀ» ã¾ÆÁÖ´Â (Line, curve¿¡¼­) ¼Ò½ºÀÔ´Ï´Ù HPEN hPen, hOldPen; HDC dcDst = MainImageForm->iMainImage->Canvas->Handle; int nFillMode; bool bResult = false; POINT pTemp[1024]; for (int i = 0; i < dt->nCount*3 +1; i++) pTemp[i] = dt->pList[i].P(); nFillMode = GetPolyFillMode(dcDst); SetPolyFillMode(dcDst, WINDING); hPen = CreatePen(PS_SOLID, dt->PenThick>5 ? dt->PenThick : 5, RGB(0,0,0)); hOldPen = SelectObject(dcDst, hPen); if (data->bClosed) pTemp[data->nCount*3] = pTemp[0]; BeginPath(dcDst); MoveToEx(dcDst, dt->pList[0].x, dt->pList[0].y, NULL); PolyBezierTo (dcDst, pTemp+1, dt->nCount*3); EndPath(dcDst); WidenPath(dcDst); rgn = PathToRegion(dcDst); if (rgn) if (PtInRegion(rgn, X, Y)) bResult = true; SetPolyFillMode(dcDst, nFillMode); if (rgn) {DeleteObject(rgn); rgn = NULL; } DeleteObject(SelectObject(dcDst, hOldPen)); return bResult; } //---------------------------------------------------------------------------