From 8a4787b3841970bc59c5503cb2eeee074a45a7f8 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Thu, 28 Sep 2023 21:30:34 +0900 Subject: [PATCH] [MSPAINT] Larger/smaller brush nib on Ctrl+Plus/Minus (#5739) - Introduce the concept of "brush width" to the tools model. - Enable changing the brush width by Ctrl+Plus/Minus key combination in TOOL_BRUSH. - Re-define brush styles. CORE-19094 --- base/applications/mspaint/drawing.cpp | 117 ++++++++++----------- base/applications/mspaint/drawing.h | 2 +- base/applications/mspaint/mouse.cpp | 5 +- base/applications/mspaint/toolsettings.cpp | 34 +++++- base/applications/mspaint/toolsmodel.cpp | 25 ++++- base/applications/mspaint/toolsmodel.h | 25 ++++- 6 files changed, 132 insertions(+), 76 deletions(-) diff --git a/base/applications/mspaint/drawing.cpp b/base/applications/mspaint/drawing.cpp index 96064fff229..3b7579196ce 100644 --- a/base/applications/mspaint/drawing.cpp +++ b/base/applications/mspaint/drawing.cpp @@ -165,73 +165,66 @@ Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r) } void -Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style) +Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style, INT thickness) { HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, color)); HBRUSH oldBrush = (HBRUSH) SelectObject(hdc, CreateSolidBrush(color)); - LONG a, b; - b = max(1, max(labs(x2 - x1), labs(y2 - y1))); - switch (style) + + if (thickness <= 1) { - case 0: - for(a = 0; a <= b; a++) - Ellipse(hdc, (x1 * (b - a) + x2 * a) / b - 3, (y1 * (b - a) + y2 * a) / b - 3, - (x1 * (b - a) + x2 * a) / b + 4, (y1 * (b - a) + y2 * a) / b + 4); - break; - case 1: - for(a = 0; a <= b; a++) - Ellipse(hdc, - (x1 * (b - a) + x2 * a) / b - 2, - (y1 * (b - a) + y2 * a) / b - 2, - (x1 * (b - a) + x2 * a) / b + 2, - (y1 * (b - a) + y2 * a) / b + 2); - break; - case 2: - MoveToEx(hdc, x1, y1, NULL); - LineTo(hdc, x2, y2); - ::SetPixelV(hdc, x2, y2, color); - break; - case 3: - for(a = 0; a <= b; a++) - Rectangle(hdc, - (x1 * (b - a) + x2 * a) / b - 4, - (y1 * (b - a) + y2 * a) / b - 4, - (x1 * (b - a) + x2 * a) / b + 4, - (y1 * (b - a) + y2 * a) / b + 4); - break; - case 4: - for(a = 0; a <= b; a++) - Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 2, (y1 * (b - a) + y2 * a) / b - 2, - (x1 * (b - a) + x2 * a) / b + 3, (y1 * (b - a) + y2 * a) / b + 3); - break; - case 5: - for(a = 0; a <= b; a++) - Rectangle(hdc, (x1 * (b - a) + x2 * a) / b - 1, (y1 * (b - a) + y2 * a) / b - 1, - (x1 * (b - a) + x2 * a) / b + 1, (y1 * (b - a) + y2 * a) / b + 1); - break; - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: + Line(hdc, x1, y1, x2, y2, color, thickness); + } + else + { + LONG a, b = max(1, max(labs(x2 - x1), labs(y2 - y1))); + switch ((BrushStyle)style) { - POINT offsTop[] = {{3, -3}, {2, -2}, {0, 0}, - {-4, -4}, {-2, -2}, {-1, 0}}; - POINT offsBtm[] = {{-3, 3}, {-2, 2}, {-1, 1}, - {3, 3}, {2, 2}, {0, 1}}; - LONG idx = style - 6; - POINT pts[4]; - pts[0].x = x1 + offsTop[idx].x; - pts[0].y = y1 + offsTop[idx].y; - pts[1].x = x1 + offsBtm[idx].x; - pts[1].y = y1 + offsBtm[idx].y; - pts[2].x = x2 + offsBtm[idx].x; - pts[2].y = y2 + offsBtm[idx].y; - pts[3].x = x2 + offsTop[idx].x; - pts[3].y = y2 + offsTop[idx].y; - Polygon(hdc, pts, 4); - break; + case BrushStyleRound: + for (a = 0; a <= b; a++) + { + Ellipse(hdc, + (x1 * (b - a) + x2 * a) / b - (thickness / 2), + (y1 * (b - a) + y2 * a) / b - (thickness / 2), + (x1 * (b - a) + x2 * a) / b + (thickness / 2), + (y1 * (b - a) + y2 * a) / b + (thickness / 2)); + } + break; + + case BrushStyleSquare: + for (a = 0; a <= b; a++) + { + Rectangle(hdc, + (x1 * (b - a) + x2 * a) / b - (thickness / 2), + (y1 * (b - a) + y2 * a) / b - (thickness / 2), + (x1 * (b - a) + x2 * a) / b + (thickness / 2), + (y1 * (b - a) + y2 * a) / b + (thickness / 2)); + } + break; + + case BrushStyleForeSlash: + case BrushStyleBackSlash: + { + POINT offsetTop, offsetBottom; + if ((BrushStyle)style == BrushStyleForeSlash) + { + offsetTop = { (thickness - 1) / 2, -(thickness - 1) / 2 }; + offsetBottom = { -thickness / 2, thickness / 2 }; + } + else + { + offsetTop = { -thickness / 2, -thickness / 2 }; + offsetBottom = { (thickness - 1) / 2, (thickness - 1) / 2 }; + } + POINT points[4] = + { + { x1 + offsetTop.x, y1 + offsetTop.y }, + { x1 + offsetBottom.x, y1 + offsetBottom.y }, + { x2 + offsetBottom.x, y2 + offsetBottom.y }, + { x2 + offsetTop.x, y2 + offsetTop.y }, + }; + Polygon(hdc, points, _countof(points)); + break; + } } } DeleteObject(SelectObject(hdc, oldBrush)); diff --git a/base/applications/mspaint/drawing.h b/base/applications/mspaint/drawing.h index 950bfdd6974..44936f08503 100644 --- a/base/applications/mspaint/drawing.h +++ b/base/applications/mspaint/drawing.h @@ -27,7 +27,7 @@ void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF void Airbrush(HDC hdc, LONG x, LONG y, COLORREF color, LONG r); -void Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style); +void Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style, INT thickness); void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2); diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp index 04e749db88b..fc4b1792bec 100644 --- a/base/applications/mspaint/mouse.cpp +++ b/base/applications/mspaint/mouse.cpp @@ -609,12 +609,13 @@ struct BrushTool : SmoothDrawTool void draw(BOOL bLeftButton, LONG x, LONG y) override { COLORREF rgb = bLeftButton ? m_fg : m_bg; - Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetBrushStyle()); + Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetBrushStyle(), + toolsModel.GetBrushWidth()); } void OnSpecialTweak(BOOL bMinus) override { - // TODO: + toolsModel.MakeBrushThickerOrThinner(bMinus); } }; diff --git a/base/applications/mspaint/toolsettings.cpp b/base/applications/mspaint/toolsettings.cpp index b2ee9039817..3d869848480 100644 --- a/base/applications/mspaint/toolsettings.cpp +++ b/base/applications/mspaint/toolsettings.cpp @@ -112,23 +112,43 @@ static inline INT getBrushRects(RECT rects[12], LPCRECT prc, LPPOINT ppt = NULL) return getSplitRects(rects, 3, 4, prc, ppt); } +struct BrushStyleAndWidth +{ + BrushStyle style; + INT width; +}; + +static const BrushStyleAndWidth c_BrushPresets[] = +{ + { BrushStyleRound, 7 }, { BrushStyleRound, 4 }, { BrushStyleRound, 1 }, + { BrushStyleSquare, 8 }, { BrushStyleSquare, 5 }, { BrushStyleSquare, 2 }, + { BrushStyleForeSlash, 8 }, { BrushStyleForeSlash, 5 }, { BrushStyleForeSlash, 2 }, + { BrushStyleBackSlash, 8 }, { BrushStyleBackSlash, 5 }, { BrushStyleBackSlash, 2 }, +}; + VOID CToolSettingsWindow::drawBrush(HDC hdc, LPCRECT prc) { RECT rects[12]; getBrushRects(rects, prc); - ::FillRect(hdc, &rects[toolsModel.GetBrushStyle()], (HBRUSH)(COLOR_HIGHLIGHT + 1)); - for (INT i = 0; i < 12; i++) { RECT rcItem = rects[i]; INT x = (rcItem.left + rcItem.right) / 2, y = (rcItem.top + rcItem.bottom) / 2; + INT iColor; - if (i == toolsModel.GetBrushStyle()) + const BrushStyleAndWidth& data = c_BrushPresets[i]; + if (data.width == toolsModel.GetBrushWidth() && data.style == toolsModel.GetBrushStyle()) + { iColor = COLOR_HIGHLIGHTTEXT; + ::FillRect(hdc, &rcItem, (HBRUSH)(COLOR_HIGHLIGHT + 1)); + } else + { iColor = COLOR_WINDOWTEXT; - Brush(hdc, x, y, x, y, ::GetSysColor(iColor), i); + } + + Brush(hdc, x, y, x, y, ::GetSysColor(iColor), data.style, data.width); } } @@ -383,7 +403,11 @@ LRESULT CToolSettingsWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lPar case TOOL_BRUSH: iItem = getBrushRects(rects, &rect1, &pt); if (iItem != -1) - toolsModel.SetBrushStyle(iItem); + { + const BrushStyleAndWidth& data = c_BrushPresets[iItem]; + toolsModel.SetBrushStyle(data.style); + toolsModel.SetBrushWidth(data.width); + } break; case TOOL_AIRBRUSH: iItem = getAirBrushRects(rects, &rect1, &pt); diff --git a/base/applications/mspaint/toolsmodel.cpp b/base/applications/mspaint/toolsmodel.cpp index 6b5e41d483a..07ded56ea99 100644 --- a/base/applications/mspaint/toolsmodel.cpp +++ b/base/applications/mspaint/toolsmodel.cpp @@ -14,8 +14,9 @@ ToolsModel toolsModel; ToolsModel::ToolsModel() { m_lineWidth = m_penWidth = 1; + m_brushWidth = 4; m_shapeStyle = 0; - m_brushStyle = 0; + m_brushStyle = BrushStyleRound; m_oldActiveTool = m_activeTool = TOOL_PEN; m_airBrushWidth = 5; m_rubberRadius = 4; @@ -68,6 +69,18 @@ void ToolsModel::SetPenWidth(INT nPenWidth) imageModel.NotifyImageChanged(); } +INT ToolsModel::GetBrushWidth() const +{ + return m_brushWidth; +} + +void ToolsModel::SetBrushWidth(INT nBrushWidth) +{ + m_brushWidth = nBrushWidth; + NotifyToolSettingsChanged(); + imageModel.NotifyImageChanged(); +} + void ToolsModel::MakeLineThickerOrThinner(BOOL bThinner) { INT thickness = GetLineWidth(); @@ -80,6 +93,12 @@ void ToolsModel::MakePenThickerOrThinner(BOOL bThinner) SetPenWidth(bThinner ? max(1, thickness - 1) : (thickness + 1)); } +void ToolsModel::MakeBrushThickerOrThinner(BOOL bThinner) +{ + INT thickness = GetBrushWidth(); + SetBrushWidth(bThinner ? max(1, thickness - 1) : (thickness + 1)); +} + int ToolsModel::GetShapeStyle() const { return m_shapeStyle; @@ -91,12 +110,12 @@ void ToolsModel::SetShapeStyle(int nShapeStyle) NotifyToolSettingsChanged(); } -int ToolsModel::GetBrushStyle() const +BrushStyle ToolsModel::GetBrushStyle() const { return m_brushStyle; } -void ToolsModel::SetBrushStyle(int nBrushStyle) +void ToolsModel::SetBrushStyle(BrushStyle nBrushStyle) { m_brushStyle = nBrushStyle; NotifyToolSettingsChanged(); diff --git a/base/applications/mspaint/toolsmodel.h b/base/applications/mspaint/toolsmodel.h index efb63b09022..b6f2c96fbdb 100644 --- a/base/applications/mspaint/toolsmodel.h +++ b/base/applications/mspaint/toolsmodel.h @@ -28,6 +28,14 @@ enum TOOLTYPE TOOL_MAX = TOOL_RRECT, }; +enum BrushStyle +{ + BrushStyleRound, + BrushStyleSquare, + BrushStyleForeSlash, + BrushStyleBackSlash, +}; + /* CLASSES **********************************************************/ struct ToolBase @@ -68,8 +76,9 @@ class ToolsModel private: int m_lineWidth; INT m_penWidth; + INT m_brushWidth; int m_shapeStyle; - int m_brushStyle; + BrushStyle m_brushStyle; TOOLTYPE m_activeTool; TOOLTYPE m_oldActiveTool; int m_airBrushWidth; @@ -97,17 +106,27 @@ public: int GetShapeStyle() const; void SetShapeStyle(int nShapeStyle); - int GetBrushStyle() const; - void SetBrushStyle(int nBrushStyle); + + INT GetBrushWidth() const; + void SetBrushWidth(INT nBrushWidth); + void MakeBrushThickerOrThinner(BOOL bThinner); + + BrushStyle GetBrushStyle() const; + void SetBrushStyle(BrushStyle nBrushStyle); + TOOLTYPE GetActiveTool() const; TOOLTYPE GetOldActiveTool() const; void SetActiveTool(TOOLTYPE nActiveTool); + int GetAirBrushWidth() const; void SetAirBrushWidth(int nAirBrushWidth); + int GetRubberRadius() const; void SetRubberRadius(int nRubberRadius); + BOOL IsBackgroundTransparent() const; void SetBackgroundTransparent(BOOL bTransparent); + int GetZoom() const; void SetZoom(int nZoom);