diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2016-04-09 23:15:09 +0200 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@cib.de> | 2016-04-26 16:42:27 +0000 |
commit | 32cec4ca8bf1e09dd33aa461984e8e8ae34f4a7c (patch) | |
tree | 5591a63de12179505a0e7a4870632754585152d3 /vcl | |
parent | 4905c8bf7834b1ca79139c62f4e8b0672e9ddc13 (diff) |
tdf#48066 render stroke-miterlimit correctly in SVG import
The property stroke-miterlimit is transported to the renderers
via a new member mfMiterMinimumAngle in class LineAttribute
Several drawPolyLine methods are adapted. This patch does not
include changes in MetaAction. Presentation mode, printing, and
PDF-export is still wrong.
Corrected LineJoinMiter to LineJoinBevel in canvas, that s closer
to NONE. Removed DrawPolyLine method without MiterMinimumAngle
and adapted calls accordingly.
Change-Id: I6bcd24add5d85c4d9a39e3788e0682091c5fc9c4
Reviewed-on: https://gerrit.libreoffice.org/23946
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/headless/svpgdi.cxx | 11 | ||||
-rw-r--r-- | vcl/inc/headless/svpgdi.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 5 | ||||
-rw-r--r-- | vcl/inc/quartz/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/inc/salgdi.hxx | 4 | ||||
-rw-r--r-- | vcl/inc/salgdiimpl.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/unx/genpspgraphics.h | 3 | ||||
-rw-r--r-- | vcl/inc/unx/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 13 | ||||
-rw-r--r-- | vcl/quartz/salgdicommon.cxx | 7 | ||||
-rw-r--r-- | vcl/source/gdi/salgdilayout.cxx | 6 | ||||
-rw-r--r-- | vcl/source/outdev/line.cxx | 18 | ||||
-rw-r--r-- | vcl/source/outdev/polygon.cxx | 3 | ||||
-rw-r--r-- | vcl/source/outdev/polyline.cxx | 36 | ||||
-rw-r--r-- | vcl/source/outdev/transparent.cxx | 19 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/gdiimpl.hxx | 3 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi.cxx | 5 | ||||
-rw-r--r-- | vcl/unx/generic/print/genpspgraphics.cxx | 3 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.cxx | 5 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.hxx | 3 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi_gdiplus.cxx | 5 |
23 files changed, 121 insertions, 48 deletions
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 37e0e17bbbe2..b6c33b709e24 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -27,6 +27,7 @@ #include <vcl/sysdata.hxx> #include <config_cairo_canvas.h> +#include <basegfx/numeric/ftools.hxx> #include <basegfx/range/b2drange.hxx> #include <basegfx/range/b2ibox.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> @@ -538,7 +539,7 @@ void SvpSalGraphics::drawPolyLine(sal_uInt32 nPoints, const SalPoint* pPtAry) aPoly.setClosed(false); drawPolyLine(aPoly, 0.0, basegfx::B2DVector(1.0, 1.0), basegfx::B2DLineJoin::Miter, - css::drawing::LineCap_BUTT); + css::drawing::LineCap_BUTT, 15.0 * F_PI180 /*default*/); } void SvpSalGraphics::drawPolygon(sal_uInt32 nPoints, const SalPoint* pPtAry) @@ -699,7 +700,8 @@ bool SvpSalGraphics::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { // short circuit if there is nothing to do const int nPointCount = rPolyLine.count(); @@ -729,6 +731,9 @@ bool SvpSalGraphics::drawPolyLine( break; } + // convert miter minimum angle to miter limit + double fMiterLimit = 1.0 / sin( fMiterMinimumAngle / 2.0); + // setup cap attribute cairo_line_cap_t eCairoLineCap(CAIRO_LINE_CAP_BUTT); @@ -759,7 +764,7 @@ bool SvpSalGraphics::drawPolyLine( cairo_set_line_join(cr, eCairoLineJoin); cairo_set_line_cap(cr, eCairoLineCap); cairo_set_line_width(cr, rLineWidths.getX()); - cairo_set_miter_limit(cr, 15.0); + cairo_set_miter_limit(cr, fMiterLimit); basegfx::B2DRange extents(0, 0, 0, 0); diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index be9aebe17332..758057500ba2 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -163,7 +163,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) override; virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) override; virtual void drawPolyPolygon( sal_uInt32 nPoly, diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index ef23328658f1..0f8b605b5fca 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -133,7 +133,7 @@ public: void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawLineSegment(float x1, float y1, float x2, float y2); void DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth); - void DrawPolyLine( const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap); + void DrawPolyLine( const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap, float fMiterMinimumAngle); void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA = false ); void DrawRegionBand( const RegionBand& rRegion ); void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false ); @@ -257,7 +257,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index a4a2608f3399..e4c9ca1a2eeb 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -246,7 +246,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap eLineCap) override; + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) override; virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) override { return false; }; // CopyArea --> No RasterOp, but ClipRegion diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 23d0d8164db1..feecc85153fc 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -273,6 +273,7 @@ public: const basegfx::B2DVector& i_rLineWidth, basegfx::B2DLineJoin i_eLineJoin, css::drawing::LineCap i_eLineCap, + double i_fMiterMinimumAngle, const OutputDevice* i_pOutDev); bool DrawPolyLineBezier( @@ -470,7 +471,8 @@ protected: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) = 0; + css::drawing::LineCap, + double fMiterMinimumAngle) = 0; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, diff --git a/vcl/inc/salgdiimpl.hxx b/vcl/inc/salgdiimpl.hxx index a70fe2c0e437..c5c8e6d42178 100644 --- a/vcl/inc/salgdiimpl.hxx +++ b/vcl/inc/salgdiimpl.hxx @@ -105,7 +105,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) = 0; + css::drawing::LineCap, + double fMiterMinimumAngle) = 0; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, diff --git a/vcl/inc/unx/genpspgraphics.h b/vcl/inc/unx/genpspgraphics.h index 6f6fa6940c9a..e609c124f4d1 100644 --- a/vcl/inc/unx/genpspgraphics.h +++ b/vcl/inc/unx/genpspgraphics.h @@ -148,7 +148,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) override; diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 88db9ce4c94b..29522824ca4a 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -176,7 +176,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin, - css::drawing::LineCap ) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawGradient( const tools::PolyPolygon&, const Gradient& ) override; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 8866dcfbc289..2c89393d9ed0 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -281,7 +281,8 @@ protected: double fTransparency, const basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) override; virtual bool drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const sal_uInt8* pFlgAry ) override; virtual bool drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPoints, const SalPoint* const* pPtAry, const BYTE* const* pFlgAry ) override; diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index b8d6fb6d9c73..8bb2c1dbe978 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -684,8 +684,6 @@ inline glm::vec2 normalize(const glm::vec2& vector) return vector; } -SAL_CONSTEXPR float constMiterMinimumAngle = 15.0f; - } // end anonymous namespace void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, css::drawing::LineCap eLineCap, float fLineWidth) @@ -769,7 +767,7 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float * - http://artgrammer.blogspot.si/2011/07/drawing-polylines-by-tessellation.html * */ -void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap) +void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, float fLineWidth, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap, float fMiterMinimumAngle) { sal_uInt32 nPoints = rPolygon.count(); bool bClosed = rPolygon.isClosed(); @@ -871,9 +869,9 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl float angle = std::atan2(previousLineVector.x * nextLineVector.y - previousLineVector.y * nextLineVector.x, previousLineVector.x * nextLineVector.x + previousLineVector.y * nextLineVector.y); - angle = (F_PI - std::fabs(angle)) / F_PI180; + angle = F_PI - std::fabs(angle); - if (angle < constMiterMinimumAngle) + if (angle < fMiterMinimumAngle) eLineJoin = basegfx::B2DLineJoin::Bevel; } @@ -2060,7 +2058,8 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { VCL_GL_INFO( "::drawPolyLine trans " << fTransparency ); if( mnLineColor == SALCOLOR_NONE ) @@ -2080,7 +2079,7 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( else aPolygon.removeDoublePoints(); - DrawPolyLine(aPolygon, fLineWidth, eLineJoin, eLineCap); + DrawPolyLine(aPolygon, fLineWidth, eLineJoin, eLineCap, fMiterMinimumAngle); } PostDraw(); diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx index eaf40deed5e4..e493be1a75fe 100644 --- a/vcl/quartz/salgdicommon.cxx +++ b/vcl/quartz/salgdicommon.cxx @@ -961,7 +961,8 @@ bool AquaSalGraphics::drawPolyLine( const basegfx::B2DPolygon& rPolyLine, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { DBG_DRAW_OPERATION("drawPolyLine", true); @@ -1000,7 +1001,8 @@ bool AquaSalGraphics::drawPolyLine( const basegfx::B2DPolygon& rPolyLine, case basegfx::B2DLineJoin::Miter: aCGLineJoin = kCGLineJoinMiter; break; case basegfx::B2DLineJoin::Round: aCGLineJoin = kCGLineJoinRound; break; } - + // convert miter minimum angle to miter limit + CGFloat fCGMiterLimit = 1.0 / sin(fMiterMinimumAngle / 2.0); // setup cap attribute CGLineCap aCGLineCap(kCGLineCapButt); @@ -1047,6 +1049,7 @@ bool AquaSalGraphics::drawPolyLine( const basegfx::B2DPolygon& rPolyLine, CGContextSetLineJoin( mrContext, aCGLineJoin ); CGContextSetLineCap( mrContext, aCGLineCap ); CGContextSetLineWidth( mrContext, rLineWidths.getX() ); + CGContextSetMiterLimit(mrContext, fCGMiterLimit); SAL_INFO( "vcl.cg", "CGContextDrawPath(" << mrContext << ",kCGPathStroke)" ); CGContextDrawPath( mrContext, kCGPathStroke ); SAL_INFO( "vcl.cg", "CGContextRestoreGState(" << mrContext << ") " << mnContextStackDepth-- ); diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 8244e023c4c2..052edc564845 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -23,6 +23,7 @@ #endif #include "salgdi.hxx" #include "salframe.hxx" +#include <basegfx/numeric/ftools.hxx> //for F_PI180 // The only common SalFrame method @@ -481,16 +482,17 @@ bool SalGraphics::DrawPolyLine( const basegfx::B2DPolygon& i_rPolygon, const basegfx::B2DVector& i_rLineWidth, basegfx::B2DLineJoin i_eLineJoin, css::drawing::LineCap i_eLineCap, + double i_fMiterMinimumAngle, const OutputDevice* i_pOutDev ) { bool bRet = false; if( (m_nLayout & SalLayoutFlags::BiDiRtl) || (i_pOutDev && i_pOutDev->IsRTLEnabled()) ) { basegfx::B2DPolygon aMirror( mirror( i_rPolygon, i_pOutDev ) ); - bRet = drawPolyLine( aMirror, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap ); + bRet = drawPolyLine( aMirror, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap, i_fMiterMinimumAngle ); } else - bRet = drawPolyLine( i_rPolygon, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap ); + bRet = drawPolyLine( i_rPolygon, i_fTransparency, i_rLineWidth, i_eLineJoin, i_eLineCap, i_fMiterMinimumAngle ); return bRet; } diff --git a/vcl/source/outdev/line.cxx b/vcl/source/outdev/line.cxx index bf4f2f6a3c8f..a04dd802ee96 100644 --- a/vcl/source/outdev/line.cxx +++ b/vcl/source/outdev/line.cxx @@ -134,7 +134,14 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, this)) + if( mpGraphics->DrawPolyLine( + aB2DPolyLine, + 0.0, + aB2DLineWidth, + basegfx::B2DLineJoin::NONE, + css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default + this)) { return; } @@ -236,7 +243,14 @@ void OutputDevice::drawLine( basegfx::B2DPolyPolygon aLinePolyPolygon, const Lin if(bTryAA) { - bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, this); + bDone = mpGraphics->DrawPolyLine( + aCandidate, + 0.0, + basegfx::B2DVector(1.0,1.0), + basegfx::B2DLineJoin::NONE, + css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default + this); } if(!bDone) diff --git a/vcl/source/outdev/polygon.cxx b/vcl/source/outdev/polygon.cxx index 0f36e30a8e00..612e93716bb1 100644 --- a/vcl/source/outdev/polygon.cxx +++ b/vcl/source/outdev/polygon.cxx @@ -97,6 +97,7 @@ void OutputDevice::DrawPolyPolygon( const tools::PolyPolygon& rPolyPoly ) aB2DLineWidth, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default this); } } @@ -207,6 +208,7 @@ void OutputDevice::DrawPolygon( const tools::Polygon& rPoly ) aB2DLineWidth, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default this); } @@ -311,6 +313,7 @@ void OutputDevice::ImplDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyP aB2DLineWidth, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default this); } } diff --git a/vcl/source/outdev/polyline.cxx b/vcl/source/outdev/polyline.cxx index 6bd72495870f..b2e5b7abbacd 100644 --- a/vcl/source/outdev/polyline.cxx +++ b/vcl/source/outdev/polyline.cxx @@ -72,8 +72,14 @@ void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly ) aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, - basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, this)) + if(mpGraphics->DrawPolyLine( + aB2DPolyLine, + 0.0, + aB2DLineWidth, + basegfx::B2DLineJoin::NONE, + css::drawing::LineCap_BUTT, + 15.0 * F_PI180 /*default fMiterMinimumAngle, not used*/, + this)) { return; } @@ -117,7 +123,12 @@ void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly, const LineInfo& rL if((mnAntialiasing & AntialiasingFlags::EnableB2dDraw) && LINE_SOLID == rLineInfo.GetStyle()) { - DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin(), rLineInfo.GetLineCap()); + DrawPolyLine( + rPoly.getB2DPolygon(), + static_cast< double >(rLineInfo.GetWidth()), + rLineInfo.GetLineJoin(), + rLineInfo.GetLineCap(), + 15.0 * F_PI180 /* default fMiterMinimumAngle, value not available in LineInfo */); return; } @@ -130,7 +141,8 @@ void OutputDevice::DrawPolyLine( const tools::Polygon& rPoly, const LineInfo& rL void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { assert(!is_double_buffered_window()); @@ -162,7 +174,7 @@ void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon, InitLineColor(); // use b2dpolygon drawing if possible - if ( DrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap) ) + if ( DrawPolyLineDirect(rB2DPolygon, fLineWidth, 0.0, eLineJoin, eLineCap, fMiterMinimumAngle) ) return; // #i101491# @@ -178,7 +190,8 @@ void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon, basegfx::tools::createAreaGeometry( rB2DPolygon, fHalfLineWidth, eLineJoin, - eLineCap)); + eLineCap, + fMiterMinimumAngle)); const Color aOldLineColor(maLineColor); const Color aOldFillColor(maFillColor); @@ -208,7 +221,7 @@ void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon, // to avoid optical gaps for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) { - DrawPolyLineDirect( aAreaPolyPolygon.getB2DPolygon(a), 0.0, 0.0, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, bTryAA ); + DrawPolyLineDirect( aAreaPolyPolygon.getB2DPolygon(a), 0.0, 0.0, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, 15.0 * F_PI180 /*default, not used*/, bTryAA); } } else @@ -276,7 +289,8 @@ bool OutputDevice::DrawPolyLineDirect( const basegfx::B2DPolygon& rB2DPolygon, double fTransparency, basegfx::B2DLineJoin eLineJoin, css::drawing::LineCap eLineCap, - bool bBypassAACheck ) + double fMiterMinimumAngle, + bool bBypassAACheck) { assert(!is_double_buffered_window()); @@ -334,6 +348,7 @@ bool OutputDevice::DrawPolyLineDirect( const basegfx::B2DPolygon& rB2DPolygon, aB2DLineWidth, eLineJoin, eLineCap, + fMiterMinimumAngle, this ); if( bDrawSuccess ) @@ -344,7 +359,10 @@ bool OutputDevice::DrawPolyLineDirect( const basegfx::B2DPolygon& rB2DPolygon, LineInfo aLineInfo; if( fLineWidth != 0.0 ) aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - + // Transport known informations, might be needed + aLineInfo.SetLineJoin(eLineJoin); + aLineInfo.SetLineCap(eLineCap); + // MiterMinimumAngle does not exist yet in LineInfo const tools::Polygon aToolsPolygon( rB2DPolygon ); mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) ); } diff --git a/vcl/source/outdev/transparent.cxx b/vcl/source/outdev/transparent.cxx index 6eed4c24c162..addf0d634708 100644 --- a/vcl/source/outdev/transparent.cxx +++ b/vcl/source/outdev/transparent.cxx @@ -256,7 +256,14 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) { const basegfx::B2DPolygon aOnePoly = aB2DPolyPolygon.getB2DPolygon( nPolyIdx ); - mpGraphics->DrawPolyLine( aOnePoly, fTransparency, aHairlineWidth, basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, this ); + mpGraphics->DrawPolyLine( + aOnePoly, + fTransparency, + aHairlineWidth, + basegfx::B2DLineJoin::NONE, + css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default + this ); } } @@ -352,8 +359,14 @@ bool OutputDevice::DrawTransparentNatively ( const tools::PolyPolygon& rPolyPoly for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) { const basegfx::B2DPolygon& rPolygon = aB2DPolyPolygon.getB2DPolygon( nPolyIdx ); - bDrawn = mpGraphics->DrawPolyLine( rPolygon, fTransparency, aLineWidths, - basegfx::B2DLineJoin::NONE, css::drawing::LineCap_BUTT, this ); + bDrawn = mpGraphics->DrawPolyLine( + rPolygon, + fTransparency, + aLineWidths, + basegfx::B2DLineJoin::NONE, + css::drawing::LineCap_BUTT, + 15.0 * F_PI180, // not used with B2DLineJoin::NONE, but the correct default + this ); } // prepare to restore the fill color mbInitFillColor = mbFillColor; diff --git a/vcl/unx/generic/gdi/gdiimpl.cxx b/vcl/unx/generic/gdi/gdiimpl.cxx index df5a77961b15..02f93255e928 100644 --- a/vcl/unx/generic/gdi/gdiimpl.cxx +++ b/vcl/unx/generic/gdi/gdiimpl.cxx @@ -1597,7 +1597,8 @@ bool X11SalGraphicsImpl::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { const bool bIsHairline = (rLineWidth.getX() == rLineWidth.getY()) && (rLineWidth.getX() <= 1.2); @@ -1654,7 +1655,7 @@ bool X11SalGraphicsImpl::drawPolyLine( } // create the area-polygon for the line - const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap) ); + const basegfx::B2DPolyPolygon aAreaPolyPoly( basegfx::tools::createAreaGeometry(aPolygon, fHalfWidth, eLineJoin, eLineCap, fMiterMinimumAngle) ); if( (rLineWidth.getX() != rLineWidth.getY()) && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx index d637237d7871..0b58543c71fa 100644 --- a/vcl/unx/generic/gdi/gdiimpl.hxx +++ b/vcl/unx/generic/gdi/gdiimpl.hxx @@ -164,7 +164,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, diff --git a/vcl/unx/generic/gdi/salgdi.cxx b/vcl/unx/generic/gdi/salgdi.cxx index 6444cc4fe522..5821a38fcaa6 100644 --- a/vcl/unx/generic/gdi/salgdi.cxx +++ b/vcl/unx/generic/gdi/salgdi.cxx @@ -564,10 +564,11 @@ bool X11SalGraphics::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { return mxImpl->drawPolyLine( rPolygon, fTransparency, rLineWidth, - eLineJoin, eLineCap ); + eLineJoin, eLineCap, fMiterMinimumAngle ); } bool X11SalGraphics::drawGradient(const tools::PolyPolygon& rPoly, const Gradient& rGradient) diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx index 85b6f17cfe3b..b018a80dd33f 100644 --- a/vcl/unx/generic/print/genpspgraphics.cxx +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -445,7 +445,8 @@ bool GenPspGraphics::drawPolyLine( double /*fTranspareny*/, const basegfx::B2DVector& /*rLineWidths*/, basegfx::B2DLineJoin /*eJoin*/, - css::drawing::LineCap /*eLineCap*/) + css::drawing::LineCap /*eLineCap*/, + double /*fMiterMinimumAngle*/) { // TODO: a PS printer can draw B2DPolyLines almost directly return false; diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index 0317ca06319a..bd03594292a2 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -2025,7 +2025,8 @@ bool WinSalGraphicsImpl::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { const sal_uInt32 nCount(rPolygon.count()); @@ -2055,7 +2056,7 @@ bool WinSalGraphicsImpl::drawPolyLine( } case basegfx::B2DLineJoin::Miter : { - const Gdiplus::REAL aMiterLimit(15.0); + const Gdiplus::REAL aMiterLimit(1.0/sin(fMiterMinimumAngle/2.0)); aPen.SetMiterLimit(aMiterLimit); // tdf#99165 MS's LineJoinMiter creates non standard conform miter additional diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx index b93d1f361292..8f4181c5a2db 100644 --- a/vcl/win/gdi/gdiimpl.hxx +++ b/vcl/win/gdi/gdiimpl.hxx @@ -111,7 +111,8 @@ public: double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, - css::drawing::LineCap) override; + css::drawing::LineCap, + double fMiterMinimumAngle) override; virtual bool drawPolyLineBezier( sal_uInt32 nPoints, diff --git a/vcl/win/gdi/salgdi_gdiplus.cxx b/vcl/win/gdi/salgdi_gdiplus.cxx index f821e03606ea..45e760ae871b 100644 --- a/vcl/win/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/gdi/salgdi_gdiplus.cxx @@ -36,10 +36,11 @@ bool WinSalGraphics::drawPolyLine( double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin, - css::drawing::LineCap eLineCap) + css::drawing::LineCap eLineCap, + double fMiterMinimumAngle) { return mpImpl->drawPolyLine(rPolygon, fTransparency, rLineWidths, - eLineJoin, eLineCap); + eLineJoin, eLineCap, fMiterMinimumAngle); } bool WinSalGraphics::blendBitmap( |