[Libreoffice-commits] core.git: canvas/source drawinglayer/source include/drawinglayer include/vcl svgio/inc svgio/source vcl/headless vcl/inc vcl/opengl vcl/quartz vcl/source vcl/unx vcl/win

Regina Henschel rb.henschel at t-online.de
Tue Apr 26 16:42:56 UTC 2016


 canvas/source/directx/dx_canvashelper.cxx               |    9 ++--
 canvas/source/vcl/canvashelper.cxx                      |   16 +++++--
 drawinglayer/source/attribute/lineattribute.cxx         |   25 ++++++++---
 drawinglayer/source/primitive2d/polygonprimitive2d.cxx  |    6 ++
 drawinglayer/source/processor2d/vclpixelprocessor2d.cxx |    4 +
 drawinglayer/source/processor2d/vclprocessor2d.cxx      |    3 -
 include/drawinglayer/attribute/lineattribute.hxx        |    5 +-
 include/vcl/outdev.hxx                                  |    8 ++-
 svgio/inc/svgio/svgreader/svgstyleattributes.hxx        |    2 
 svgio/inc/svgio/svgreader/svgtools.hxx                  |    3 -
 svgio/source/svgreader/svgstyleattributes.cxx           |   24 ++++++++--
 svgio/source/svgreader/svgtools.cxx                     |   18 +++++---
 vcl/headless/svpgdi.cxx                                 |   11 +++-
 vcl/inc/headless/svpgdi.hxx                             |    3 -
 vcl/inc/openglgdiimpl.hxx                               |    5 +-
 vcl/inc/quartz/salgdi.h                                 |    3 -
 vcl/inc/salgdi.hxx                                      |    4 +
 vcl/inc/salgdiimpl.hxx                                  |    3 -
 vcl/inc/unx/genpspgraphics.h                            |    3 -
 vcl/inc/unx/salgdi.h                                    |    3 -
 vcl/inc/win/salgdi.h                                    |    3 -
 vcl/opengl/gdiimpl.cxx                                  |   13 ++---
 vcl/quartz/salgdicommon.cxx                             |    7 ++-
 vcl/source/gdi/salgdilayout.cxx                         |    6 +-
 vcl/source/outdev/line.cxx                              |   18 +++++++-
 vcl/source/outdev/polygon.cxx                           |    3 +
 vcl/source/outdev/polyline.cxx                          |   36 ++++++++++++----
 vcl/source/outdev/transparent.cxx                       |   19 +++++++-
 vcl/unx/generic/gdi/gdiimpl.cxx                         |    5 +-
 vcl/unx/generic/gdi/gdiimpl.hxx                         |    3 -
 vcl/unx/generic/gdi/salgdi.cxx                          |    5 +-
 vcl/unx/generic/print/genpspgraphics.cxx                |    3 -
 vcl/win/gdi/gdiimpl.cxx                                 |    5 +-
 vcl/win/gdi/gdiimpl.hxx                                 |    3 -
 vcl/win/gdi/salgdi_gdiplus.cxx                          |    5 +-
 35 files changed, 214 insertions(+), 78 deletions(-)

New commits:
commit 32cec4ca8bf1e09dd33aa461984e8e8ae34f4a7c
Author: Regina Henschel <rb.henschel at t-online.de>
Date:   Sat Apr 9 23:15:09 2016 +0200

    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 at libreoffice.org>
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at cib.de>
    Reviewed-by: Regina Henschel <rb.henschel at t-online.de>

diff --git a/canvas/source/directx/dx_canvashelper.cxx b/canvas/source/directx/dx_canvashelper.cxx
index be53b37..8ca63ec 100644
--- a/canvas/source/directx/dx_canvashelper.cxx
+++ b/canvas/source/directx/dx_canvashelper.cxx
@@ -75,10 +75,13 @@ namespace dxcanvas
             switch( nJoinType )
             {
                 case rendering::PathJoinType::NONE:
-                    SAL_WARN( "canvas.directx", "gdiJoinFromJoin(): Join NONE not possible, mapping to MITER" );
-                    // FALLTHROUGH intended
+                    SAL_WARN( "canvas.directx", "gdiJoinFromJoin(): Join NONE not possible, mapping to BEVEL (closest to NONE)" );
+                    return Gdiplus::LineJoinBevel;
+
                 case rendering::PathJoinType::MITER:
-                    return Gdiplus::LineJoinMiter;
+                    // in GDI+ fallback to Bevel, if miter limit is exceeded, is not done
+                    // by Gdiplus::LineJoinMiter but by Gdiplus::LineJoinMiterClipped
+                    return Gdiplus::LineJoinMiterClipped;
 
                 case rendering::PathJoinType::ROUND:
                     return Gdiplus::LineJoinRound;
diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx
index 82ee770..b294b73 100644
--- a/canvas/source/vcl/canvashelper.cxx
+++ b/canvas/source/vcl/canvashelper.cxx
@@ -390,8 +390,15 @@ namespace vclcanvas
 
                 for( sal_uInt32 i=0; i<aPolyPoly.count(); ++i )
                 {
-                    // TODO(F2): Use MiterLimit from StrokeAttributes,
-                    // need to convert it here to angle.
+                    double fMiterMinimumAngle;
+                    if (strokeAttributes.MiterLimit <= 1.0)
+                    {
+                        fMiterMinimumAngle = F_PI2;
+                    }
+                    else
+                    {
+                        fMiterMinimumAngle = 2.0 * asin(1.0/strokeAttributes.MiterLimit);
+                    }
 
                     // TODO(F2): Also use Cap settings from
                     // StrokeAttributes, the
@@ -403,7 +410,10 @@ namespace vclcanvas
                         aPolyPoly.getB2DPolygon(i),
                         strokeAttributes.StrokeWidth*0.5,
                         b2DJoineFromJoin(strokeAttributes.JoinType),
-                        unoCapeFromCap(strokeAttributes.StartCapType)
+                        unoCapeFromCap(strokeAttributes.StartCapType),
+                        12.5 * F_PI180 /* default fMaxAllowedAngle*/ ,
+                        0.4 /* default fMaxPartOfEdge*/ ,
+                        fMiterMinimumAngle
                         ));
                     //aStrokedPolyPoly.append(
                     //    ::basegfx::tools::createAreaGeometryForPolygon( aPolyPoly.getB2DPolygon(i),
diff --git a/drawinglayer/source/attribute/lineattribute.cxx b/drawinglayer/source/attribute/lineattribute.cxx
index 5e720fb..89ce998 100644
--- a/drawinglayer/source/attribute/lineattribute.cxx
+++ b/drawinglayer/source/attribute/lineattribute.cxx
@@ -34,16 +34,19 @@ namespace drawinglayer
             double                                  mfWidth;                // absolute line width
             basegfx::B2DLineJoin                    meLineJoin;             // type of LineJoin
             css::drawing::LineCap                   meLineCap;              // BUTT, ROUND, or SQUARE
+            double                                  mfMiterMinimumAngle;     // as needed for createAreaGeometry
 
             ImpLineAttribute(
                 const basegfx::BColor& rColor,
                 double fWidth,
                 basegfx::B2DLineJoin aB2DLineJoin,
-                css::drawing::LineCap aLineCap)
+                css::drawing::LineCap aLineCap,
+                double fMiterMinimumAngle)
             :   maColor(rColor),
                 mfWidth(fWidth),
                 meLineJoin(aB2DLineJoin),
-                meLineCap(aLineCap)
+                meLineCap(aLineCap),
+                mfMiterMinimumAngle(fMiterMinimumAngle)
             {
             }
 
@@ -51,7 +54,8 @@ namespace drawinglayer
             :   maColor(basegfx::BColor()),
                 mfWidth(0.0),
                 meLineJoin(basegfx::B2DLineJoin::Round),
-                meLineCap(css::drawing::LineCap_BUTT)
+                meLineCap(css::drawing::LineCap_BUTT),
+                mfMiterMinimumAngle(15.0 * F_PI180)
             {
             }
 
@@ -60,13 +64,15 @@ namespace drawinglayer
             double getWidth() const { return mfWidth; }
             basegfx::B2DLineJoin getLineJoin() const { return meLineJoin; }
             css::drawing::LineCap getLineCap() const { return meLineCap; }
+            double getMiterMinimumAngle() const { return mfMiterMinimumAngle; }
 
             bool operator==(const ImpLineAttribute& rCandidate) const
             {
                 return (getColor() == rCandidate.getColor()
                     && getWidth() == rCandidate.getWidth()
                     && getLineJoin() == rCandidate.getLineJoin()
-                    && getLineCap() == rCandidate.getLineCap());
+                    && getLineCap() == rCandidate.getLineCap()
+                    && getMiterMinimumAngle() == rCandidate.getMiterMinimumAngle());
             }
         };
 
@@ -80,13 +86,15 @@ namespace drawinglayer
             const basegfx::BColor& rColor,
             double fWidth,
             basegfx::B2DLineJoin aB2DLineJoin,
-            css::drawing::LineCap aLineCap)
+            css::drawing::LineCap aLineCap,
+            double fMiterMinimumAngle)
         :   mpLineAttribute(
                 ImpLineAttribute(
                     rColor,
                     fWidth,
                     aB2DLineJoin,
-                    aLineCap))
+                    aLineCap,
+                    fMiterMinimumAngle))
         {
         }
 
@@ -144,6 +152,11 @@ namespace drawinglayer
             return mpLineAttribute->getLineCap();
         }
 
+        double LineAttribute::getMiterMinimumAngle() const
+        {
+            return mpLineAttribute->getMiterMinimumAngle();
+        }
+
     } // end of namespace attribute
 } // end of namespace drawinglayer
 
diff --git a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
index ddc83d0..76fc498 100644
--- a/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/polygonprimitive2d.cxx
@@ -252,6 +252,7 @@ namespace drawinglayer
                     const basegfx::B2DLineJoin aLineJoin(getLineAttribute().getLineJoin());
                     const css::drawing::LineCap aLineCap(getLineAttribute().getLineCap());
                     basegfx::B2DPolyPolygon aAreaPolyPolygon;
+                    const double fMiterMinimumAngle(getLineAttribute().getMiterMinimumAngle());
 
                     for(sal_uInt32 a(0L); a < nCount; a++)
                     {
@@ -260,7 +261,10 @@ namespace drawinglayer
                             aHairLinePolyPolygon.getB2DPolygon(a),
                             fHalfLineWidth,
                             aLineJoin,
-                            aLineCap));
+                            aLineCap,
+                            12.5 * F_PI180 /* default fMaxAllowedAngle*/ ,
+                            0.4 /* default fMaxPartOfEdge*/ ,
+                            fMiterMinimumAngle));
                     }
 
                     // prepare return value
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 7b18c59..f3b08ec 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -259,7 +259,9 @@ namespace drawinglayer
                         fLineWidth,
                         fTransparency,
                         rSource.getLineAttribute().getLineJoin(),
-                        rSource.getLineAttribute().getLineCap()))
+                        rSource.getLineAttribute().getLineCap(),
+                        rSource.getLineAttribute().getMiterMinimumAngle(),
+                        false /*bBypassAACheck, default*/))
                     {
                         bTryWorked = true;
                     }
diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx
index e6ce0f5..f5d24cf 100644
--- a/drawinglayer/source/processor2d/vclprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx
@@ -1301,7 +1301,8 @@ namespace drawinglayer
                                 aHairlinePolyPolygon.getB2DPolygon(a),
                                 fDiscreteLineWidth,
                                 rLineAttribute.getLineJoin(),
-                                rLineAttribute.getLineCap());
+                                rLineAttribute.getLineCap(),
+                                rLineAttribute.getMiterMinimumAngle());
                         }
 
                         bDone = true;
diff --git a/include/drawinglayer/attribute/lineattribute.hxx b/include/drawinglayer/attribute/lineattribute.hxx
index a405ebc..a2ad66d 100644
--- a/include/drawinglayer/attribute/lineattribute.hxx
+++ b/include/drawinglayer/attribute/lineattribute.hxx
@@ -22,6 +22,7 @@
 
 #include <drawinglayer/drawinglayerdllapi.h>
 
+#include <basegfx/numeric/ftools.hxx> // for F_PI180
 #include <basegfx/vector/b2enums.hxx>
 #include <com/sun/star/drawing/LineCap.hpp>
 #include <o3tl/cow_wrapper.hxx>
@@ -56,7 +57,8 @@ namespace drawinglayer
                 const basegfx::BColor& rColor,
                 double fWidth = 0.0,
                 basegfx::B2DLineJoin aB2DLineJoin = basegfx::B2DLineJoin::Round,
-                css::drawing::LineCap aLineCap = css::drawing::LineCap_BUTT);
+                css::drawing::LineCap aLineCap = css::drawing::LineCap_BUTT,
+                double fMiterMinimumAngle = 15.0 * F_PI180);
             LineAttribute();
             LineAttribute(const LineAttribute& rCandidate);
             LineAttribute& operator=(const LineAttribute& rCandidate);
@@ -73,6 +75,7 @@ namespace drawinglayer
             double getWidth() const;
             basegfx::B2DLineJoin getLineJoin() const;
             css::drawing::LineCap getLineCap() const;
+            double getMiterMinimumAngle() const;
         };
     } // end of namespace attribute
 } // end of namespace drawinglayer
diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 9ad1a09..720c45c 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -41,6 +41,7 @@
 #include <vcl/outdevstate.hxx>
 #include <vcl/outdevmap.hxx>
 
+#include <basegfx/numeric/ftools.hxx>
 #include <basegfx/vector/b2enums.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 
@@ -826,7 +827,8 @@ public:
                                     const basegfx::B2DPolygon&,
                                     double fLineWidth = 0.0,
                                     basegfx::B2DLineJoin eLineJoin = basegfx::B2DLineJoin::Round,
-                                    css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT);
+                                    css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT,
+                                    double fMiterMinimumAngle = 15.0 * F_PI180);
 
     /** Render the given polygon as a line stroke
 
@@ -849,7 +851,9 @@ public:
                                     double fTransparency = 0.0,
                                     basegfx::B2DLineJoin eLineJoin = basegfx::B2DLineJoin::NONE,
                                     css::drawing::LineCap eLineCap = css::drawing::LineCap_BUTT,
-                                    bool bBypassAACheck = false );
+                                    double fMiterMinimumAngle = 15.0 * F_PI180,
+                                    bool bBypassAACheck = false);
+
 private:
 
     // #i101491#
diff --git a/svgio/inc/svgio/svgreader/svgstyleattributes.hxx b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
index f711feb..141218b 100644
--- a/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
+++ b/svgio/inc/svgio/svgreader/svgstyleattributes.hxx
@@ -378,7 +378,7 @@ namespace svgio
 
             /// StrokeMiterLimit content
             SvgNumber getStrokeMiterLimit() const;
-            void setStrokeMiterLimit(const SvgNumber& rStrokeMiterLimit = SvgNumber()) { maStrokeMiterLimit = rStrokeMiterLimit; }
+            void setStrokeMiterLimit(const SvgNumber& rStrokeMiterLimit = SvgNumber(4.0,Unit_none,false)) { maStrokeMiterLimit = rStrokeMiterLimit; }
 
             /// StrokeOpacity content
             SvgNumber getStrokeOpacity() const;
diff --git a/svgio/inc/svgio/svgreader/svgtools.hxx b/svgio/inc/svgio/svgreader/svgtools.hxx
index 4c940ee..f65cf05 100644
--- a/svgio/inc/svgio/svgreader/svgtools.hxx
+++ b/svgio/inc/svgio/svgreader/svgtools.hxx
@@ -83,7 +83,8 @@ namespace svgio
             Unit_mm,        // 3.543307 px
             Unit_in,        // 90 px
 
-            Unit_percent    // relative to range
+            Unit_percent,   // relative to range
+            Unit_none       // for stroke-miterlimit, which has no unit
         };
 
         class SvgNumber
diff --git a/svgio/source/svgreader/svgstyleattributes.cxx b/svgio/source/svgreader/svgstyleattributes.cxx
index 2d5bc85..201ec68 100644
--- a/svgio/source/svgreader/svgstyleattributes.cxx
+++ b/svgio/source/svgreader/svgstyleattributes.cxx
@@ -676,13 +676,27 @@ namespace svgio
 
                         // todo: Handle getStrokeDashOffset()
 
+                        // convert svg:stroke-miterlimit to LineAttrute:mfMiterMinimumAngle
+                        // The default needs to be set explicitely, because svg default <> Draw default
+                        double fMiterMinimumAngle;
+                        if (getStrokeMiterLimit().isSet())
+                        {
+                            fMiterMinimumAngle = 2.0 * asin(1.0/getStrokeMiterLimit().getNumber());
+                        }
+                        else
+                        {
+                            fMiterMinimumAngle = 2.0 * asin(0.25); // 1.0/default 4.0
+                        }
+
                         // prepare line attribute
                         drawinglayer::primitive2d::Primitive2DReference aNewLinePrimitive;
+
                         const drawinglayer::attribute::LineAttribute aLineAttribute(
                             pStroke ? *pStroke : basegfx::BColor(0.0, 0.0, 0.0),
                             fStrokeWidth,
                             aB2DLineJoin,
-                            aLineCap);
+                            aLineCap,
+                            fMiterMinimumAngle);
 
                         if(aDashArray.empty())
                         {
@@ -1411,9 +1425,9 @@ namespace svgio
 
                     if(readSingleNumber(aContent, aNum))
                     {
-                        if(aNum.isPositive())
-                        {
-                            setStrokeMiterLimit(aNum);
+                        if(basegfx::fTools::moreOrEqual(aNum.getNumber(), 1.0))
+                        { //readSingleNumber sets Unit_px as default, if unit is missing. Correct it here.
+                            setStrokeMiterLimit(SvgNumber(aNum.getNumber(), Unit_none));
                         }
                     }
                     break;
@@ -2297,7 +2311,7 @@ namespace svgio
             }
 
             // default is 4
-            return SvgNumber(4.0);
+            return SvgNumber(4.0, Unit_none);
         }
 
         SvgNumber SvgStyleAttributes::getStrokeOpacity() const
diff --git a/svgio/source/svgreader/svgtools.cxx b/svgio/source/svgreader/svgtools.cxx
index 14e5bda..3bc4573 100644
--- a/svgio/source/svgreader/svgtools.cxx
+++ b/svgio/source/svgreader/svgtools.cxx
@@ -189,6 +189,13 @@ namespace svgio
 
                         return fRetval;
                     }
+                    case Unit_none:
+                    {
+#ifdef DBG_UTIL
+                        myAssert("Design error, this case should have been handled in the caller");
+#endif
+                        return mfNumber;
+                    }
                     default:
                     {
                         OSL_ENSURE(false, "Do not use with percentage! ");
@@ -219,6 +226,7 @@ namespace svgio
                     case Unit_in:
                     case Unit_em:
                     case Unit_ex:
+                    case Unit_none:
                     {
                         return solveNonPercentage( rInfoProvider);
                     }
@@ -473,13 +481,13 @@ namespace svgio
                             }
                             else if('t' == aCharB)
                             {
-                                // 'pt' == 1.25 px
+                                // 'pt' == 4/3 px
                                 aRetval = Unit_pt;
                                 bTwoCharValid = true;
                             }
                             else if('c' == aCharB)
                             {
-                                // 'pc' == 15 px
+                                // 'pc' == 16 px
                                 aRetval = Unit_pc;
                                 bTwoCharValid = true;
                             }
@@ -489,7 +497,7 @@ namespace svgio
                         {
                             if('n' == aCharB)
                             {
-                                // 'in' == 90 px
+                                // 'in' == 96 px, since CSS 2.1
                                 aRetval = Unit_in;
                                 bTwoCharValid = true;
                             }
@@ -499,7 +507,7 @@ namespace svgio
                         {
                             if('m' == aCharB)
                             {
-                                // 'cm' == 35.43307 px
+                                // 'cm' == 37.79527559 px
                                 aRetval = Unit_cm;
                                 bTwoCharValid = true;
                             }
@@ -509,7 +517,7 @@ namespace svgio
                         {
                             if('m' == aCharB)
                             {
-                                // 'mm' == 3.543307 px
+                                // 'mm' == 3.779528 px
                                 aRetval = Unit_mm;
                                 bTwoCharValid = true;
                             }
diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx
index 37e0e17..b6c33b7 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 be9aebe..7580575 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 ef23328..0f8b605 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 a4a2608..e4c9ca1 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 23d0d81..feecc851 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 a70fe2c..c5c8e6d 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 6f6fa69..e609c12 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 88db9ce..2952282 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 8866dcf..2c89393 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 b8d6fb6..8bb2c1d 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 eaf40de..e493be1 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 8244e02..052edc5 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 bf4f2f6..a04dd80 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 0f36e30..612e937 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 6bd7249..b2e5b7a 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 6eed4c2..addf0d6 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 df5a779..02f9325 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 d637237..0b58543 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 6444cc4..5821a38 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 85b6f17..b018a80 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 0317ca0..bd03594 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 b93d1f3..8f4181c 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 f821e03..45e760a 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(


More information about the Libreoffice-commits mailing list