diff options
author | Armin Le Grand (Collabora) <Armin.Le.Grand@me.com> | 2020-02-06 18:53:12 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2020-02-07 18:49:18 +0100 |
commit | 5f61c9fe99ac93087b898adddbb4d4733f1fcd07 (patch) | |
tree | 50e5e98702db8a12eba1e4f5dc730e76db2cca1e /vcl/win | |
parent | 1fb4887613f2487be6081dd62c4df30f6170e2c0 (diff) |
tdf#130478 Enhance Dashed line drawing on all systems
For more info and explanation including state of process
information and discussion(s) see task please.
Adding corrections for gerrit build
Change-Id: Ie10fb8093a86459dee80db5ab4355b47e46c1f8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88130
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'vcl/win')
-rw-r--r-- | vcl/win/gdi/gdiimpl.cxx | 99 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi_gdiplus.cxx | 2 |
3 files changed, 83 insertions, 19 deletions
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index 875f4924fbf4..919395f48304 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -20,6 +20,7 @@ #include <sal/config.h> #include <memory> +#include <numeric> #include <svsys.h> @@ -1987,18 +1988,19 @@ private: // all other values the triangulation is based on and // need to be compared with to check for data validity bool mbNoLineJoin; + std::vector< double > maStroke; public: SystemDependentData_GraphicsPath( basegfx::SystemDependentDataManager& rSystemDependentDataManager, std::shared_ptr<Gdiplus::GraphicsPath>& rpGraphicsPath, - bool bNoLineJoin); + bool bNoLineJoin, + const std::vector< double >* pStroke); // MM01 - // read access to Gdiplus::GraphicsPath + // read access std::shared_ptr<Gdiplus::GraphicsPath>& getGraphicsPath() { return mpGraphicsPath; } - - // other data-validity access bool getNoLineJoin() const { return mbNoLineJoin; } + const std::vector< double >& getStroke() const { return maStroke; } virtual sal_Int64 estimateUsageInBytes() const override; }; @@ -2008,11 +2010,17 @@ public: SystemDependentData_GraphicsPath::SystemDependentData_GraphicsPath( basegfx::SystemDependentDataManager& rSystemDependentDataManager, std::shared_ptr<Gdiplus::GraphicsPath>& rpGraphicsPath, - bool bNoLineJoin) + bool bNoLineJoin, + const std::vector< double >* pStroke) : basegfx::SystemDependentData(rSystemDependentDataManager), mpGraphicsPath(rpGraphicsPath), - mbNoLineJoin(bNoLineJoin) + mbNoLineJoin(bNoLineJoin), + maStroke() { + if(nullptr != pStroke) + { + maStroke = *pStroke; + } } sal_Int64 SystemDependentData_GraphicsPath::estimateUsageInBytes() const @@ -2136,7 +2144,8 @@ bool WinSalGraphicsImpl::drawPolyPolygon( rPolyPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>( ImplGetSystemDependentDataManager(), pGraphicsPath, - false); + false, + nullptr); } if(mrParent.getAntiAliasB2DDraw()) @@ -2196,12 +2205,14 @@ bool WinSalGraphicsImpl::drawPolyLine( const basegfx::B2DPolygon& rPolygon, double fTransparency, const basegfx::B2DVector& rLineWidths, + const std::vector< double >* pStroke, // MM01 basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap, double fMiterMinimumAngle, bool bPixelSnapHairline) { - if(!mbPen || 0 == rPolygon.count()) + // MM01 check done for simple reasons + if(!mbPen || !rPolygon.count() || fTransparency < 0.0 || fTransparency > 1.0) { return true; } @@ -2293,6 +2304,25 @@ bool WinSalGraphicsImpl::drawPolyLine( std::shared_ptr<SystemDependentData_GraphicsPath> pSystemDependentData_GraphicsPath( rPolygon.getSystemDependentData<SystemDependentData_GraphicsPath>()); + // MM01 need to do line dashing as fallback stuff here now + const double fDotDashLength(nullptr != pStroke ? std::accumulate(pStroke->begin(), pStroke->end(), 0.0) : 0.0); + const bool bStrokeUsed(0.0 != fDotDashLength); + + if(pSystemDependentData_GraphicsPath) + { + // MM01 - check on stroke change. Used against not used, or if oth used, + // equal or different? Triangulation geometry creation depends heavily + // on stroke, independent of being transformation independent + const bool bStrokeWasUsed(!pSystemDependentData_GraphicsPath->getStroke().empty()); + + if(bStrokeWasUsed != bStrokeUsed + || (bStrokeUsed && *pStroke != pSystemDependentData_GraphicsPath->getStroke())) + { + // data invalid, forget + pSystemDependentData_GraphicsPath.reset(); + } + } + if(pSystemDependentData_GraphicsPath) { // check data validity @@ -2314,17 +2344,47 @@ bool WinSalGraphicsImpl::drawPolyLine( // fill data of buffered data pGraphicsPath = std::make_shared<Gdiplus::GraphicsPath>(); - impAddB2DPolygonToGDIPlusGraphicsPathReal( - *pGraphicsPath, - rPolygon, - rObjectToDevice, - bNoLineJoin, - bPixelSnapHairline); - - if(rPolygon.isClosed() && !bNoLineJoin) + if(bStrokeUsed) { - // #i101491# needed to create the correct line joins - pGraphicsPath->CloseFigure(); + // MM01 need to do line dashing as fallback stuff here now + basegfx::B2DPolyPolygon aPolyPolygonLine; + + // apply LineStyle + basegfx::utils::applyLineDashing( + rPolygon, // source + *pStroke, // pattern + &aPolyPolygonLine, // traget for lines + nullptr, // target for gaps + fDotDashLength); // full length if available + + // MM01 checked/verified, ok + for(sal_uInt32 a(0); a < aPolyPolygonLine.count(); a++) + { + const basegfx::B2DPolygon aPolyLine(aPolyPolygonLine.getB2DPolygon(a)); + pGraphicsPath->StartFigure(); + impAddB2DPolygonToGDIPlusGraphicsPathReal( + *pGraphicsPath, + aPolyLine, + rObjectToDevice, + bNoLineJoin, + bPixelSnapHairline); + } + } + else + { + // no line dashing, just copy + impAddB2DPolygonToGDIPlusGraphicsPathReal( + *pGraphicsPath, + rPolygon, + rObjectToDevice, + bNoLineJoin, + bPixelSnapHairline); + + if(rPolygon.isClosed() && !bNoLineJoin) + { + // #i101491# needed to create the correct line joins + pGraphicsPath->CloseFigure(); + } } // add to buffering mechanism @@ -2333,7 +2393,8 @@ bool WinSalGraphicsImpl::drawPolyLine( rPolygon.addOrReplaceSystemDependentData<SystemDependentData_GraphicsPath>( ImplGetSystemDependentDataManager(), pGraphicsPath, - bNoLineJoin); + bNoLineJoin, + pStroke); } } diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx index 3b3b1837b930..eb56388ff42d 100644 --- a/vcl/win/gdi/gdiimpl.hxx +++ b/vcl/win/gdi/gdiimpl.hxx @@ -130,6 +130,7 @@ public: const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, + const std::vector< double >* pStroke, // MM01 basegfx::B2DLineJoin, css::drawing::LineCap, double fMiterMinimumAngle, diff --git a/vcl/win/gdi/salgdi_gdiplus.cxx b/vcl/win/gdi/salgdi_gdiplus.cxx index 99c7d0e506e9..ce2f2cc69c20 100644 --- a/vcl/win/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/gdi/salgdi_gdiplus.cxx @@ -42,6 +42,7 @@ bool WinSalGraphics::drawPolyLine( const basegfx::B2DPolygon& rPolygon, double fTransparency, const basegfx::B2DVector& rLineWidths, + const std::vector< double >* pStroke, // MM01 basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap, double fMiterMinimumAngle, @@ -52,6 +53,7 @@ bool WinSalGraphics::drawPolyLine( rPolygon, fTransparency, rLineWidths, + pStroke, // MM01 eLineJoin, eLineCap, fMiterMinimumAngle, |