kbrown / rpms / libreoffice

Forked from rpms/libreoffice 2 years ago
Clone

Blame SOURCES/0006-EMF-Line-thickness-has-to-be-considered-when-drawing.patch

f0633d
From 26bfc77430c40530113d3ce739896139522565f4 Mon Sep 17 00:00:00 2001
f0633d
From: Jan Holesovsky <kendy@collabora.com>
f0633d
Date: Wed, 27 Nov 2013 11:51:32 +0100
f0633d
Subject: [PATCH 006/109] EMF+: Line thickness has to be considered when
f0633d
 drawing the caps.
f0633d
f0633d
Change-Id: I6043ee3c214f453afaef06125993c73be624c07e
f0633d
Reviewed-on: https://gerrit.libreoffice.org/6832
f0633d
Reviewed-by: Andras Timar <andras.timar@collabora.com>
f0633d
Tested-by: Andras Timar <andras.timar@collabora.com>
f0633d
---
f0633d
 basegfx/source/polygon/b2dlinegeometry.cxx  |  7 +--
f0633d
 cppcanvas/source/inc/implrenderer.hxx       |  3 +-
f0633d
 cppcanvas/source/mtfrenderer/emfplus.cxx    | 75 +++++++++++++++++------------
f0633d
 include/basegfx/polygon/b2dlinegeometry.hxx |  7 ++-
f0633d
 4 files changed, 55 insertions(+), 37 deletions(-)
f0633d
f0633d
diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx
f0633d
index 5c016bb..417944d 100644
f0633d
--- a/basegfx/source/polygon/b2dlinegeometry.cxx
f0633d
+++ b/basegfx/source/polygon/b2dlinegeometry.cxx
f0633d
@@ -44,7 +44,8 @@ namespace basegfx
f0633d
             double fWidth,
f0633d
             double fCandidateLength,
f0633d
             double fDockingPosition, // 0->top, 1->bottom
f0633d
-            double* pConsumedLength)
f0633d
+            double* pConsumedLength,
f0633d
+            double fShift)
f0633d
         {
f0633d
             B2DPolyPolygon aRetval;
f0633d
             OSL_ENSURE(rCandidate.count() > 1L, "createAreaGeometryForLineStartEnd: Line polygon has too less points (!)");
f0633d
@@ -89,7 +90,7 @@ namespace basegfx
f0633d
                 const double fArrowYLength(B2DVector(aUpperCenter).getLength());
f0633d
 
f0633d
                 // move arrow to have docking position centered
f0633d
-                aArrowTransform.translate(0.0, -fArrowYLength * fDockingPosition);
f0633d
+                aArrowTransform.translate(0.0, -fArrowYLength * fDockingPosition + fShift);
f0633d
 
f0633d
                 // prepare polygon length
f0633d
                 if(fTools::equalZero(fCandidateLength))
f0633d
@@ -98,7 +99,7 @@ namespace basegfx
f0633d
                 }
f0633d
 
f0633d
                 // get the polygon vector we want to plant this arrow on
f0633d
-                const double fConsumedLength(fArrowYLength * (1.0 - fDockingPosition));
f0633d
+                const double fConsumedLength(fArrowYLength * (1.0 - fDockingPosition) - fShift);
f0633d
                 const B2DVector aHead(rCandidate.getB2DPoint((bStart) ? 0L : rCandidate.count() - 1L));
f0633d
                 const B2DVector aTail(getPositionAbsolute(rCandidate,
f0633d
                     (bStart) ? fConsumedLength : fCandidateLength - fConsumedLength, fCandidateLength));
f0633d
diff --git a/cppcanvas/source/inc/implrenderer.hxx b/cppcanvas/source/inc/implrenderer.hxx
f0633d
index 270c0de..d602945 100644
f0633d
--- a/cppcanvas/source/inc/implrenderer.hxx
f0633d
+++ b/cppcanvas/source/inc/implrenderer.hxx
f0633d
@@ -282,7 +282,8 @@ static float GetSwapFloat( SvStream& rSt )
f0633d
             double setFont( sal_uInt8 objectId, const ActionFactoryParameters& rParms, OutDevState& rState );
f0633d
 
f0633d
             /// Render LineCap, like the start or end arrow of a polygon.
f0633d
-            void EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
f0633d
+            /// @return how much we should shorten the original polygon.
f0633d
+            double EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
f0633d
                     const ::basegfx::B2DPolyPolygon& rLineCap, bool bStart,
f0633d
                     const com::sun::star::rendering::StrokeAttributes& rAttributes,
f0633d
                     const ActionFactoryParameters& rParms, OutDevState& rState);
f0633d
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
f0633d
index 1d752e7..bf9720b 100644
f0633d
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
f0633d
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
f0633d
@@ -1320,13 +1320,12 @@ namespace cppcanvas
f0633d
             }
f0633d
         }
f0633d
 
f0633d
-
f0633d
-        void ImplRenderer::EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
f0633d
+        double ImplRenderer::EMFPPlusDrawLineCap(const ::basegfx::B2DPolygon& rPolygon, double fPolyLength,
f0633d
                 const ::basegfx::B2DPolyPolygon& rLineCap, bool bStart, const rendering::StrokeAttributes& rAttributes,
f0633d
                 const ActionFactoryParameters& rParms, OutDevState& rState)
f0633d
         {
f0633d
             if (!rLineCap.count())
f0633d
-                return;
f0633d
+                return 0.0;
f0633d
 
f0633d
             // it seems the line caps in EMF+ are 4*larger than what
f0633d
             // LibreOffice expects, and the mapping in
f0633d
@@ -1338,7 +1337,7 @@ namespace cppcanvas
f0633d
 
f0633d
             basegfx::B2DPolyPolygon aArrow(basegfx::tools::createAreaGeometryForLineStartEnd(
f0633d
                         rPolygon, rLineCap, bStart,
f0633d
-                        fWidth, fPolyLength, 0.0, NULL));
f0633d
+                        fWidth, fPolyLength, 0, NULL, rAttributes.StrokeWidth));
f0633d
 
f0633d
             // createAreaGeometryForLineStartEnd from some reason always sets
f0633d
             // the path as closed, correct it
f0633d
@@ -1350,6 +1349,8 @@ namespace cppcanvas
f0633d
                 maActions.push_back(MtfAction(pAction, rParms.mrCurrActionIndex));
f0633d
                 rParms.mrCurrActionIndex += pAction->getActionCount()-1;
f0633d
             }
f0633d
+
f0633d
+            return rAttributes.StrokeWidth;
f0633d
         }
f0633d
 
f0633d
         void ImplRenderer::EMFPPlusDrawPolygon (const ::basegfx::B2DPolyPolygon& polygon, const ActionFactoryParameters& rParms,
f0633d
@@ -1379,49 +1380,59 @@ namespace cppcanvas
f0633d
                 rendering::StrokeAttributes aPolygonAttributes(aCommonAttributes);
f0633d
                 pen->SetStrokeDashing(aPolygonAttributes);
f0633d
 
f0633d
-                // render the polygon
f0633d
-                ActionSharedPtr pPolyAction(internal::PolyPolyActionFactory::createPolyPolyAction(aPolyPolygon, rParms.mrCanvas, rState, aPolygonAttributes));
f0633d
-                if( pPolyAction )
f0633d
-                {
f0633d
-                    maActions.push_back(MtfAction(pPolyAction, rParms.mrCurrActionIndex));
f0633d
-                    rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
f0633d
-                }
f0633d
+                basegfx::B2DPolyPolygon aFinalPolyPolygon;
f0633d
 
f0633d
-                // render line starts & ends
f0633d
-                if (pen->customStartCap || pen->customEndCap)
f0633d
+                // render line starts & ends if present
f0633d
+                if (!pen->customStartCap && !pen->customEndCap)
f0633d
+                    aFinalPolyPolygon = aPolyPolygon;
f0633d
+                else
f0633d
                 {
f0633d
                     for (sal_uInt32 i = 0; i < aPolyPolygon.count(); ++i)
f0633d
                     {
f0633d
-                        // break the polypolygon into polygons
f0633d
                         basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(i));
f0633d
 
f0633d
-                        if (aPolygon.isClosed())
f0633d
-                            continue;
f0633d
+                        if (!aPolygon.isClosed())
f0633d
+                        {
f0633d
+                            double fStart = 0.0;
f0633d
+                            double fEnd = 0.0;
f0633d
+                            double fPolyLength = basegfx::tools::getLength(aPolygon);
f0633d
 
f0633d
-                        double fPolyLength = basegfx::tools::getLength(aPolygon);
f0633d
+                            // line start
f0633d
+                            if (pen->customStartCap)
f0633d
+                            {
f0633d
+                                rendering::StrokeAttributes aAttributes(aCommonAttributes);
f0633d
+                                pen->customStartCap->SetAttributes(aAttributes);
f0633d
 
f0633d
-                        // line start
f0633d
-                        if (pen->customStartCap)
f0633d
-                        {
f0633d
-                            rendering::StrokeAttributes aAttributes(aCommonAttributes);
f0633d
-                            pen->customStartCap->SetAttributes(aAttributes);
f0633d
+                                fStart = EMFPPlusDrawLineCap(aPolygon, fPolyLength, pen->customStartCap->polygon,
f0633d
+                                        true, aAttributes, rParms, rState);
f0633d
+                            }
f0633d
 
f0633d
-                            EMFPPlusDrawLineCap(aPolygon, fPolyLength, pen->customStartCap->polygon,
f0633d
-                                    true, aAttributes, rParms, rState);
f0633d
-                        }
f0633d
+                            // line end
f0633d
+                            if (pen->customEndCap)
f0633d
+                            {
f0633d
+                                rendering::StrokeAttributes aAttributes(aCommonAttributes);
f0633d
+                                pen->customEndCap->SetAttributes(aAttributes);
f0633d
 
f0633d
-                        // line end
f0633d
-                        if (pen->customEndCap)
f0633d
-                        {
f0633d
-                            rendering::StrokeAttributes aAttributes(aCommonAttributes);
f0633d
-                            pen->customEndCap->SetAttributes(aAttributes);
f0633d
+                                fEnd = EMFPPlusDrawLineCap(aPolygon, fPolyLength, pen->customEndCap->polygon,
f0633d
+                                        false, aAttributes, rParms, rState);
f0633d
+                            }
f0633d
 
f0633d
-                            EMFPPlusDrawLineCap(aPolygon, fPolyLength, pen->customEndCap->polygon,
f0633d
-                                    false, aAttributes, rParms, rState);
f0633d
+                            // build new poly, consume something from the old poly
f0633d
+                            if (fStart != 0.0 || fEnd != 0.0)
f0633d
+                                aPolygon = basegfx::tools::getSnippetAbsolute(aPolygon, fStart, fPolyLength - fEnd, fPolyLength);
f0633d
                         }
f0633d
+
f0633d
+                        aFinalPolyPolygon.append(aPolygon);
f0633d
                     }
f0633d
                 }
f0633d
 
f0633d
+                // finally render the polygon
f0633d
+                ActionSharedPtr pPolyAction(internal::PolyPolyActionFactory::createPolyPolyAction(aFinalPolyPolygon, rParms.mrCanvas, rState, aPolygonAttributes));
f0633d
+                if( pPolyAction )
f0633d
+                {
f0633d
+                    maActions.push_back(MtfAction(pPolyAction, rParms.mrCurrActionIndex));
f0633d
+                    rParms.mrCurrActionIndex += pPolyAction->getActionCount()-1;
f0633d
+                }
f0633d
             }
f0633d
         }
f0633d
 
f0633d
diff --git a/include/basegfx/polygon/b2dlinegeometry.hxx b/include/basegfx/polygon/b2dlinegeometry.hxx
f0633d
index 934158f..62e230f 100644
f0633d
--- a/include/basegfx/polygon/b2dlinegeometry.hxx
f0633d
+++ b/include/basegfx/polygon/b2dlinegeometry.hxx
f0633d
@@ -63,6 +63,10 @@ namespace basegfx
f0633d
             again calculating the length (which may be expensive with beziers). If 0.0 is
f0633d
             given, the length is calculated on demand.
f0633d
 
f0633d
+            @param fShift
f0633d
+            When it is necessary to count with the thickness of the line, it
f0633d
+            makes sense to move the start position slightly - so define the shift.
f0633d
+
f0633d
             @return
f0633d
             The Line start and end polygon, correctly rotated and scaled
f0633d
         */
f0633d
@@ -73,7 +77,8 @@ namespace basegfx
f0633d
             double fWidth,
f0633d
             double fCandidateLength = 0.0, // 0.0 -> calculate self
f0633d
             double fDockingPosition = 0.5, // 0->top, 1->bottom
f0633d
-            double* pConsumedLength = 0L);
f0633d
+            double* pConsumedLength = 0L,
f0633d
+            double fShift = 0.0);
f0633d
 
f0633d
         /** create filled polygon geometry for lines with a line width
f0633d
 
f0633d
-- 
f0633d
1.8.4.2
f0633d