From 3957fa63950d55e3813425d6bb7aca8df38db82f Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 25 Oct 2008 11:07:13 +0900 Subject: [PATCH] [13/19] paint: Add [Flip/Rotate] dialog --- programs/paint/En.rc | 16 ++++ programs/paint/bitmap.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++ programs/paint/canvas.c | 116 +++++++++++++++++++++++++++++ programs/paint/main.h | 10 +++ programs/paint/paint.c | 70 +++++++++++++++++- 5 files changed, 399 insertions(+), 1 deletions(-) diff --git a/programs/paint/En.rc b/programs/paint/En.rc index 01a44c5..09ec9cc 100644 --- a/programs/paint/En.rc +++ b/programs/paint/En.rc @@ -148,6 +148,22 @@ FONT 8, "MS Shell Dlg" PUSHBUTTON "Cancel", IDCANCEL, 142, 24, 50, 14 } +IDD_FLIP_ROTATE DIALOG 32, 16, 200, 107 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "Flip and Rotate" +FONT 8, "MS Shell Dlg" +{ + GROUPBOX "Flip or rotate", grp1, 7, 7, 127, 94 + CONTROL "&Flip horizontal", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 13, 20, 77, 9 + CONTROL "Flip &vertical", rad2, "BUTTON", BS_AUTORADIOBUTTON, 13, 33, 72, 9 + CONTROL "&Rotate by angle", rad3, "BUTTON", BS_AUTORADIOBUTTON, 13, 46, 72, 9 + CONTROL "&90\xB0", rad4, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_DISABLED, 49, 60, 30, 10 + CONTROL "&180\xB0", rad5, "BUTTON", BS_AUTORADIOBUTTON | WS_DISABLED, 49, 73, 31, 10 + CONTROL "&270\xB0", rad6, "BUTTON", BS_AUTORADIOBUTTON | WS_DISABLED, 49, 86, 33, 10 + DEFPUSHBUTTON "OK", IDOK, 142, 7, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 142, 24, 50, 14 +} + IDD_STRETCH_SKEW DIALOG 18, 48, 232, 150 STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU CAPTION "Stretch and Skew" diff --git a/programs/paint/bitmap.c b/programs/paint/bitmap.c index a276195..2c44f34 100644 --- a/programs/paint/bitmap.c +++ b/programs/paint/bitmap.c @@ -124,6 +124,194 @@ HBITMAP BM_CreateStretched(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz) return hbmNew; } +HBITMAP BM_CreateHFliped(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + + hbmNew = BM_Create(siz); + if (hbmNew != NULL) + { + dwError = 0; + hDC = GetDC(hWnd); + hdcMem1 = CreateCompatibleDC(hDC); + if (hdcMem1 != NULL) + { + hbmOld1 = SelectObject(hdcMem1, hbmNew); + + hdcMem2 = CreateCompatibleDC(hDC); + if (hdcMem2 != NULL) + { + hbmOld2 = SelectObject(hdcMem2, hbm); + StretchBlt(hdcMem1, siz.cx - 1, 0, -siz.cx, siz.cy, + hdcMem2, 0, 0, siz.cx, siz.cy, SRCCOPY); + SelectObject(hdcMem2, hbmOld2); + DeleteDC(hdcMem2); + } + else + dwError = GetLastError(); + SelectObject(hdcMem1, hbmOld1); + + DeleteDC(hdcMem1); + } + else + dwError = GetLastError(); + ReleaseDC(hWnd, hDC); + SetLastError(dwError); + } + + return hbmNew; +} + +HBITMAP BM_CreateVFliped(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + + hbmNew = BM_Create(siz); + if (hbmNew != NULL) + { + dwError = 0; + hDC = GetDC(hWnd); + hdcMem1 = CreateCompatibleDC(hDC); + if (hdcMem1 != NULL) + { + hbmOld1 = SelectObject(hdcMem1, hbmNew); + + hdcMem2 = CreateCompatibleDC(hDC); + if (hdcMem2 != NULL) + { + hbmOld2 = SelectObject(hdcMem2, hbm); + StretchBlt(hdcMem1, 0, siz.cy - 1, siz.cx, -siz.cy, + hdcMem2, 0, 0, siz.cx, siz.cy, SRCCOPY); + SelectObject(hdcMem2, hbmOld2); + DeleteDC(hdcMem2); + } + else + dwError = GetLastError(); + SelectObject(hdcMem1, hbmOld1); + + DeleteDC(hdcMem1); + } + else + dwError = GetLastError(); + ReleaseDC(hWnd, hDC); + SetLastError(dwError); + } + + return hbmNew; +} + +HBITMAP BM_CreateXYSwaped(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + INT x, y; + SIZE siz2; + siz2.cx = siz.cy; + siz2.cy = siz.cx; + + hbmNew = BM_Create(siz2); + if (hbmNew != NULL) + { + dwError = 0; + hDC = GetDC(hWnd); + hdcMem1 = CreateCompatibleDC(hDC); + if (hdcMem1 != NULL) + { + hbmOld1 = SelectObject(hdcMem1, hbmNew); + + hdcMem2 = CreateCompatibleDC(hDC); + if (hdcMem2 != NULL) + { + hbmOld2 = SelectObject(hdcMem2, hbm); + + for (y = 0; y < siz2.cy; y++) + { + for (x = 0; x < siz2.cx; x++) + { + SetPixel(hdcMem1, x, y, GetPixel(hdcMem2, y, x)); + } + } + + SelectObject(hdcMem2, hbmOld2); + DeleteDC(hdcMem2); + } + else + dwError = GetLastError(); + SelectObject(hdcMem1, hbmOld1); + + DeleteDC(hdcMem1); + } + else + dwError = GetLastError(); + ReleaseDC(hWnd, hDC); + SetLastError(dwError); + } + + return hbmNew; +} + +HBITMAP BM_CreateRotated90Degree(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HBITMAP hbmNew1, hbmNew2; + SIZE siz2; + siz2.cx = siz.cy; + siz2.cy = siz.cx; + hbmNew1 = BM_CreateXYSwaped(hWnd, hbm, siz); + hbmNew2 = NULL; + if (hbmNew1 != NULL) + { + dwError = 0; + hbmNew2 = BM_CreateHFliped(hWnd, hbmNew1, siz2); + if (hbmNew2 == NULL) + dwError = GetLastError(); + DeleteObject(hbmNew1); + SetLastError(dwError); + } + return hbmNew2; +} + +HBITMAP BM_CreateRotated180Degree(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HBITMAP hbmNew1, hbmNew2; + hbmNew1 = BM_CreateHFliped(hWnd, hbm, siz); + hbmNew2 = NULL; + if (hbmNew1 != NULL) + { + dwError = 0; + hbmNew2 = BM_CreateVFliped(hWnd, hbmNew1, siz); + if (hbmNew2 == NULL) + dwError = GetLastError(); + DeleteObject(hbmNew1); + SetLastError(dwError); + } + return hbmNew2; +} + +HBITMAP BM_CreateRotated270Degree(HWND hWnd, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HBITMAP hbmNew1, hbmNew2; + hbmNew1 = BM_CreateHFliped(hWnd, hbm, siz); + hbmNew2 = NULL; + if (hbmNew1 != NULL) + { + dwError = 0; + hbmNew2 = BM_CreateXYSwaped(hWnd, hbmNew1, siz); + if (hbmNew2 == NULL) + dwError = GetLastError(); + DeleteObject(hbmNew1); + SetLastError(dwError); + } + return hbmNew2; +} + HBITMAP BM_Copy(HBITMAP hbm) { return (HBITMAP)CopyImage(hbm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG); diff --git a/programs/paint/canvas.c b/programs/paint/canvas.c index 8ac3b2c..47656e7 100644 --- a/programs/paint/canvas.c +++ b/programs/paint/canvas.c @@ -1398,6 +1398,122 @@ VOID Canvas_Stretch(HWND hWnd, SIZE sizNew) ShowLastError(); } +VOID Canvas_HFlip(HWND hWnd) +{ + HBITMAP hbmNew = BM_CreateHFliped(hWnd, Globals.hbmImage, + Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_VFlip(HWND hWnd) +{ + HBITMAP hbmNew = BM_CreateVFliped(Globals.hCanvasWnd, + Globals.hbmImage, Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_Rotate90Degree(HWND hWnd) +{ + SIZE siz; + HBITMAP hbmNew = BM_CreateRotated90Degree(hWnd, + Globals.hbmImage, Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + siz.cx = Globals.sizImage.cy; + siz.cy = Globals.sizImage.cx; + Globals.sizImage = siz; + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx *= Globals.nZoom; + siz.cy *= Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(siz); + Globals.fModified = TRUE; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(hWnd, WM_SIZE, 0, 0); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_Rotate180Degree(HWND hWnd) +{ + HBITMAP hbmNew = BM_CreateRotated180Degree(hWnd, + Globals.hbmImage, Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_Rotate270Degree(HWND hWnd) +{ + SIZE siz; + HBITMAP hbmNew = BM_CreateRotated270Degree(hWnd, + Globals.hbmImage, Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + siz.cx = Globals.sizImage.cy; + siz.cy = Globals.sizImage.cx; + Globals.sizImage = siz; + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx *= Globals.nZoom; + siz.cy *= Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(siz); + Globals.fModified = TRUE; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(hWnd, WM_SIZE, 0, 0); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + VOID Canvas_OnButtonDblClk(HWND hWnd, INT x, INT y, BOOL fRight) { HDC hDC, hMemDC; diff --git a/programs/paint/main.h b/programs/paint/main.h index 8ec22de..1ac816c 100644 --- a/programs/paint/main.h +++ b/programs/paint/main.h @@ -146,9 +146,19 @@ LRESULT CALLBACK CanvasWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); VOID Canvas_Resize(HWND hWnd, SIZE sizNew); VOID Canvas_Stretch(HWND hWnd, SIZE sizNew); +VOID Canvas_HFlip(HWND hWnd); +VOID Canvas_VFlip(HWND hWnd); +VOID Canvas_Rotate90Degree(HWND hWnd); +VOID Canvas_Rotate180Degree(HWND hWnd); +VOID Canvas_Rotate270Degree(HWND hWnd); /* bitmap.c */ HBITMAP BM_Create(SIZE siz); HBITMAP BM_CreateResized(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz); HBITMAP BM_CreateStretched(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz); +HBITMAP BM_CreateHFliped(HWND hWnd, HBITMAP hbm, SIZE siz); +HBITMAP BM_CreateVFliped(HWND hWnd, HBITMAP hbm, SIZE siz); +HBITMAP BM_CreateRotated90Degree(HWND hWnd, HBITMAP hbm, SIZE siz); +HBITMAP BM_CreateRotated180Degree(HWND hWnd, HBITMAP hbm, SIZE siz); +HBITMAP BM_CreateRotated270Degree(HWND hWnd, HBITMAP hbm, SIZE siz); HBITMAP BM_Copy(HBITMAP hbm); diff --git a/programs/paint/paint.c b/programs/paint/paint.c index b3e6cd2..17f6251 100644 --- a/programs/paint/paint.c +++ b/programs/paint/paint.c @@ -642,9 +642,77 @@ VOID PAINT_Attributes(VOID) NotSupportedYet(); } +BOOL CALLBACK +FlipRotateDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + CheckDlgButton(hDlg, rad1, 1); + CheckDlgButton(hDlg, rad4, 1); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case rad1: + case rad2: + EnableWindow(GetDlgItem(hDlg, rad4), FALSE); + EnableWindow(GetDlgItem(hDlg, rad5), FALSE); + EnableWindow(GetDlgItem(hDlg, rad6), FALSE); + break; + + case rad3: + EnableWindow(GetDlgItem(hDlg, rad4), TRUE); + EnableWindow(GetDlgItem(hDlg, rad5), TRUE); + EnableWindow(GetDlgItem(hDlg, rad6), TRUE); + break; + + case IDOK: + if (IsDlgButtonChecked(hDlg, rad1) & 1) + { + Canvas_HFlip(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad2) & 1) + { + Canvas_VFlip(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad3) & 1) + { + if (IsDlgButtonChecked(hDlg, rad4) & 1) + { + Canvas_Rotate90Degree(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad5) & 1) + { + Canvas_Rotate180Degree(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad6) & 1) + { + Canvas_Rotate270Degree(Globals.hCanvasWnd); + } + } + + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + break; + } + return FALSE; +} + VOID PAINT_FlipRotate(VOID) { - NotSupportedYet(); + if (DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_FLIP_ROTATE), + Globals.hMainWnd, FlipRotateDlgProc) == IDOK) + { + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } } VOID PAINT_EditColor(BOOL fBack) -- 1.6.0.2