[Libreoffice-commits] core.git: basegfx/source include/basegfx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Aug 14 16:23:38 UTC 2018


 basegfx/source/polygon/b2dsvgpolypolygon.cxx    |   96 ++++++++++++------------
 include/basegfx/polygon/b2dpolypolygontools.hxx |    9 ++
 2 files changed, 57 insertions(+), 48 deletions(-)

New commits:
commit 071d8aff7cbe38c0522c5a87ee77dd1b0d2da91f
Author:     Mark Hung <marklh9 at gmail.com>
AuthorDate: Fri Aug 10 22:15:36 2018 +0800
Commit:     Mark Hung <marklh9 at gmail.com>
CommitDate: Tue Aug 14 18:23:14 2018 +0200

    tdf#118825 Implement OOXMLMotionPath in exportToSvgD of basegfx.
    
    Powerpoint only allows M,L,C,Z,E,m,l,c,z,e , i.e. V,H,S ( and
    their corresponding relative command ) must not be used and
    ending E is mandatory. Command and space delimiters also can not
    be skipped.
    
    Change-Id: Icad38ec2eed3e49143eb9a03aa56cc178baae99d
    Reviewed-on: https://gerrit.libreoffice.org/58848
    Tested-by: Jenkins
    Reviewed-by: Mark Hung <marklh9 at gmail.com>

diff --git a/basegfx/source/polygon/b2dsvgpolypolygon.cxx b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
index a0ff38155a26..2a195641d5f0 100644
--- a/basegfx/source/polygon/b2dsvgpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dsvgpolypolygon.cxx
@@ -32,31 +32,28 @@
 namespace
 {
 
-void putCommandChar(OUStringBuffer& rBuffer,sal_Unicode& rLastSVGCommand, sal_Unicode aChar, bool bToLower)
+void putCommandChar(OUStringBuffer& rBuffer,sal_Unicode& rLastSVGCommand, sal_Unicode aChar, bool bToLower,bool bVerbose)
 {
     const sal_Unicode aCommand = bToLower ? rtl::toAsciiLowerCase(aChar) : aChar;
 
-    if (rLastSVGCommand != aCommand)
+    if (bVerbose && rBuffer.getLength())
+        rBuffer.append(' ');
+
+    if (bVerbose || rLastSVGCommand != aCommand)
     {
         rBuffer.append(aCommand);
         rLastSVGCommand = aCommand;
     }
 }
 
-void putNumberChar(OUStringBuffer& rStr,double fValue, double fOldValue, bool bUseRelativeCoordinates)
+void putNumberChar(OUStringBuffer& rStr,double fValue, double fOldValue, bool bUseRelativeCoordinates,bool bVerbose)
 {
     if (bUseRelativeCoordinates)
         fValue -= fOldValue;
 
     const sal_Int32 aLen(rStr.getLength());
-    if (aLen)
-    {
-        if (basegfx::internal::isOnNumberChar(rStr[aLen - 1], false) &&
-            fValue >= 0.0 )
-        {
-            rStr.append(' ');
-        }
-    }
+    if (bVerbose || (aLen && basegfx::internal::isOnNumberChar(rStr[aLen - 1], false) && fValue >= 0.0))
+        rStr.append(' ');
 
     rStr.append(fValue);
 }
@@ -727,7 +724,8 @@ namespace basegfx
             const B2DPolyPolygon& rPolyPolygon,
             bool bUseRelativeCoordinates,
             bool bDetectQuadraticBeziers,
-            bool bHandleRelativeNextPointCompatible)
+            bool bHandleRelativeNextPointCompatible,
+            bool bOOXMLMotionPath)
         {
             const sal_uInt32 nCount(rPolyPolygon.count());
             OUStringBuffer aResult;
@@ -758,9 +756,9 @@ namespace basegfx
                     }
 
                     // Write 'moveto' and the 1st coordinates, set aLastSVGCommand to 'lineto'
-                    putCommandChar(aResult, aLastSVGCommand, 'M', bUseRelativeCoordinatesForFirstPoint);
-                    putNumberChar(aResult, aEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinatesForFirstPoint);
-                    putNumberChar(aResult, aEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinatesForFirstPoint);
+                    putCommandChar(aResult, aLastSVGCommand, 'M', bUseRelativeCoordinatesForFirstPoint, bOOXMLMotionPath);
+                    putNumberChar(aResult, aEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinatesForFirstPoint, bOOXMLMotionPath);
+                    putNumberChar(aResult, aEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinatesForFirstPoint, bOOXMLMotionPath);
                     aLastSVGCommand =  bUseRelativeCoordinatesForFirstPoint ? 'l' : 'L';
                     aCurrentSVGPosition = aEdgeStart;
 
@@ -793,7 +791,7 @@ namespace basegfx
                             // That's what is done from our import, so avoid exporting it as first statement
                             // is necessary.
                             const bool bSymmetricAtEdgeStart(
-                                nIndex != 0
+                                !bOOXMLMotionPath && nIndex != 0
                                 && aPolygon.getContinuityInPoint(nIndex) == B2VectorContinuity::C2);
 
                             if(bDetectQuadraticBeziers)
@@ -815,20 +813,20 @@ namespace basegfx
                                 // approximately equal, export as quadratic bezier
                                 if(bSymmetricAtEdgeStart)
                                 {
-                                    putCommandChar(aResult, aLastSVGCommand, 'T', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'T', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                                 else
                                 {
-                                    putCommandChar(aResult, aLastSVGCommand, 'Q', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'Q', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aLeft.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aLeft.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aLeft.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aLeft.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                             }
@@ -837,24 +835,24 @@ namespace basegfx
                                 // export as cubic bezier
                                 if(bSymmetricAtEdgeStart)
                                 {
-                                    putCommandChar(aResult, aLastSVGCommand, 'S', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'S', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                                 else
                                 {
-                                    putCommandChar(aResult, aLastSVGCommand, 'C', bUseRelativeCoordinates);
-
-                                    putNumberChar(aResult, aControlEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aControlEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'C', bUseRelativeCoordinates, bOOXMLMotionPath);
+
+                                    putNumberChar(aResult, aControlEdgeStart.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aControlEdgeStart.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aControlEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aControlEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                             }
@@ -876,29 +874,29 @@ namespace basegfx
                                 {
                                     // point is a double point; do not export at all
                                 }
-                                else if(bXEqual)
+                                else if(bXEqual && !bOOXMLMotionPath)
                                 {
                                     // export as vertical line
-                                    putCommandChar(aResult, aLastSVGCommand, 'V', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'V', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
-                                else if(bYEqual)
+                                else if(bYEqual && !bOOXMLMotionPath)
                                 {
                                     // export as horizontal line
-                                    putCommandChar(aResult, aLastSVGCommand, 'H', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'H', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                                 else
                                 {
                                     // export as line
-                                    putCommandChar(aResult, aLastSVGCommand, 'L', bUseRelativeCoordinates);
+                                    putCommandChar(aResult, aLastSVGCommand, 'L', bUseRelativeCoordinates, bOOXMLMotionPath);
 
-                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates);
-                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates);
+                                    putNumberChar(aResult, aEdgeEnd.getX(), aCurrentSVGPosition.getX(), bUseRelativeCoordinates, bOOXMLMotionPath);
+                                    putNumberChar(aResult, aEdgeEnd.getY(), aCurrentSVGPosition.getY(), bUseRelativeCoordinates, bOOXMLMotionPath);
                                     aCurrentSVGPosition = aEdgeEnd;
                                 }
                             }
@@ -911,7 +909,11 @@ namespace basegfx
                     // close path if closed poly (Z and z are equivalent here, but looks nicer when case is matched)
                     if(aPolygon.isClosed())
                     {
-                        putCommandChar(aResult, aLastSVGCommand, 'Z', bUseRelativeCoordinates);
+                        putCommandChar(aResult, aLastSVGCommand, 'Z', bUseRelativeCoordinates, bOOXMLMotionPath);
+                    }
+                    else if (bOOXMLMotionPath)
+                    {
+                        putCommandChar(aResult, aLastSVGCommand, 'E', bUseRelativeCoordinates, bOOXMLMotionPath);
                     }
 
                     if(!bHandleRelativeNextPointCompatible)
diff --git a/include/basegfx/polygon/b2dpolypolygontools.hxx b/include/basegfx/polygon/b2dpolypolygontools.hxx
index 8de5e6c90cc3..b14d003be4a4 100644
--- a/include/basegfx/polygon/b2dpolypolygontools.hxx
+++ b/include/basegfx/polygon/b2dpolypolygontools.hxx
@@ -228,6 +228,12 @@ namespace basegfx
             polygon is kept; this is needed to read odf files.
             If false, pure svg is used; this is needed for svg import.
 
+            @param bOOXMLMotionPath
+            If set to true, export string format that is acceptable for
+            for animation motion path for PowerPoint: always space delimited,
+            never neglect command char, always end with E, and do not export
+            H or V.
+
             @return the generated SVG-D statement (the XML d attribute
             value alone, without any "<path ...>" or "d="...")
          */
@@ -235,7 +241,8 @@ namespace basegfx
             const B2DPolyPolygon& rPolyPoly,
             bool bUseRelativeCoordinates,
             bool bDetectQuadraticBeziers,
-            bool bHandleRelativeNextPointCompatible);
+            bool bHandleRelativeNextPointCompatible,
+            bool bOOXMLMotionPath = false);
 
         // #i76891# Try to remove existing curve segments if they are simply edges
         BASEGFX_DLLPUBLIC B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate);


More information about the Libreoffice-commits mailing list