[Libreoffice-commits] core.git: Branch 'libreoffice-4-1' - cppcanvas/source

Andrzej Hunt andrzej.hunt at collabora.com
Thu Jan 30 04:04:52 PST 2014


 cppcanvas/source/mtfrenderer/emfplus.cxx |   49 ++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 17 deletions(-)

New commits:
commit 2d0b2cb6b7ca48663d09118acfb01a1dd194a1e1
Author: Andrzej Hunt <andrzej.hunt at collabora.com>
Date:   Wed Jan 29 18:40:21 2014 +0000

    EMF+: Only draw endcap outline if not filled, fix endcap scaling.
    
    Change-Id: I4520eea08e43ccd657c1db03b258ef84612da971
    Reviewed-on: https://gerrit.libreoffice.org/7726
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>
    (cherry picked from commit 8d1ca883b119857daa3b8d0ece9da90917589040)
    Reviewed-on: https://gerrit.libreoffice.org/7742
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index 7614bbb..cb0a37b 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -1336,29 +1336,27 @@ namespace cppcanvas
             if (!rLineCap.count())
                 return 0.0;
 
-            // it seems the line caps in EMF+ are 4*larger than what
-            // LibreOffice expects, and the mapping in
-            // createAreaGeometryForLineStartEnd scales that down, so
-            // correct it
-            // [unfortunately found no proof for this in the spec :-( - please
-            // feel free to correct this if it causes trouble]
-            double fWidth = rAttributes.StrokeWidth*4;
-
+            // createAreaGeometryForLineStartEnd normalises the arrows height
+            // before scaling (i.e. scales down by rPolygon.height), hence
+            // we pre-scale it (which means we can avoid changing the logic
+            // that would affect arrows rendered outside of EMF+).
+            const double fWidth = rAttributes.StrokeWidth*rLineCap.getB2DRange().getWidth();
+
+            // When drawing an outline (as opposed to a filled endCap), we also
+            // need to take account that the brush width also adds to the area
+            // of the polygon.
+            const double fShift = bIsFilled ? 0 : rAttributes.StrokeWidth;
+            double fConsumed = 0;
             basegfx::B2DPolyPolygon aArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
                         rPolygon, rLineCap, bStart,
-                        fWidth, fPolyLength, 0, NULL, rAttributes.StrokeWidth));
+                        fWidth, fPolyLength, 0, &fConsumed, fShift));
 
             // createAreaGeometryForLineStartEnd from some reason always sets
             // the path as closed, correct it
             aArrow.setClosed(rLineCap.isClosed());
 
-            ActionSharedPtr pAction(internal::PolyPolyActionFactory::createPolyPolyAction(aArrow, rParms.mrCanvas, rState, rAttributes));
-            if (pAction)
-            {
-                maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
-                rParms.mrCurrActionIndex += pAction->getActionCount()-1;
-            }
-
+            // If the endcap is filled, we draw ONLY the filling, if it isn't
+            // filled we draw ONLY the outline, but never both.
             if (bIsFilled)
             {
                 bool bWasFillColorSet = rState.isFillColorSet;
@@ -1372,8 +1370,25 @@ namespace cppcanvas
                 }
                 rState.isFillColorSet = bWasFillColorSet;
             }
+            else
+            {
+                ActionSharedPtr pAction(internal::PolyPolyActionFactory::createPolyPolyAction(aArrow, rParms.mrCanvas, rState, rAttributes));
+                if (pAction)
+                {
+                    maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
+                    rParms.mrCurrActionIndex += pAction->getActionCount()-1;
+                }
+            }
 
-            return rAttributes.StrokeWidth;
+            // There isn't any clear definition of how far the line should extend
+            // for arrows, however the following values seem to give best results
+            // (fConsumed/2 draws the line to the center-point of the endcap
+            // for filled caps -- however it is likely this will need to be
+            // changed once we start taking baseInset into account).
+            if (bIsFilled)
+                return fConsumed/2;
+            else
+                return rAttributes.StrokeWidth;
         }
 
         void ImplRenderer::EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,


More information about the Libreoffice-commits mailing list