From 33131a183f9f34d798a741f317a91d87537684f6 Mon Sep 17 00:00:00 2001 From: Rick Yorgason Date: Wed, 17 Oct 2018 20:06:34 -0700 Subject: [PATCH 1/2] New "Outline thin strokes" view mode which draws thin strokes in outline mode so they're easier to see, while still drawing everything else normally. Very useful for making hairline strokes (0.001") for laser cutters. --- share/ui/menus.xml | 1 + src/desktop.cpp | 3 +++ src/desktop.h | 3 +++ src/display/drawing-context.h | 2 ++ src/display/drawing-shape.cpp | 22 ++++++++++++++++++++++ src/display/drawing-text.cpp | 10 ++++++++++ src/display/drawing.cpp | 7 ++++++- src/display/drawing.h | 1 + src/display/rendermode.h | 3 ++- src/ui/interface.cpp | 2 ++ src/verbs.cpp | 5 +++++ src/verbs.h | 1 + src/widgets/desktop-widget.cpp | 2 ++ 13 files changed, 60 insertions(+), 2 deletions(-) diff --git a/share/ui/menus.xml b/share/ui/menus.xml index 5bcaca8cf6..818e7a9680 100644 --- a/share/ui/menus.xml +++ b/share/ui/menus.xml @@ -108,6 +108,7 @@ + diff --git a/src/desktop.cpp b/src/desktop.cpp index 46589ca040..c1891301c2 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -519,6 +519,9 @@ void SPDesktop::displayModeToggle() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); break; case Inkscape::RENDERMODE_OUTLINE: + _setDisplayMode(Inkscape::RENDERMODE_OUTLINE_THIN); + break; + case Inkscape::RENDERMODE_OUTLINE_THIN: _setDisplayMode(Inkscape::RENDERMODE_NORMAL); break; default: diff --git a/src/desktop.h b/src/desktop.h index 379d36a786..a38876de1e 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -266,6 +266,9 @@ public: void setDisplayModeOutline() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); } + void setDisplayModeOutlineThin() { + _setDisplayMode(Inkscape::RENDERMODE_OUTLINE_THIN); + } void displayModeToggle(); Inkscape::RenderMode _display_mode; Inkscape::RenderMode getMode() const { return _display_mode; } diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h index 8587fbf66f..12d192a7cb 100644 --- a/src/display/drawing-context.h +++ b/src/display/drawing-context.h @@ -52,6 +52,8 @@ public: void translate(double dx, double dy) { cairo_translate(_ct, dx, dy); } void scale(Geom::Scale const &s) { cairo_scale(_ct, s[Geom::X], s[Geom::Y]); } void scale(double sx, double sy) { cairo_scale(_ct, sx, sy); } + void device_to_user_distance(double &dx, double &dy) { cairo_device_to_user_distance(_ct, &dx, &dy); } + void user_to_device_distance(double &dx, double &dy) { cairo_user_to_device_distance(_ct, &dx, &dy); } void moveTo(Geom::Point const &p) { cairo_move_to(_ct, p[Geom::X], p[Geom::Y]); } void lineTo(Geom::Point const &p) { cairo_line_to(_ct, p[Geom::X], p[Geom::Y]); } diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 63db9475de..c2208d1617 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -185,6 +185,17 @@ DrawingShape::_renderStroke(DrawingContext &dc) dc.save(); } _nrstyle.applyStroke(dc); + + // Special handling for thin outline mode when we're drawing lines smaller than half a + // pixel + if (_drawing.outlineThin()) { + double outline_thin_size = 0.5, trash = 0.5; + dc.device_to_user_distance(outline_thin_size, trash); + if (_nrstyle.stroke_width < outline_thin_size) { + dc.setLineWidth(outline_thin_size); + } + } + dc.strokePreserve(); dc.newPath(); // clear path } @@ -255,6 +266,17 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne } if (has_stroke) { _nrstyle.applyStroke(dc); + + // Special handling for thin outline mode when we're drawing lines smaller than + // half a pixel + if (_drawing.outlineThin()) { + double outline_thin_size = 0.5, trash = 0.5; + dc.device_to_user_distance(outline_thin_size, trash); + if (_nrstyle.stroke_width < outline_thin_size) { + dc.setLineWidth(outline_thin_size); + } + } + dc.strokePreserve(); } dc.newPath(); // clear path diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index 76c392d67c..b48ce7d31b 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -603,6 +603,16 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are } if (has_stroke) { _nrstyle.applyStroke(dc); + + // Special handling for thin outline mode when we're drawing lines smaller than half a pixel + if (_drawing.outlineThin()) { + double outline_thin_size = 0.5, trash = 0.5; + dc.device_to_user_distance(outline_thin_size, trash); + if (_nrstyle.stroke_width < outline_thin_size) { + dc.setLineWidth(outline_thin_size); + } + } + dc.strokePreserve(); } } diff --git a/src/display/drawing.cpp b/src/display/drawing.cpp index 18c2d98e8f..7ecaea9872 100644 --- a/src/display/drawing.cpp +++ b/src/display/drawing.cpp @@ -79,9 +79,14 @@ Drawing::outline() const return renderMode() == RENDERMODE_OUTLINE; } bool +Drawing::outlineThin() const +{ + return renderMode() == RENDERMODE_OUTLINE_THIN; +} +bool Drawing::renderFilters() const { - return renderMode() == RENDERMODE_NORMAL; + return renderMode() == RENDERMODE_NORMAL || renderMode() == RENDERMODE_OUTLINE_THIN; } int Drawing::blurQuality() const diff --git a/src/display/drawing.h b/src/display/drawing.h index 1348f02af0..1669cc3a49 100644 --- a/src/display/drawing.h +++ b/src/display/drawing.h @@ -50,6 +50,7 @@ public: RenderMode renderMode() const; ColorMode colorMode() const; bool outline() const; + bool outlineThin() const; bool renderFilters() const; int blurQuality() const; int filterQuality() const; diff --git a/src/display/rendermode.h b/src/display/rendermode.h index cbd35de73f..36dd0ead32 100644 --- a/src/display/rendermode.h +++ b/src/display/rendermode.h @@ -12,7 +12,8 @@ namespace Inkscape { enum RenderMode { RENDERMODE_NORMAL, RENDERMODE_NO_FILTERS, - RENDERMODE_OUTLINE + RENDERMODE_OUTLINE, + RENDERMODE_OUTLINE_THIN }; enum ColorMode { diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 41f5f29a0c..1f04f3a492 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -682,6 +682,8 @@ static gboolean update_view_menu(GtkWidget *widget, cairo_t * /*cr*/, gpointer u new_state = mode == Inkscape::RENDERMODE_NO_FILTERS; } else if (!strcmp(action->id, "ViewModeOutline")) { new_state = mode == Inkscape::RENDERMODE_OUTLINE; + } else if (!strcmp(action->id, "ViewModeOutlineThin")) { + new_state = mode == Inkscape::RENDERMODE_OUTLINE_THIN; } else if (!strcmp(action->id, "ViewColorModeNormal")) { new_state = colormode == Inkscape::COLORMODE_NORMAL; } else if (!strcmp(action->id, "ViewColorModeGrayscale")) { diff --git a/src/verbs.cpp b/src/verbs.cpp index 47c532a3f0..2c7cfb25f3 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2132,6 +2132,9 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_VIEW_MODE_OUTLINE: dt->setDisplayModeOutline(); break; + case SP_VERB_VIEW_MODE_OUTLINE_THIN: + dt->setDisplayModeOutlineThin(); + break; case SP_VERB_VIEW_MODE_TOGGLE: dt->displayModeToggle(); break; @@ -3108,6 +3111,8 @@ Verb *Verb::_base_verbs[] = { N_("Switch to normal display without filters"), nullptr), new ZoomVerb(SP_VERB_VIEW_MODE_OUTLINE, "ViewModeOutline", N_("_Outline"), N_("Switch to outline (wireframe) display mode"), nullptr), + new ZoomVerb(SP_VERB_VIEW_MODE_OUTLINE_THIN, "ViewModeOutlineThin", N_("O_utline thin strokes"), + N_("Outline strokes that are smaller than 1 pixel and draw the rest normally"), nullptr), new ZoomVerb(SP_VERB_VIEW_MODE_TOGGLE, "ViewModeToggle", N_("_Toggle"), N_("Toggle between normal and outline display modes"), nullptr), new ZoomVerb(SP_VERB_VIEW_COLOR_MODE_NORMAL, "ViewColorModeNormal", N_("_Normal"), diff --git a/src/verbs.h b/src/verbs.h index fe17cb2d12..b9402ed108 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -297,6 +297,7 @@ enum { SP_VERB_VIEW_MODE_NORMAL, SP_VERB_VIEW_MODE_NO_FILTERS, SP_VERB_VIEW_MODE_OUTLINE, + SP_VERB_VIEW_MODE_OUTLINE_THIN, SP_VERB_VIEW_MODE_TOGGLE, SP_VERB_VIEW_COLOR_MODE_NORMAL, SP_VERB_VIEW_COLOR_MODE_GRAYSCALE, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 35a9df65b2..65b4272082 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -813,6 +813,8 @@ SPDesktopWidget::updateTitle(gchar const* uri) Name += N_("outline"); } else if (desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { Name += N_("no filters"); + } else if (desktop->getMode() == Inkscape::RENDERMODE_OUTLINE_THIN) { + Name += N_("outline thin"); } if (desktop->getColorMode() != Inkscape::COLORMODE_NORMAL && -- GitLab From 83bf2fdf80496f0368438e16bc3adb8ee0e86fb7 Mon Sep 17 00:00:00 2001 From: Rick Yorgason Date: Thu, 18 Oct 2018 01:21:15 -0700 Subject: [PATCH 2/2] Renamed "Outline thin strokes" to "visible hairlines" to make the intent clearer. --- share/ui/menus.xml | 2 +- src/desktop.cpp | 4 ++-- src/desktop.h | 4 ++-- src/display/drawing-shape.cpp | 28 ++++++++++++++-------------- src/display/drawing-text.cpp | 13 +++++++------ src/display/drawing.cpp | 6 +++--- src/display/drawing.h | 2 +- src/display/rendermode.h | 2 +- src/ui/interface.cpp | 4 ++-- src/verbs.cpp | 8 ++++---- src/verbs.h | 2 +- src/widgets/desktop-widget.cpp | 4 ++-- 12 files changed, 40 insertions(+), 39 deletions(-) diff --git a/share/ui/menus.xml b/share/ui/menus.xml index 818e7a9680..03cd74d748 100644 --- a/share/ui/menus.xml +++ b/share/ui/menus.xml @@ -108,7 +108,7 @@ - + diff --git a/src/desktop.cpp b/src/desktop.cpp index c1891301c2..335afa17d1 100644 --- a/src/desktop.cpp +++ b/src/desktop.cpp @@ -519,9 +519,9 @@ void SPDesktop::displayModeToggle() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); break; case Inkscape::RENDERMODE_OUTLINE: - _setDisplayMode(Inkscape::RENDERMODE_OUTLINE_THIN); + _setDisplayMode(Inkscape::RENDERMODE_VISIBLE_HAIRLINES); break; - case Inkscape::RENDERMODE_OUTLINE_THIN: + case Inkscape::RENDERMODE_VISIBLE_HAIRLINES: _setDisplayMode(Inkscape::RENDERMODE_NORMAL); break; default: diff --git a/src/desktop.h b/src/desktop.h index a38876de1e..ec6ea99f7f 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -266,8 +266,8 @@ public: void setDisplayModeOutline() { _setDisplayMode(Inkscape::RENDERMODE_OUTLINE); } - void setDisplayModeOutlineThin() { - _setDisplayMode(Inkscape::RENDERMODE_OUTLINE_THIN); + void setDisplayModeVisibleHairlines() { + _setDisplayMode(Inkscape::RENDERMODE_VISIBLE_HAIRLINES); } void displayModeToggle(); Inkscape::RenderMode _display_mode; diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index c2208d1617..05123297ee 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -186,13 +186,13 @@ DrawingShape::_renderStroke(DrawingContext &dc) } _nrstyle.applyStroke(dc); - // Special handling for thin outline mode when we're drawing lines smaller than half a - // pixel - if (_drawing.outlineThin()) { - double outline_thin_size = 0.5, trash = 0.5; - dc.device_to_user_distance(outline_thin_size, trash); - if (_nrstyle.stroke_width < outline_thin_size) { - dc.setLineWidth(outline_thin_size); + // If the draw mode is set to visible hairlines, don't let them get smaller than half a + // pixel. + if (_drawing.visibleHairlines()) { + double half_pixel_size = 0.5, trash = 0.5; + dc.device_to_user_distance(half_pixel_size, trash); + if (_nrstyle.stroke_width < half_pixel_size) { + dc.setLineWidth(half_pixel_size); } } @@ -267,13 +267,13 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne if (has_stroke) { _nrstyle.applyStroke(dc); - // Special handling for thin outline mode when we're drawing lines smaller than - // half a pixel - if (_drawing.outlineThin()) { - double outline_thin_size = 0.5, trash = 0.5; - dc.device_to_user_distance(outline_thin_size, trash); - if (_nrstyle.stroke_width < outline_thin_size) { - dc.setLineWidth(outline_thin_size); + // If the draw mode is set to visible hairlines, don't let anything get smaller + // than half a pixel. + if (_drawing.visibleHairlines()) { + double half_pixel_size = 0.5, trash = 0.5; + dc.device_to_user_distance(half_pixel_size, trash); + if (_nrstyle.stroke_width < half_pixel_size) { + dc.setLineWidth(half_pixel_size); } } diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index b48ce7d31b..d823012e3d 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -604,12 +604,13 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are if (has_stroke) { _nrstyle.applyStroke(dc); - // Special handling for thin outline mode when we're drawing lines smaller than half a pixel - if (_drawing.outlineThin()) { - double outline_thin_size = 0.5, trash = 0.5; - dc.device_to_user_distance(outline_thin_size, trash); - if (_nrstyle.stroke_width < outline_thin_size) { - dc.setLineWidth(outline_thin_size); + // If the draw mode is set to visible hairlines, don't let anything get smaller + // than half a pixel. + if (_drawing.visibleHairlines()) { + double half_pixel_size = 0.5, trash = 0.5; + dc.device_to_user_distance(half_pixel_size, trash); + if (_nrstyle.stroke_width < half_pixel_size) { + dc.setLineWidth(half_pixel_size); } } diff --git a/src/display/drawing.cpp b/src/display/drawing.cpp index 7ecaea9872..4b2a2cadfc 100644 --- a/src/display/drawing.cpp +++ b/src/display/drawing.cpp @@ -79,14 +79,14 @@ Drawing::outline() const return renderMode() == RENDERMODE_OUTLINE; } bool -Drawing::outlineThin() const +Drawing::visibleHairlines() const { - return renderMode() == RENDERMODE_OUTLINE_THIN; + return renderMode() == RENDERMODE_VISIBLE_HAIRLINES; } bool Drawing::renderFilters() const { - return renderMode() == RENDERMODE_NORMAL || renderMode() == RENDERMODE_OUTLINE_THIN; + return renderMode() == RENDERMODE_NORMAL || renderMode() == RENDERMODE_VISIBLE_HAIRLINES; } int Drawing::blurQuality() const diff --git a/src/display/drawing.h b/src/display/drawing.h index 1669cc3a49..931fe8e468 100644 --- a/src/display/drawing.h +++ b/src/display/drawing.h @@ -50,7 +50,7 @@ public: RenderMode renderMode() const; ColorMode colorMode() const; bool outline() const; - bool outlineThin() const; + bool visibleHairlines() const; bool renderFilters() const; int blurQuality() const; int filterQuality() const; diff --git a/src/display/rendermode.h b/src/display/rendermode.h index 36dd0ead32..80e6da2ddc 100644 --- a/src/display/rendermode.h +++ b/src/display/rendermode.h @@ -13,7 +13,7 @@ enum RenderMode { RENDERMODE_NORMAL, RENDERMODE_NO_FILTERS, RENDERMODE_OUTLINE, - RENDERMODE_OUTLINE_THIN + RENDERMODE_VISIBLE_HAIRLINES }; enum ColorMode { diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp index 1f04f3a492..f644aa174b 100644 --- a/src/ui/interface.cpp +++ b/src/ui/interface.cpp @@ -682,8 +682,8 @@ static gboolean update_view_menu(GtkWidget *widget, cairo_t * /*cr*/, gpointer u new_state = mode == Inkscape::RENDERMODE_NO_FILTERS; } else if (!strcmp(action->id, "ViewModeOutline")) { new_state = mode == Inkscape::RENDERMODE_OUTLINE; - } else if (!strcmp(action->id, "ViewModeOutlineThin")) { - new_state = mode == Inkscape::RENDERMODE_OUTLINE_THIN; + } else if (!strcmp(action->id, "ViewModeVisibleHairlines")) { + new_state = mode == Inkscape::RENDERMODE_VISIBLE_HAIRLINES; } else if (!strcmp(action->id, "ViewColorModeNormal")) { new_state = colormode == Inkscape::COLORMODE_NORMAL; } else if (!strcmp(action->id, "ViewColorModeGrayscale")) { diff --git a/src/verbs.cpp b/src/verbs.cpp index 2c7cfb25f3..fe617148a9 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -2132,8 +2132,8 @@ void ZoomVerb::perform(SPAction *action, void *data) case SP_VERB_VIEW_MODE_OUTLINE: dt->setDisplayModeOutline(); break; - case SP_VERB_VIEW_MODE_OUTLINE_THIN: - dt->setDisplayModeOutlineThin(); + case SP_VERB_VIEW_MODE_VISIBLE_HAIRLINES: + dt->setDisplayModeVisibleHairlines(); break; case SP_VERB_VIEW_MODE_TOGGLE: dt->displayModeToggle(); @@ -3111,8 +3111,8 @@ Verb *Verb::_base_verbs[] = { N_("Switch to normal display without filters"), nullptr), new ZoomVerb(SP_VERB_VIEW_MODE_OUTLINE, "ViewModeOutline", N_("_Outline"), N_("Switch to outline (wireframe) display mode"), nullptr), - new ZoomVerb(SP_VERB_VIEW_MODE_OUTLINE_THIN, "ViewModeOutlineThin", N_("O_utline thin strokes"), - N_("Outline strokes that are smaller than 1 pixel and draw the rest normally"), nullptr), + new ZoomVerb(SP_VERB_VIEW_MODE_VISIBLE_HAIRLINES, "ViewModeVisibleHairlines", N_("Visible _Hairlines"), + N_("Make sure hairlines are always drawn thick enough to see"), nullptr), new ZoomVerb(SP_VERB_VIEW_MODE_TOGGLE, "ViewModeToggle", N_("_Toggle"), N_("Toggle between normal and outline display modes"), nullptr), new ZoomVerb(SP_VERB_VIEW_COLOR_MODE_NORMAL, "ViewColorModeNormal", N_("_Normal"), diff --git a/src/verbs.h b/src/verbs.h index b9402ed108..fec42cca24 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -297,7 +297,7 @@ enum { SP_VERB_VIEW_MODE_NORMAL, SP_VERB_VIEW_MODE_NO_FILTERS, SP_VERB_VIEW_MODE_OUTLINE, - SP_VERB_VIEW_MODE_OUTLINE_THIN, + SP_VERB_VIEW_MODE_VISIBLE_HAIRLINES, SP_VERB_VIEW_MODE_TOGGLE, SP_VERB_VIEW_COLOR_MODE_NORMAL, SP_VERB_VIEW_COLOR_MODE_GRAYSCALE, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 65b4272082..1b717f351c 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -813,8 +813,8 @@ SPDesktopWidget::updateTitle(gchar const* uri) Name += N_("outline"); } else if (desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { Name += N_("no filters"); - } else if (desktop->getMode() == Inkscape::RENDERMODE_OUTLINE_THIN) { - Name += N_("outline thin"); + } else if (desktop->getMode() == Inkscape::RENDERMODE_VISIBLE_HAIRLINES) { + Name += N_("visible hairlines"); } if (desktop->getColorMode() != Inkscape::COLORMODE_NORMAL && -- GitLab