[Libreoffice-commits] core.git: vcl/win

Armin Le Grand (Collabora) (via logerrit) logerrit at kemper.freedesktop.org
Tue Feb 11 20:10:10 UTC 2020


 vcl/win/gdi/gdiimpl.cxx |   61 +++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 3 deletions(-)

New commits:
commit c3e098483f4db12e9502c6cbc056e3d7498b7b6c
Author:     Armin Le Grand (Collabora) <Armin.Le.Grand at me.com>
AuthorDate: Tue Feb 11 16:33:28 2020 +0100
Commit:     Armin Le Grand <Armin.Le.Grand at me.com>
CommitDate: Tue Feb 11 21:09:33 2020 +0100

    tdf#130478 add direct dash paint in GDIPlus (win)
    
    Not as easy as hoped, see more info in the adapted
    file vcl\win\gdi\gdiimpl.cxx itself.
    
    Change-Id: I265888c65658d5e8a2a04b6f064d2baf3e1d9bad
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88463
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <Armin.Le.Grand at me.com>

diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index f15f13a94370..a26d85d1e378 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -2309,7 +2309,62 @@ bool WinSalGraphicsImpl::drawPolyLine(
     const bool bStrokeUsed(0.0 != fDotDashLength);
     assert(!bStrokeUsed || (bStrokeUsed && pStroke));
 
-    if(pSystemDependentData_GraphicsPath)
+    // MM01 decide if to stroke directly
+    static bool bDoDirectGDIPlusStroke(true);
+
+    // activate to stroke directly
+    if(bDoDirectGDIPlusStroke && bStrokeUsed)
+    {
+        // tdf#130478
+        // Unfortunately GDIPlus wants to have the dash pattern relative to line width
+        // which gets problematic due to the good old office's hairline definition. This
+        // means that we do not *have* the real line width here, but 0.0 - or in the case
+        // of GDIPlus (here) 1.0.
+        // This is 'corrected' in several locations, e.g. OutputDevice::DrawPolyLineDirect
+        // to 1.0 and VclPixelProcessor2D::tryDrawPolygonStrokePrimitive2DDirect to 0.0.
+        // This would need some cleanup what will be highly problematic due to the usage
+        // of hairlines with line width of 0.0 being a pixel always and leading to different
+        // visualizations. More bad - the potential of having pretty 'invisible' lines
+        // in unexpected places when zooming far out. Another problematic aspect of that hairline
+        // definition is that this makes hairlines per definition view-transformation dependent
+        // regarding their 'core' line width and the area they cover - handled in Primitives,
+        // but not easy to do.
+        // The way out here is to calculate back a single pixel from device to logic
+        // (Object coordinates) to have the 'logic', view-dependent line width and use it.
+        // That works for the cost of a matrix inversion - sigh.
+        std::vector<Gdiplus::REAL> aDashArray(pStroke->size());
+        double fFactor(1.0);
+
+        if(rLineWidths.getX() <= 1.0)
+        {
+            // no 'real' line width, need to calculate back the logic line width
+            // for a one pixel hairline
+            basegfx::B2DHomMatrix aObjectToDeviceInv(rObjectToDevice);
+            aObjectToDeviceInv.invert();
+            const basegfx::B2DVector aOnePixel(aObjectToDeviceInv * basegfx::B2DVector(1.0, 1.0));
+
+            if(aOnePixel.getX() > 0.0)
+            {
+                fFactor = 1.0 / aOnePixel.getX();
+            }
+        }
+        else
+        {
+            // use logic line width
+            fFactor = 1.0 / rLineWidths.getX();
+        }
+
+        for(size_t a(0); a < pStroke->size(); a++)
+        {
+            aDashArray[a] = Gdiplus::REAL((*pStroke)[a] * fFactor);
+        }
+
+        aPen.SetDashCap(Gdiplus::DashCapFlat);
+        aPen.SetDashOffset(Gdiplus::REAL(0.0));
+        aPen.SetDashPattern(aDashArray.data(), aDashArray.size());
+    }
+
+    if(!bDoDirectGDIPlusStroke && pSystemDependentData_GraphicsPath)
     {
         // MM01 - check on stroke change. Used against not used, or if oth used,
         // equal or different? Triangulation geometry creation depends heavily
@@ -2345,7 +2400,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
         // fill data of buffered data
         pGraphicsPath = std::make_shared<Gdiplus::GraphicsPath>();
 
-        if(bStrokeUsed)
+        if(!bDoDirectGDIPlusStroke && bStrokeUsed)
         {
             // MM01 need to do line dashing as fallback stuff here now
             basegfx::B2DPolyPolygon aPolyPolygonLine;
@@ -2373,7 +2428,7 @@ bool WinSalGraphicsImpl::drawPolyLine(
         }
         else
         {
-            // no line dashing, just copy
+            // no line dashing or direct stroke, just copy
             impAddB2DPolygonToGDIPlusGraphicsPathReal(
                 *pGraphicsPath,
                 rPolygon,


More information about the Libreoffice-commits mailing list