From b5fc5d2fc2c74507aa2dcf2daa4fe404e9b1ba06 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 21 Oct 2008 03:41:08 +0900 Subject: [PATCH] paint: Add new program --- .gitignore | 1 + configure | 11 + configure.ac | 1 + programs/paint/En.rc | 335 ++++++ programs/paint/Ja.rc | 334 ++++++ programs/paint/Makefile.in | 24 + programs/paint/airbrush.bmp | Bin 0 -> 670 bytes programs/paint/airbrush.cur | Bin 0 -> 326 bytes programs/paint/bdiagon.cur | Bin 0 -> 326 bytes programs/paint/bitmap.c | 664 +++++++++++ programs/paint/brush.bmp | Bin 0 -> 670 bytes programs/paint/canvas.c | 2614 +++++++++++++++++++++++++++++++++++++++++++ programs/paint/cross.cur | Bin 0 -> 326 bytes programs/paint/cross2.cur | Bin 0 -> 326 bytes programs/paint/eraser.bmp | Bin 0 -> 9174 bytes programs/paint/fdiagon.cur | Bin 0 -> 326 bytes programs/paint/fill.bmp | Bin 0 -> 1638 bytes programs/paint/flood.cur | Bin 0 -> 326 bytes programs/paint/horizon.cur | Bin 0 -> 326 bytes programs/paint/hslant.ico | Bin 0 -> 766 bytes programs/paint/hstretch.ico | Bin 0 -> 766 bytes programs/paint/line.bmp | Bin 0 -> 670 bytes programs/paint/main.c | 1491 ++++++++++++++++++++++++ programs/paint/main.h | 179 +++ programs/paint/move.cur | Bin 0 -> 326 bytes programs/paint/paint.c | 1243 ++++++++++++++++++++ programs/paint/paint.h | 71 ++ programs/paint/paint.ico | Bin 0 -> 15086 bytes programs/paint/paint.svg | 305 +++++ programs/paint/pencil.cur | Bin 0 -> 326 bytes programs/paint/resource.h | 175 +++ programs/paint/rsrc.rc | 113 ++ programs/paint/spoit.cur | Bin 0 -> 326 bytes programs/paint/tools.bmp | Bin 0 -> 1692 bytes programs/paint/trans.bmp | Bin 0 -> 1638 bytes programs/paint/vertical.cur | Bin 0 -> 326 bytes programs/paint/vibeam.cur | Bin 0 -> 326 bytes programs/paint/vslant.ico | Bin 0 -> 766 bytes programs/paint/vstretch.ico | Bin 0 -> 766 bytes programs/paint/zoom.bmp | Bin 0 -> 670 bytes programs/paint/zoom.cur | Bin 0 -> 326 bytes tools/make_makefiles | 1 + 42 files changed, 7562 insertions(+), 0 deletions(-) create mode 100644 programs/paint/En.rc create mode 100644 programs/paint/Ja.rc create mode 100644 programs/paint/Makefile.in create mode 100644 programs/paint/airbrush.bmp create mode 100644 programs/paint/airbrush.cur create mode 100644 programs/paint/bdiagon.cur create mode 100644 programs/paint/bitmap.c create mode 100644 programs/paint/brush.bmp create mode 100644 programs/paint/canvas.c create mode 100644 programs/paint/cross.cur create mode 100644 programs/paint/cross2.cur create mode 100644 programs/paint/eraser.bmp create mode 100644 programs/paint/fdiagon.cur create mode 100644 programs/paint/fill.bmp create mode 100644 programs/paint/flood.cur create mode 100644 programs/paint/horizon.cur create mode 100644 programs/paint/hslant.ico create mode 100644 programs/paint/hstretch.ico create mode 100644 programs/paint/line.bmp create mode 100644 programs/paint/main.c create mode 100644 programs/paint/main.h create mode 100644 programs/paint/move.cur create mode 100644 programs/paint/paint.c create mode 100644 programs/paint/paint.h create mode 100644 programs/paint/paint.ico create mode 100644 programs/paint/paint.svg create mode 100644 programs/paint/pencil.cur create mode 100644 programs/paint/resource.h create mode 100644 programs/paint/rsrc.rc create mode 100644 programs/paint/spoit.cur create mode 100644 programs/paint/tools.bmp create mode 100644 programs/paint/trans.bmp create mode 100644 programs/paint/vertical.cur create mode 100644 programs/paint/vibeam.cur create mode 100644 programs/paint/vslant.ico create mode 100644 programs/paint/vstretch.ico create mode 100644 programs/paint/zoom.bmp create mode 100644 programs/paint/zoom.cur diff --git a/.gitignore b/.gitignore index 1caea1b..33fdbfe 100644 --- a/.gitignore +++ b/.gitignore @@ -233,6 +233,7 @@ programs/msiexec/msiexec programs/net/net programs/notepad/notepad programs/oleview/oleview +programs/paint/paint programs/progman/progman programs/reg/reg programs/regedit/regedit diff --git a/configure b/configure index 1debef2..2899f59 100644 --- a/configure +++ b/configure @@ -25566,6 +25566,16 @@ programs/oleview/Makefile: programs/oleview/Makefile.in programs/Makeprog.rules" ac_config_files="$ac_config_files programs/oleview/Makefile" ALL_MAKEFILES="$ALL_MAKEFILES \\ + programs/paint/Makefile" +test "x$enable_paint" != xno && ALL_PROGRAM_DIRS="$ALL_PROGRAM_DIRS \\ + paint" && ALL_PROGRAM_INSTALL_DIRS="$ALL_PROGRAM_INSTALL_DIRS \\ + paint" && ALL_PROGRAM_BIN_INSTALL_DIRS="$ALL_PROGRAM_BIN_INSTALL_DIRS \\ + paint" +ALL_MAKEFILE_DEPENDS="$ALL_MAKEFILE_DEPENDS +programs/paint/Makefile: programs/paint/Makefile.in programs/Makeprog.rules" +ac_config_files="$ac_config_files programs/paint/Makefile" + +ALL_MAKEFILES="$ALL_MAKEFILES \\ programs/progman/Makefile" test "x$enable_progman" != xno && ALL_PROGRAM_DIRS="$ALL_PROGRAM_DIRS \\ progman" && ALL_PROGRAM_INSTALL_DIRS="$ALL_PROGRAM_INSTALL_DIRS \\ @@ -26879,6 +26889,7 @@ do "programs/net/Makefile") CONFIG_FILES="$CONFIG_FILES programs/net/Makefile" ;; "programs/notepad/Makefile") CONFIG_FILES="$CONFIG_FILES programs/notepad/Makefile" ;; "programs/oleview/Makefile") CONFIG_FILES="$CONFIG_FILES programs/oleview/Makefile" ;; + "programs/paint/Makefile") CONFIG_FILES="$CONFIG_FILES programs/paint/Makefile" ;; "programs/progman/Makefile") CONFIG_FILES="$CONFIG_FILES programs/progman/Makefile" ;; "programs/reg/Makefile") CONFIG_FILES="$CONFIG_FILES programs/reg/Makefile" ;; "programs/regedit/Makefile") CONFIG_FILES="$CONFIG_FILES programs/regedit/Makefile" ;; diff --git a/configure.ac b/configure.ac index dac47c6..aa4b7d6 100644 --- a/configure.ac +++ b/configure.ac @@ -2101,6 +2101,7 @@ WINE_CONFIG_MAKEFILE([programs/msiexec/Makefile],[programs/Makeprog.rules],[prog WINE_CONFIG_MAKEFILE([programs/net/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/notepad/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/oleview/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) +WINE_CONFIG_MAKEFILE([programs/paint/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/progman/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/reg/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS]) WINE_CONFIG_MAKEFILE([programs/regedit/Makefile],[programs/Makeprog.rules],[programs],[ALL_PROGRAM_DIRS,ALL_PROGRAM_INSTALL_DIRS,ALL_PROGRAM_BIN_INSTALL_DIRS]) diff --git a/programs/paint/En.rc b/programs/paint/En.rc new file mode 100644 index 0000000..875180d --- /dev/null +++ b/programs/paint/En.rc @@ -0,0 +1,335 @@ +/* + * Paint (English resources) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +MAIN_MENU MENU +{ + POPUP "&File" + { + MENUITEM "&New\tCtrl+N", CMD_NEW + MENUITEM "&Open...\tCtrl+O", CMD_OPEN + MENUITEM "&Save\tCtrl+S", CMD_SAVE + MENUITEM "Save &As...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "Print Pre&view", CMD_PRINT_PREVIEW, GRAYED + MENUITEM "Page Set&up...", CMD_PAGE_SETUP, GRAYED + MENUITEM "&Print...\tCtrl+P", CMD_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Set As &Wallpaper (Tiled)", CMD_WALLPAPAER_TILED, GRAYED + MENUITEM "Set As Wa&llpaper (Centered)", CMD_WALLPAPAER_CENTERED, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", CMD_EXIT + } + POPUP "&Edit" + { + MENUITEM "&Undo\tCtrl+Z", CMD_UNDO, GRAYED + MENUITEM "&Repeat\tCtrl+Y", CMD_REPEAT, GRAYED + MENUITEM SEPARATOR + MENUITEM "Cu&t\tCtrl+X", CMD_CUT + MENUITEM "&Copy\tCtrl+C", CMD_COPY + MENUITEM "&Paste\tCtrl+V", CMD_PASTE + MENUITEM "&Delete\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "Select &All\tCtrl+A", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "C&opy To...", CMD_COPY_TO + MENUITEM "Paste &From...", CMD_PASTE_FROM + } + POPUP "&View" + { + MENUITEM "&Tool Box\tCtrl+T", CMD_TOOL_BOX, CHECKED + MENUITEM "&Color Box\tCtrl+L", CMD_COLOR_BOX, CHECKED + MENUITEM "&Status Bar", CMD_STATUS_BAR, CHECKED + MENUITEM "&Text Tool", CMD_TEXT_TOOL, CHECKED, GRAYED + MENUITEM SEPARATOR + POPUP "&Zoom" + { + MENUITEM "&Normal Size\tCtrl+PgUp", CMD_ZOOM_NORMAL + MENUITEM "&Large Size\tCtrl+PgDn", CMD_ZOOM_LARGE + MENUITEM "C&ustom", CMD_ZOOM_CUSTOM + MENUITEM SEPARATOR + MENUITEM "Show &Grid\tCtrl+G", CMD_SHOW_GRID + MENUITEM "Show T&humbnail", CMD_SHOW_THUMBNAIL, GRAYED + } + MENUITEM "&View bitmap\tCtrl+F", CMD_VIEW_BITMAP, GRAYED + } + POPUP "&Image" + { + MENUITEM "Flip/Rotate...\tCtrl+R", CMD_FLIP_ROTATE + MENUITEM "Stretch/Skew...\tCtrl+W", CMD_STRETCH_SKEW + MENUITEM "Invert Colors\tCtrl+I", CMD_INVERT_COLORS + MENUITEM "Attributes...\tCtrl+E", CMD_ATTRIBUTES + MENUITEM "Clear Image\tCtrl+Shift+N", CMD_CLEAR_IMAGE + MENUITEM "Draw Opaque", CMD_DRAW_OPAQUE, CHECKED, GRAYED + } + POPUP "&Color" + { + MENUITEM "&Edit color...", CMD_EDIT_COLOR + MENUITEM "&Get Colors...", CMD_GET_COLORS, GRAYED + MENUITEM "&Save Colors...", CMD_SAVE_COLORS, GRAYED + } + POPUP "&Help" + { + MENUITEM "&Contents", CMD_HELP_CONTENTS + MENUITEM "&Help on help", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "&About Paint", CMD_HELP_ABOUT_PAINT + } +} + +TEXT_MENU MENU +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +{ + POPUP "Text" + { + MENUITEM "Undo", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "Cut", CMD_CUT + MENUITEM "Copy", CMD_COPY + MENUITEM "Paste", CMD_PASTE + MENUITEM "Clear Selection", CMD_CLEAR_SELECTION + MENUITEM "Select All", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "Text Toolbar", CMD_TEXT_TOOL + } +} + +SELECTION_MENU MENU +{ + POPUP "Selection" + { + MENUITEM "Cu&t", CMD_CUT + MENUITEM "&Copy", CMD_COPY + MENUITEM "&Paste", CMD_PASTE + MENUITEM "C&lear Selection", CMD_CLEAR_SELECTION + MENUITEM "Select &All", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "C&opy To...", CMD_COPY_TO, GRAYED + MENUITEM "Paste &From...", CMD_PASTE_FROM + MENUITEM SEPARATOR + MENUITEM "Flip/&Rotate...", CMD_FLIP_ROTATE + MENUITEM "&Stretch/Skew...", CMD_STRETCH_SKEW + MENUITEM "&Invert Colors", CMD_INVERT_COLORS + } +} + +IDD_ZOOM DIALOG 0, 0, 200, 83 +STYLE DS_MODALFRAME | DS_CENTER | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Custom Zoom" +FONT 8, "MS Shell Dlg" +{ + LTEXT "Current zoom:", stc1, 13, 7, 47, 7 + RTEXT "", stc2, 61, 7, 49, 9 + GROUPBOX "Zoom to", grp1, 7, 20, 127, 57 + CONTROL "&100%", rad1, "BUTTON", BS_AUTORADIOBUTTON, 13, 38, 33, 10 + CONTROL "&200%", rad2, "BUTTON", BS_AUTORADIOBUTTON, 13, 57, 33, 10 + CONTROL "&400%", rad3, "BUTTON", BS_AUTORADIOBUTTON, 56, 38, 33, 10 + CONTROL "&600%", rad4, "BUTTON", BS_AUTORADIOBUTTON, 56, 57, 33, 10 + CONTROL "&800%", rad5, "BUTTON", BS_AUTORADIOBUTTON, 94, 38, 33, 10 + DEFPUSHBUTTON "OK", IDOK, 142, 7, 50, 14 + 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" +FONT 9, "MS Shell Dlg" +{ + GROUPBOX "Stretch", IDC_STATIC, 7, 7, 160, 67 + ICON 100, ico1, 15, 20, 21, 22 + LTEXT "&Horizontal:", IDC_STATIC, 47, 27, 46, 8 + EDITTEXT edt1, 95, 26, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 28, 8, 8 + ICON 101, ico2, 15, 45, 21, 22 + LTEXT "&Vertical:", IDC_STATIC, 47, 51, 46, 8 + EDITTEXT edt2, 95, 50, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 52, 8, 8 + GROUPBOX "Skew", IDC_STATIC, 7, 77, 160, 67, WS_DISABLED + ICON 102, ico3, 15, 90, 21, 22, WS_DISABLED + LTEXT "H&orizontal:", IDC_STATIC, 47, 97, 46, 8, WS_DISABLED + EDITTEXT edt3, 95, 96, 32, 12, ES_AUTOHSCROLL | WS_DISABLED + LTEXT "Degree", IDC_STATIC, 130, 98, 28, 8, WS_DISABLED + ICON 103, ico4, 15, 115, 21, 22, WS_DISABLED + LTEXT "V&ertical:", IDC_STATIC, 47, 121, 46, 8, WS_DISABLED + EDITTEXT edt4, 95, 120, 32, 12, ES_AUTOHSCROLL | WS_DISABLED + LTEXT "Degree", IDC_STATIC, 130, 122, 28, 8, WS_DISABLED + DEFPUSHBUTTON "OK", IDOK, 175, 7, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 175, 24, 50, 14 +} + +IDD_ATTRIBUTES DIALOG 0, 0, 234, 166 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "Attributes" +FONT 8, "MS Shell Dlg" +{ + LTEXT "", stc1, 13, 7, 144, 8 + LTEXT "", stc2, 13, 17, 144, 8 + LTEXT "&Width:", IDC_STATIC, 13, 34, 22, 10 + EDITTEXT edt1, 42, 32, 32, 12, ES_AUTOHSCROLL | WS_GROUP + LTEXT "&Height:", IDC_STATIC, 92, 34, 22, 10 + EDITTEXT edt2, 123, 32, 32, 12, ES_AUTOHSCROLL + GROUPBOX "Units", IDC_STATIC, 7, 48, 154, 28 + AUTORADIOBUTTON "&Inches", rad1, 13, 60, 34, 10, WS_GROUP | WS_DISABLED + AUTORADIOBUTTON "C&m", rad2, 63, 60, 27, 10, WS_DISABLED + AUTORADIOBUTTON "&Pixels", rad3, 105, 60, 30, 10 + GROUPBOX "Colors", IDC_STATIC, 7, 80, 154, 28 + AUTORADIOBUTTON "&Black and white", rad4, 13, 92, 64, 10, WS_GROUP | WS_DISABLED + AUTORADIOBUTTON "Co&lors", rad5, 105, 92, 34, 10 + GROUPBOX "Transparency", IDC_STATIC, 7, 112, 154, 48 + AUTOCHECKBOX "Use &Transparent background color", chx1, 13, 124, 126, 10, WS_DISABLED + PUSHBUTTON "Select &Color...", psh1, 33, 138, 73, 14, WS_DISABLED + CONTROL "", stc4, "STATIC", SS_SIMPLE | SS_SUNKEN | WS_DISABLED, 119, 138, 16, 14 + DEFPUSHBUTTON "OK", IDOK, 176, 7, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 176, 24, 50, 14 + PUSHBUTTON "&Default", psh2, 176, 41, 50, 14, WS_DISABLED +} + +STRINGTABLE DISCARDABLE +{ + STRING_PAINT, "Paint" + STRING_UNTITLED, "Untitled" + STRING_ALL_FILES, "All Files (*.*)" + STRING_BMP_FILES_BMP, "Bitmap Files (*.bmp)" + STRING_DOESNOTEXIST, "File '%s' does not exist.\n\nDo you want to create a new file?" + STRING_SAVECHANGE, "Save changes to %s?" + STRING_NOTFOUND, "'%s' could not be found." + STRING_MONOCROME_BM, "Monochrome Bitmap (*.bmp)" + STRING_16COLOR_BM, "16 Color Bitmap (*.bmp)" + STRING_256COLOR_BM, "256 Color Bitmap (*.bmp)" + STRING_24BIT_BM, "24-bit Bitmap (*.bmp)" + STRING_JPEG_FILES, "JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)" + STRING_GIF_FILES, "GIF (*.GIF)" + STRING_TIFF_FILES, "TIFF (*.TIF;*.TIFF)" + STRING_PNG_FILES, "PNG (*.PNG)" + STRING_ICON_FILES, "Icon Files (*.ico)" + STRING_PCX_FILES, "PCX Files (*.pcx)" + STRING_ALL_PICTURE, "All Picture Files" + STRING_PALETTE, "Palette (*.pal)" +} + +STRINGTABLE DISCARDABLE +{ + STRING_POLYSELECT, "Selects a free-form part of the picture to move, copy, or edit." + STRING_BOXSELECT, "Selects a rectangular part of the picture to move, copy, or edit." + STRING_ERASER, "Erases a portion of the picture, using the selected eraser shape." + STRING_FLOODFILL, "Fills an area with the current drawing color." + STRING_SPOIT, "Picks up a color from the picture for drawing." + STRING_MAGNIFIER, "Changes the magnification." + STRING_PENCIL, "Draws a free-form line one pixel wide." + STRING_BRUSH, "Draws using a brush with the selected shape and size." + STRING_AIRBRUSH, "Draws using an airbrush of the selected size." + STRING_TEXT, "Inserts text into the picture." + STRING_LINE, "Draws a straight line with the selected line width." + STRING_CURVE, "Draws a curved line with the selected line width." + STRING_BOX, "Draws a rectangle with the selected fill style." + STRING_POLYGON, "Draws a polygon with the selected fill style." + STRING_ELLIPSE, "Draws an ellipse with the selected fill style." + STRING_ROUNDRECT, "Draws a rounded rectangle with the selected fill style." +} + +STRINGTABLE DISCARDABLE +{ + STRING_NEW, "Creates a new document." + STRING_OPEN, "Opens an existing document." + STRING_SAVE, "Saves the active document." + STRING_SAVE_AS, "Saves the active document with a new name." + STRING_PRINT_PREVIEW, "Displays full pages." + STRING_PAGE_SETUP, "Changes the page layout." + STRING_PRINT, "Prints the active document and sets printing options." + STRING_EXIT, "Quits Paint." + + STRING_WALLPAPAER_TILED, "Tiles this bitmap as the desktop wallpaper." + STRING_WALLPAPAER_CENTERED, "Centers this bitmap as the desktop wallpaper." + + STRING_UNDO, "Undoes the last action." + STRING_CUT, "Cuts the selection and puts it on the Clipboard." + STRING_COPY, "Copies the selection and puts it on the Clipboard." + STRING_PASTE, "Inserts the contents of the Clipboard." + STRING_DELETE, "Deletes the selection." + STRING_SELECT_ALL, "Selects everything." + STRING_REPEAT, "Repeats the last action." + STRING_COPY_TO, "Copies the selection to a file." + STRING_PASTE_FROM, "Pastes a file into the selection." + + STRING_TOOL_BOX, "Shows or hides the tool box." + STRING_COLOR_BOX, "Shows or hides the color box." + STRING_STATUS_BAR, "Shows or hides the status bar." + STRING_TEXT_TOOL, "Shows or hides the text toolbar." + STRING_ZOOM_NORMAL, "Zooms the picture to 100%." + STRING_ZOOM_LARGE, "Zooms the picture to 400%." + STRING_ZOOM_CUSTOM, "Zooms the picture." + STRING_SHOW_GRID, "Shows or hides the grid." + STRING_VIEW_BITMAP, "Displays the entire picture." + STRING_SHOW_THUMBNAIL, "Shows or hides the thumbnail." + + STRING_FLIP_ROTATE, "Flips or rotates the picture or a selection." + STRING_STRETCH_SKEW, "Stretches or skews the picture or a selection." + STRING_INVERT_COLORS, "Inverts the colors of the picture or a selection." + STRING_ATTRIBUTES, "Changes the attributes of the picture." + STRING_CLEAR_IMAGE, "Clears the picture or selection." + STRING_DRAW_OPAQUE, "Makes the current selection either opaque or transparent." + STRING_CLEAR_SELECTION, "Clears the picture or selection." + + STRING_EDIT_COLOR, "Creates a new color." + STRING_GET_COLORS, "Uses a previously saved palette of colors." + STRING_SAVE_COLORS, "Saves the current palette of colors to a file." + + STRING_HELP_CONTENTS, "Opens Paint Help." + STRING_HELP_ON_HELP, "Displays instructions about how to use Help." + STRING_HELP_ABOUT_PAINT, "Displays program information, version number, and copyright." +} + +STRINGTABLE DISCARDABLE +{ + STRING_SIZE, "Changes the window size." + STRING_MOVE, "Changes the window position." + STRING_MINIMIZE, "Reduces the window to an icon." + STRING_MAXIMIZE, "Enlarges the window to full size." + STRING_NEXTWINDOW, "Switches to the next document window." + STRING_PREVWINDOW, "Switches to the previous document window." + STRING_CLOSE, "Closes the active window and asks if you want to save changes." + STRING_RESTORE, "Restores the window to normal size." + STRING_TASKLIST, "Activates the task list." +} + +STRINGTABLE DISCARDABLE +{ + STRING_READY, "Ready" + STRING_POSITIVE_INT, "Please enter a positive integer." + STRING_INVALID_BM, "Invalid bitmap file" + STRING_LOSS_COLOR, "Saving into this format may cause some loss of color information.\nDo you want to continue?" +} diff --git a/programs/paint/Ja.rc b/programs/paint/Ja.rc new file mode 100644 index 0000000..78c30f8 --- /dev/null +++ b/programs/paint/Ja.rc @@ -0,0 +1,334 @@ +/* + * Paint (Japanese resources) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +MAIN_MENU MENU +{ + POPUP "ファイル(&F)" + { + MENUITEM "新規(&N)\tCtrl+N", CMD_NEW + MENUITEM "開く(&O)...\tCtrl+O", CMD_OPEN + MENUITEM "上書き保存(&S)\tCtrl+S", CMD_SAVE + MENUITEM "名前を付けて保存(&A)...", CMD_SAVE_AS + MENUITEM SEPARATOR + MENUITEM "印刷プレビュー(&V)", CMD_PRINT_PREVIEW, GRAYED + MENUITEM "ページ設定(&U)...", CMD_PAGE_SETUP, GRAYED + MENUITEM "印刷(&P)...\tCtrl+P", CMD_PRINT, GRAYED + MENUITEM SEPARATOR + MENUITEM "背景に設定 (並べて表\示)(&B)", CMD_WALLPAPAER_TILED, GRAYED + MENUITEM "背景に設定 (中央に表\示)(&K)", CMD_WALLPAPAER_CENTERED, GRAYED + MENUITEM SEPARATOR + MENUITEM "ペイントの終了(&X)", CMD_EXIT + } + POPUP "編集(&E)" + { + MENUITEM "元に戻す(&U)\tCtrl+Z", CMD_UNDO, GRAYED + MENUITEM "繰り返し(&R)\tCtrl+Y", CMD_REPEAT, GRAYED + MENUITEM SEPARATOR + MENUITEM "切り取り(&T)\tCtrl+X", CMD_CUT + MENUITEM "コピー(&C)\tCtrl+C", CMD_COPY + MENUITEM "貼\り付け(&P)\tCtrl+V", CMD_PASTE + MENUITEM "削除(&D)\tDel", CMD_DELETE + MENUITEM SEPARATOR + MENUITEM "すべて選択(&A)\tCtrl+A", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "ファイルへコピー(&O)...", CMD_COPY_TO + MENUITEM "ファイルから貼\り付け(&F)...", CMD_PASTE_FROM + } + POPUP "表\示(&V)" + { + MENUITEM "ツール ボックス(&T)\tCtrl+T", CMD_TOOL_BOX, CHECKED + MENUITEM "カラー ボックス(&C)\tCtrl+L", CMD_COLOR_BOX, CHECKED + MENUITEM "ステータス バー(&S)", CMD_STATUS_BAR, CHECKED + MENUITEM "書式バー(&E)", CMD_TEXT_TOOL, CHECKED, GRAYED + MENUITEM SEPARATOR + POPUP "拡大(&Z)" + { + MENUITEM "標準に戻す(&N)\tCtrl+PgUp", CMD_ZOOM_NORMAL + MENUITEM "拡大する(&L)\tCtrl+PgDn", CMD_ZOOM_LARGE + MENUITEM "拡大率の指定(&U)", CMD_ZOOM_CUSTOM + MENUITEM SEPARATOR + MENUITEM "グリッドを表\示(&G)\tCtrl+G", CMD_SHOW_GRID + MENUITEM "実寸表\示(&H)", CMD_SHOW_THUMBNAIL, GRAYED + } + MENUITEM "ビットマップ表\示(&V)\tCtrl+F", CMD_VIEW_BITMAP, GRAYED + } + POPUP "変形(&I)" + { + MENUITEM "反転と回転(&F)...\tCtrl+R", CMD_FLIP_ROTATE + MENUITEM "伸縮と傾き(&S)...\tCtrl+W", CMD_STRETCH_SKEW + MENUITEM "色の反転(&I)\tCtrl+I", CMD_INVERT_COLORS + MENUITEM "キャンバスの色とサイズ(&A)...\tCtrl+E", CMD_ATTRIBUTES + MENUITEM "すべてクリア(&C)\tCtrl+Shift+N", CMD_CLEAR_IMAGE + MENUITEM "背景色を不透明にする(&D)", CMD_DRAW_OPAQUE, CHECKED, GRAYED + } + POPUP "色(&C)" + { + MENUITEM "色の編集(&E)...", CMD_EDIT_COLOR + MENUITEM "&Get Colors...", CMD_GET_COLORS, GRAYED + MENUITEM "&Save Colors...", CMD_SAVE_COLORS, GRAYED + } + POPUP "ヘルプ(&H)" + { + MENUITEM "&Contents", CMD_HELP_CONTENTS + MENUITEM "ヘルプの使い方(&H)", CMD_HELP_ON_HELP + MENUITEM SEPARATOR + MENUITEM "バージョン情報(&A)", CMD_HELP_ABOUT_PAINT + } +} + +TEXT_MENU MENU +{ + POPUP "テキスト" + { + MENUITEM "元に戻す", CMD_UNDO + MENUITEM SEPARATOR + MENUITEM "切り取り", CMD_CUT + MENUITEM "コピー", CMD_COPY + MENUITEM "貼\り付け", CMD_PASTE + MENUITEM "選択範囲のクリア", CMD_CLEAR_SELECTION + MENUITEM "すべて選択", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "書式バー", CMD_TEXT_TOOL + } +} + +SELECTION_MENU MENU +{ + POPUP "選択" + { + MENUITEM "切り取り(&T)", CMD_CUT + MENUITEM "コピー(&C)", CMD_COPY + MENUITEM "貼\り付け(&P)", CMD_PASTE + MENUITEM "選択範囲のクリア(&L)", CMD_CLEAR_SELECTION + MENUITEM "すべて選択(&A)", CMD_SELECT_ALL + MENUITEM SEPARATOR + MENUITEM "ファイルへコピー(&O)...", CMD_COPY_TO + MENUITEM "ファイルから貼\り付け(&F)...", CMD_PASTE_FROM + MENUITEM SEPARATOR + MENUITEM "反転と回転(&R)...", CMD_FLIP_ROTATE + MENUITEM "伸縮と傾き(&S)...", CMD_STRETCH_SKEW + MENUITEM "色の反転(&I)", CMD_INVERT_COLORS + } +} + +IDD_ZOOM DIALOG 16, 16, 200, 83 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "拡大率の指定" +FONT 9, "MS Shell Dlg" +{ + LTEXT "現在の拡大率:", stc1, 13, 7, 47, 9 + RTEXT "", stc2, 61, 7, 49, 9 + GROUPBOX "拡大率", grp1, 7, 20, 127, 57, WS_GROUP + AUTORADIOBUTTON "100%(&1)", rad1, 13, 38, 39, 10 + AUTORADIOBUTTON "200%(&2)", rad2, 13, 57, 38, 10 + AUTORADIOBUTTON "400%(&4)", rad3, 56, 38, 37, 10 + AUTORADIOBUTTON "600%(&6)", rad4, 56, 57, 37, 10 + AUTORADIOBUTTON "800%(&8)", rad5, 94, 38, 36, 10 + DEFPUSHBUTTON "OK", IDOK, 142, 7, 50, 14 + PUSHBUTTON "キャンセル", IDCANCEL, 142, 24, 50, 14 +} + +IDD_FLIP_ROTATE DIALOG 32, 16, 200, 107 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "反転と回転" +FONT 9, "MS Shell Dlg" +{ + GROUPBOX "反転と回転", grp1, 7, 7, 127, 94 + CONTROL "水平方向(&F)", rad1, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP, 13, 20, 77, 9 + CONTROL "垂直方向(&V)", rad2, "BUTTON", BS_AUTORADIOBUTTON, 13, 33, 72, 9 + CONTROL "角度を指定(&R)", rad3, "BUTTON", BS_AUTORADIOBUTTON, 13, 46, 72, 9 + CONTROL "90°(&9)", rad4, "BUTTON", BS_AUTORADIOBUTTON | WS_GROUP | WS_DISABLED, 49, 60, 40, 10 + CONTROL "180°(&1)", rad5, "BUTTON", BS_AUTORADIOBUTTON | WS_DISABLED, 49, 73, 43, 10 + CONTROL "270°(&2)", rad6, "BUTTON", BS_AUTORADIOBUTTON | WS_DISABLED, 49, 86, 43, 10 + DEFPUSHBUTTON "OK", IDOK, 142, 7, 50, 14 + PUSHBUTTON "キャンセル", IDCANCEL, 142, 24, 50, 14 +} + +IDD_STRETCH_SKEW DIALOG 18, 48, 232, 150 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "伸縮と傾き" +FONT 9, "MS Shell Dlg" +{ + GROUPBOX "伸縮", IDC_STATIC, 7, 7, 160, 67, WS_GROUP + ICON 100, ico1, 15, 20, 21, 22 + LTEXT "水平方向(&H):", IDC_STATIC, 47, 27, 46, 8 + EDITTEXT edt1, 95, 26, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 28, 8, 8 + ICON 101, ico2, 15, 45, 21, 22 + LTEXT "垂直方向(&V):", IDC_STATIC, 47, 51, 46, 8 + EDITTEXT edt2, 95, 50, 32, 12, ES_AUTOHSCROLL + LTEXT "%", IDC_STATIC, 130, 52, 8, 8 + GROUPBOX "傾き", IDC_STATIC, 7, 77, 160, 67, WS_GROUP + ICON 102, ico3, 15, 90, 21, 22 + LTEXT "水平方向(&O):", IDC_STATIC, 47, 97, 46, 8 + EDITTEXT edt3, 95, 96, 32, 12, ES_AUTOHSCROLL + LTEXT "度", IDC_STATIC, 130, 98, 28, 8 + ICON 103, ico4, 15, 115, 21, 22 + LTEXT "垂直方向(&E):", IDC_STATIC, 47, 121, 46, 8 + EDITTEXT edt4, 95, 120, 32, 12, ES_AUTOHSCROLL + LTEXT "度", IDC_STATIC, 130, 122, 28, 8 + DEFPUSHBUTTON "OK", IDOK, 175, 7, 50, 14 + PUSHBUTTON "キャンセル", IDCANCEL, 175, 24, 50, 14 +} + +IDD_ATTRIBUTES DIALOG 0, 0, 234, 166 +STYLE DS_MODALFRAME | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "キャンバスの色とサイズ" +FONT 9, "MS Shell Dlg" +{ + LTEXT "", stc1, 13, 7, 144, 8 + LTEXT "", stc2, 13, 17, 144, 8 + LTEXT "幅(&W):", IDC_STATIC, 13, 44, 22, 10 + EDITTEXT edt1, 42, 42, 32, 12, ES_AUTOHSCROLL + LTEXT "高さ(&H):", IDC_STATIC, 92, 44, 28, 10 + EDITTEXT edt2, 123, 42, 32, 12, ES_AUTOHSCROLL + GROUPBOX "単位", IDC_STATIC, 7, 58, 154, 28, WS_GROUP + AUTORADIOBUTTON "インチ(&I)", rad1, 13, 70, 35, 10 + AUTORADIOBUTTON "cm(&M)", rad2, 63, 70, 34, 10 + AUTORADIOBUTTON "ピクセル(&P)", rad3, 105, 70, 46, 10 + GROUPBOX "色", IDC_STATIC, 7, 90, 154, 28, WS_GROUP + AUTORADIOBUTTON "白黒(&B)", rad4, 13, 102, 64, 10 + AUTORADIOBUTTON "カラー(&L)", rad5, 105, 102, 45, 10 + GROUPBOX "透明色", IDC_STATIC, 7, 122, 154, 48, WS_GROUP + AUTOCHECKBOX "背景色を透明する(&T)", chx1, 13, 134, 126, 10 + PUSHBUTTON "色の選択(&C)...", psh1, 33, 148, 73, 14 + CONTROL "", stc4, "STATIC", NOT WS_GROUP | SS_GRAYFRAME | SS_SUNKEN, 119, 148, 16, 14 + DEFPUSHBUTTON "OK", IDOK, 176, 7, 50, 14 + PUSHBUTTON "キャンセル", IDCANCEL, 176, 24, 50, 14 + PUSHBUTTON "既定値(&D)", psh2, 176, 41, 50, 14 +} + +STRINGTABLE DISCARDABLE +{ + STRING_PAINT, "ペイント" + STRING_UNTITLED, "無題" + STRING_ALL_FILES, "すべてのファイル (*.*)" + STRING_BMP_FILES_BMP, "ビットマップ ファイル (*.bmp)" + STRING_DOESNOTEXIST, "ファイル '%s' は存在しません。\n\n新しいファイルを作成しますか?" + STRING_SAVECHANGE, "%s への変更を保存しますか?" + STRING_NOTFOUND, "'%s'は見つかりません。" + STRING_MONOCROME_BM, "白黒ビットマップ (*.bmp)" + STRING_16COLOR_BM, "16色ビットマップ (*.bmp)" + STRING_256COLOR_BM, "256色ビットマップ (*.bmp)" + STRING_24BIT_BM, "24ビット ビットマップ (*.bmp)" + STRING_JPEG_FILES, "JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)" + STRING_GIF_FILES, "GIF (*.GIF)" + STRING_TIFF_FILES, "TIFF (*.TIF;*.TIFF)" + STRING_PNG_FILES, "PNG (*.PNG)" + STRING_ICON_FILES, "アイコン ファイル (*.ico)" + STRING_PCX_FILES, "PCX ファイル (*.pcx)" + STRING_ALL_PICTURE, "すべてのピクチャ ファイル" + STRING_PALETTE, "パレット (*.pal)" +} + +STRINGTABLE DISCARDABLE +{ + STRING_POLYSELECT, "絵の一部を選択して、移動、コピー、または編集します。" + STRING_BOXSELECT, "絵の一部を四角形で選択して、移動、コピー、または編集します。" + STRING_ERASER, "選択された消しゴムで、絵の一部を消します。" + STRING_FLOODFILL, "現在の色で領域を塗りつぶします。" + STRING_SPOIT, "絵の中から、色を選択します。" + STRING_MAGNIFIER, "拡大または縮小します。" + STRING_PENCIL, "1 ピクセル幅の線を引きます。" + STRING_BRUSH, "選択された形や幅のブラシで描きます。" + STRING_AIRBRUSH, "選択されたサイズのエアブラシで描きます。" + STRING_TEXT, "絵の中にテキストを貼\り付けます。" + STRING_LINE, "選択された太さの線で、直線を引きます。" + STRING_CURVE, "選択された太さの線で、曲線を引きます。" + STRING_BOX, "選択された塗りつぶし形式で、四角形を描きます。" + STRING_POLYGON, "選択された塗りつぶし形式で、多角形を描きます。" + STRING_ELLIPSE, "選択された塗りつぶし形式で、楕円を描きます。" + STRING_ROUNDRECT, "選択された塗りつぶし形式で、角の丸い四角形を描きます。" +} + +STRINGTABLE DISCARDABLE +{ + STRING_NEW, "新しいドキュメントを作成します。" + STRING_OPEN, "既存のドキュメントを開きます。" + STRING_SAVE, "現在のドキュメントを保存します。" + STRING_SAVE_AS, "現在のドキュメントを新しい名前で保存します。" + STRING_PRINT_PREVIEW, "ページ全体を表\示します。" + STRING_PAGE_SETUP, "ページ レイアウトの設定を変更します。" + STRING_PRINT, "印刷オプションを設定し、現在のファイルを印刷します。" + STRING_EXIT, "ペイントを終了します。" + + STRING_WALLPAPAER_TILED, "このビットマップをデスクトップの背景として使用し、並べて表\示します。" + STRING_WALLPAPAER_CENTERED, "このビットマップをデスクトップの背景として使用し、中央に表\示します。" + + STRING_UNDO, "直前に行った操作を取り消します。" + STRING_CUT, "選択範囲を切り取ってクリップボードに移動します。" + STRING_COPY, "選択範囲をクリップボードにコピーします。" + STRING_PASTE, "クリップボードの内容を挿入します。" + STRING_DELETE, "選択範囲を削除します。" + STRING_SELECT_ALL, "すべての範囲を選択します。" + STRING_REPEAT, "取り消した操作をやり直します。" + STRING_COPY_TO, "選択範囲をファイルにコピーします。" + STRING_PASTE_FROM, "選択範囲にファイルを貼\り付けます。" + + STRING_TOOL_BOX, "ツール ボックスの表\示/非表\示を切り替えます。" + STRING_COLOR_BOX, "カラー ボックスの表\示/非表\示を切り替えます。" + STRING_STATUS_BAR, "ステータス バーの表\示/非表\示を切り替えます。" + STRING_TEXT_TOOL, "書式バーの表\示/非表\示を切り替えます。" + STRING_ZOOM_NORMAL, "絵を 100% に戻します。" + STRING_ZOOM_LARGE, "絵を 4 倍に拡大します。" + STRING_ZOOM_CUSTOM, "絵を拡大します。" + STRING_SHOW_GRID, "グリッドの表\示/非表\示を切り替えます。" + STRING_VIEW_BITMAP, "絵を画面全体に表\示します。" + STRING_SHOW_THUMBNAIL, "実寸の表\示/非表\示を切り替えます。" + + STRING_FLIP_ROTATE, "絵または選択範囲を反転/回転させます。" + STRING_STRETCH_SKEW, "絵または選択範囲を伸縮/傾斜させます。" + STRING_INVERT_COLORS, "絵または選択範囲の色を反転させます。" + STRING_ATTRIBUTES, "キャンバスの色とサイズを変更します。" + STRING_CLEAR_IMAGE, "絵または選択範囲をクリアします。" + STRING_DRAW_OPAQUE, "選択範囲の背景色を不透明または透明にします。" + STRING_CLEAR_SELECTION, "絵または選択範囲をクリアします。" + + STRING_EDIT_COLOR, "新しい色を作成します。" + STRING_GET_COLORS, "以前に保存したパレットを使用します。" + STRING_SAVE_COLORS, "現在のパレットをファイルに保存します。" + + STRING_HELP_CONTENTS, "ペイントのヘルプを開きます。" + STRING_HELP_ON_HELP, "ヘルプの使い方を表\示します。" + STRING_HELP_ABOUT_PAINT, "プログラム情報、バージョン、著作権を表\示します。" +} + +STRINGTABLE DISCARDABLE +{ + STRING_SIZE, "このウィンドウのサイズを変更します。" + STRING_MOVE, "このウィンドウを画面の別の位置に移動します。" + STRING_MINIMIZE, "このウィンドウを最小化します。" + STRING_MAXIMIZE, "このウィンドウを画面いっぱいに拡大します。" + STRING_NEXTWINDOW, "次のドキュメント ウィンドウに切り替えます。" + STRING_PREVWINDOW, "前のドキュメント ウィンドウに切り替えます。" + STRING_CLOSE, "変更の保存を確認してから、アクティブ ウィンドウを閉じます。" + STRING_RESTORE, "ウィンドウを通常の大きさに戻します。" + STRING_TASKLIST, "タスク リストを表\示します。" +} + +STRINGTABLE DISCARDABLE +{ + STRING_READY, "準備完了" + STRING_POSITIVE_INT, "正の整数を入力してください。" + STRING_INVALID_BM, "不正なビットマップです。" + STRING_LOSS_COLOR, "この形式に保存すると、色情報の一部が失われる可能\性があります。\n続行しますか?" +} diff --git a/programs/paint/Makefile.in b/programs/paint/Makefile.in new file mode 100644 index 0000000..52694cc --- /dev/null +++ b/programs/paint/Makefile.in @@ -0,0 +1,24 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +MODULE = paint.exe +APPMODE = -mwindows -mno-cygwin +IMPORTS = comdlg32 shell32 shlwapi user32 gdi32 advapi32 kernel32 +EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt +MODCFLAGS = @BUILTINFLAG@ +EXTRADEFS = -DNO_LIBWINE_PORT + +C_SRCS = \ + bitmap.c \ + canvas.c \ + main.c \ + paint.c + +RC_SRCS = rsrc.rc + +SVG_SRCS = paint.svg + +@MAKE_PROG_RULES@ + +@DEPENDENCIES@ # everything below this line is overwritten by make depend diff --git a/programs/paint/airbrush.bmp b/programs/paint/airbrush.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8b1ff48922a58e8a38b9bd2ba1abfdabb35b3460 GIT binary patch literal 670 zcmZ?royWug26jMF1B!isG$Rm#Kmt(y2pWFD-`0)>(~o11gXOo!8-wZ1e|Lh#zx)3O z^B>>&4W|3}`oZ)+;q74h`NVKAeYqQA-&ZGpF#p*7crg9P7NY-;A%y<75<*kU|HPZ~ z9qgX}|2v?xB82{@e;*tV|4#1*g$w`xMejkh_z#qpb|Ns9ZICxlK?F|M% z(>xd$8d?|_9fcSensgZ$U1Av+R_tP6^eSOsSe?PZ7&(D~VSxezL-YYWrlCp!-9RKb r4^-C<#LWNy|6~0B{}03e|385E1CadzDE5IJi1~q79*FIM>WBjXE`x%_ literal 0 HcmV?d00001 diff --git a/programs/paint/bdiagon.cur b/programs/paint/bdiagon.cur new file mode 100644 index 0000000000000000000000000000000000000000..570cbbb571cc62fb2eca1f4fa2655338c06b5936 GIT binary patch literal 326 zcma)$F%E)26hvpy-j14t#?m98p`z9ca0L&bMhXg#VCgXl<6GE-66WXa>`Z<(D`g5Q z3hBU{f|N@-0+lKV%%o& literal 0 HcmV?d00001 diff --git a/programs/paint/bitmap.c b/programs/paint/bitmap.c new file mode 100644 index 0000000..4709d82 --- /dev/null +++ b/programs/paint/bitmap.c @@ -0,0 +1,664 @@ +/* + * Paint (bitmap.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include "resource.h" + +#define WIDTHBYTES(x) (((x) + 31) / 32 * 4) + +typedef struct tagBITMAPINFOEX +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[256]; +} BITMAPINFOEX, FAR * LPBITMAPINFOEX; + +HBITMAP BM_Load(LPCWSTR pszFileName) +{ + HANDLE hFile; + BITMAPFILEHEADER bf; + BITMAPINFOEX bi; + DWORD cb, cbImage; + DWORD dwError; + LPVOID pBits, pBits2; + HDC hDC, hMemDC; + HBITMAP hbm; +#ifndef LR_LOADREALSIZE +#define LR_LOADREALSIZE 128 +#endif + hbm = (HBITMAP)LoadImageW(NULL, pszFileName, IMAGE_BITMAP, 0, 0, + LR_LOADFROMFILE | LR_LOADREALSIZE | LR_CREATEDIBSECTION); + if (hbm != NULL) + return hbm; + + hFile = CreateFileW(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile == INVALID_HANDLE_VALUE) + return NULL; + + if (!ReadFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &cb, NULL)) + { + dwError = GetLastError(); + CloseHandle(NULL); + SetLastError(dwError); + return NULL; + } + + pBits = NULL; + dwError = 0; + if (bf.bfType == 0x4D42 && bf.bfReserved1 == 0 && bf.bfReserved2 == 0 && + bf.bfSize > bf.bfOffBits && bf.bfOffBits > sizeof(BITMAPFILEHEADER) && + bf.bfOffBits <= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOEX)) + { + cbImage = bf.bfSize - bf.bfOffBits; + pBits = HeapAlloc(GetProcessHeap(), 0, cbImage); + if (pBits != NULL) + { + if (ReadFile(hFile, &bi, bf.bfOffBits - + sizeof(BITMAPFILEHEADER), &cb, NULL) && + ReadFile(hFile, pBits, cbImage, &cb, NULL)) + { + ; + } + else + { + dwError = GetLastError(); + HeapFree(GetProcessHeap(), 0, pBits); + pBits = NULL; + } + } + else + dwError = GetLastError(); + } + else + dwError = -STRING_INVALID_BM; + + CloseHandle(hFile); + + if (pBits == NULL) + { + SetLastError(dwError); + return NULL; + } + + hbm = NULL; + dwError = 0; + hDC = GetDC(NULL); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbm = CreateDIBSection(hMemDC, (BITMAPINFO*)&bi, DIB_RGB_COLORS, + &pBits2, NULL, 0); + if (hbm != NULL) + { + if (SetDIBits(hMemDC, hbm, 0, abs(bi.bmiHeader.biHeight), + pBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) + { + ; + } + else + { + dwError = GetLastError(); + DeleteObject(hbm); + hbm = NULL; + } + } + else + dwError = GetLastError(); + + DeleteDC(hMemDC); + } + else + dwError = GetLastError(); + + ReleaseDC(NULL, hDC); + } + else + dwError = GetLastError(); + + HeapFree(GetProcessHeap(), 0, pBits); + SetLastError(dwError); + + return hbm; +} + +BOOL BM_Save(LPCWSTR pszFileName, HBITMAP hbm) +{ + BOOL f; + DWORD dwError; + BITMAPFILEHEADER bf; + BITMAPINFOEX bi; + DWORD cb; + DWORD cColors, cbColors; + HDC hDC; + HANDLE hFile; + LPVOID pBits; + BITMAP bm; + BITMAPINFOHEADER *pbmih = &bi.bmiHeader; + + if (!GetObject(hbm, sizeof(BITMAP), &bm)) + return FALSE; + + ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER)); + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biWidth = bm.bmWidth; + pbmih->biHeight = bm.bmHeight; + pbmih->biPlanes = 1; + pbmih->biBitCount = bm.bmBitsPixel; + pbmih->biCompression = BI_RGB; + pbmih->biSizeImage = bm.bmWidthBytes * bm.bmHeight; + + if (bm.bmBitsPixel < 16) + cColors = 1 << bm.bmBitsPixel; + else + cColors = 0; + cbColors = cColors * sizeof(RGBQUAD); + + bf.bfType = 0x4d42; + bf.bfReserved1 = 0; + bf.bfReserved2 = 0; + cb = sizeof(BITMAPFILEHEADER) + pbmih->biSize + cbColors; + bf.bfOffBits = cb; + bf.bfSize = cb + pbmih->biSizeImage; + + pBits = HeapAlloc(GetProcessHeap(), 0, pbmih->biSizeImage); + if (pBits == NULL) + return FALSE; + + f = FALSE; + dwError = 0; + hDC = GetDC(NULL); + if (hDC != NULL) + { + if (GetDIBits(hDC, hbm, 0, bm.bmHeight, pBits, (BITMAPINFO*)&bi, + DIB_RGB_COLORS)) + { + hFile = CreateFileW(pszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | + FILE_FLAG_WRITE_THROUGH, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + f = WriteFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &cb, NULL) && + WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &cb, NULL) && + WriteFile(hFile, &bi.bmiColors, cbColors, &cb, NULL) && + WriteFile(hFile, pBits, pbmih->biSizeImage, &cb, NULL); + if (!f) + dwError = GetLastError(); + CloseHandle(hFile); + + if (!f) + DeleteFileW(pszFileName); + } + else + dwError = GetLastError(); + } + else + dwError = GetLastError(); + ReleaseDC(NULL, hDC); + } + else + dwError = GetLastError(); + + HeapFree(GetProcessHeap(), 0, pBits); + SetLastError(dwError); + return f; +} + +HBITMAP BM_Create(SIZE siz) +{ + BITMAPINFO bi; + VOID *pBits; + ZeroMemory(&bi.bmiHeader, sizeof(BITMAPINFOHEADER)); + bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bi.bmiHeader.biWidth = siz.cx; + bi.bmiHeader.biHeight = -siz.cy; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 24; + bi.bmiHeader.biCompression = BI_RGB; + return CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pBits, NULL, 0); +} + +HBITMAP BM_CreateResized(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + RECT rc; + + hbmNew = BM_Create(sizNew); + if (hbmNew != NULL) + { + dwError = 0; + hDC = GetDC(hWnd); + hdcMem1 = CreateCompatibleDC(hDC); + if (hdcMem1 != NULL) + { + hbmOld1 = SelectObject(hdcMem1, hbmNew); + + rc.left = rc.top = 0; + rc.right = sizNew.cx; + rc.bottom = sizNew.cy; + FillRect(hdcMem1, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hdcMem2 = CreateCompatibleDC(hDC); + if (hdcMem2 != NULL) + { + hbmOld2 = SelectObject(hdcMem2, hbm); + BitBlt(hdcMem1, 0, 0, siz.cx, siz.cy, + hdcMem2, 0, 0, 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_CreateStretched(HWND hWnd, SIZE sizNew, HBITMAP hbm, SIZE siz) +{ + DWORD dwError; + HDC hDC, hdcMem1, hdcMem2; + HBITMAP hbmNew, hbmOld1, hbmOld2; + + hbmNew = BM_Create(sizNew); + 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); + SetStretchBltMode(hdcMem1, COLORONCOLOR); + StretchBlt(hdcMem1, 0, 0, sizNew.cx, sizNew.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_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); +} + +HGLOBAL BM_Pack(HBITMAP hbm) +{ + BOOL f; + DWORD dwError; + HGLOBAL hPack; + BITMAPINFOEX bi; + DWORD cb, cbPack, cColors, cbColors; + HDC hDC; + LPVOID pPack, pBits; + BITMAP bm; + BITMAPINFOHEADER *pbmih = &bi.bmiHeader; + + if (!GetObject(hbm, sizeof(BITMAP), &bm)) + return FALSE; + + ZeroMemory(pbmih, sizeof(BITMAPINFOHEADER)); + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biWidth = bm.bmWidth; + pbmih->biHeight = bm.bmHeight; + pbmih->biPlanes = 1; + pbmih->biBitCount = bm.bmBitsPixel; + pbmih->biCompression = BI_RGB; + pbmih->biSizeImage = bm.bmWidthBytes * bm.bmHeight; + + if (bm.bmBitsPixel < 16) + cColors = 1 << bm.bmBitsPixel; + else + cColors = 0; + cbColors = cColors * sizeof(RGBQUAD); + + cb = pbmih->biSize + cbColors; + cbPack = cb + pbmih->biSizeImage; + + hPack = GlobalAlloc(GMEM_DDESHARE|GHND, cbPack); + pPack = GlobalLock(hPack); + if (pPack == NULL) + return NULL; + + f = FALSE; + dwError = 0; + pBits = HeapAlloc(GetProcessHeap(), 0, pbmih->biSizeImage); + if (pBits != NULL) + { + hDC = GetDC(NULL); + if (hDC != NULL) + { + if (GetDIBits(hDC, hbm, 0, bm.bmHeight, pBits, (BITMAPINFO*)&bi, + DIB_RGB_COLORS)) + { + CopyMemory(pPack, &bi, sizeof(BITMAPINFOHEADER)); + CopyMemory((LPBYTE)pPack + sizeof(BITMAPINFOHEADER), &bi.bmiColors, cbColors); + CopyMemory((LPBYTE)pPack + cb, pBits, pbmih->biSizeImage); + f = TRUE; + } + else + dwError = GetLastError(); + ReleaseDC(NULL, hDC); + } + else + dwError = GetLastError(); + + HeapFree(GetProcessHeap(), 0, pBits); + } + + GlobalUnlock(hPack); + if (!f) + { + GlobalFree(hPack); + hPack = NULL; + } + + SetLastError(dwError); + return hPack; +} + +HBITMAP BM_Unpack(HGLOBAL hPack) +{ + HBITMAP hbm; + DWORD dwError; + BITMAPINFOEX bi; + DWORD cb, cColors, cbColors; + HDC hDC, hMemDC; + LPVOID pPack, pBits; + BITMAPINFOHEADER *pbmih = &bi.bmiHeader; + + pPack = GlobalLock(hPack); + if (pPack == NULL) + return NULL; + + CopyMemory(pbmih, pPack, sizeof(BITMAPINFOHEADER)); + pbmih->biSizeImage = WIDTHBYTES(pbmih->biWidth * pbmih->biBitCount) * + abs(pbmih->biHeight); + if (pbmih->biClrUsed != 0) + cColors = pbmih->biClrUsed; + else if (pbmih->biBitCount < 16) + cColors = 1 << pbmih->biBitCount; + else + cColors = 0; + + cbColors = cColors * sizeof(RGBQUAD); + cb = pbmih->biSize + cbColors; + CopyMemory(&bi, pPack, cb); + + hbm = NULL; + dwError = 0; + hDC = GetDC(NULL); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbm = CreateDIBSection(hMemDC, (BITMAPINFO*)&bi, DIB_RGB_COLORS, + &pBits, NULL, 0); + if (hbm != NULL) + { + CopyMemory(pBits, (LPBYTE)pPack + cb, pbmih->biSizeImage); + + if (SetDIBits(hMemDC, hbm, 0, abs(bi.bmiHeader.biHeight), + pBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS)) + { + ; + } + else + { + dwError = GetLastError(); + DeleteObject(hbm); + hbm = NULL; + } + } + else + dwError = GetLastError(); + + DeleteDC(hMemDC); + } + else + dwError = GetLastError(); + } + else + dwError = GetLastError(); + + GlobalUnlock(hPack); + SetLastError(dwError); + return hbm; +} diff --git a/programs/paint/brush.bmp b/programs/paint/brush.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d4c7ec0861f0e58238e0fa1aa9778b49933b36e5 GIT binary patch literal 670 zcmcJL%?-jZ3`PTs^vV=O;#_uM6K}#Q5$Yh#tw(w*QU&JoALRlPLQNGvC3ftm9**a2 z(zQq2`EJ1tK3ONv>)|ahbHYYUpIJOl#s|+@f9FX#^OXzUPuw$sIO%{KA*XeToxU)2}wxf8j;v)n;MF|B`c1e4<|T*7Uo1|B-A?&4c;n?!^M1k?cO| I<=HP@PnUvhDF6Tf literal 0 HcmV?d00001 diff --git a/programs/paint/canvas.c b/programs/paint/canvas.c new file mode 100644 index 0000000..c47fc23 --- /dev/null +++ b/programs/paint/canvas.c @@ -0,0 +1,2614 @@ +/* + * Paint (canvas.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +static const WCHAR empty[] = {0}; + +VOID CanvasToImage(POINT *ppt) +{ + ppt->x = (ppt->x + Globals.xScrollPos - 4) / Globals.nZoom; + ppt->y = (ppt->y + Globals.yScrollPos - 4) / Globals.nZoom; +} + +VOID ImageToCanvas(POINT *ppt) +{ + ppt->x = ppt->x * Globals.nZoom + 4 - Globals.xScrollPos; + ppt->y = ppt->y * Globals.nZoom + 4 - Globals.yScrollPos; +} + +VOID ImageToCanvas2(POINT *ppt) +{ + ppt->x = ppt->x * Globals.nZoom + 4; + ppt->y = ppt->y * Globals.nZoom + 4; +} + +VOID NormalizeRect(RECT *prc) +{ + LONG n; + + if (prc->left > prc->right) + { + n = prc->left; + prc->left = prc->right; + prc->right = n; + } + if (prc->top > prc->bottom) + { + n = prc->top; + prc->top = prc->bottom; + prc->bottom = n; + } +} + +INT sgn(INT x) +{ + if (x > 0) return 1; + if (x < 0) return -1; + return 0; +} + +VOID Regularize(POINT pt0, LPPOINT ppt1) +{ + INT cx = abs(ppt1->x - pt0.x); + INT cy = abs(ppt1->y - pt0.y); + INT m = min(cx, cy); + ppt1->x = pt0.x + sgn(ppt1->x - pt0.x) * m; + ppt1->y = pt0.y + sgn(ppt1->y - pt0.y) * m; +} + +HBITMAP Selection_CreateBitmap(VOID) +{ + HDC hDC, hMemDC1, hMemDC2; + HGDIOBJ hbmOld1, hbmOld2; + HBITMAP hbmNew; + SIZE siz; + + hbmNew = NULL; + hDC = GetDC(Globals.hCanvasWnd); + if (hDC != NULL) + { + hMemDC1 = CreateCompatibleDC(hDC); + if (hMemDC1 != NULL) + { + hbmOld1 = SelectObject(hMemDC1, Globals.hbmImage); + hMemDC2 = CreateCompatibleDC(hDC); + if (hMemDC2 != NULL) + { + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_Create(siz); + if (hbmNew != NULL) + { + hbmOld2 = SelectObject(hMemDC2, hbmNew); + BitBlt(hMemDC2, 0, 0, siz.cx, siz.cy, + hMemDC1, Globals.pt0.x, Globals.pt0.y, + SRCCOPY); + SelectObject(hMemDC1, hbmOld2); + } + DeleteDC(hMemDC2); + } + SelectObject(hMemDC1, hbmOld1); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + } + + return hbmNew; +} + +VOID PrepareForUndo(VOID) +{ + Globals.fCanUndo = TRUE; + if (Globals.hbmImageUndo != NULL) + DeleteObject(Globals.hbmImageUndo); + Globals.hbmImageUndo = BM_Copy(Globals.hbmImage); + Globals.sizImageUndo = Globals.sizImage; +} + +VOID Selection_TakeOff(VOID) +{ + HDC hDC, hMemDC1; + HGDIOBJ hbmOld1; + HBITMAP hbmNew; + HBRUSH hbr; + + if (Globals.fSelect && Globals.hbmSelect == NULL) + { + hbmNew = Selection_CreateBitmap(); + hDC = GetDC(Globals.hCanvasWnd); + if (hDC != NULL) + { + hMemDC1 = CreateCompatibleDC(hDC); + if (hMemDC1 != NULL) + { + hbmOld1 = SelectObject(hMemDC1, Globals.hbmImage); + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hMemDC1, (RECT*)&Globals.pt0, hbr); + DeleteObject(hbr); + SelectObject(hMemDC1, hbmOld1); + DeleteDC(hMemDC1); + Globals.fModified = TRUE; + } + ReleaseDC(Globals.hCanvasWnd, hDC); + } + Globals.hbmSelect = hbmNew; + } +} + +VOID Selection_Land(VOID) +{ + HDC hDC, hMemDC1, hMemDC2; + HGDIOBJ hbmOld1, hbmOld2; + + if (Globals.fSelect && Globals.hbmSelect) + { + hDC = GetDC(Globals.hCanvasWnd); + hMemDC1 = CreateCompatibleDC(hDC); + if (hMemDC1 != NULL) + { + hbmOld1 = SelectObject(hMemDC1, Globals.hbmImage); + hMemDC2 = CreateCompatibleDC(hDC); + if (hMemDC2 != NULL) + { + hbmOld2 = SelectObject(hMemDC2, Globals.hbmSelect); + BitBlt(hMemDC1, Globals.pt0.x, Globals.pt0.y, + Globals.pt1.x - Globals.pt0.x, + Globals.pt1.y - Globals.pt0.y, + hMemDC2, 0, 0, SRCCOPY); + SelectObject(hMemDC1, hbmOld2); + DeleteDC(hMemDC2); + } + SelectObject(hMemDC1, hbmOld1); + DeleteDC(hMemDC1); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + } + Globals.fSelect = FALSE; +} + +VOID DrawBrush(HDC hMemDC, INT x, INT y, COLORREF rgb) +{ + switch (Globals.iBrushType) + { + case 0: + Ellipse(hMemDC, x - 3, y - 3, x + 4, y + 4); + break; + + case 1: + Ellipse(hMemDC, x - 2, y - 2, x + 2, y + 2); + break; + + case 2: + SetPixel(hMemDC, x, y, rgb); + break; + + case 3: + Rectangle(hMemDC, x - 4, y - 4, x + 4, y + 4); + break; + + case 4: + Rectangle(hMemDC, x - 2, y - 2, x + 3, y + 3); + break; + + case 5: + Rectangle(hMemDC, x - 1, y - 1, x + 1, y + 1); + break; + + case 6: + MoveToEx(hMemDC, x + 4, y - 4, NULL); + LineTo(hMemDC, x - 4, y + 4); + break; + + case 7: + MoveToEx(hMemDC, x + 2, y - 2, NULL); + LineTo(hMemDC, x - 3, y + 3); + break; + + case 8: + MoveToEx(hMemDC, x + 1, y - 1, NULL); + LineTo(hMemDC, x - 1, y + 1); + break; + + case 9: + MoveToEx(hMemDC, x - 4, y - 4, NULL); + LineTo(hMemDC, x + 4, y + 4); + break; + + case 10: + MoveToEx(hMemDC, x - 2, y - 2, NULL); + LineTo(hMemDC, x + 3, y + 3); + break; + + case 11: + MoveToEx(hMemDC, x - 1, y - 1, NULL); + LineTo(hMemDC, x + 1, y + 1); + break; + } +} + +VOID CALLBACK ForeBrushDDAProc(INT x, INT y, LPARAM lParam) +{ + HBRUSH hbr; + HPEN hPen; + HGDIOBJ hbrOld, hpenOld; + HDC hMemDC = (HDC)lParam; + hPen = CreatePen(PS_SOLID, 0, Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbFore); + hpenOld = SelectObject(hMemDC, hPen); + hbrOld = SelectObject(hMemDC, hbr); + DrawBrush(hMemDC, x, y, Globals.rgbFore); + SelectObject(hMemDC, hpenOld); + SelectObject(hMemDC, hbrOld); + DeleteObject(hPen); + DeleteObject(hbr); +} + +VOID CALLBACK BackBrushDDAProc(INT x, INT y, LPARAM lParam) +{ + HBRUSH hbr; + HPEN hPen; + HGDIOBJ hbrOld, hpenOld; + HDC hMemDC = (HDC)lParam; + hPen = CreatePen(PS_SOLID, 0, Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbBack); + hpenOld = SelectObject(hMemDC, hPen); + hbrOld = SelectObject(hMemDC, hbr); + DrawBrush(hMemDC, x, y, Globals.rgbBack); + SelectObject(hMemDC, hpenOld); + SelectObject(hMemDC, hbrOld); + DeleteObject(hPen); + DeleteObject(hbr); +} + +VOID Canvas_DrawBuffer(HDC hDC) +{ + HDC hMemDC; + HPEN hPen; + HBRUSH hbr; + HGDIOBJ hbmOld, hpenOld, hbrOld; + + switch(Globals.iToolSelect) + { + case TOOL_BOXSELECT: + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmSelect); + BitBlt(hDC, Globals.pt0.x, Globals.pt0.y, + Globals.pt1.x - Globals.pt0.x, + Globals.pt1.y - Globals.pt0.y, + hMemDC, 0, 0, SRCCOPY); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + + if (Globals.mode == MODE_CANVAS) + { + hPen = CreatePen(PS_DOT, 1, 0); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + hbrOld = SelectObject(hDC, hbr); + hpenOld = SelectObject(hDC, hPen); + SetROP2(hDC, R2_XORPEN); + Rectangle(hDC, Globals.pt0.x, Globals.pt0.y, + Globals.pt1.x, Globals.pt1.y); + SetROP2(hDC, R2_COPYPEN); + SelectObject(hDC, hbrOld); + SelectObject(hDC, hpenOld); + DeleteObject(hPen); + } + break; + + case TOOL_ERASER: + { + POINT pt; + RECT rc; + GetCursorPos(&pt); + ScreenToClient(Globals.hCanvasWnd, &pt); + CanvasToImage(&pt); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + if (PtInRect(&rc, pt)) + { + SelectObject(hDC, GetStockObject(WHITE_BRUSH)); + SelectObject(hDC, GetStockObject(BLACK_PEN)); + Rectangle(hDC, + pt.x - Globals.nEraserSize / 2, + pt.y - Globals.nEraserSize / 2, + pt.x + Globals.nEraserSize / 2, + pt.y + Globals.nEraserSize / 2); + } + } + break; + + case TOOL_CURVE: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, Globals.fSwapColor ? + Globals.rgbBack : Globals.rgbFore); + hpenOld = SelectObject(hDC, hPen); + PolyBezier(hDC, &Globals.pt0, 4); + SelectObject(hDC, hpenOld); + DeleteObject(hPen); + break; + + case TOOL_POLYGON: + Polyline(hDC, Globals.pPolyline, Globals.cPolyline); + break; + + case TOOL_LINE: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, Globals.fSwapColor ? + Globals.rgbBack : Globals.rgbFore); + hpenOld = SelectObject(hDC, hPen); + MoveToEx(hDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hDC, Globals.pt1.x, Globals.pt1.y); + SetPixel(hDC, Globals.pt1.x, Globals.pt1.y, Globals.fSwapColor ? + Globals.rgbBack : Globals.rgbFore); + SelectObject(hDC, hpenOld); + DeleteObject(hPen); + break; + + case TOOL_BRUSH: + if (Globals.fSwapColor) + BackBrushDDAProc(Globals.pt0.x, Globals.pt0.y, (LPARAM)hDC); + else + ForeBrushDDAProc(Globals.pt0.x, Globals.pt0.y, (LPARAM)hDC); + break; + + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + if (Globals.fSwapColor) + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbFore); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbBack); + } + } + else + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbBack); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbFore); + } + } + hpenOld = SelectObject(hDC, hPen); + hbrOld = SelectObject(hDC, hbr); + if (GetKeyState(VK_SHIFT) < 0) + Regularize(Globals.pt0, &Globals.pt1); + switch(Globals.iToolSelect) + { + case TOOL_BOX: + Rectangle(hDC, Globals.pt0.x, Globals.pt0.y, Globals.pt1.x, Globals.pt1.y); + break; + + case TOOL_ELLIPSE: + Ellipse(hDC, Globals.pt0.x, Globals.pt0.y, Globals.pt1.x, Globals.pt1.y); + break; + + default: + RoundRect(hDC, Globals.pt0.x, Globals.pt0.y, Globals.pt1.x, Globals.pt1.y, 16, 16); + } + SelectObject(hDC, hpenOld); + SelectObject(hDC, hbrOld); + DeleteObject(hPen); + DeleteObject(hbr); + break; + + case TOOL_MAGNIFIER: + if (Globals.nZoom == 1) + { + POINT pt, pt0, pt1; + RECT rc; + GetCursorPos(&pt); + ScreenToClient(Globals.hCanvasWnd, &pt); + CanvasToImage(&pt); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + if (PtInRect(&rc, pt)) + { + GetClientRect(Globals.hCanvasWnd, &rc); + hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 255)); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + hbrOld = SelectObject(hDC, hbr); + hpenOld = SelectObject(hDC, hPen); + SetROP2(hDC, R2_XORPEN); + + pt0.x = pt.x - (rc.right - rc.left) / 4 / 2; + if (pt0.x < 0) + pt0.x = 0; + if (pt.x + (rc.right - rc.left) / 4 / 2 > Globals.sizImage.cx) + pt0.x = Globals.sizImage.cx - (rc.right - rc.left) / 4; + if (pt0.x < 0) + { + pt0.x = 0; + pt1.x = Globals.sizImage.cx; + } + else + { + pt1.x = pt0.x + (rc.right - rc.left) / 4; + } + + pt0.y = pt.y - (rc.bottom - rc.top) / 4 / 2; + if (pt0.y < 0) + pt0.y = 0; + if (pt.y + (rc.bottom - rc.top) / 4 / 2 > Globals.sizImage.cy) + pt0.y = Globals.sizImage.cy - (rc.bottom - rc.top) / 4; + if (pt0.y < 0) + { + pt0.y = 0; + pt1.y = Globals.sizImage.cy; + } + else + { + pt1.y = pt0.y + (rc.bottom - rc.top) / 4; + } + + Rectangle(hDC, pt0.x, pt0.y, pt1.x, pt1.y); + SetROP2(hDC, R2_COPYPEN); + SelectObject(hDC, hbrOld); + SelectObject(hDC, hpenOld); + DeleteObject(hPen); + } + } + break; + + default: + break; + } +} + +VOID Canvas_OnPaint(HWND hWnd, HDC hDC) +{ + HBRUSH hbr; + HGDIOBJ hbmOld1, hbmOld2, hpenOld, hbrOld; + HDC hMemDC1, hMemDC2; + RECT rc; + INT x, y; + + SetWindowOrgEx(hDC, Globals.xScrollPos, Globals.yScrollPos, NULL); + + hMemDC1 = CreateCompatibleDC(hDC); + if (hMemDC1 != NULL) + { + hMemDC2 = CreateCompatibleDC(hDC); + if (hMemDC2 != NULL) + { + hbmOld1 = SelectObject(hMemDC1, Globals.hbmImage); + hbmOld2 = SelectObject(hMemDC2, Globals.hbmBuffer); + BitBlt(hMemDC2, 0, 0, Globals.sizImage.cx, Globals.sizImage.cy, + hMemDC1, 0, 0, SRCCOPY); + SelectObject(hMemDC1, hbmOld1); + Canvas_DrawBuffer(hMemDC2); + + /* FIXME: speed up by smaller buffer */ + hbmOld1 = SelectObject(hMemDC1, Globals.hbmZoomBuffer); + SetStretchBltMode(hDC, COLORONCOLOR); + StretchBlt(hMemDC1, 0, 0, Globals.sizImage.cx * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom, hMemDC2, + 0, 0, Globals.sizImage.cx, Globals.sizImage.cy, SRCCOPY); + SelectObject(hMemDC2, hbmOld2); + + if (Globals.fShowGrid && Globals.nZoom >= 3) + { + LOGBRUSH lb; + HPEN hPen1, hPen2; + hPen1 = CreatePen(PS_SOLID, 1, RGB(192, 192, 192)); + hpenOld = SelectObject(hMemDC1, hPen1); + for (x = 0; x < Globals.sizImage.cx; x++) + { + MoveToEx(hMemDC1, x * Globals.nZoom, 0, NULL); + LineTo(hMemDC1, x * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom); + } + for (y = 0; y < Globals.sizImage.cy; y++) + { + MoveToEx(hMemDC1, 0, y * Globals.nZoom, NULL); + LineTo(hMemDC1, Globals.sizImage.cx * Globals.nZoom, + y * Globals.nZoom); + } + lb.lbColor = RGB(128, 128, 128); + lb.lbStyle = BS_SOLID; + hPen2 = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE|PS_ENDCAP_SQUARE|PS_JOIN_BEVEL, 1, &lb, 0, NULL); + SelectObject(hMemDC1, hPen2); + for (x = 0; x < Globals.sizImage.cx; x++) + { + MoveToEx(hMemDC1, x * Globals.nZoom, 0, NULL); + LineTo(hMemDC1, x * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom); + } + for (y = 0; y < Globals.sizImage.cy; y++) + { + MoveToEx(hMemDC1, 0, y * Globals.nZoom, NULL); + LineTo(hMemDC1, Globals.sizImage.cx * Globals.nZoom, + y * Globals.nZoom); + } + SelectObject(hMemDC1, hpenOld); + DeleteObject(hPen1); + DeleteObject(hPen2); + } + + if (GetSysColor(COLOR_3DFACE) == RGB(0, 0, 0)) + hbr = CreateSolidBrush(RGB(0, 0, 0)); + else + hbr = CreateSolidBrush(RGB(123, 125, 123)); + + hbmOld2 = SelectObject(hMemDC2, Globals.hbmCanvasBuffer); + GetClientRect(hWnd, &rc); + FillRect(hMemDC2, &rc, hbr); + DeleteObject(hbr); + BitBlt(hMemDC2, 4 - Globals.xScrollPos, 4 - Globals.yScrollPos, + Globals.sizImage.cx * Globals.nZoom, + Globals.sizImage.cy * Globals.nZoom, + hMemDC1, 0, 0, SRCCOPY); + SelectObject(hMemDC1, hbmOld1); + + if (Globals.fSelect && Globals.mode == MODE_NORMAL) + { + POINT pt0, pt1; + HPEN hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_HIGHLIGHT)); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + hbrOld = SelectObject(hMemDC2, hbr); + hpenOld = SelectObject(hMemDC2, hPen); + pt0 = Globals.pt0; + ImageToCanvas2(&pt0); + pt1 = Globals.pt1; + ImageToCanvas2(&pt1); + Rectangle(hMemDC2, + pt0.x - Globals.xScrollPos, pt0.y - Globals.yScrollPos, + pt1.x - Globals.xScrollPos, pt1.y - Globals.yScrollPos); + SelectObject(hMemDC2, hbrOld); + SelectObject(hMemDC2, hpenOld); + DeleteObject(hPen); + } + + BitBlt(hDC, Globals.xScrollPos, Globals.yScrollPos, + Globals.sizCanvas.cx, Globals.sizCanvas.cy, + hMemDC2, 0, 0, SRCCOPY); + SelectObject(hMemDC2, hbmOld2); + } + } + + if (!Globals.fSelect) + { + rc.left = 0; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 0; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 0; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 0; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + hbr = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT)); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + } +} + +VOID Canvas_OnButtonDown(HWND hWnd, INT x, INT y, BOOL fRight) +{ + POINT pt, pt0; + RECT rc; + HDC hDC, hMemDC; + HGDIOBJ hbmOld, hbrOld; + HBRUSH hbr; + pt.x = x; + pt.y = y; + + if (!fRight) + { + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurHorizontal); + Globals.mode = MODE_RIGHT_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurVertical); + Globals.mode = MODE_DOWN_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurBDiagonal); + Globals.mode = MODE_LOWER_RIGHT_EDGE; + SetCapture(hWnd); + Globals.pt0 = pt; + SetRectEmpty((RECT*)&Globals.pt0); + return; + } + } + + rc.left = 4; + rc.top = 4; + rc.right = 4 + Globals.sizImage.cx * Globals.nZoom; + rc.bottom = 4 + Globals.sizImage.cy * Globals.nZoom; + + if (PtInRect(&rc, pt)) + { + switch (Globals.iToolSelect) + { + case TOOL_MAGNIFIER: + CanvasToImage(&pt); + GetClientRect(hWnd, &rc); + + pt0.x = pt.x - (rc.right - rc.left) / 4 / 2; + if (pt0.x < 0) + pt0.x = 0; + if (pt.x + (rc.right - rc.left) / 4 / 2 > Globals.sizImage.cx) + pt0.x = Globals.sizImage.cx - (rc.right - rc.left) / 4; + if (pt0.x < 0) + { + pt0.x = 0; + } + + pt0.y = pt.y - (rc.bottom - rc.top) / 4 / 2; + if (pt0.y < 0) + pt0.y = 0; + if (pt.y + (rc.bottom - rc.top) / 4 / 2 > Globals.sizImage.cy) + pt0.y = Globals.sizImage.cy - (rc.bottom - rc.top) / 4; + if (pt0.y < 0) + { + pt0.y = 0; + } + Globals.iToolSelect = Globals.iToolPrev; + Globals.iToolClicking = -1; + Globals.ipt = 0; + if (Globals.pPolyline != NULL) + HeapFree(GetProcessHeap(), 0, Globals.pPolyline); + Globals.pPolyline = NULL; + Globals.cPolyline = 0; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + + if (Globals.nZoom == 1) + { + if (rc.right - rc.left < Globals.sizImage.cx) pt.x = 0; + if (rc.bottom - rc.top < Globals.sizImage.cy) pt.y = 0; + PAINT_Zoom2(pt0.x, pt0.y, 4); + } + else + PAINT_Zoom(1); + break; + + case TOOL_BOXSELECT: + if (fRight) + { + HMENU hMenu, hSubMenu; + Globals.mode = MODE_NORMAL; + ReleaseCapture(); + hMenu = LoadMenu(Globals.hInstance, + MAKEINTRESOURCE(SELECTION_MENU)); + hSubMenu = GetSubMenu(hMenu, 0); + GetCursorPos(&pt); + + SetForegroundWindow(Globals.hMainWnd); + TrackPopupMenu(hSubMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON, + pt.x, pt.y, 0, Globals.hMainWnd, NULL); + PostMessage(Globals.hMainWnd, WM_NULL, 0, 0); + DestroyMenu(hMenu); + } + else + { + CanvasToImage(&pt); + if (Globals.fSelect) + { + if (PtInRect((RECT*)&Globals.pt0, pt)) + { + SetCursor(Globals.hcurMove); + Globals.mode = MODE_SELECTION; + SetCapture(hWnd); + NormalizeRect((RECT*)&Globals.pt0); + Globals.pt2.x = pt.x - Globals.pt0.x; + Globals.pt2.y = pt.y - Globals.pt0.y; + PrepareForUndo(); + Selection_TakeOff(); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + { + SetCursor(Globals.hcurCross2); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + Selection_Land(); + Globals.fSelect = FALSE; + Globals.pt0 = Globals.pt1 = pt; + } + } + else + { + SetCursor(Globals.hcurCross2); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + Globals.fSelect = FALSE; + Globals.pt0 = Globals.pt1 = pt; + } + } + break; + + case TOOL_ERASER: + if (!fRight) + { + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + SetCursor(NULL); + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + rc.left = pt.x - Globals.nEraserSize / 2; + rc.top = pt.y - Globals.nEraserSize / 2; + rc.right = rc.left + Globals.nEraserSize; + rc.bottom = rc.top + Globals.nEraserSize; + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hMemDC, &rc, hbr); + DeleteObject(hbr); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + Globals.pt0 = pt; + } + break; + + case TOOL_BRUSH: + SetCursor(Globals.hcurCross); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + if (fRight) + BackBrushDDAProc(pt.x, pt.y, (LPARAM)hMemDC); + else + ForeBrushDDAProc(pt.x, pt.y, (LPARAM)hMemDC); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + break; + + case TOOL_FILL: + SetCursor(Globals.hcurFill); + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbr = CreateSolidBrush(fRight ? Globals.rgbBack : + Globals.rgbFore); + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + hbrOld = SelectObject(hMemDC, hbr); + ExtFloodFill(hMemDC, pt.x, pt.y, + GetPixel(hMemDC, pt.x, pt.y), + FLOODFILLSURFACE); + SelectObject(hMemDC, hbrOld); + SelectObject(hMemDC, hbmOld); + DeleteObject(hbr); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + SetPixelV(hMemDC, pt.x, pt.y, + fRight ? Globals.rgbBack : Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + Globals.pt0 = pt; + break; + + case TOOL_AIRBRUSH: + SetCursor(Globals.hcurAirBrush); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + PrepareForUndo(); + KillTimer(hWnd, Globals.idTimer); + Globals.idTimer = SetTimer(hWnd, 1, 30, NULL); + Globals.fModified = TRUE; + break; + + case TOOL_SPOIT: + SetCursor(Globals.hcurSpoit); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + Globals.rgbSpoit = GetPixel(hMemDC, pt.x, pt.y); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + break; + + case TOOL_POLYGON: + SetCursor(Globals.hcurCross2); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + if (Globals.cPolyline == 0) + { + Globals.cPolyline = 2; + Globals.pPolyline = (POINT*)HeapAlloc(GetProcessHeap(), 0, + 2 * sizeof(POINT)); + + Globals.pPolyline[0] = Globals.pPolyline[1] = pt; + } + else + { + DWORD cb; + Globals.cPolyline++; + cb = Globals.cPolyline * sizeof(POINT); + Globals.pPolyline = (POINT*)HeapReAlloc(GetProcessHeap(), 0, + Globals.pPolyline, cb); + Globals.pPolyline[Globals.cPolyline - 1] = pt; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_CURVE: + SetCursor(Globals.hcurCross2); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + switch (Globals.ipt) + { + case 0: + Globals.pt0 = Globals.pt1 = Globals.pt2 = Globals.pt3 = pt; + Globals.ipt = 1; + break; + + case 1: + Globals.pt2 = Globals.pt3 = pt; + break; + + case 2: + Globals.pt1 = pt; + break; + + case 3: + Globals.pt2 = pt; + break; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_LINE: + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + SetCursor(Globals.hcurCross2); + Globals.mode = MODE_CANVAS; + SetCapture(hWnd); + CanvasToImage(&pt); + Globals.pt0 = Globals.pt1 = pt; + break; + default: + break; + } + } + else + { + if (Globals.iToolSelect == TOOL_BOXSELECT) + { + CanvasToImage(&pt); + if (Globals.fSelect && PtInRect((RECT*)&Globals.pt0, pt)) + { + SetCursor(Globals.hcurMove); + NormalizeRect((RECT*)&Globals.pt0); + Globals.pt2.x = pt.x - Globals.pt0.x; + Globals.pt2.y = pt.y - Globals.pt0.y; + Selection_TakeOff(); + SetCapture(hWnd); + Globals.mode = MODE_SELECTION; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + { + SetCursor(Globals.hcurCross2); + Selection_Land(); + Globals.fSelect = FALSE; + } + } + } +} + +VOID CALLBACK EraserDDAProc(INT x, INT y, LPARAM lParam) +{ + RECT rc; + HDC hMemDC = (HDC)lParam; + HBRUSH hbr; + rc.left = x - Globals.nEraserSize / 2; + rc.top = y - Globals.nEraserSize / 2; + rc.right = rc.left + Globals.nEraserSize; + rc.bottom = rc.top + Globals.nEraserSize; + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hMemDC, &rc, hbr); + DeleteObject(hbr); +} + +VOID ShowPos(POINT pt) +{ + WCHAR sz[64]; + static const WCHAR format[] = {'%','d',',','%','d',0}; + wsprintf(sz, format, pt.x, pt.y); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 1 | 0, (LPARAM)sz); +} + +VOID ShowSize(INT cx, INT cy) +{ + WCHAR sz[64]; + static const WCHAR format[] = {'%','d','x','%','d',0}; + wsprintf(sz, format, cx, cy); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 2 | 0, (LPARAM)sz); +} + +VOID ShowNoSize(VOID) +{ + SendMessage(Globals.hStatusBar, SB_SETTEXT, 2 | 0, (LPARAM)empty); +} + +VOID Canvas_OnMouseMove(HWND hWnd, INT x, INT y, BOOL fLeftDown, BOOL fRightDown) +{ + POINT pt; + RECT rc; + HDC hDC, hMemDC; + WCHAR sz[256]; + pt.x = x; + pt.y = y; + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + + if (fLeftDown) + { + rc.left = 4; + rc.top = 4; + Globals.fSwapColor = FALSE; + switch (Globals.mode) + { + case MODE_RIGHT_EDGE: + SetCursor(Globals.hcurHorizontal); + CanvasToImage(&pt); + ShowSize(pt.x, Globals.sizImage.cy); + ImageToCanvas(&pt); + rc.right = pt.x; + rc.bottom = Globals.sizImage.cy * Globals.nZoom + 4; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_DOWN_EDGE: + SetCursor(Globals.hcurVertical); + CanvasToImage(&pt); + ShowSize(Globals.sizImage.cx, pt.y); + ImageToCanvas(&pt); + rc.right = Globals.sizImage.cx * Globals.nZoom + 4; + rc.bottom = pt.y; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_LOWER_RIGHT_EDGE: + SetCursor(Globals.hcurBDiagonal); + CanvasToImage(&pt); + ShowSize(pt.x, pt.y); + ImageToCanvas(&pt); + rc.right = pt.x; + rc.bottom = pt.y; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + DrawFocusRect(hDC, &rc); + ReleaseDC(hWnd, hDC); + } + break; + + case MODE_SELECTION: + SetCursor(Globals.hcurMove); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + OffsetRect((RECT*)&Globals.pt0, + pt.x - Globals.pt0.x - Globals.pt2.x, + pt.y - Globals.pt0.y - Globals.pt2.y); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case MODE_CANVAS: + switch (Globals.iToolSelect) + { + case TOOL_BOXSELECT: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pt1 = pt; + ShowSize(Globals.pt1.x - Globals.pt0.x, + Globals.pt1.y - Globals.pt0.x); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_BRUSH: + SetCursor(Globals.hcurCross); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + LineDDA(Globals.pt0.x, Globals.pt0.y, pt.x, pt.y, + ForeBrushDDAProc, (LPARAM)hMemDC); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + } + Globals.pt0 = pt; + ShowPos(pt); + ShowNoSize(); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_ERASER: + SetCursor(NULL); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + LineDDA(Globals.pt0.x, Globals.pt0.y, pt.x, pt.y, + EraserDDAProc, (LPARAM)hMemDC); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + Globals.pt0 = pt; + ShowPos(pt); + ShowNoSize(); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_POLYGON: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pPolyline[Globals.cPolyline - 1] = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_CURVE: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + if (Globals.ipt == 1) + { + Globals.pt2 = Globals.pt3 = pt; + } + else if (Globals.ipt == 2) + { + Globals.pt1 = pt; + } + else if (Globals.ipt == 3) + { + Globals.pt2 = pt; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_LINE: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pt1 = pt; + ShowSize(Globals.pt1.x - Globals.pt0.x, + Globals.pt1.y - Globals.pt0.y); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pt1 = pt; + ShowSize(Globals.pt1.x - Globals.pt0.x, + Globals.pt1.y - Globals.pt0.y); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_SPOIT: + SetCursor(Globals.hcurSpoit); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + Globals.rgbSpoit = GetPixel(hMemDC, pt.x, pt.y); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + break; + + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen = CreatePen(PS_SOLID, 0, Globals.rgbFore); + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + HGDIOBJ hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixelV(hMemDC, pt.x, pt.y, Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + default: + break; + } + break; + default: + break; + } + } + else if (fRightDown) + { + Globals.fSwapColor = TRUE; + if (Globals.mode == MODE_CANVAS) + { + switch (Globals.iToolSelect) + { + case TOOL_BRUSH: + SetCursor(Globals.hcurCross); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + LineDDA(Globals.pt0.x, Globals.pt0.y, pt.x, pt.y, + BackBrushDDAProc, (LPARAM)hMemDC); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_POLYGON: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pPolyline[Globals.cPolyline - 1] = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_CURVE: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + if (Globals.ipt == 1) + { + Globals.pt2 = Globals.pt3 = pt; + } + else if (Globals.ipt == 2) + { + Globals.pt1 = pt; + } + else if (Globals.ipt == 3) + { + Globals.pt2 = pt; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_LINE: + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pt1 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_SPOIT: + SetCursor(Globals.hcurSpoit); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + Globals.rgbSpoit = GetPixel(hMemDC, pt.x, pt.y); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + break; + + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen = CreatePen(PS_SOLID, 0, Globals.rgbBack); + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + HGDIOBJ hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixelV(hMemDC, pt.x, pt.y, Globals.rgbBack); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + Globals.pt0 = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + default: + break; + } + } + } + else + { + Globals.fSwapColor = FALSE; + Globals.mode = MODE_NORMAL; + ReleaseCapture(); + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom / 2 - 2 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurHorizontal); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom / 2 - 2 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurVertical); + return; + } + + rc.left = 4 + Globals.sizImage.cx * Globals.nZoom + 1 - Globals.xScrollPos; + rc.top = 4 + Globals.sizImage.cy * Globals.nZoom + 1 - Globals.yScrollPos; + rc.right = rc.left + 3; + rc.bottom = rc.top + 3; + if (PtInRect(&rc, pt)) + { + SetCursor(Globals.hcurBDiagonal); + return; + } + + rc.left = 4 + Globals.xScrollPos; + rc.top = 4 + Globals.yScrollPos; + rc.right = 4 + Globals.sizImage.cx * Globals.nZoom + Globals.xScrollPos; + rc.bottom = 4 + Globals.sizImage.cy * Globals.nZoom + Globals.yScrollPos; + + if (PtInRect(&rc, pt)) + { + switch (Globals.iToolSelect) + { + case TOOL_BOXSELECT: + if (Globals.fSelect && PtInRect((RECT*)&Globals.pt0, pt)) + { + SetCursor(Globals.hcurMove); + } + else + { + SetCursor(Globals.hcurCross2); + } + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + case TOOL_MAGNIFIER: + SetCursor(Globals.hcurZoom); + CanvasToImage(&pt); + Globals.pt0 = pt; + ShowPos(pt); + ShowNoSize(); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_BRUSH: + SetCursor(Globals.hcurCross); + CanvasToImage(&pt); + Globals.pt0 = pt; + ShowPos(pt); + ShowNoSize(); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_ERASER: + SetCursor(NULL); + CanvasToImage(&pt); + Globals.pt0 = pt; + ShowPos(pt); + ShowNoSize(); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_FILL: + SetCursor(Globals.hcurFill); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + case TOOL_SPOIT: + SetCursor(Globals.hcurSpoit); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + case TOOL_PENCIL: + SetCursor(Globals.hcurPencil); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + case TOOL_AIRBRUSH: + SetCursor(Globals.hcurAirBrush); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + + default: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + break; + } + } + else + { + SendMessage(Globals.hStatusBar, SB_SETTEXT, 1 | 0, (LPARAM)empty); + if (Globals.fSelect && PtInRect((RECT*)&Globals.pt0, pt)) + { + SetCursor(Globals.hcurMove); + } + else + { + SetCursor(Globals.hcurArrow); + if (Globals.iToolSelect == TOOL_MAGNIFIER || Globals.iToolSelect == TOOL_ERASER) + { + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + } + return; + } + } +} + +VOID Canvas_Resize(HWND hWnd, SIZE sizNew) +{ + HBITMAP hbmNew = BM_CreateResized(hWnd, sizNew, Globals.hbmImage, + Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + Globals.sizImage = sizNew; + + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + sizNew.cx *= Globals.nZoom; + sizNew.cy *= Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(sizNew); + Globals.fModified = TRUE; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(hWnd, WM_SIZE, 0, 0); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Selection_Stretch(HWND hWnd, SIZE sizNew) +{ + HBITMAP hbmNew; + SIZE siz; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateStretched(hWnd, sizNew, Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbmNew; + Globals.pt1.x = Globals.pt0.x + sizNew.cx; + Globals.pt1.y = Globals.pt0.y + sizNew.cy; + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Canvas_Stretch(HWND hWnd, SIZE sizNew) +{ + HBITMAP hbmNew = BM_CreateStretched(hWnd, sizNew, + Globals.hbmImage, Globals.sizImage); + if (hbmNew != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = hbmNew; + Globals.sizImage = sizNew; + + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + sizNew.cx *= Globals.nZoom; + sizNew.cy *= Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(sizNew); + Globals.fModified = TRUE; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(hWnd, WM_SIZE, 0, 0); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + ShowLastError(); +} + +VOID Selection_HFlip(HWND hWnd) +{ + HBITMAP hbmNew; + SIZE siz; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateHFliped(hWnd, Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbmNew; + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + } + else + 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 Selection_VFlip(HWND hWnd) +{ + HBITMAP hbmNew; + SIZE siz; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateVFliped(hWnd, Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = 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 Selection_Rotate90Degree(HWND hWnd) +{ + SIZE siz; + HBITMAP hbmNew; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateRotated90Degree(hWnd, + Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbmNew; + Globals.pt1.x = Globals.pt0.x + siz.cy; + Globals.pt1.y = Globals.pt0.y + siz.cx; + 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 Selection_Rotate180Degree(HWND hWnd) +{ + HBITMAP hbmNew; + SIZE siz; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateRotated180Degree(hWnd, + Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbmNew; + Globals.fModified = TRUE; + 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 Selection_Rotate270Degree(HWND hWnd) +{ + SIZE siz; + HBITMAP hbmNew; + Selection_TakeOff(); + siz.cx = Globals.pt1.x - Globals.pt0.x; + siz.cy = Globals.pt1.y - Globals.pt0.y; + hbmNew = BM_CreateRotated270Degree(hWnd, + Globals.hbmSelect, siz); + if (hbmNew != NULL) + { + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbmNew; + Globals.pt1.x = Globals.pt0.x + siz.cy; + Globals.pt1.y = Globals.pt0.y + siz.cx; + 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; + POINT pt; + pt.x = x; + pt.y = y; + + switch (Globals.iToolSelect) + { + case TOOL_POLYGON: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen; + HBRUSH hbr; + HGDIOBJ hpenOld, hbrOld, hbmOld; + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + if (fRight) + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbFore); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbBack); + break; + } + } + else + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbBack); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbFore); + break; + } + } + hpenOld = SelectObject(hMemDC, hPen); + hbrOld = SelectObject(hMemDC, hbr); + Polygon(hMemDC, Globals.pPolyline, Globals.cPolyline); + SelectObject(hMemDC, hpenOld); + SelectObject(hMemDC, hbrOld); + SelectObject(hMemDC, hbmOld); + DeleteObject(hPen); + DeleteObject(hbr); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + } + HeapFree(GetProcessHeap(), 0, Globals.pPolyline); + Globals.pPolyline = NULL; + Globals.cPolyline = 0; + Globals.fModified = TRUE; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + default: + break; + } +} + +VOID Canvas_OnButtonUp(HWND hWnd, INT x, INT y, BOOL fRight) +{ + HDC hDC, hMemDC; + HGDIOBJ hbmOld; + POINT pt; + SIZE siz; + RECT rc; + pt.x = x; + pt.y = y; + + switch (Globals.mode) + { + case MODE_RIGHT_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = pt.x; + siz.cy = Globals.sizImage.cy; + if (siz.cx < 1) siz.cx = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_DOWN_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = Globals.sizImage.cx; + siz.cy = pt.y; + if (siz.cy < 1) siz.cy = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_LOWER_RIGHT_EDGE: + CanvasToImage(&pt); + PrepareForUndo(); + Globals.fModified = TRUE; + siz.cx = pt.x; + siz.cy = pt.y; + if (siz.cx < 1) siz.cx = 1; + if (siz.cy < 1) siz.cy = 1; + Canvas_Resize(hWnd, siz); + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case MODE_SELECTION: + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + break; + + case MODE_CANVAS: + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + switch (Globals.iToolSelect) + { + case TOOL_BOXSELECT: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pt1 = pt; + NormalizeRect((RECT*)&Globals.pt0); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + IntersectRect((RECT*)&Globals.pt0, (RECT*)&Globals.pt0, &rc); + Globals.fSelect = !IsRectEmpty((RECT*)&Globals.pt0); + Globals.hbmSelect = NULL; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + + case TOOL_POLYGON: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + Globals.pPolyline[Globals.cPolyline - 1] = pt; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_CURVE: + SetCursor(Globals.hcurCross2); + CanvasToImage(&pt); + if (Globals.ipt == 1) + { + Globals.pt2 = Globals.pt3 = pt; + Globals.ipt = 2; + } + else if (Globals.ipt == 2) + { + Globals.pt1 = pt; + Globals.ipt = 3; + } + else if (Globals.ipt == 3) + { + Globals.pt2 = pt; + Globals.ipt = 0; + PrepareForUndo(); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen; + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + fRight ? Globals.rgbBack : Globals.rgbFore); + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + SelectObject(hMemDC, hPen); + PolyBezier(hMemDC, &Globals.pt0, 4); + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + DeleteObject(hPen); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + break; + + case TOOL_PENCIL: + CanvasToImage(&pt); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen; + HGDIOBJ hpenOld; + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + hPen = CreatePen(PS_SOLID, 1, fRight ? Globals.rgbBack : + Globals.rgbFore); + hpenOld = SelectObject(hMemDC, hPen); + MoveToEx(hMemDC, Globals.pt0.x, Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixel(hMemDC, pt.x, pt.y, fRight ? + Globals.rgbBack : Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + + case TOOL_AIRBRUSH: + SetCursor(Globals.hcurAirBrush); + KillTimer(hWnd, Globals.idTimer); + break; + + case TOOL_BOX: + case TOOL_ELLIPSE: + case TOOL_ROUNDRECT: + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HGDIOBJ hpenOld, hbrOld, hbmOld; + HPEN hPen; + HBRUSH hbr; + + if (Globals.fSwapColor) + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbFore); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbBack); + hbr = CreateSolidBrush(Globals.rgbBack); + } + } + else + { + switch (Globals.iFillStyle) + { + case 0: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = (HBRUSH)GetStockObject(NULL_BRUSH); + break; + + case 1: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbBack); + break; + + default: + hPen = CreatePen(PS_SOLID, Globals.nLineWidth, + Globals.rgbFore); + hbr = CreateSolidBrush(Globals.rgbFore); + } + } + + hbmOld = SelectObject(hMemDC, Globals.hbmImage); + hpenOld = SelectObject(hMemDC, hPen); + hbrOld = SelectObject(hMemDC, hbr); + if (GetKeyState(VK_SHIFT) < 0) + Regularize(Globals.pt0, &pt); + switch(Globals.iToolSelect) + { + case TOOL_BOX: + Rectangle(hMemDC, Globals.pt0.x, Globals.pt0.y, + pt.x, pt.y); + break; + + case TOOL_ELLIPSE: + Ellipse(hMemDC, Globals.pt0.x, Globals.pt0.y, + pt.x, pt.y); + break; + + default: + RoundRect(hMemDC, Globals.pt0.x, Globals.pt0.y, + pt.x, pt.y, 16, 16); + } + SelectObject(hMemDC, hpenOld); + SelectObject(hMemDC, hbrOld); + SelectObject(hMemDC, hbmOld); + DeleteObject(hPen); + DeleteObject(hbr); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + SetRectEmpty((RECT*)&Globals.pt0); + break; + + case TOOL_SPOIT: + Globals.iToolSelect = Globals.iToolPrev; + if (fRight) + Globals.rgbBack = Globals.rgbSpoit; + else + Globals.rgbFore = Globals.rgbSpoit; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + InvalidateRect(Globals.hColorBox, NULL, TRUE); + UpdateWindow(Globals.hColorBox); + break; + + case TOOL_LINE: + CanvasToImage(&pt); + PrepareForUndo(); + hDC = GetDC(hWnd); + if (hDC != NULL) + { + hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + HPEN hPen = CreatePen(PS_SOLID, Globals.nLineWidth, fRight ? + Globals.rgbBack : Globals.rgbFore); + HGDIOBJ hpenOld = SelectObject(hMemDC, hPen); + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + MoveToEx(hMemDC, Globals.pt0.x , Globals.pt0.y, NULL); + LineTo(hMemDC, pt.x, pt.y); + SetPixel(hMemDC, pt.x, pt.y, fRight ? Globals.rgbBack : + Globals.rgbFore); + SelectObject(hMemDC, hbmOld); + SelectObject(hMemDC, hpenOld); + DeleteObject(hPen); + DeleteDC(hMemDC); + Globals.fModified = TRUE; + } + ReleaseDC(hWnd, hDC); + } + break; + default: + break; + } + break; + default: + break; + } + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); +} + +VOID Canvas_OnSize(HWND hWnd) +{ + RECT rc; + SIZE siz; + + GetClientRect(hWnd, &rc); + siz.cx = rc.right - rc.left; + siz.cy = rc.bottom - rc.top; + if (siz.cx < Globals.sizImage.cx * Globals.nZoom + 8) + { + SCROLLINFO si; + EnableScrollBar(hWnd, SB_HORZ, ESB_ENABLE_BOTH); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + si.nMin = 0; + si.nMax = Globals.sizImage.cx * Globals.nZoom + 8; + si.nPage = siz.cx; + si.nPos = Globals.xScrollPos; + SetScrollInfo(hWnd, SB_HORZ, &si, TRUE); + ShowScrollBar(hWnd, SB_HORZ, TRUE); + } + else + { + EnableScrollBar(hWnd, SB_HORZ, ESB_DISABLE_BOTH); + ShowScrollBar(hWnd, SB_HORZ, FALSE); + } + + if (siz.cy < Globals.sizImage.cy * Globals.nZoom + 8) + { + SCROLLINFO si; + EnableScrollBar(hWnd, SB_VERT, ESB_ENABLE_BOTH); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + si.nMin = 0; + si.nMax = Globals.sizImage.cy * Globals.nZoom + 8; + si.nPage = siz.cy; + si.nPos = Globals.yScrollPos; + SetScrollInfo(hWnd, SB_VERT, &si, TRUE); + ShowScrollBar(hWnd, SB_VERT, TRUE); + } + else + { + EnableScrollBar(hWnd, SB_VERT, ESB_DISABLE_BOTH); + ShowScrollBar(hWnd, SB_VERT, FALSE); + } + + if (Globals.hbmCanvasBuffer == NULL || + siz.cx + 100 < Globals.sizCanvas.cx || + Globals.sizCanvas.cx < siz.cx || + siz.cy + 100 < Globals.sizCanvas.cy || + Globals.sizCanvas.cy < siz.cy) + { + if (Globals.hbmCanvasBuffer != NULL) + DeleteObject(Globals.hbmCanvasBuffer); + siz.cx += 50; + siz.cy += 50; + Globals.hbmCanvasBuffer = BM_Create(siz); + Globals.sizCanvas = siz; + } +} + +LRESULT CALLBACK CanvasWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + INT c, c2; + RECT rc; + + switch (uMsg) + { + case WM_LBUTTONDOWN: + Canvas_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + case WM_RBUTTONDOWN: + Canvas_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONDBLCLK: + Canvas_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDBLCLK: + Canvas_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONUP: + Canvas_OnButtonUp(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONUP: + Canvas_OnButtonUp(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_MOUSEMOVE: + Canvas_OnMouseMove(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), wParam & MK_LBUTTON, + wParam & MK_RBUTTON); + break; + + case WM_KEYDOWN: + switch ((INT)wParam) + { + case VK_ESCAPE: + if (Globals.mode != MODE_NORMAL) + { + ReleaseCapture(); + Globals.mode = MODE_NORMAL; + Globals.ipt = 0; + if (Globals.pPolyline != NULL) + HeapFree(GetProcessHeap(), 0, Globals.pPolyline); + Globals.pPolyline = NULL; + Globals.cPolyline = 0; + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + } + break; + + case WM_TIMER: + { + HDC hDC = GetDC(hWnd); + HDC hMemDC = CreateCompatibleDC(hDC); + if (hMemDC != NULL) + { + POINT pt; + INT i, j, n; + HGDIOBJ hbmOld = SelectObject(hMemDC, Globals.hbmImage); + GetCursorPos(&pt); + ScreenToClient(hWnd, &pt); + CanvasToImage(&pt); + ShowPos(pt); + ShowNoSize(); + + n = Globals.nAirBrushRadius; + for (i = 0; i < 5; i++) + { + j = rand(); + SetPixelV(hMemDC, pt.x + n / 2 - cos(j) * (rand() % n), + pt.y + n / 2 - sin(j) * (rand() % n), + (GetKeyState(VK_RBUTTON) < 0) ? Globals.rgbBack : + Globals.rgbFore); + } + Globals.fModified = TRUE; + SelectObject(hMemDC, hbmOld); + DeleteDC(hMemDC); + } + ReleaseDC(hWnd, hDC); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + break; + } + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + Canvas_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + + case WM_ERASEBKGND: + break; + + case WM_SIZE: + Canvas_OnSize(hWnd); + break; + + case WM_HSCROLL: + switch (LOWORD(wParam)) + { + case SB_PAGELEFT: + GetClientRect(hWnd, &rc); + Globals.xScrollPos -= rc.right - rc.left; + if (Globals.xScrollPos < 0) + Globals.xScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_PAGERIGHT: + GetClientRect(hWnd, &rc); + c = rc.right - rc.left; + Globals.xScrollPos += c; + c2 = Globals.sizImage.cx * Globals.nZoom + 8 - c; + if (Globals.xScrollPos > c2) + Globals.xScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_LINELEFT: + Globals.xScrollPos -= Globals.nZoom; + if (Globals.xScrollPos < 0) + Globals.xScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_LINERIGHT: + GetClientRect(hWnd, &rc); + c = rc.right - rc.left; + Globals.xScrollPos += Globals.nZoom; + c2 = Globals.sizImage.cx * Globals.nZoom + 8 - c; + if (Globals.xScrollPos > c2) + Globals.xScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, Globals.xScrollPos, TRUE); + break; + + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + Globals.xScrollPos = (SHORT)HIWORD(wParam); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_HORZ, (SHORT)HIWORD(wParam), TRUE); + break; + } + break; + + case WM_VSCROLL: + switch (LOWORD(wParam)) + { + case SB_PAGEUP: + GetClientRect(hWnd, &rc); + Globals.yScrollPos -= rc.bottom - rc.top; + if (Globals.yScrollPos < 0) + Globals.yScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_PAGEDOWN: + GetClientRect(hWnd, &rc); + c = rc.bottom - rc.top; + Globals.yScrollPos += c; + c2 = Globals.sizImage.cy * Globals.nZoom + 8 - c; + if (Globals.yScrollPos > c2) + Globals.yScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_LINEUP: + Globals.yScrollPos -= Globals.nZoom; + if (Globals.yScrollPos < 0) + Globals.yScrollPos = 0; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_LINEDOWN: + GetClientRect(hWnd, &rc); + c = rc.bottom - rc.top; + Globals.yScrollPos += Globals.nZoom; + c2 = Globals.sizImage.cy * Globals.nZoom + 8 - c; + if (Globals.yScrollPos > c2) + Globals.yScrollPos = c2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, Globals.yScrollPos, TRUE); + break; + + case SB_THUMBPOSITION: + case SB_THUMBTRACK: + Globals.yScrollPos = (SHORT)HIWORD(wParam); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + SetScrollPos(hWnd, SB_VERT, (SHORT)HIWORD(wParam), TRUE); + break; + } + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} diff --git a/programs/paint/cross.cur b/programs/paint/cross.cur new file mode 100644 index 0000000000000000000000000000000000000000..18a8cb91eab30dc590514f4192a5d8d14ea8f18e GIT binary patch literal 326 zcmaKmISzm@3Yk8vb}W0V3j3%kJzY_diivMGMG l6it6?t-Z-AZy?EjUa^pH9XXV4$n^+~EPPMI|IyyZ61^Rog7yFa literal 0 HcmV?d00001 diff --git a/programs/paint/cross2.cur b/programs/paint/cross2.cur new file mode 100644 index 0000000000000000000000000000000000000000..b5db12d01445e741394889540988cc8915d06702 GIT binary patch literal 326 zcmZQzU}9ioP*7lC5CB30Mg|5k1_lNVAO;FCH~=vt5P|`ef^ZPz|Ns9H9Ap-w15h&_ v3{=bfNB#i=Lj#ls3gA-@lEVRjZomZp?En8Kfd4QakcVMHYQgfDwtz(d@=SP5 literal 0 HcmV?d00001 diff --git a/programs/paint/eraser.bmp b/programs/paint/eraser.bmp new file mode 100644 index 0000000000000000000000000000000000000000..6e4739ba94ccd3029ae6ee655c49fc536e7ffcd5 GIT binary patch literal 9174 zcmeH|K@Ng25Jlk@?%i+#58xW_=&8JpHl-nxUlve*)x_6?GBZs7hu4H&Z;$hk$0f~E zx#n~qhf}WK%k!L+>B;yp0&#aF?)s+U6;phT1R_|8jV`s6c*V4CHddmM#737|O1xrP zHybO_NMfT4QV@Uu1R&5rKz_?h+MsiE3BHNIQD_bQaQ+PEhOJ=<1Rwwb2tc3*0Xh16 vSZr$IyNShK{1#{Xhad<62tWV=5P-lQ0_)Mgr`g!^Z@xx!NI?Js?+|zaZBv(W literal 0 HcmV?d00001 diff --git a/programs/paint/fdiagon.cur b/programs/paint/fdiagon.cur new file mode 100644 index 0000000000000000000000000000000000000000..fd34a8420702798655e80234823a4ab1e9f0bdd8 GIT binary patch literal 326 zcma*hy$ypf5QgE;ED&g@ok&QCDwI@2DKbD73NQ{+fRs8T<#-K9l;*6*_hZYll*q|@ zDb+=HC*_h#Fwz5#wZ@*d=Ge{bXkt~{@i4AjyrDovU%x0uyb%tb81P3t_`|uFK4vSf U&zSIK_G>6I^auwbyB#SK3;ZL2Y5)KL literal 0 HcmV?d00001 diff --git a/programs/paint/fill.bmp b/programs/paint/fill.bmp new file mode 100644 index 0000000000000000000000000000000000000000..897e204251ef17a8b9755e90cd2d8dd00d7b83af GIT binary patch literal 1638 zcmZ?rO=DvKgEAng0mVK*nvsD8EdGI&f#C=r1cL?OL<0i@5HU0~Kqw#yWCC#m!+`?_ zfD-?~h~fW#5DSQb5F`ZR4=V5h=sF|-cH3|k8&rWmK#sv0za7Y+0g?`og*t|a7*b*e aG6yJxhlaIS(*cUpKS0vKP!t<9=>P!K=il}K literal 0 HcmV?d00001 diff --git a/programs/paint/flood.cur b/programs/paint/flood.cur new file mode 100644 index 0000000000000000000000000000000000000000..cf7783ae98def00424c053e76ca282801ecd44f5 GIT binary patch literal 326 zcmaivFAl_cGAuvoL5%}#m++u@-WD@}}{ zUfZOF9)T=_0V8Gs_b_$3MBxl>Z+ye2_<2dc;$OC`2&;my-eGl%Z5G&mj-AKYHpLDJ zcB~1P7H%1&4I~v9o$wpF@hqiBF5M^6bts+sQe#pT{Da7tM=kc^OzyL#@2C?mQ0al> literal 0 HcmV?d00001 diff --git a/programs/paint/horizon.cur b/programs/paint/horizon.cur new file mode 100644 index 0000000000000000000000000000000000000000..c460cae5ae217ada097742612752bf7d7aac1bc0 GIT binary patch literal 326 zcmb7;u?|2`3`Nhg5ebtRjYfaK=&#s}KFgntT)d?n6I`S9cle)pyjEt=P8uBTOjEoGW=A6U`RSfOQrS|!8wp1lR z!Bf{8`W5aAU<+VRt7!+C))k(;-|%d*<9#A}hBS{50vi%Ph-gIP(UQ8EIGq!Go-4UT z@w7c{Ohx`oa7<|IH|KDb#21_CQjiIij5O^KJ1Vv^2+S+eyG$ jZYbq}CGWM6o=;_%Ah2DLuP+hT%i#K!^G;cF(fSwO+5YYf literal 0 HcmV?d00001 diff --git a/programs/paint/hstretch.ico b/programs/paint/hstretch.ico new file mode 100644 index 0000000000000000000000000000000000000000..62e2810aaddbb97bb49fc9a842e84a6cfcfcc418 GIT binary patch literal 766 zcmd^6F%rTs3{yFlZcNM>`9=C9Hb%0wTf6o( + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +PAINT_GLOBALS Globals; + +COLORREF argbDefaultColor[] = +{ + RGB(0, 0, 0), RGB(255, 255, 255), + RGB(128, 128, 128), RGB(192, 192, 192), + RGB(128, 0, 0), RGB(255, 0, 0), + RGB(128, 128, 0), RGB(255, 255, 0), + RGB(0, 128, 0), RGB(0, 255, 0), + RGB(0, 128, 128), RGB(0, 255, 255), + RGB(0, 0, 128), RGB(0, 0, 255), + RGB(128, 0, 128), RGB(255, 0, 255), + RGB(128, 128, 64), RGB(255, 255, 128), + RGB(0, 64, 64), RGB(0, 255, 128), + RGB(0, 128, 255), RGB(128, 255, 255), + RGB(0, 64, 128), RGB(128, 128, 255), + RGB(64, 0, 128), RGB(255, 0, 128), + RGB(128, 64, 0), RGB(255, 128, 64), +}; + +COLORREF argbDefaultMono[] = +{ + RGB(0, 0, 0), RGB(255, 255, 255), + RGB(9, 9, 9), RGB(128, 128, 128), + RGB(18, 18, 18), RGB(137, 137, 137), + RGB(27, 27, 27), RGB(146, 146, 146), + RGB(37, 37, 37), RGB(155, 155, 155), + RGB(46, 46, 46), RGB(164, 164, 164), + RGB(55, 55, 55), RGB(173, 173, 173), + RGB(63, 63, 63), RGB(182, 182, 182), + RGB(73, 73, 73), RGB(191, 191, 191), + RGB(82, 82, 82), RGB(201, 201, 201), + RGB(92, 92, 92), RGB(212, 212, 212), + RGB(101, 101, 101), RGB(222, 222, 222), + RGB(110, 110, 110), RGB(231, 231, 231), + RGB(119, 119, 119), RGB(245, 245, 245) +}; + +COLORREF gargbColorTableMono[] = +{ + RGB(0, 0, 0), + RGB(255, 255, 255) +}; + +static const WCHAR paint_reg_key[] = {'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'A','p','p','l','e','t','s','\\','P','a','i','n','t',0 + }; +static const WCHAR setting[] = {'S','e','t','t','i','n','g','s',0}; +static const WCHAR recent_file_list[] = {'R','e','c','e','n','t',' ', + 'F','i','l','e',' ','L','i','s','t',0 + }; +static const WCHAR text[] = {'T','e','x','t',0}; + +static const WCHAR canvasClassName[] = {'c','a','n','v','a','s',0}; +static const WCHAR colorBoxClassName[] = + {'c','o','l','o','r',' ','b','o','x',0}; +static const WCHAR toolBoxClassName[] = + {'t','o','o','l',' ','b','o','x',0}; + +VOID SetFileName(LPCWSTR szFileName) +{ + lstrcpy(Globals.szFileName, szFileName); + Globals.szFileTitle[0] = 0; + GetFileTitle(szFileName, Globals.szFileTitle, SIZEOF(Globals.szFileTitle)); +} + +static VOID PAINT_SaveSettingToRegistry(void) +{ + HKEY hkey, hkey2; + DWORD disp; + static const WCHAR recent[] = {'R','e','c','e','n','t',' ', + 'F','i','l','e',' ','L','i','s','t',0 + }; + static const WCHAR text[] = {'T','e','x','t',0}; + static const WCHAR view[] = {'V','i','e','w',0}; + static const WCHAR placement[] = {'W','i','n','d','o','w', + 'P','l','a','c','e','m','e','n','t',0 + }; + static const WCHAR BMPHeight[] = {'B','M','P','H','e','i','g','h','t',0}; + static const WCHAR BMPWidth[] = {'B','M','P','W','i','d','t','h',0}; + + if (RegCreateKeyEx(HKEY_CURRENT_USER, paint_reg_key, 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disp) == + ERROR_SUCCESS) + { + if (RegCreateKeyEx(hkey, recent, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + /*FIXME: Load recent file list */ + RegCloseKey(hkey2); + } + + if (RegCreateKeyEx(hkey, text, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + /*FIXME: Load text settings */ + RegCloseKey(hkey2); + } + + if (RegCreateKeyEx(hkey, view, 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_ALL_ACCESS, NULL, &hkey2, &disp) == ERROR_SUCCESS) + { + DWORD data; + WINDOWPLACEMENT wndpl; + GetWindowPlacement(Globals.hMainWnd, &wndpl); + RegSetValueEx(hkey2, placement, 0, REG_BINARY, (BYTE*)&wndpl, + sizeof(WINDOWPLACEMENT)); + /* FIXME: How do we save width and height? */ + if (Globals.szFileName[0] == '\0') + { + data = (DWORD)Globals.sizImage.cx; + RegSetValueEx(hkey2, BMPWidth, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD)); + data = (DWORD)Globals.sizImage.cy; + RegSetValueEx(hkey2, BMPHeight, 0, REG_DWORD, (BYTE*)&data, sizeof(DWORD)); + } + RegCloseKey(hkey2); + } + RegCloseKey(hkey); + } +} + +static VOID PAINT_LoadSettingFromRegistry(void) +{ + HKEY hkey, hkey2; + DWORD size; + static const WCHAR view[] = {'V','i','e','w',0}; + static const WCHAR placement[] = {'W','i','n','d','o','w', + 'P','l','a','c','e','m','e','n','t',0 + }; + static const WCHAR BMPHeight[] = {'B','M','P','H','e','i','g','h','t',0}; + static const WCHAR BMPWidth[] = {'B','M','P','W','i','d','t','h',0}; + if (RegOpenKey(HKEY_CURRENT_USER, paint_reg_key, &hkey) == ERROR_SUCCESS) + { + if (RegOpenKey(hkey, view, &hkey2) == ERROR_SUCCESS) + { + DWORD value; + WINDOWPLACEMENT wndpl; + size = sizeof(WINDOWPLACEMENT); + if (RegQueryValueEx(hkey2, placement, 0, NULL, (BYTE*)&wndpl, + &size) == ERROR_SUCCESS) + { + SetWindowPlacement(Globals.hMainWnd, &wndpl); + } + if (RegQueryValueEx(hkey2, BMPWidth, 0, NULL, (BYTE*)&value, + &size) == ERROR_SUCCESS) + { + Globals.sizImage.cx = (INT)value; + } + if (RegQueryValueEx(hkey2, BMPHeight, 0, NULL, (BYTE*)&value, + &size) == ERROR_SUCCESS) + { + Globals.sizImage.cy = (INT)value; + } + } + } +} + +static int PAINT_OnCommand(WPARAM wParam) +{ + switch (wParam) + { + case CMD_NEW: PAINT_FileNew(); break; + case CMD_OPEN: PAINT_FileOpen(); break; + case CMD_SAVE: PAINT_FileSave(); break; + case CMD_SAVE_AS: PAINT_FileSaveAs(); break; + case CMD_PRINT_PREVIEW: PAINT_FilePrintPreview(); break; + case CMD_PRINT: PAINT_FilePrint(); break; + case CMD_PAGE_SETUP: PAINT_FilePageSetup(); break; + case CMD_WALLPAPAER_TILED: PAINT_SetAsWallpaperTiled(); break; + case CMD_WALLPAPAER_CENTERED: PAINT_SetAsWallpaperCentered(); break; + case CMD_EXIT: PAINT_FileExit(); break; + + case CMD_UNDO: PAINT_EditUndo(); break; + case CMD_REPEAT: PAINT_EditRepeat(); break; + case CMD_CUT: PAINT_EditCut(); break; + case CMD_COPY: PAINT_EditCopy(); break; + case CMD_PASTE: PAINT_EditPaste(); break; + case CMD_DELETE: PAINT_EditDelete(); break; + case CMD_SELECT_ALL: PAINT_EditSelectAll(); break; + case CMD_COPY_TO: PAINT_CopyTo(); break; + case CMD_PASTE_FROM: PAINT_PasteFrom(); break; + + case CMD_TOOL_BOX: PAINT_ToolBox(); break; + case CMD_COLOR_BOX: PAINT_ColorBox(); break; + case CMD_STATUS_BAR: PAINT_StatusBar(); break; + case CMD_ZOOM_NORMAL: PAINT_Zoom(1); break; + case CMD_ZOOM_LARGE: PAINT_Zoom(4); break; + case CMD_SHOW_GRID: PAINT_ShowGrid(); break; + case CMD_ZOOM_CUSTOM: PAINT_ZoomCustom(); break; + + case CMD_FLIP_ROTATE: PAINT_FlipRotate(); break; + case CMD_STRETCH_SKEW: PAINT_StretchSkew(); break; + case CMD_INVERT_COLORS: PAINT_InvertColors(); break; + case CMD_ATTRIBUTES: PAINT_Attributes(); break; + case CMD_CLEAR_IMAGE: PAINT_ClearImage(); break; + case CMD_DRAW_OPAQUE: break; + case CMD_CLEAR_SELECTION: PAINT_ClearSelection(); break; + + case CMD_EDIT_COLOR: PAINT_EditColor(FALSE); break; + + case CMD_HELP_CONTENTS: PAINT_HelpContents(); break; + case CMD_HELP_ON_HELP: PAINT_HelpHelp(); break; + case CMD_HELP_ABOUT_PAINT: PAINT_HelpAboutPaint(); break; + } + return 0; +} + +static VOID PAINT_InitData(VOID) +{ + WCHAR sz[256]; + LPWSTR p = Globals.szFilter; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + static const WCHAR all_files[] = { '*','.','*',0 }; + + LoadString(Globals.hInstance, STRING_BMP_FILES_BMP, p, MAX_STRING_LEN); + p += lstrlen(p) + 1; + lstrcpy(p, bmp_files); + p += lstrlen(p) + 1; + LoadString(Globals.hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN); + p += lstrlen(p) + 1; + lstrcpy(p, all_files); + p += lstrlen(p) + 1; + *p = '\0'; + + Globals.cColors = 28; + CopyMemory(Globals.argbColors, argbDefaultColor, sizeof(Globals.argbColors)); + + Globals.iForeColor = 0; + Globals.iBackColor = 1; + Globals.rgbFore = RGB(0, 0, 0); + Globals.rgbBack = RGB(255, 255, 255); + Globals.iToolSelect = TOOL_PENCIL; + Globals.iToolClicking = -1; + + Globals.hbmImage = NULL; + Globals.hbmBuffer = NULL; + Globals.hbmZoomBuffer = NULL; + Globals.hbmCanvasBuffer = NULL; + + Globals.hbmSelect = NULL; + Globals.fSelect = FALSE; + Globals.fModified = FALSE; + Globals.sizImage.cx = 100; + Globals.sizImage.cy = 100; + Globals.sizCanvas.cx = 0; + Globals.sizCanvas.cy = 0; + + Globals.hcurArrow = LoadCursor(NULL, IDC_ARROW); + Globals.hcurHorizontal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(1)); + Globals.hcurVertical = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(2)); + Globals.hcurBDiagonal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(3)); + Globals.hcurFDiagonal = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(4)); + Globals.hcurPencil = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(5)); + Globals.hcurFill = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(6)); + Globals.hcurSpoit = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(7)); + Globals.hcurAirBrush = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(8)); + Globals.hcurZoom = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(9)); + Globals.hcurCross = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(10)); + Globals.hcurMove = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(11)); + Globals.hcurCross2 = LoadCursor(Globals.hInstance, MAKEINTRESOURCE(12)); + + Globals.fTransparent = FALSE; + Globals.nAirBrushRadius = 6; + Globals.nEraserSize = 8; + Globals.nLineWidth = 1; + Globals.iBrushType = 1; + Globals.iFillStyle = 0; + + Globals.nZoom = 1; + Globals.fShowGrid = FALSE; + Globals.xScrollPos = Globals.yScrollPos = 0; + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); +} + +static VOID PAINT_OnInitMenuPopup(HMENU hMenu, int index) +{ + CheckMenuItem(hMenu, CMD_TOOL_BOX, + IsWindowVisible(Globals.hToolBox) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_COLOR_BOX, + IsWindowVisible(Globals.hColorBox) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_STATUS_BAR, + IsWindowVisible(Globals.hStatusBar) ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hMenu, CMD_SHOW_GRID, + Globals.fShowGrid ? MF_CHECKED : MF_UNCHECKED); + EnableMenuItem(hMenu, CMD_SHOW_GRID, + Globals.nZoom >= 3 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_ZOOM_NORMAL, + Globals.nZoom != 1 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_ZOOM_LARGE, + Globals.nZoom != 4 ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_CLEAR_IMAGE, + Globals.fSelect ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hMenu, CMD_UNDO, + Globals.fCanUndo ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_REPEAT, + !Globals.fCanUndo && Globals.hbmImageUndo ? + MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_CUT, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_COPY, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_PASTE, + IsClipboardFormatAvailable(CF_DIB) ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_DELETE, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); + EnableMenuItem(hMenu, CMD_COPY_TO, + Globals.fSelect ? MF_ENABLED : MF_GRAYED); +} + +VOID ColorBox_OnPaint(HWND hWnd, HDC hDC) +{ + INT i; + HBRUSH hbr; + RECT rc; + + rc.left = 10; + rc.top = 10; + rc.right = rc.left + 34; + rc.bottom = rc.top + 34; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_ADJUST|BF_RECT); + FillRect(hDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + + rc.left = 23; + rc.top = 23; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_RAISED, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + + rc.left = 15; + rc.top = 15; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_RAISED, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.rgbFore); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_ADJUST|BF_RECT); + hbr = CreateSolidBrush(Globals.argbColors[i]); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + } +} + +VOID ColorBox_OnButtonDown(HWND hWnd, INT x, INT y, BOOL fRight) +{ + INT i; + POINT pt; + RECT rc; + + pt.x = x; + pt.y = y; + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + + if (PtInRect(&rc, pt)) + { + if (fRight) + { + Globals.rgbBack = Globals.argbColors[i]; + Globals.iBackColor = i; + } + else + { + Globals.rgbFore = Globals.argbColors[i]; + Globals.iForeColor = i; + } + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } +} + +VOID ColorBox_OnButtonDblClk(HWND hWnd, INT x, INT y, BOOL fRight) +{ + INT i; + POINT pt; + RECT rc; + + pt.x = x; + pt.y = y; + + for (i = 0; i < SIZEOF(argbDefaultColor); i++) + { + rc.left = 60 + i / 2 * 17; + rc.top = 10 + (i % 2) * 17; + rc.right = rc.left + 16; + rc.bottom = rc.top + 16; + + if (PtInRect(&rc, pt)) + { + PAINT_EditColor(fRight); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + return; + } + } +} + +LRESULT CALLBACK ColorBoxWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_LBUTTONDOWN: + ColorBox_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDOWN: + ColorBox_OnButtonDown(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONDBLCLK: + ColorBox_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), FALSE); + break; + + case WM_RBUTTONDBLCLK: + ColorBox_OnButtonDblClk(hWnd, (INT)(SHORT)LOWORD(lParam), + (INT)(SHORT)HIWORD(lParam), TRUE); + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + ColorBox_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +VOID ToolBox_OnPaint(HWND hWnd, HDC hDC) +{ + HBITMAP hbm, hbmOld; + INT i; + RECT rc; + POINT pt; + HDC hdcMem; + INT cMap; + COLORMAP aMap[] = + { + {RGB(255, 0, 0), 0}, + {RGB(0, 0, 0), RGB(255, 255, 255)}, + }; + + aMap[0].to = GetSysColor(COLOR_3DFACE); + if (GetSysColor(COLOR_3DFACE) == RGB(0, 0, 0)) + cMap = 2; + else + cMap = 1; + + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + hbm = CreateMappedBitmap(Globals.hInstance, IDB_TOOLS, 0, + aMap, cMap); + hbmOld = SelectObject(hdcMem, hbm); + + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + + GetCursorPos(&pt); + ScreenToClient(hWnd, &pt); + if (Globals.iToolSelect == i || (Globals.iToolClicking == i && PtInRect(&rc, pt))) + { + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_RECT | BF_SOFT); + BitBlt(hDC, rc.left + 5, rc.top + 5, 16, 16, + hdcMem, i * 16, 0, SRCCOPY); + } + else + { + DrawEdge(hDC, &rc, EDGE_RAISED, BF_RECT | BF_SOFT); + BitBlt(hDC, rc.left + 4, rc.top + 4, 16, 16, + hdcMem, i * 16, 0, SRCCOPY); + } + } + + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 5; + rc.top = 210; + rc.right = 49; + rc.bottom = 290; + DrawEdge(hDC, &rc, EDGE_SUNKEN, BF_RECT|BF_ADJUST); + + switch (Globals.iToolSelect) + { + case TOOL_ERASER: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_ERASER)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 6; + rc.right = 48; + switch (Globals.nEraserSize) + { + case 4: + rc.top = 210 + (290 - 210) * 0 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 6: + rc.top = 210 + (290 - 210) * 1 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 8: + rc.top = 210 + (290 - 210) * 2 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 10: + rc.top = 210 + (290 - 210) * 3 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + } + break; + + case TOOL_LINE: + case TOOL_CURVE: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_LINE)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + if (Globals.nLineWidth == 0) + Globals.nLineWidth = 1; + rc.left = 6; + rc.top = 210 + (290 - 210) * (Globals.nLineWidth - 1) / 5; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 5; + InvertRect(hDC, &rc); + break; + + case TOOL_MAGNIFIER: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_ZOOM)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 6; + rc.right = 48; + switch (Globals.nZoom) + { + case 1: + rc.top = 210 + (290 - 210) * 0 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 2: + rc.top = 210 + (290 - 210) * 1 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 6: + rc.top = 210 + (290 - 210) * 2 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + case 8: + rc.top = 210 + (290 - 210) * 3 / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + } + break; + + case TOOL_SPOIT: + if (Globals.rgbSpoit != CLR_INVALID) + { + HBRUSH hbr = CreateSolidBrush(Globals.rgbSpoit); + FillRect(hDC, &rc, hbr); + DeleteObject(hbr); + } + break; + + case TOOL_BRUSH: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_BRUSH)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 6 + (48 - 6) * (Globals.iBrushType % 3) / 3; + rc.right = rc.left + (48 - 6) / 3; + rc.top = 210 + (290 - 210) * (Globals.iBrushType / 3) / 4; + rc.bottom = rc.top + (290 - 210) / 4; + InvertRect(hDC, &rc); + break; + + case TOOL_BOX: + case TOOL_POLYGON: + case TOOL_ROUNDRECT: + case TOOL_ELLIPSE: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_FILL)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 6; + rc.top = 210 + (290 - 210) * Globals.iFillStyle / 3; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 3; + InvertRect(hDC, &rc); + break; + + case TOOL_BOXSELECT: + case TOOL_POLYSELECT: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_TRANS)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + rc.left = 6; + rc.top = 210 + (290 - 210) * Globals.fTransparent / 2; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 2; + InvertRect(hDC, &rc); + break; + + case TOOL_AIRBRUSH: + hbm = LoadBitmap(Globals.hInstance, MAKEINTRESOURCE(IDB_AIRBRUSH)); + hbmOld = SelectObject(hdcMem, hbm); + BitBlt(hDC, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hbmOld); + DeleteObject(hbm); + + switch (Globals.nAirBrushRadius) + { + case 6: + rc.left = 5; + rc.top = 210; + rc.right = 27; + rc.bottom = 250; + break; + + case 10: + rc.left = 28; + rc.top = 210; + rc.right = 49; + rc.bottom = 250; + break; + + case 14: + rc.left = 5; + rc.top = 251; + rc.right = 49; + rc.bottom = 290; + break; + } + InvertRect(hDC, &rc); + break; + + default: + break; + } + DeleteDC(hdcMem); + } +} + +void ToolBox_OnLButton(HWND hWnd, int x, int y, BOOL fDown) +{ + RECT rc; + POINT pt; + INT i; + static const WCHAR not_supported[] = {'N','o','t',' ','s','u','p','p','o', + 'r','t','e','d',' ','y','e','t',0}; + + pt.x = x; + pt.y = y; + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + if (PtInRect(&rc, pt)) + { + if (!fDown && Globals.iToolClicking == i) + { + Globals.iToolPrev = Globals.iToolSelect; + Globals.iToolSelect = i; + Globals.iToolClicking = -1; + Globals.ipt = 0; + if (Globals.pPolyline != NULL) + HeapFree(GetProcessHeap(), 0, Globals.pPolyline); + Globals.pPolyline = NULL; + Globals.cPolyline = 0; + Selection_Land(); + SetRectEmpty((RECT*)&Globals.pt0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + + switch (i) + { + case TOOL_SPOIT: + Globals.rgbSpoit = CLR_INVALID; + break; + + case TOOL_POLYSELECT: + case TOOL_TEXT: + MessageBox(Globals.hMainWnd, not_supported, NULL, + MB_ICONERROR|MB_OK); + break; + + default: + break; + } + } + else if (fDown) + { + Globals.iToolClicking = i; + SetCapture(hWnd); + } + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + return; + } + } + + switch (Globals.iToolSelect) + { + case TOOL_BRUSH: + for (i = 0; i < 12; i++) + { + rc.left = 6 + (48 - 6) * (i % 3) / 3; + rc.right = rc.left + (48 - 6) / 3; + rc.top = 210 + (290 - 210) * (i / 3) / 4; + rc.bottom = rc.top + (290 - 210) / 4; + + if (PtInRect(&rc, pt)) + { + Globals.iBrushType = i; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } + Globals.pt0.x = Globals.pt0.y = 0xFFFFFFFF; + break; + + case TOOL_BOX: + case TOOL_ROUNDRECT: + case TOOL_ELLIPSE: + case TOOL_POLYGON: + for (i = 0; i < 3; i++) + { + rc.left = 6; + rc.top = 210 + (290 - 210) * i / 3; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 3; + + if (PtInRect(&rc, pt)) + { + Globals.iFillStyle = i; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } + break; + + case TOOL_ERASER: + rc.left = 6; + rc.right = 48; + for (i = 0; i < 4; i++) + { + rc.top = 210 + (290 - 210) * i / 4; + rc.bottom = rc.top + (290 - 210) / 4; + if (PtInRect(&rc, pt)) + { + Globals.nEraserSize = 4 + i * 2; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } + break; + + case TOOL_BOXSELECT: + case TOOL_POLYSELECT: + rc.left = 6; + rc.top = 210 + (290 - 210) * 0 / 2; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 2; + if (PtInRect(&rc, pt)) + { + Globals.fTransparent = FALSE; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + rc.left = 6; + rc.top = 210 + (290 - 210) * 1 / 2; + rc.right = 48; + rc.bottom = rc.top + (290 - 210) / 2; + if (PtInRect(&rc, pt)) + { + Globals.fTransparent = TRUE; + MessageBox(hWnd, L"Not supported yet", NULL, MB_ICONERROR); + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + break; + + case TOOL_MAGNIFIER: + rc.left = 6; + rc.right = 48; + for (i = 0; i < 4; i++) + { + rc.top = 210 + (290 - 210) * i / 4; + rc.bottom = rc.top + (290 - 210) / 4; + if (PtInRect(&rc, pt)) + { + switch (i) + { + case 0: + PAINT_Zoom(1); + break; + case 1: + PAINT_Zoom(2); + break; + case 2: + PAINT_Zoom(6); + break; + case 3: + PAINT_Zoom(8); + break; + } + Globals.iToolSelect = Globals.iToolPrev; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } + break; + + case TOOL_LINE: + case TOOL_CURVE: + rc.left = 6; + rc.right = 48; + for (i = 0; i < 5; i++) + { + rc.top = 210 + (290 - 210) * i / 5; + rc.bottom = rc.top + (290 - 210) / 5; + if (PtInRect(&rc, pt)) + { + Globals.nLineWidth = i + 1; + InvalidateRect(hWnd, NULL, TRUE); + UpdateWindow(hWnd); + break; + } + } + break; + + case TOOL_AIRBRUSH: + rc.left = 5; + rc.top = 210; + rc.right = 27; + rc.bottom = 250; + if (PtInRect(&rc, pt)) + { + Globals.nAirBrushRadius = 6; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + return; + } + rc.left = 28; + rc.top = 210; + rc.right = 49; + rc.bottom = 250; + if (PtInRect(&rc, pt)) + { + Globals.nAirBrushRadius = 10; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + return; + } + rc.left = 5; + rc.top = 251; + rc.right = 49; + rc.bottom = 290; + if (PtInRect(&rc, pt)) + { + Globals.nAirBrushRadius = 14; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + return; + } + break; + + default: + rc.left = 6; + rc.top = 210; + rc.right = 48; + rc.bottom = 290; + if (PtInRect(&rc, pt)) + { + MessageBeep(0xFFFFFFFF); + } + } +} + +void ToolBox_OnMouseMove(HWND hWnd, int x, int y, BOOL fDown) +{ + RECT rc; + POINT pt; + WCHAR sz[256]; + INT i; + pt.x = x; + pt.y = y; + + if (!fDown) + { + ReleaseCapture(); + Globals.iToolClicking = -1; + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + } + else if (Globals.iToolClicking != -1) + { + rc.left = 3 + Globals.iToolClicking % 2 * 25; + rc.top = 3 + Globals.iToolClicking / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + InvalidateRect(Globals.hToolBox, NULL, FALSE); + UpdateWindow(Globals.hToolBox); + return; + } + + for (i = 0; i < 16; i++) + { + rc.left = 3 + i % 2 * 25; + rc.top = 3 + i / 2 * 25; + rc.right = rc.left + 25; + rc.bottom = rc.top + 25; + if (PtInRect(&rc, pt)) + { + LoadString(Globals.hInstance, i + STRING_POLYSELECT, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + return; + } + } + + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); +} + +static LRESULT CALLBACK ToolBoxWndProc(HWND hWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_LBUTTONDOWN: + ToolBox_OnLButton(hWnd, LOWORD(lParam), HIWORD(lParam), TRUE); + break; + + case WM_LBUTTONUP: + ToolBox_OnLButton(hWnd, LOWORD(lParam), HIWORD(lParam), FALSE); + break; + + case WM_MOUSEMOVE: + ToolBox_OnMouseMove(hWnd, LOWORD(lParam), HIWORD(lParam), wParam & MK_LBUTTON); + break; + + case WM_CAPTURECHANGED: + Globals.iToolClicking = -1; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + break; + + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + if (hDC != NULL) + { + ToolBox_OnPaint(hWnd, hDC); + EndPaint(hWnd, &ps); + } + break; + } + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +VOID SetParts(HWND hWnd) +{ + INT aWidth[3]; + RECT rc; + + GetClientRect(hWnd, &rc); + if (rc.right - rc.left < 450) + { + aWidth[0] = 250; + aWidth[1] = 300; + aWidth[2] = 350; + } + else + { + aWidth[0] = rc.right - rc.left - 250; + aWidth[1] = rc.right - rc.left - 125; + aWidth[2] = rc.right - rc.left - 20; + } + SendMessage(Globals.hStatusBar, SB_SETPARTS, 3, (LPARAM)aWidth); +} + +VOID PAINT_OnDestroy(HWND hWnd) +{ + if (Globals.hbmImage != NULL) DeleteObject(Globals.hbmImage); + if (Globals.hbmBuffer != NULL) DeleteObject(Globals.hbmBuffer); + if (Globals.hbmZoomBuffer != NULL) DeleteObject(Globals.hbmZoomBuffer); + if (Globals.hbmCanvasBuffer != NULL) DeleteObject(Globals.hbmCanvasBuffer); + if (Globals.hbmImageUndo != NULL) DeleteObject(Globals.hbmImageUndo); + if (Globals.hbmSelect != NULL) DeleteObject(Globals.hbmSelect); + DestroyCursor(Globals.hcurArrow); + DestroyCursor(Globals.hcurBDiagonal); + DestroyCursor(Globals.hcurFDiagonal); + DestroyCursor(Globals.hcurHorizontal); + DestroyCursor(Globals.hcurVertical); + DestroyCursor(Globals.hcurPencil); + DestroyCursor(Globals.hcurFill); + DestroyCursor(Globals.hcurSpoit); + DestroyCursor(Globals.hcurAirBrush); + DestroyCursor(Globals.hcurZoom); + DestroyCursor(Globals.hcurCross); + DestroyCursor(Globals.hcurMove); + KillTimer(Globals.hCanvasWnd, Globals.idTimer); + if (Globals.pPolyline != NULL) + HeapFree(GetProcessHeap(), 0, Globals.pPolyline); +} + +static LRESULT CALLBACK PaintWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + RECT rc; + WCHAR sz[MAX_STRING_LEN]; + WCHAR wszTitle[] = {0}; + + switch (uMsg) + { + case WM_CREATE: + GetClientRect(hWnd, &rc); + Globals.hCanvasWnd = CreateWindowEx(WS_EX_CLIENTEDGE, canvasClassName, + wszTitle, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, hWnd, + NULL, Globals.hInstance, NULL); + if (Globals.hCanvasWnd == NULL) + return -1; + Globals.hColorBox = CreateWindowEx(WS_EX_WINDOWEDGE, + colorBoxClassName, wszTitle, WS_CHILD|WS_VISIBLE, + 0, 0, 0, 0, hWnd, NULL, Globals.hInstance, NULL); + if (Globals.hColorBox == NULL) + return -1; + Globals.hStatusBar = CreateStatusWindow(WS_VISIBLE|WS_CHILD, + wszTitle, hWnd, 3); + if (Globals.hStatusBar == NULL) + return -1; + Globals.hToolBox = CreateWindowEx(WS_EX_WINDOWEDGE, toolBoxClassName, + wszTitle, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0, hWnd, + NULL, Globals.hInstance, NULL); + if (Globals.hToolBox == NULL) + return -1; + + SetParts(hWnd); + break; + + case WM_KEYDOWN: + SendMessage(Globals.hCanvasWnd, uMsg, wParam, lParam); + break; + + case WM_COMMAND: + PAINT_OnCommand(LOWORD(wParam)); + break; + + case WM_MENUSELECT: + if ((HIWORD(wParam) & (MF_SYSMENU|MF_POPUP|MF_SEPARATOR)) == 0) + { + LoadString(Globals.hInstance, LOWORD(wParam) + 0x200, sz, MAX_STRING_LEN); + } + else if ((HIWORD(wParam) & (MF_SYSMENU|MF_POPUP|MF_SEPARATOR)) == MF_SYSMENU) + { + INT id; + switch(LOWORD(wParam)) + { + case SC_SIZE: id = STRING_SIZE; break; + case SC_MOVE: id = STRING_MOVE; break; + case SC_MINIMIZE: id = STRING_MINIMIZE; break; + case SC_MAXIMIZE: id = STRING_MAXIMIZE; break; + case SC_NEXTWINDOW: id = STRING_NEXTWINDOW; break; + case SC_PREVWINDOW: id = STRING_PREVWINDOW; break; + case SC_CLOSE: id = STRING_CLOSE; break; + case SC_RESTORE: id = STRING_RESTORE; break; + case SC_TASKLIST: id = STRING_TASKLIST; break; + default: id = STRING_READY; + } + LoadString(Globals.hInstance, id, sz, MAX_STRING_LEN); + } + else + { + sz[0] = '\0'; + } + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + break; + + case WM_EXITMENULOOP: + LoadString(Globals.hInstance, STRING_READY, sz, 256); + SendMessage(Globals.hStatusBar, SB_SETTEXT, 0 | 0, (LPARAM)sz); + break; + + case WM_CLOSE: + if (DoCloseFile()) + { + DestroyWindow(hWnd); + } + break; + + case WM_GETMINMAXINFO: + { + MINMAXINFO *pmmi = (MINMAXINFO*)lParam; + pmmi->ptMinTrackSize.x = 330; + pmmi->ptMinTrackSize.y = 410; + break; + } + + case WM_SIZE: + { + RECT rc2; + INT leftSave; + HDWP hDwp; + + GetClientRect(hWnd, &rc); + + hDwp = BeginDeferWindowPos(1 + + !!IsWindowVisible(Globals.hStatusBar) + + !!IsWindowVisible(Globals.hColorBox) + + !!IsWindowVisible(Globals.hToolBox)); + if (IsWindowVisible(Globals.hStatusBar)) + { + PostMessage(Globals.hStatusBar, WM_SIZE, 0, 0); + GetWindowRect(Globals.hStatusBar, &rc2); + DeferWindowPos(hDwp, Globals.hStatusBar, NULL, + rc2.left, rc2.top, + rc2.right - rc2.left, rc2.bottom - rc2.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + rc.bottom -= (rc2.bottom - rc2.top); + } + if (IsWindowVisible(Globals.hColorBox)) + { + rc.bottom -= 55; + } + leftSave = rc.left; + if (IsWindowVisible(Globals.hToolBox)) + { + LONG rightSave = rc.right; + rc.right = rc.left + 60; + DeferWindowPos(hDwp, Globals.hToolBox, NULL, + rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + rc.left = rc.right; + rc.right = rightSave; + } + DeferWindowPos(hDwp, Globals.hCanvasWnd, NULL, + rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + if (IsWindowVisible(Globals.hColorBox)) + { + rc.left = leftSave; + rc.top = rc.bottom; + rc.bottom = rc.top + 55; + DeferWindowPos(hDwp, Globals.hColorBox, NULL, rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOACTIVATE | SWP_NOREPOSITION | SWP_NOZORDER); + } + EndDeferWindowPos(hDwp); + SetParts(hWnd); + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + break; + } + + case WM_QUERYENDSESSION: + if (DoCloseFile()) + return 1; + break; + + case WM_DESTROY: + PAINT_SaveSettingToRegistry(); + PAINT_OnDestroy(hWnd); + PostQuitMessage(0); + break; + + case WM_SETFOCUS: + break; + + case WM_DROPFILES: + { + WCHAR szFileName[MAX_PATH]; + HDROP hDrop = (HDROP)wParam; + + DragQueryFile(hDrop, 0, szFileName, SIZEOF(szFileName)); + DragFinish(hDrop); + DoOpenFile(szFileName); + break; + } + + case WM_INITMENUPOPUP: + PAINT_OnInitMenuPopup((HMENU)wParam, lParam); + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + return 0; +} + +static int AlertFileDoesNotExist(LPCWSTR szFileName) +{ + int nResult; + WCHAR szMessage[MAX_STRING_LEN]; + WCHAR szResource[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, STRING_DOESNOTEXIST, szResource, + SIZEOF(szResource)); + wsprintf(szMessage, szResource, szFileName); + + MessageBeep(MB_ICONEXCLAMATION); + nResult = MessageBox(Globals.hMainWnd, szMessage, NULL, + MB_ICONEXCLAMATION | MB_YESNO); + + return nResult; +} + +static void HandleCommandLine(LPWSTR cmdline) +{ + WCHAR delimiter; + int opt_print = 0; + + /* skip white space */ + while (*cmdline == ' ') cmdline++; + + /* skip executable name */ + delimiter = (*cmdline == '"' ? '"' : ' '); + + if (*cmdline == delimiter) cmdline++; + + while (*cmdline && *cmdline != delimiter) cmdline++; + + if (*cmdline == delimiter) cmdline++; + + while (*cmdline == ' ' || *cmdline == '-' || *cmdline == '/') + { + WCHAR option; + + if (*cmdline++ == ' ') continue; + + option = *cmdline; + if (option) cmdline++; + while (*cmdline == ' ') cmdline++; + + switch (option) + { + case 'p': + case 'P': + opt_print=1; + break; + } + } + + if (*cmdline) + { + LPCWSTR file_name; + BOOL file_exists; + WCHAR buf[MAX_PATH]; + + if (cmdline[0] == '"') + { + WCHAR* wc; + cmdline++; + wc = cmdline; + while (*wc && *wc != '"') wc++; + *wc = 0; + } + + if (FileExists(cmdline)) + { + file_exists = TRUE; + file_name = cmdline; + } + else + { + static const WCHAR txtW[] = { '.','b','m','p',0 }; + + /* try to find file with ".txt" extension */ + if (!lstrcmp(txtW, cmdline + lstrlen(cmdline) - lstrlen(txtW))) + { + file_exists = FALSE; + file_name = cmdline; + } + else + { + lstrcpyn(buf, cmdline, MAX_PATH - lstrlen(txtW) - 1); + lstrcat(buf, txtW); + file_name = buf; + file_exists = FileExists(buf); + } + } + + if (file_exists) + { + DoOpenFile(file_name); + InvalidateRect(Globals.hMainWnd, NULL, FALSE); + if (opt_print) + PAINT_FilePrint(); + } + else + { + switch (AlertFileDoesNotExist(file_name)) + { + case IDYES: + DoOpenFile(file_name); + break; + + case IDNO: + break; + } + } + } +} + +int WINAPI WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR pszCmdLine, + int nCmdShow) +{ + MSG msg; + HACCEL hAccel; + WNDCLASSEX wcx; + + static const WCHAR className[] = {'P','a','i','n','t',0}; + static const WCHAR winName[] = {'P','a','i','n','t',0}; + + ZeroMemory(&Globals, sizeof(Globals)); + Globals.hInstance = hInstance; + + ZeroMemory(&wcx, sizeof(wcx)); + wcx.cbSize = sizeof(wcx); + wcx.lpfnWndProc = PaintWndProc; + wcx.hInstance = Globals.hInstance; + wcx.hIcon = LoadIcon(Globals.hInstance, MAKEINTRESOURCE(IDI_PAINT)); + wcx.hCursor = LoadCursor(0, IDC_ARROW); + wcx.hbrBackground = (HBRUSH)(COLOR_3DDKSHADOW + 1); + wcx.lpszMenuName = MAKEINTRESOURCE(MAIN_MENU); + wcx.lpszClassName = className; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.style = CS_DBLCLKS; + wcx.lpfnWndProc = CanvasWndProc; + wcx.hIcon = NULL; + wcx.hbrBackground = NULL; + wcx.lpszMenuName = NULL; + wcx.lpszClassName = canvasClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.lpfnWndProc = ColorBoxWndProc; + wcx.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); + wcx.lpszClassName = colorBoxClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + wcx.style = 0; + wcx.lpfnWndProc = ToolBoxWndProc; + wcx.lpszClassName = toolBoxClassName; + + if (!RegisterClassEx(&wcx)) return FALSE; + + Globals.hMainWnd = CreateWindow(className, winName, + WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN, + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, + Globals.hInstance, NULL); + if (Globals.hMainWnd == NULL) + { + ShowLastError(); + return 1; + } + + PAINT_InitData(); + PAINT_LoadSettingFromRegistry(); + PAINT_FileNew(); + + ShowWindow(Globals.hMainWnd, nCmdShow); + UpdateWindow(Globals.hMainWnd); + DragAcceptFiles(Globals.hMainWnd, TRUE); + + HandleCommandLine(GetCommandLine()); + + hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(ID_ACCEL)); + + while (GetMessage(&msg, 0, 0, 0)) + { + if (!TranslateAccelerator(Globals.hMainWnd, hAccel, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return msg.wParam; +} diff --git a/programs/paint/main.h b/programs/paint/main.h new file mode 100644 index 0000000..aa26479 --- /dev/null +++ b/programs/paint/main.h @@ -0,0 +1,179 @@ +/* + * Paint (main.h) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define MAX_STRING_LEN 255 + +#define SIZEOF(a) sizeof(a)/sizeof((a)[0]) + +typedef enum +{ + MODE_NORMAL, + MODE_RIGHT_EDGE, + MODE_DOWN_EDGE, + MODE_LOWER_RIGHT_EDGE, + MODE_SELECTION, + MODE_CANVAS +} MODE; + +typedef enum +{ + TOOL_POLYSELECT, + TOOL_BOXSELECT, + TOOL_ERASER, + TOOL_FILL, + TOOL_SPOIT, + TOOL_MAGNIFIER, + TOOL_PENCIL, + TOOL_BRUSH, + TOOL_AIRBRUSH, + TOOL_TEXT, + TOOL_LINE, + TOOL_CURVE, + TOOL_BOX, + TOOL_POLYGON, + TOOL_ELLIPSE, + TOOL_ROUNDRECT +} TOOL; + +typedef struct +{ + HANDLE hInstance; + + HWND hMainWnd; + HWND hCanvasWnd; + HWND hToolBox; + HWND hColorBox; + HWND hStatusBar; + HWND hTextTool; + + SIZE sizImage; + SIZE sizCanvas; + HBITMAP hbmImage; + HBITMAP hbmBuffer; + HBITMAP hbmZoomBuffer; + HBITMAP hbmCanvasBuffer; + + BOOL fCanUndo; + HBITMAP hbmImageUndo; + SIZE sizImageUndo; + + BOOL fSelect; + HBITMAP hbmSelect; + + BOOL fModified; + + INT cColors; + COLORREF argbColors[28]; + INT iForeColor; + INT iBackColor; + COLORREF rgbFore; + COLORREF rgbBack; + + WCHAR szFileName[MAX_PATH]; + WCHAR szFileTitle[MAX_PATH]; + WCHAR szFilter[1024]; + + TOOL iToolSelect; + TOOL iToolClicking; + TOOL iToolPrev; + + HCURSOR hcurArrow; + HCURSOR hcurBDiagonal; + HCURSOR hcurFDiagonal; + HCURSOR hcurHorizontal; + HCURSOR hcurVertical; + HCURSOR hcurPencil; + HCURSOR hcurFill; + HCURSOR hcurSpoit; + HCURSOR hcurAirBrush; + HCURSOR hcurZoom; + HCURSOR hcurCross; + HCURSOR hcurMove; + HCURSOR hcurCross2; + + UINT idTimer; + COLORREF rgbSpoit; + + INT nZoom; + BOOL fShowGrid; + + BOOL fTransparent; + INT nAirBrushRadius; + INT nEraserSize; + INT nLineWidth; + INT iBrushType; + INT iFillStyle; + + INT xScrollPos; + INT yScrollPos; + + MODE mode; + BOOL fSwapColor; + POINT pt0; + POINT pt1; + POINT pt2; + POINT pt3; + INT ipt; + COLORREF rgbPrev; + + INT cPolyline; + POINT *pPolyline; +} PAINT_GLOBALS; + +extern PAINT_GLOBALS Globals; + +/* main.c */ +VOID SetFileName(LPCWSTR szFileName); + +/* canvas.c */ +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); +HBITMAP Selection_CreateBitmap(VOID); +VOID Selection_TakeOff(VOID); +VOID Selection_Land(VOID); +VOID Selection_Stretch(HWND hWnd, SIZE sizNew); +VOID Selection_HFlip(HWND hWnd); +VOID Selection_VFlip(HWND hWnd); +VOID Selection_Rotate90Degree(HWND hWnd); +VOID Selection_Rotate180Degree(HWND hWnd); +VOID Selection_Rotate270Degree(HWND hWnd); + +/* bitmap.c */ +HBITMAP BM_Load(LPCWSTR pszFileName); +BOOL BM_Save(LPCWSTR pszFileName, HBITMAP hbm); +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_CreateRotated(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); +HGLOBAL BM_Pack(HBITMAP hbm); +HBITMAP BM_Unpack(HGLOBAL hPack); diff --git a/programs/paint/move.cur b/programs/paint/move.cur new file mode 100644 index 0000000000000000000000000000000000000000..b1050d3ef8f93c09b4aec53563c689cf382bcba4 GIT binary patch literal 326 zcmbV{F%H5&38Yo*s(dd{UsJ>cF*x0O`5#>d(o&ds^^owLST#f~@J+;jH; literal 0 HcmV?d00001 diff --git a/programs/paint/paint.c b/programs/paint/paint.c new file mode 100644 index 0000000..91e3a0d --- /dev/null +++ b/programs/paint/paint.c @@ -0,0 +1,1243 @@ +/* + * Paint (paint.c) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define UNICODE + +#include +#include +#include +#include + +#include "main.h" +#include "paint.h" +#include "resource.h" + +static const WCHAR helpfileW[] = + { 'p','a','i','n','t','.','h','l','p',0 }; + +static const WCHAR desktop_key[] = + {'C','o','n','t','r','o','l',' ', + 'P','a','n','e','l','\\', + 'D','e','s','k','t','o','p',0 + }; +static const WCHAR wallpaper_style[] = + {'W','a','l','l','p','a','p','e','r', + 'S','t','y','l','e',0 + }; +static const WCHAR tile_wallpaper[] = + {'T','i','l','e', + 'W','a','l','l','p','a','p','e','r',0 + }; + +COLORREF aCustColors[16] = +{ + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255), + RGB(255, 255, 255) +}; + +VOID ShowLastError(void) +{ + WCHAR szMsg[MAX_STRING_LEN]; + LONG nError = GetLastError(); + if (nError != NO_ERROR) + { + if (nError > 0) + { + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, nError, 0, szMsg, MAX_STRING_LEN, NULL); + } + else + { + LoadString(Globals.hInstance, -nError, szMsg, MAX_STRING_LEN); + } + MessageBeep(MB_ICONERROR); + MessageBox(NULL, szMsg, NULL, MB_OK | MB_ICONERROR); + } +} + +static void UpdateWindowCaption(void) +{ + WCHAR szCaption[MAX_STRING_LEN]; + WCHAR szPaint[MAX_STRING_LEN]; + static const WCHAR hyphenW[] = { ' ','-',' ',0 }; + + if (Globals.szFileTitle[0] != '\0') + lstrcpy(szCaption, Globals.szFileTitle); + else + LoadString(Globals.hInstance, STRING_UNTITLED, szCaption, + MAX_STRING_LEN); + + LoadString(Globals.hInstance, STRING_PAINT, szPaint, MAX_STRING_LEN); + lstrcat(szCaption, hyphenW); + lstrcat(szCaption, szPaint); + + SetWindowText(Globals.hMainWnd, szCaption); +} + +int PAINT_StringMsgBox(HWND hParent, int formatId, LPCWSTR szString, + UINT uFlags) +{ + WCHAR szMessage[MAX_STRING_LEN]; + WCHAR szResource[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, formatId, szResource, MAX_STRING_LEN); + wnsprintf(szMessage, MAX_STRING_LEN, szResource, szString); + + LoadString(Globals.hInstance, STRING_PAINT, szResource, MAX_STRING_LEN); + + if (hParent == NULL) + hParent = Globals.hMainWnd; + + MessageBeep(uFlags & MB_ICONMASK); + return MessageBox(hParent, szMessage, szResource, uFlags); +} + +static void AlertFileNotFound(LPCWSTR szFileName) +{ + PAINT_StringMsgBox(NULL, STRING_NOTFOUND, szFileName, + MB_ICONEXCLAMATION | MB_OK); +} + +static int AlertFileNotSaved(LPCWSTR szFileName) +{ + WCHAR szUntitled[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, STRING_UNTITLED, szUntitled, MAX_STRING_LEN); + return PAINT_StringMsgBox(NULL, STRING_SAVECHANGE, + szFileName[0] ? szFileName : szUntitled, + MB_ICONWARNING | MB_YESNOCANCEL); +} + +BOOL FileExists(LPCWSTR szFileName) +{ + WIN32_FIND_DATA entry; + HANDLE hFile; + + hFile = FindFirstFile(szFileName, &entry); + FindClose(hFile); + + return (hFile != INVALID_HANDLE_VALUE); +} + +static VOID DoSaveFile(VOID) +{ + /* FIXME: Support different BPP */ + /* FIXME: Support GIF, JPEG, PNG files */ + if (BM_Save(Globals.szFileName, Globals.hbmImage)) + Globals.fModified = FALSE; +} + +/** + * Returns: + * TRUE - User agreed to close (both save/don't save) + * FALSE - User cancelled close by selecting "Cancel" + */ +BOOL DoCloseFile(void) +{ + int nResult; + static const WCHAR empty_strW[] = { 0 }; + + if (Globals.fModified) + { + nResult = AlertFileNotSaved(Globals.szFileName); + switch (nResult) + { + case IDYES: + if (!PAINT_FileSave()) + return FALSE; + break; + + case IDNO: + break; + + case IDCANCEL: + return FALSE; + + default: + return FALSE; + } + } + + SetFileName(empty_strW); + UpdateWindowCaption(); + return TRUE; +} + +void DoOpenFile(LPCWSTR pszFileName) +{ + HANDLE hFile; + BOOL fEmpty; + DWORD filesize; + BITMAP bm; + + if (!DoCloseFile()) + return; + + if (!FileExists(pszFileName)) + { + AlertFileNotFound(pszFileName); + return; + } + + /* FIXME: Support PCX, ICO, GIF, JPEG, PNG files */ + fEmpty = TRUE; + hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + filesize = GetFileSize(hFile, NULL); + if (filesize != 0) + { + fEmpty = FALSE; + } + CloseHandle(hFile); + + if (!fEmpty) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = BM_Load(pszFileName); + GetObject(Globals.hbmImage, sizeof(BITMAP), &bm); + Globals.sizImage.cx = bm.bmWidth; + Globals.sizImage.cy = bm.bmHeight; + } + + SetFileName(pszFileName); + UpdateWindowCaption(); + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_FileNew(VOID) +{ + HDC hDC, hdcMem; + HGDIOBJ hbmOld; + RECT rc; + SIZE sizZoom; + + if (DoCloseFile()) + { + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + if (Globals.hbmImage != NULL) + DeleteObject(Globals.hbmImage); + Globals.hbmImage = BM_Create(Globals.sizImage); + + hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + FillRect(hdcMem, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + SelectObject(hdcMem, hbmOld); + + if (Globals.hbmBuffer != NULL) + DeleteObject(Globals.hbmBuffer); + Globals.hbmBuffer = BM_Copy(Globals.hbmImage); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + sizZoom.cx = Globals.sizImage.cx * Globals.nZoom; + sizZoom.cy = Globals.sizImage.cy * Globals.nZoom; + Globals.hbmZoomBuffer = BM_Create(sizZoom); + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + } + + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_FileOpen(VOID) +{ + OPENFILENAME ofn; + WCHAR szFileName[MAX_PATH]; + WCHAR szDir[MAX_PATH]; + static const WCHAR szDefaultExt[] = { 'b','m','p',0 }; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + + ZeroMemory(&ofn, sizeof(ofn)); + + GetCurrentDirectory(MAX_PATH, szDir); + lstrcpy(szFileName, bmp_files); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = Globals.hMainWnd; + ofn.hInstance = Globals.hInstance; + ofn.lpstrFilter = Globals.szFilter; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrInitialDir = szDir; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | + OFN_HIDEREADONLY; + ofn.lpstrDefExt = szDefaultExt; + + if (GetOpenFileName(&ofn)) + DoOpenFile(szFileName); +} + +BOOL PAINT_FileSave(VOID) +{ + if (Globals.szFileName[0] == '\0') + return PAINT_FileSaveAs(); + else + DoSaveFile(); + return TRUE; +} + +BOOL PAINT_FileSaveAs(VOID) +{ + OPENFILENAME ofn; + WCHAR szPath[MAX_PATH]; + WCHAR szDir[MAX_PATH]; + static const WCHAR szDefaultExt[] = { 'b','m','p',0 }; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + + ZeroMemory(&ofn, sizeof(ofn)); + + GetCurrentDirectory(MAX_PATH, szDir); + lstrcpy(szPath, bmp_files); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = Globals.hMainWnd; + ofn.hInstance = Globals.hInstance; + ofn.lpstrFilter = Globals.szFilter; + ofn.lpstrFile = szPath; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrInitialDir = szDir; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | + OFN_HIDEREADONLY; + ofn.lpstrDefExt = szDefaultExt; + + if (GetSaveFileName(&ofn)) + { + SetFileName(szPath); + UpdateWindowCaption(); + DoSaveFile(); + return TRUE; + } + return FALSE; +} + +VOID PAINT_FilePrintPreview(VOID) +{ +} + +VOID PAINT_FilePrint(VOID) +{ +} + +VOID PAINT_FilePageSetup(VOID) +{ +} + +VOID PAINT_SetAsWallpaperTiled(VOID) +{ +} + +VOID PAINT_SetAsWallpaperCentered(VOID) +{ +} + +VOID PAINT_FileExit(VOID) +{ + PostMessage(Globals.hMainWnd, WM_CLOSE, 0, 0); +} + +VOID PAINT_EditUndo(VOID) +{ + HBITMAP hbm; + SIZE siz; + + if (Globals.fCanUndo) + { + hbm = Globals.hbmImage; + Globals.hbmImage = Globals.hbmImageUndo; + Globals.hbmImageUndo = hbm; + Globals.fCanUndo = FALSE; + siz = Globals.sizImage; + Globals.sizImage = Globals.sizImageUndo; + Globals.sizImageUndo = siz; + Globals.fSelect = FALSE; + if (Globals.hbmSelect != NULL) + { + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + } + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + Globals.fCanUndo = FALSE; + } +} + +VOID PAINT_EditRepeat(VOID) +{ + HBITMAP hbm; + SIZE siz; + + if (!Globals.fCanUndo && Globals.hbmImageUndo != NULL) + { + hbm = Globals.hbmImage; + Globals.hbmImage = Globals.hbmImageUndo; + Globals.hbmImageUndo = hbm; + Globals.fCanUndo = FALSE; + siz = Globals.sizImage; + Globals.sizImage = Globals.sizImageUndo; + Globals.sizImageUndo = siz; + Globals.fSelect = FALSE; + if (Globals.hbmSelect != NULL) + { + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + } + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + Globals.fCanUndo = TRUE; + } +} + +VOID PAINT_EditCut(VOID) +{ + HBITMAP hbm; + HGLOBAL hPack; + if (Globals.fSelect) + { + Selection_TakeOff(); + hbm = Globals.hbmSelect; + Globals.hbmSelect = NULL; + Globals.fSelect = FALSE; + hPack = BM_Pack(hbm); + DeleteObject(hbm); + if (OpenClipboard(Globals.hCanvasWnd)) + { + EmptyClipboard(); + SetClipboardData(CF_DIB, hPack); + CloseClipboard(); + } + InvalidateRect(Globals.hCanvasWnd, NULL, FALSE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +VOID PAINT_EditCopy(VOID) +{ + HBITMAP hbm; + HGLOBAL hPack; + + if (Globals.fSelect) + { + hbm = Selection_CreateBitmap(); + hPack = BM_Pack(hbm); + DeleteObject(hbm); + if (OpenClipboard(Globals.hCanvasWnd)) + { + EmptyClipboard(); + SetClipboardData(CF_DIB, hPack); + CloseClipboard(); + } + InvalidateRect(Globals.hCanvasWnd, NULL, FALSE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +VOID PAINT_EditPaste(VOID) +{ + HGLOBAL hPack; + HBITMAP hbm; + BITMAP bm; + SIZE siz; + + Selection_Land(); + hPack = NULL; + if (OpenClipboard(Globals.hCanvasWnd)) + { + hPack = GetClipboardData(CF_DIB); + CloseClipboard(); + } + if (hPack == NULL) + return; + + Globals.iToolPrev = Globals.iToolSelect; + Globals.iToolSelect = TOOL_BOXSELECT; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + + hbm = BM_Unpack(hPack); + if (hbm != NULL) + { + Globals.fSelect = TRUE; + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbm; + GetObject(Globals.hbmSelect, sizeof(BITMAP), &bm); + if (Globals.sizImage.cx < bm.bmWidth || + Globals.sizImage.cy < bm.bmHeight) + { + siz.cx = bm.bmWidth; + siz.cy = bm.bmHeight; + Canvas_Resize(Globals.hCanvasWnd, siz); + Globals.sizImage = siz; + Globals.pt0.x = 0; + Globals.pt0.y = 0; + Globals.pt1.x = bm.bmWidth; + Globals.pt1.y = bm.bmHeight; + } + else + { + Globals.pt0.x = Globals.xScrollPos / Globals.nZoom; + Globals.pt0.y = Globals.yScrollPos / Globals.nZoom; + Globals.pt1.x = Globals.pt0.x + bm.bmWidth; + Globals.pt1.y = Globals.pt0.y + bm.bmHeight; + } + + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } + else + ShowLastError(); +} + +VOID PAINT_EditDelete(VOID) +{ + PAINT_ClearSelection(); +} + +VOID PAINT_ClearSelection(VOID) +{ + if (Globals.fSelect) + { + Selection_TakeOff(); + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = NULL; + Globals.fSelect = FALSE; + InvalidateRect(Globals.hCanvasWnd, NULL, FALSE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +VOID PAINT_CopyTo(VOID) +{ + OPENFILENAME ofn; + WCHAR szFileName[MAX_PATH]; + WCHAR szDir[MAX_PATH]; + BOOL fModified; + static const WCHAR szDefaultExt[] = { 'b','m','p',0 }; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + + fModified = Globals.fModified; + Selection_TakeOff(); + + ZeroMemory(&ofn, sizeof(ofn)); + + GetCurrentDirectory(MAX_PATH, szDir); + lstrcpy(szFileName, bmp_files); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = Globals.hMainWnd; + ofn.hInstance = Globals.hInstance; + ofn.lpstrFilter = Globals.szFilter; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrInitialDir = szDir; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT | + OFN_HIDEREADONLY; + ofn.lpstrDefExt = szDefaultExt; + + if (!GetSaveFileName(&ofn)) + return; + + BM_Save(szFileName, Globals.hbmSelect); + Selection_Land(); + Globals.fModified = fModified; + + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_PasteFrom(VOID) +{ + OPENFILENAME ofn; + WCHAR szFileName[MAX_PATH]; + WCHAR szDir[MAX_PATH]; + BITMAP bm; + HBITMAP hbm; + SIZE siz; + static const WCHAR szDefaultExt[] = { 'b','m','p',0 }; + static const WCHAR bmp_files[] = { '*','.','b','m','p',0 }; + + Selection_Land(); + + ZeroMemory(&ofn, sizeof(ofn)); + + GetCurrentDirectory(MAX_PATH, szDir); + lstrcpy(szFileName, bmp_files); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = Globals.hMainWnd; + ofn.hInstance = Globals.hInstance; + ofn.lpstrFilter = Globals.szFilter; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrInitialDir = szDir; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | + OFN_HIDEREADONLY; + ofn.lpstrDefExt = szDefaultExt; + + if (!GetOpenFileName(&ofn)) + return; + + if (!FileExists(szFileName)) + { + AlertFileNotFound(szFileName); + return; + } + + Globals.iToolPrev = Globals.iToolSelect; + Globals.iToolSelect = TOOL_BOXSELECT; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + + hbm = BM_Load(szFileName); + if (hbm != NULL) + { + Globals.fSelect = TRUE; + if (Globals.hbmSelect != NULL) + DeleteObject(Globals.hbmSelect); + Globals.hbmSelect = hbm; + GetObject(hbm, sizeof(BITMAP), &bm); + + if (Globals.sizImage.cx < bm.bmWidth || + Globals.sizImage.cy < bm.bmHeight) + { + siz.cx = bm.bmWidth; + siz.cy = bm.bmHeight; + Canvas_Resize(Globals.hCanvasWnd, siz); + Globals.sizImage = siz; + Globals.pt0.x = 0; + Globals.pt0.y = 0; + Globals.pt1.x = bm.bmWidth; + Globals.pt1.y = bm.bmHeight; + } + else + { + Globals.pt0.x = Globals.xScrollPos / Globals.nZoom; + Globals.pt0.y = Globals.yScrollPos / Globals.nZoom; + Globals.pt1.x = Globals.pt0.x + bm.bmWidth; + Globals.pt1.y = Globals.pt0.y + bm.bmHeight; + } + + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } + else + ShowLastError(); +} + +VOID PAINT_EditSelectAll(VOID) +{ + Globals.fSelect = TRUE; + Globals.pt0.x = 0; + Globals.pt0.y = 0; + Globals.pt1.x = Globals.sizImage.cx; + Globals.pt1.y = Globals.sizImage.cy; + Globals.iToolSelect = TOOL_BOXSELECT; + Globals.hbmSelect = NULL; + InvalidateRect(Globals.hToolBox, NULL, TRUE); + UpdateWindow(Globals.hToolBox); + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_HelpContents(VOID) +{ + WinHelp(Globals.hMainWnd, helpfileW, HELP_INDEX, 0); +} + +VOID PAINT_HelpHelp(VOID) +{ + WinHelp(Globals.hMainWnd, helpfileW, HELP_HELPONHELP, 0); +} + +VOID PAINT_HelpAboutPaint(VOID) +{ + static const WCHAR paintW[] = { 'P','a','i','n','t',0 }; + WCHAR szPaint[MAX_STRING_LEN]; + HICON icon = LoadImageW(Globals.hInstance, MAKEINTRESOURCE(IDI_PAINT), + IMAGE_ICON, 48, 48, LR_SHARED); + + LoadString(Globals.hInstance, STRING_PAINT, szPaint, SIZEOF(szPaint)); + ShellAbout(Globals.hMainWnd, szPaint, paintW, icon); +} + + +VOID PAINT_ToolBox(VOID) +{ + if (IsWindowVisible(Globals.hToolBox)) + ShowWindow(Globals.hToolBox, SW_HIDE); + else + ShowWindow(Globals.hToolBox, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_ColorBox(VOID) +{ + if (IsWindowVisible(Globals.hColorBox)) + ShowWindow(Globals.hColorBox, SW_HIDE); + else + ShowWindow(Globals.hColorBox, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_StatusBar(VOID) +{ + if (IsWindowVisible(Globals.hStatusBar)) + ShowWindow(Globals.hStatusBar, SW_HIDE); + else + ShowWindow(Globals.hStatusBar, SW_SHOWNORMAL); + + PostMessage(Globals.hMainWnd, WM_SIZE, 0, 0); +} + +VOID PAINT_Zoom(INT nZoom) +{ + SIZE siz; + Globals.nZoom = nZoom; + Globals.xScrollPos = Globals.yScrollPos = 0; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + Globals.hbmZoomBuffer = BM_Create(siz); + + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_Zoom2(INT x, INT y, INT nZoom) +{ + SIZE siz; + Globals.nZoom = nZoom; + Globals.xScrollPos = x * nZoom; + Globals.yScrollPos = y * nZoom; + PostMessage(Globals.hCanvasWnd, WM_SIZE, 0, 0); + + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + Globals.hbmZoomBuffer = BM_Create(siz); + + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_ShowGrid(VOID) +{ + Globals.fShowGrid = !Globals.fShowGrid; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_InvertColors(VOID) +{ + HDC hDC, hdcMem; + HGDIOBJ hbmOld; + RECT rc; + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + if (Globals.fSelect) + { + Selection_TakeOff(); + hbmOld = SelectObject(hdcMem, Globals.hbmSelect); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + InvertRect(hdcMem, &rc); + SelectObject(hdcMem, hbmOld); + } + else + { + hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + InvertRect(hdcMem, &rc); + SelectObject(hdcMem, hbmOld); + } + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + Globals.fModified = TRUE; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +VOID PAINT_ClearImage(VOID) +{ + HDC hDC, hdcMem; + RECT rc; + hDC = GetDC(Globals.hCanvasWnd); + hdcMem = CreateCompatibleDC(hDC); + if (hdcMem != NULL) + { + HBRUSH hbr; + HGDIOBJ hbmOld = SelectObject(hdcMem, Globals.hbmImage); + rc.left = rc.top = 0; + rc.right = Globals.sizImage.cx; + rc.bottom = Globals.sizImage.cy; + hbr = CreateSolidBrush(Globals.rgbBack); + FillRect(hdcMem, &rc, hbr); + DeleteObject(hbr); + SelectObject(hdcMem, hbmOld); + DeleteDC(hdcMem); + } + ReleaseDC(Globals.hCanvasWnd, hDC); + Globals.fModified = TRUE; + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); +} + +BOOL CALLBACK ZoomDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WCHAR sz[32]; + SIZE siz; + static const WCHAR format[] = {'%','d','0','0','%','%',0}; + + switch (uMsg) + { + case WM_INITDIALOG: + switch (Globals.nZoom) + { + case 1: CheckDlgButton(hDlg, rad1, 1); break; + case 2: CheckDlgButton(hDlg, rad2, 1); break; + case 4: CheckDlgButton(hDlg, rad3, 1); break; + case 6: CheckDlgButton(hDlg, rad4, 1); break; + case 8: CheckDlgButton(hDlg, rad5, 1); break; + } + wsprintf(sz, format, Globals.nZoom); + SetDlgItemText(hDlg, stc2, sz); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (IsDlgButtonChecked(hDlg, rad1) & 1) Globals.nZoom = 1; + else if (IsDlgButtonChecked(hDlg, rad2) & 1) Globals.nZoom = 2; + else if (IsDlgButtonChecked(hDlg, rad3) & 1) Globals.nZoom = 4; + else if (IsDlgButtonChecked(hDlg, rad4) & 1) Globals.nZoom = 6; + else if (IsDlgButtonChecked(hDlg, rad5) & 1) Globals.nZoom = 8; + + siz.cx = Globals.nZoom * Globals.sizImage.cx; + siz.cy = Globals.nZoom * Globals.sizImage.cy; + if (Globals.hbmZoomBuffer != NULL) + DeleteObject(Globals.hbmZoomBuffer); + Globals.hbmZoomBuffer = BM_Create(siz); + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + } + return FALSE; +} + +VOID PAINT_ZoomCustom(VOID) +{ + if (DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_ZOOM), + Globals.hMainWnd, ZoomDlgProc) == IDOK) + { + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +BOOL CALLBACK +StretchSkewDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + INT cxPercent, cyPercent; + BOOL fTranslated; + SIZE sizNew; + static const WCHAR sz100[] = {'1','0','0',0}; + switch (uMsg) + { + case WM_INITDIALOG: + SetDlgItemText(hDlg, edt1, sz100); + SetDlgItemText(hDlg, edt2, sz100); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + cxPercent = GetDlgItemInt(hDlg, edt1, &fTranslated, FALSE); + if (!fTranslated || cxPercent <= 0) + { + WCHAR sz[MAX_STRING_LEN]; + LoadString(Globals.hInstance, STRING_POSITIVE_INT, sz, + MAX_STRING_LEN); + MessageBeep(MB_ICONERROR); + MessageBox(hDlg, sz, NULL, MB_OK|MB_ICONERROR); + SendDlgItemMessage(hDlg, edt1, EM_SETSEL, 0, -1); + SetFocus(GetDlgItem(hDlg, edt1)); + break; + } + cyPercent = GetDlgItemInt(hDlg, edt2, &fTranslated, FALSE); + if (!fTranslated || cyPercent <= 0) + { + WCHAR sz[MAX_STRING_LEN]; + LoadString(Globals.hInstance, STRING_POSITIVE_INT, sz, + MAX_STRING_LEN); + MessageBeep(MB_ICONERROR); + MessageBox(hDlg, sz, NULL, MB_OK|MB_ICONERROR); + SendDlgItemMessage(hDlg, edt2, EM_SETSEL, 0, -1); + SetFocus(GetDlgItem(hDlg, edt2)); + break; + } + if (Globals.fSelect) + { + sizNew.cx = MulDiv(Globals.pt1.x - Globals.pt0.x + 1, cxPercent, + 100); + sizNew.cy = MulDiv(Globals.pt1.y - Globals.pt0.y + 1, cyPercent, + 100); + Selection_Stretch(Globals.hCanvasWnd, sizNew); + } + else + { + sizNew.cx = MulDiv(Globals.sizImage.cx, cxPercent, 100); + sizNew.cy = MulDiv(Globals.sizImage.cy, cyPercent, 100); + Canvas_Stretch(Globals.hCanvasWnd, sizNew); + } + + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + break; + } + return FALSE; +} + +VOID PAINT_StretchSkew(VOID) +{ + if (DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_STRETCH_SKEW), + Globals.hMainWnd, StretchSkewDlgProc) == IDOK) + { + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +BOOL CALLBACK +AttributesDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WCHAR sz[128], szSize[64], szDate[32], szTime[32]; + HANDLE hFile; + DWORD cb; + FILETIME ft, ft2; + SYSTEMTIME st; + BOOL fTranslated; + SIZE sizNew; + static SIZE siz; + static const WCHAR last[] = {'F','i','l','e',' ','l','a','s','t',' ', + 's','a','v','e','d',':','\t', + '%','s',' ','%','s',0 + }; + static const WCHAR size[] = {'S','i','z','e',' ','o','n',' ', + 'd','i','s','k',':','\t','%','s',0 + }; + static const WCHAR no_data[] = {'N','o','t',' ', + 'A','v','a','i','l','a','b','l','e',0 + }; + static const WCHAR empty[] = {0}; + switch (uMsg) + { + case WM_INITDIALOG: + CheckDlgButton(hDlg, rad3, 1); + + siz = Globals.sizImage; + + SetDlgItemInt(hDlg, edt1, siz.cx, FALSE); + SetDlgItemInt(hDlg, edt2, siz.cy, FALSE); + + wsprintf(sz, last, no_data, empty); + SetDlgItemText(hDlg, stc1, sz); + wsprintf(sz, size, no_data); + SetDlgItemText(hDlg, stc2, sz); + + hFile = CreateFile(Globals.szFileName, GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + if (GetFileTime(hFile, NULL, NULL, &ft)) + { + FileTimeToLocalFileTime(&ft, &ft2); + FileTimeToSystemTime(&ft2, &st); + + GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &st, NULL, + szDate, 32); + GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, + szTime, 32); + wsprintf(sz, last, szDate, szTime); + SetDlgItemText(hDlg, stc1, sz); + } + + cb = GetFileSize(hFile, NULL); + if (cb != 0xFFFFFFFF) + { + StrFormatByteSize(cb, szSize, 64); + wsprintf(sz, size, szSize); + SetDlgItemText(hDlg, stc2, sz); + } + CloseHandle(hFile); + } + + CheckDlgButton(hDlg, rad5, 1); + return TRUE; + + case WM_COMMAND: + switch (HIWORD(wParam)) + { + case EN_CHANGE: + switch (LOWORD(wParam)) + { + case edt1: + break; + + case edt2: + break; + } + break; + + case BN_CLICKED: + switch (LOWORD(wParam)) + { + case rad1: + break; + + case rad2: + break; + + case rad3: + SetDlgItemInt(hDlg, edt1, siz.cx, FALSE); + SetDlgItemInt(hDlg, edt2, siz.cy, FALSE); + break; + + case IDOK: + sizNew.cx = GetDlgItemInt(hDlg, edt1, &fTranslated, FALSE); + if (!fTranslated || sizNew.cx <= 0) + { + WCHAR sz[MAX_STRING_LEN]; + LoadString(Globals.hInstance, STRING_POSITIVE_INT, sz, + MAX_STRING_LEN); + MessageBeep(MB_ICONERROR); + MessageBox(hDlg, sz, NULL, MB_OK|MB_ICONERROR); + SendDlgItemMessage(hDlg, edt1, EM_SETSEL, 0, -1); + SetFocus(GetDlgItem(hDlg, edt1)); + break; + } + sizNew.cy = GetDlgItemInt(hDlg, edt2, &fTranslated, FALSE); + if (!fTranslated || sizNew.cy <= 0) + { + WCHAR sz[MAX_STRING_LEN]; + LoadString(Globals.hInstance, STRING_POSITIVE_INT, sz, + MAX_STRING_LEN); + MessageBeep(MB_ICONERROR); + MessageBox(hDlg, sz, NULL, MB_OK|MB_ICONERROR); + SendDlgItemMessage(hDlg, edt2, EM_SETSEL, 0, -1); + SetFocus(GetDlgItem(hDlg, edt2)); + break; + } + + Canvas_Resize(Globals.hCanvasWnd, sizNew); + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + break; + } + break; + } + return FALSE; +} + +VOID PAINT_Attributes(VOID) +{ + if (DialogBox(Globals.hInstance, MAKEINTRESOURCE(IDD_ATTRIBUTES), + Globals.hMainWnd, AttributesDlgProc) == IDOK) + { + InvalidateRect(Globals.hCanvasWnd, NULL, TRUE); + UpdateWindow(Globals.hCanvasWnd); + } +} + +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) + { + if (Globals.fSelect) + Selection_HFlip(Globals.hCanvasWnd); + else + Canvas_HFlip(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad2) & 1) + { + if (Globals.fSelect) + Selection_VFlip(Globals.hCanvasWnd); + else + Canvas_VFlip(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad3) & 1) + { + if (IsDlgButtonChecked(hDlg, rad4) & 1) + { + if (Globals.fSelect) + Selection_Rotate90Degree(Globals.hCanvasWnd); + else + Canvas_Rotate90Degree(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad5) & 1) + { + if (Globals.fSelect) + Selection_Rotate180Degree(Globals.hCanvasWnd); + else + Canvas_Rotate180Degree(Globals.hCanvasWnd); + } + else if (IsDlgButtonChecked(hDlg, rad6) & 1) + { + if (Globals.fSelect) + Selection_Rotate270Degree(Globals.hCanvasWnd); + else + Canvas_Rotate270Degree(Globals.hCanvasWnd); + } + } + + EndDialog(hDlg, IDOK); + break; + + case IDCANCEL: + EndDialog(hDlg, IDCANCEL); + break; + } + break; + } + return FALSE; +} + +VOID PAINT_FlipRotate(VOID) +{ + 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) +{ + CHOOSECOLOR cc; + + ZeroMemory(&cc, sizeof(CHOOSECOLOR)); + cc.lStructSize = sizeof(CHOOSECOLOR); + cc.hwndOwner = Globals.hMainWnd; + if (fBack) + cc.rgbResult = Globals.rgbBack; + else + cc.rgbResult = Globals.rgbFore; + cc.lpCustColors = aCustColors; + cc.Flags = CC_RGBINIT; + + if (ChooseColor(&cc)) + { + if (fBack) + { + Globals.argbColors[Globals.iBackColor] = cc.rgbResult; + Globals.rgbBack = cc.rgbResult; + } + else + { + Globals.argbColors[Globals.iForeColor] = cc.rgbResult; + Globals.rgbFore = cc.rgbResult; + } + } + InvalidateRect(Globals.hColorBox, NULL, TRUE); + UpdateWindow(Globals.hColorBox); +} diff --git a/programs/paint/paint.h b/programs/paint/paint.h new file mode 100644 index 0000000..0f988a6 --- /dev/null +++ b/programs/paint/paint.h @@ -0,0 +1,71 @@ +/* + * Paint (paint.h) + * + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +VOID PAINT_FileNew(VOID); +VOID PAINT_FileOpen(VOID); +BOOL PAINT_FileSave(VOID); +BOOL PAINT_FileSaveAs(VOID); +VOID PAINT_FilePrintPreview(VOID); +VOID PAINT_FilePrint(VOID); +VOID PAINT_FilePageSetup(VOID); +VOID PAINT_FilePrinterSetup(VOID); +VOID PAINT_SetAsWallpaperTiled(VOID); +VOID PAINT_SetAsWallpaperCentered(VOID); +VOID PAINT_FileExit(VOID); + +VOID PAINT_EditUndo(VOID); +VOID PAINT_EditRepeat(VOID); +VOID PAINT_EditCut(VOID); +VOID PAINT_EditCopy(VOID); +VOID PAINT_EditPaste(VOID); +VOID PAINT_EditDelete(VOID); +VOID PAINT_EditSelectAll(VOID); +VOID PAINT_CopyTo(VOID); +VOID PAINT_PasteFrom(VOID); + +VOID PAINT_ClearSelection(VOID); + +VOID PAINT_HelpContents(VOID); +VOID PAINT_HelpHelp(VOID); +VOID PAINT_HelpAboutPaint(VOID); + +VOID PAINT_ToolBox(VOID); +VOID PAINT_ColorBox(VOID); +VOID PAINT_StatusBar(VOID); +VOID PAINT_Zoom(INT nZoom); +VOID PAINT_Zoom2(INT x, INT y, INT nZoom); +VOID PAINT_ShowGrid(VOID); +VOID PAINT_ZoomCustom(VOID); + +VOID PAINT_FlipRotate(VOID); +VOID PAINT_StretchSkew(VOID); +VOID PAINT_InvertColors(VOID); +VOID PAINT_Attributes(VOID); +VOID PAINT_ClearImage(VOID); + +VOID PAINT_EditColor(BOOL fBack); + +int PAINT_StringMsgBox(HWND hParent, int formatId, LPCWSTR szString, UINT uFlags); + +/* utility functions */ +VOID ShowLastError(void); +BOOL FileExists(LPCWSTR szFilename); +BOOL DoCloseFile(void); +void DoOpenFile(LPCWSTR szFileName); diff --git a/programs/paint/paint.ico b/programs/paint/paint.ico new file mode 100644 index 0000000000000000000000000000000000000000..95df1ffb8780828f2e3cfd837b31677e6ff3420e GIT binary patch literal 15086 zcmeI3d2m!k9>?FCBa=)Bi5!BEm~g}dkVAp2ATS(m!XX~0EO!FI0FfKQ5rafLIE3X8 z1mp^b5I`tc5W}Tmsoj+-7Qt(ADP$tGP>Ny{R|5|7+wZrNml|Sbm`R4J{exfCC;i@= z?*9F{Umw5je$g~tGizj-N-5R(iX$VdW!_35vC7#%%c+O_*qnl<}CqN5i`RMbF2 zR{=8Nuu#X}%)G?ID5E)nk*}}tJ;dXX^#||>s0n;YKdZH-^y%}d^y+m%dh{rgE?q84 z%a(iGVPQ?E=PNJ{Bmfhrs;~^}0pD>&``vg}1Xh8EfMI(}Tr-^y(OJIJiHQSb?AT%% zHq0pl23(M5o+*;#g>`%t z^ap&Ow7E`oQbADcr$H#g zg9v2l(zo0K`T1v&qeo9mix#T=oWO7FYssLxLi?|P5g-)sy#`C>*Q-}gx_9r6x!J;c z_hd8fdw@X4hl;i}#)EG`1_-wOldV>(BqStYE*K!omMxQW=g!I6wQE@p_POVQ1H^)= zieW!}A{z*1{TIf^$IHTn3necvPYMbO(ZXs{-;2Njx&nXO5Ph>^3}Hw=3_jZ!gyX>= z5DBz=5KQTX%*5P(s#qtjmCz}hC2Zzyv9#(=UF^r~b8JU^5B|t;O^Zj`VIUoh2DCp5 z3hB>biK#oXv&>iP)KcG4R7lJlC@ z7-`aA|44*J+nI{%nP4`^0jf`rM%chtW&!-hzI@&M^f(DoZDK^8okA%Vx72JY?C)iSk`t4 z&)zS3RDJ4t70`bAME8NpBo}Tm;{7J#8ZwITYr4^);}6`mz) zCbP>rZUy?l1_{mDD)t$>#oA>EbsY!Y0qy7bQkfK#j+3Jh-{`ZGam~7)1&q31glm?G z{Y1S_=11S6x^gcv_|)v^FCkeQRUfcV-zA|#F_xMw)J1=eW%wg715c@on@=#zA|7pj z0T_MuMO?oOUI%Z0rGWjIbAy%+xQ^$VCK$3z3#)-Xu+D9pvPq3Y_VJtCdYu^RVjJQ( zMEj$Gr!>b6`~;5iBLK_5@rHf&CGZNE2mTD+1S~@=(B1&_bsK?TNGviDbFYzZTh?Z@ zp?nE{ai3V4b*8S*0qctWpyE1;>$Mx$f8+2;#-?ns|G5RdW zvgP1yuo=*=(Ebj%e^RkN@TkhtTnh;k>)@Bf#<_Uu<>zrla*s}_-?(@J-pzQw_@-gfW)JH^8ukyHt zy0cBfT%5H{!gKbEErsK`_9b9jq5YhDj5^C5K4N&e{l>-h>(?bEB^l}Hd$JvE0Bk$7 zzZK97`?=n(?*1jRC>M^UpIaOQl|RaH)IMPg^}(-Hd(5=ID=_M8*09uJhS|4-*REZY zo;_2{@G&3I|xh1{1aM(Wq1;>3|wDQFYE9s+lfDN8k=Rc>eOOBoJ;7#(S8%S6SCYC z-yXiicJ$%RVyYWQz4HObQTh^%p}8KyFAg0#d>Q^U{Yd2t4Mk}9LQ!Z#H37$z+oNm$Mq2hA+RyeM0q(T?)fCrK z>{&apwpI2|Lr8y`ZK%}$HK8Ay)cU3;p7jIV2TBGGzv9y`%gk~TC#Dk_F*z+#3^eP;$X@5>x4C?0G zLwoPa-5U76sDaYC0}WM)XXr{1v|f=Cn--};3wMJ>iq)>Lh%>bGzC0{@UZ{2)L<*z0 z^B|I2A=Jw5%fmJ*o*Vs_@flK&3*U8kh9zb9C0dDk&X9H$8zIgiVtJ3yfzWAoYqJp+ zB4jyovDPjNxx>NxV=9a+3u8+|`0ae|t`H(q^_*ehYz;~sk{ioK!fc@(#k3gq7Mn%c z=Zr<@&@`t579#w8{qjlacUp0130*xiAe`cir5Z8vE$k11LWY(<9>f4aa%!}%~5VIM5tkl=xeCx01h`0&Rc0)IPY!mP$ z&voqhoUB{-y)0kOZz8^t{{2@|KlcuM_)1vGZ`>Q~52!y7`GMay96fqXeb=yN&6m_~ ztXTueX8|G)27Kp%2t00+T)K2a&Y!=IZxeo^{trN)<)4c*!$F|>kwlyS)KgDYJeN1Otebu>g zc6PRLrhEvQP`^K86J`(X0yqa8pek}ivqy*}dANj4-72~@ly%Sx+^!v@x$52i(V3V-d%MK;>=opqbbM+o1L@ber0< zV)?z*!5R!z(3cK)2Eu)Bo`0kPb#819&;VVpSxcSig-y#h&hvJc>91_f4LzxV_0F>| zo*luLP-k|k4t&*{H`8z?w+iP$ThtyJA|XFj{)%;g`sMk< z{ekY2rSeRQd)eGaHP>%~ywsYK`aSCt>*=oejc2Zt0MBk-1~|V`=N``>ROd}q8IRBg zaGt?Epp3Ve&n`gyEr22Dp9Aq*Pr$PC?1g*IJg-{;a)E~S5%7G#{NJ;t&r|0q;WPij zdz52*cq>aWUP zf3zv48Qwv@)X3h)yqtjg9e^{FXYtkb*|TRE510YQL0z2#Q~$k8QU&qe4=d5{Y0&92 zr;Yt;>JPLJ8m9KNwCkn%p{dUOESu2=O(_2+h$(+8SXEOz-l?4v&)4E@MP zQ{NUa1jaj1ZIJD-Qgrpd4AkEmR97;so&H4Kg!$11Pch0_Sy-KS@2TUzxH0y@I(q(a z_u9W2C~utZR1sISSzJ-vX(*)_2j0bTx;V=yOw*+>&8)~pnCrx#R%{cUltjACC9y8E z%i%J+9WI;OfhUS$gvF6An=`h=>~s{HkBKwV&`Sq~3(GiAzE5%Ic7i7~Y&ZpTV}ol@ z=WYD|6~7tn`Z}&l=N4R0l9I;Y{}nDuhYp<6y?%>H|9l8w+poAU+xGqUe~@k4eqj16 z;7z#ST&YAv)O2QK(7)2S9)QnPsqkB_N(F1XfASmQo;~TO{I1_JO%pJY7v99w+M#?A z{QerK?GX?D&>-Z?Giq&v$McGpb8S=d#1fxW!G_wdQs0$h`w;$iOZ|IhVjVHpSQ9*k z=VkTK7ilH~ey>2kN1e}kCM&5d58>oC^Y^ljKC*tM(T=ONjx!aYrQBY?N;BKWz4;JTz6_D7F_ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/programs/paint/pencil.cur b/programs/paint/pencil.cur new file mode 100644 index 0000000000000000000000000000000000000000..a5f2c18d9e26c3bf44205c9c1ed1714b6ff7b8b8 GIT binary patch literal 326 zcmaLRy$!-J5QgE`35Z{b4$ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define MAIN_MENU 0x201 +#define TEXT_MENU 0x202 +#define SELECTION_MENU 0x203 +#define ID_ACCEL 0x204 +#define IDB_TOOLS 0x205 +#define IDB_AIRBRUSH 0x206 +#define IDB_ERASER 0x20B +#define IDB_ZOOM 0x20C +#define IDB_LINE 0x20D +#define IDB_BRUSH 0x20E +#define IDB_FILL 0x20F +#define IDB_TRANS 0x210 +#define IDD_ZOOM 0x207 +#define IDD_STRETCH_SKEW 0x208 +#define IDD_ATTRIBUTES 0x209 +#define IDD_FLIP_ROTATE 0x20A +#define IDI_PAINT 0x1 + +/* Commands */ +#define CMD_NEW 0x100 +#define CMD_OPEN 0x101 +#define CMD_SAVE 0x102 +#define CMD_SAVE_AS 0x103 +#define CMD_PRINT_PREVIEW 0x104 +#define CMD_PRINT 0x105 +#define CMD_PAGE_SETUP 0x106 +#define CMD_EXIT 0x107 +#define CMD_WALLPAPAER_TILED 0x108 +#define CMD_WALLPAPAER_CENTERED 0x109 +#define CMD_UNDO 0x10A +#define CMD_CUT 0x10B +#define CMD_COPY 0x10C +#define CMD_PASTE 0x10D +#define CMD_DELETE 0x10E +#define CMD_SELECT_ALL 0x10F +#define CMD_REPEAT 0x110 +#define CMD_COPY_TO 0x111 +#define CMD_PASTE_FROM 0x112 +#define CMD_TOOL_BOX 0x113 +#define CMD_COLOR_BOX 0x114 +#define CMD_STATUS_BAR 0x115 +#define CMD_TEXT_TOOL 0x116 +#define CMD_ZOOM_NORMAL 0x117 +#define CMD_ZOOM_LARGE 0x118 +#define CMD_ZOOM_CUSTOM 0x119 +#define CMD_SHOW_GRID 0x11A +#define CMD_VIEW_BITMAP 0x11B +#define CMD_SHOW_THUMBNAIL 0x11C +#define CMD_FLIP_ROTATE 0x11D +#define CMD_STRETCH_SKEW 0x11E +#define CMD_INVERT_COLORS 0x12F +#define CMD_ATTRIBUTES 0x120 +#define CMD_CLEAR_IMAGE 0x121 +#define CMD_DRAW_OPAQUE 0x122 +#define CMD_CLEAR_SELECTION 0x123 +#define CMD_EDIT_COLOR 0x124 +#define CMD_GET_COLORS 0x125 +#define CMD_SAVE_COLORS 0x126 +#define CMD_HELP_CONTENTS 0x127 +#define CMD_HELP_ON_HELP 0x128 +#define CMD_HELP_ABOUT_PAINT 0x129 + +#define IDC_STATIC -1 + +#define STRING_PAINT 0x170 +#define STRING_UNTITLED 0x174 +#define STRING_ALL_FILES 0x175 +#define STRING_BMP_FILES_BMP 0x176 +#define STRING_DOESNOTEXIST 0x179 +#define STRING_SAVECHANGE 0x17A +#define STRING_NOTFOUND 0x17B + +#define STRING_POLYSELECT 0x200 +#define STRING_BOXSELECT 0x201 +#define STRING_ERASER 0x202 +#define STRING_FLOODFILL 0x203 +#define STRING_SPOIT 0x204 +#define STRING_MAGNIFIER 0x205 +#define STRING_PENCIL 0x206 +#define STRING_BRUSH 0x207 +#define STRING_AIRBRUSH 0x208 +#define STRING_TEXT 0x209 +#define STRING_LINE 0x20A +#define STRING_CURVE 0x20B +#define STRING_BOX 0x20C +#define STRING_POLYGON 0x20D +#define STRING_ELLIPSE 0x20E +#define STRING_ROUNDRECT 0x20F +#define STRING_READY 0x210 +#define STRING_POSITIVE_INT 0x211 +#define STRING_INVALID_BM 0x212 +#define STRING_LOSS_COLOR 0x213 +#define STRING_MONOCROME_BM 0x215 +#define STRING_16COLOR_BM 0x216 +#define STRING_256COLOR_BM 0x217 +#define STRING_24BIT_BM 0x218 +#define STRING_JPEG_FILES 0x219 +#define STRING_GIF_FILES 0x21A +#define STRING_TIFF_FILES 0x21B +#define STRING_PNG_FILES 0x21C +#define STRING_ICON_FILES 0x21D +#define STRING_PCX_FILES 0x21E +#define STRING_ALL_PICTURE 0x21F +#define STRING_PALETTE 0x220 +#define STRING_NEW 0x300 +#define STRING_OPEN 0x301 +#define STRING_SAVE 0x302 +#define STRING_SAVE_AS 0x303 +#define STRING_PRINT_PREVIEW 0x304 +#define STRING_PAGE_SETUP 0x305 +#define STRING_PRINT 0x306 +#define STRING_EXIT 0x307 +#define STRING_WALLPAPAER_TILED 0x308 +#define STRING_WALLPAPAER_CENTERED 0x309 +#define STRING_UNDO 0x30A +#define STRING_CUT 0x30B +#define STRING_COPY 0x30C +#define STRING_PASTE 0x30D +#define STRING_DELETE 0x30E +#define STRING_SELECT_ALL 0x30F +#define STRING_REPEAT 0x310 +#define STRING_COPY_TO 0x311 +#define STRING_PASTE_FROM 0x312 +#define STRING_TOOL_BOX 0x313 +#define STRING_COLOR_BOX 0x314 +#define STRING_STATUS_BAR 0x315 +#define STRING_TEXT_TOOL 0x316 +#define STRING_ZOOM_NORMAL 0x317 +#define STRING_ZOOM_LARGE 0x318 +#define STRING_ZOOM_CUSTOM 0x319 +#define STRING_SHOW_GRID 0x31A +#define STRING_VIEW_BITMAP 0x31B +#define STRING_SHOW_THUMBNAIL 0x31C +#define STRING_FLIP_ROTATE 0x31D +#define STRING_STRETCH_SKEW 0x31E +#define STRING_INVERT_COLORS 0x32F +#define STRING_ATTRIBUTES 0x320 +#define STRING_CLEAR_IMAGE 0x321 +#define STRING_DRAW_OPAQUE 0x322 +#define STRING_CLEAR_SELECTION 0x323 +#define STRING_EDIT_COLOR 0x324 +#define STRING_GET_COLORS 0x325 +#define STRING_SAVE_COLORS 0x326 +#define STRING_HELP_CONTENTS 0x327 +#define STRING_HELP_ON_HELP 0x328 +#define STRING_HELP_ABOUT_PAINT 0x329 +#define STRING_SIZE 0x400 +#define STRING_MOVE 0x401 +#define STRING_MINIMIZE 0x402 +#define STRING_MAXIMIZE 0x403 +#define STRING_NEXTWINDOW 0x404 +#define STRING_PREVWINDOW 0x405 +#define STRING_CLOSE 0x406 +#define STRING_RESTORE 0x407 +#define STRING_TASKLIST 0x408 diff --git a/programs/paint/rsrc.rc b/programs/paint/rsrc.rc new file mode 100644 index 0000000..bf936d5 --- /dev/null +++ b/programs/paint/rsrc.rc @@ -0,0 +1,113 @@ +/* + * Copyright 2008 Katayama Hirofumi MZ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "main.h" +#include "winnls.h" +#include "commctrl.h" +#include "dlgs.h" +#include "resource.h" + +ID_ACCEL ACCELERATORS +{ + "^N", CMD_CLEAR_IMAGE, ASCII, SHIFT + "^A", CMD_SELECT_ALL + "^C", CMD_COPY + "^N", CMD_NEW + "^O", CMD_OPEN + "^P", CMD_PRINT + "^S", CMD_SAVE + "^X", CMD_CUT + "^C", CMD_COPY + "^V", CMD_PASTE + "^X", CMD_CUT + "^Z", CMD_UNDO + "^Y", CMD_REPEAT + "^T", CMD_TOOL_BOX + "^L", CMD_COLOR_BOX + "^F", CMD_VIEW_BITMAP + "^G", CMD_SHOW_GRID + "^I", CMD_INVERT_COLORS + "^W", CMD_STRETCH_SKEW + "^R", CMD_FLIP_ROTATE + "^E", CMD_ATTRIBUTES + VK_DELETE, CMD_DELETE, VIRTKEY + VK_BACK, CMD_UNDO, VIRTKEY, ALT + VK_INSERT, CMD_COPY, VIRTKEY, CONTROL + VK_INSERT, CMD_PASTE, VIRTKEY, SHIFT + VK_PRIOR, CMD_ZOOM_NORMAL, VIRTKEY, CONTROL + VK_NEXT, CMD_ZOOM_LARGE, VIRTKEY, CONTROL +} + +/* @makedep: paint.ico */ +IDI_PAINT ICON "paint.ico" +/* @makedep: hstretch.ico */ +100 ICON "hstretch.ico" +/* @makedep: vstretch.ico */ +101 ICON "vstretch.ico" +/* @makedep: hslant.ico */ +102 ICON "hslant.ico" +/* @makedep: vslant.ico */ +103 ICON "vslant.ico" + +/* @makedep: tools.bmp */ +IDB_TOOLS BITMAP "tools.bmp" +/* @makedep: airbrush.bmp */ +IDB_AIRBRUSH BITMAP "airbrush.bmp" +/* @makedep: eraser.bmp */ +IDB_ERASER BITMAP "eraser.bmp" +/* @makedep: zoom.bmp */ +IDB_ZOOM BITMAP "zoom.bmp" +/* @makedep: line.bmp */ +IDB_LINE BITMAP "line.bmp" +/* @makedep: brush.bmp */ +IDB_BRUSH BITMAP "brush.bmp" +/* @makedep: fill.bmp */ +IDB_FILL BITMAP "fill.bmp" +/* @makedep: trans.bmp */ +IDB_TRANS BITMAP "trans.bmp" + +/* @makedep: horizon.cur */ +1 CURSOR "horizon.cur" +/* @makedep: vertical.cur */ +2 CURSOR "vertical.cur" +/* @makedep: bdiagon.cur */ +3 CURSOR "bdiagon.cur" +/* @makedep: fdiagon.cur */ +4 CURSOR "fdiagon.cur" +/* @makedep: pencil.cur */ +5 CURSOR "pencil.cur" +/* @makedep: flood.cur */ +6 CURSOR "flood.cur" +/* @makedep: spoit.cur */ +7 CURSOR "spoit.cur" +/* @makedep: airbrush.cur */ +8 CURSOR "airbrush.cur" +/* @makedep: zoom.cur */ +9 CURSOR "zoom.cur" +/* @makedep: cross.cur */ +10 CURSOR "cross.cur" +/* @makedep: move.cur */ +11 CURSOR "move.cur" +/* @makedep: cross2.cur */ +12 CURSOR "cross2.cur" + +#include "En.rc" +#include "Ja.rc" diff --git a/programs/paint/spoit.cur b/programs/paint/spoit.cur new file mode 100644 index 0000000000000000000000000000000000000000..1984742640dc7dfa656880b2f3475e98d31b61d0 GIT binary patch literal 326 zcmaLRF%AJi6o>I|R)j=v8^uPY!Vw&S1Gs}5ScyXC8V;aR(K&|11(b@7=gX3)?3?`N z&CGw28OTT!1$4=oCg=krdBjY~QP;P9HorL{ew%-*mBCI&owU@rgnSOY1GKM@ZG9}W t`%v0=VWFW0YA*lKTzlh=T1qN)UPs&}5f6i>D#Mpyg-A&-`7S2 zAK7fu4OcwMcDt3;YK4U^ex&R8gfHIw3l|N>eGKNtHgAHN;Old_3c~;81J=qQwh=4Z z9O7xcn8h7cFtuKr9d^n^j8=CNM7`7DTHM%q^G&#GI*Gev*oEA)(;*If-iAuvAq!$l zCmtVl##_nvF?Mc|r~cz&zV%`v_^kqVi3c*StDvNfeZaxGkpg)|T~;hjYl9WzY$*6o zWGvPN$2e+4lrBYEL`WqrcxfDxiS^xFN@k8KES@4}XLeLEFf>Uwkm&()7QtjCGA4Ao zX_u0>$XpNy45WnA0LP%oB=j??1UjUNK4}I@A!2)W9o9Mc;0|<+s`KZ_ zM6xZUqHhcC+q7HTE1ly+Xg&x{>ns9HzHw4ID6YRH1}^7qT1*BG<>3 zxE{E4=Xg2;-1aWPMirjDi26hvbXF!&{R>=FnoeQe3se^eXMn{411i0%sXd`Wg{@ji|BqIX~b7E$ZI->CJ!sElW4vERXx`;%&*XI2~0c~XZiciBBU)wIM<_3rU2 zXs+dM%dW5vUMHWSh-awBhbp*@{C)2YJqOPUpacI1YfwHGIM8;xE_IY>c0Zu{Th@3$ zh3a}&{*I`uFsdM9=6He0PUue&hQK&(b8}h+0pAEFDAu|Gm?GA d^D&OsW6TlbID5(ZE2apz?e%^_#tTlW(O=xwQ8@qr literal 0 HcmV?d00001 diff --git a/programs/paint/trans.bmp b/programs/paint/trans.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3798d963e8cd4c13d9791fe54667c83dcaa973a3 GIT binary patch literal 1638 zcmeHG!41MN3^Wq(Bx^7SZ&-s7cxSXe7|0u#yK~c2YQOM^aBRoDT%*`=Zja~LBro{u zYtS+0!WqN`1ng9?l+apn8D?Au`{&Pd&UyRZKfwa#R)01C literal 0 HcmV?d00001 diff --git a/programs/paint/vibeam.cur b/programs/paint/vibeam.cur new file mode 100644 index 0000000000000000000000000000000000000000..534cf3bb79e21301806c30f4c7443f46864f9801 GIT binary patch literal 326 zcmZQzU}9ioP*7lC5MbbEFkob05My9q&;Vkf5Q75{GXfzPKq&|ZLH_^$AHgAo)c`aQ RhU@$X z;s-q8E;!{TNXPrIkqYFO`@#{xm-m1pfUouOf^(eJ`m}oUy8Vgry5xW8{SAtNz9oVd sG=RS4R{OG>Vv(^e^41iI{UwZOCZLA&*y!-o>c?}`FSs=r!2~qwFS+5~Q~&?~ literal 0 HcmV?d00001 diff --git a/programs/paint/vstretch.ico b/programs/paint/vstretch.ico new file mode 100644 index 0000000000000000000000000000000000000000..e08e0b6f233d5126be3f46d87fa3ecaa5ac3266d GIT binary patch literal 766 zcmdT>F%AMT4D%r*?lvaojy!{3u~uSXyfwe+##h)F8H?TOhD65zV!^G`I%!%Z1qP0k z_Ox5vH^2eFkxb-?l)r(ob!31OIroK@Ta;3`Dp1=*t=f?sa>)dY=LJ15@=(L`2YLeB zeKtEinK^A{vpXO2|4hevV!a6cK&+2n;QH~6zAothnX#*H_@MtrUdVxz{)Ea=uI^CY G>N_vDky)ew literal 0 HcmV?d00001 diff --git a/programs/paint/zoom.bmp b/programs/paint/zoom.bmp new file mode 100644 index 0000000000000000000000000000000000000000..af8c0abe5649b9bcb9187795af14bc74c1702c99 GIT binary patch literal 670 zcmcJM!41MN3`JA+;LZ{Ssb|=MMM4hUgHiO-x2^a$84l-F zu(d_p)V&8ge7cUcZekWhBw!`s#P2V%Q}O#a}mbTAF3_%aP&+>n+q*I6e}W7mVri`t05l m6dujUf5_ 1, "notepad" => 1, + "paint" => 1, "progman" => 1, "regedit" => 1, "regsvr32" => 1, -- 1.6.0.2