svx/source/sdr/overlay/overlayselection.cxx | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
New commits: commit dc243f0122ba656d2630e93bebfb84a2bfe4042a Author: Rafael Lima <rafael.palma.l...@gmail.com> AuthorDate: Sat Jun 8 00:32:10 2024 +0200 Commit: Rafael Lima <rafael.palma.l...@gmail.com> CommitDate: Mon Jun 10 19:20:30 2024 +0200 tdf#161204 Improve visibility of outline in the selection overlay As discussed in the design meeting, this patch adds an internal white outline to the selection overlay to provide better contrast. FTR: This is the same approach used by other office suites (Excel, OnlyOffice, etc). Change-Id: I9b279ebfa9efbd2b5d9894b94ebda653c3dba6e9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168538 Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org> Tested-by: Jenkins Reviewed-by: Rafael Lima <rafael.palma.l...@gmail.com> diff --git a/svx/source/sdr/overlay/overlayselection.cxx b/svx/source/sdr/overlay/overlayselection.cxx index ba1d90d7092a..963546145b46 100644 --- a/svx/source/sdr/overlay/overlayselection.cxx +++ b/svx/source/sdr/overlay/overlayselection.cxx @@ -60,6 +60,37 @@ namespace sdr::overlay return aRetval; } + // Creates an ORed polygon with all the ranges shriked by 1px + // This is used to draw the internal white line in the selection + static basegfx::B2DPolyPolygon impCombineRangesToInternalPolyPolygon(const std::vector< basegfx::B2DRange >& rRanges) + { + // Determines the offset in twips + Size aSize(1, 1); + aSize = o3tl::convert(aSize, o3tl::Length::px, o3tl::Length::twip); + const sal_Int32 nShrink = aSize.getWidth(); + + const sal_uInt32 nCount(rRanges.size()); + basegfx::B2DPolyPolygon aRetval; + + for(sal_uInt32 a(0); a < nCount; a++) + { + basegfx::B2DRange aRange(rRanges[a]); + aRange.grow(-nShrink); + const basegfx::B2DPolygon aDiscretePolygon(basegfx::utils::createPolygonFromRect(aRange)); + + if(0 == a) + { + aRetval.append(aDiscretePolygon); + } + else + { + aRetval = basegfx::utils::solvePolygonOperationOr(aRetval, basegfx::B2DPolyPolygon(aDiscretePolygon)); + } + } + + return aRetval; + } + // check if wanted type OverlayType::Transparent or OverlayType::Solid // is possible. If not, fallback to invert mode (classic mode) static OverlayType impCheckPossibleOverlayType(OverlayType aOverlayType) @@ -137,14 +168,23 @@ namespace sdr::overlay if(mbBorder) { + // External outline using themed color basegfx::B2DPolyPolygon aPolyPolygon(impCombineRangesToPolyPolygon(getRanges())); const drawinglayer::primitive2d::Primitive2DReference aSelectionOutline( new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( std::move(aPolyPolygon), aRGBColor)); + // Internal outline with white color to provide contrast + basegfx::B2DPolyPolygon aInternalPolyPolygon(impCombineRangesToInternalPolyPolygon(getRanges())); + const drawinglayer::primitive2d::Primitive2DReference aInternalSelectionOutline( + new drawinglayer::primitive2d::PolyPolygonHairlinePrimitive2D( + std::move(aInternalPolyPolygon), + basegfx::BColor(1.0, 1.0, 1.0))); + // add both to result aRetval = drawinglayer::primitive2d::Primitive2DContainer { aUnifiedTransparence, aSelectionOutline }; + aRetval.append(drawinglayer::primitive2d::Primitive2DContainer{aUnifiedTransparence, aInternalSelectionOutline}); } else {