[Libreoffice-commits] core.git: filter/source oox/source sw/qa

Zolnai Tamás tamas.zolnai at collabora.com
Sun Feb 2 17:48:40 PST 2014


 filter/source/msfilter/escherex.cxx                               |   89 ++++++++++
 oox/source/export/drawingml.cxx                                   |    2 
 oox/source/export/shapes.cxx                                      |   20 +-
 sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx                          |   64 +++++++
 5 files changed, 168 insertions(+), 7 deletions(-)

New commits:
commit 5c39b6b997ddc85e6848efc230a427a124b97264
Author: Zolnai Tamás <tamas.zolnai at collabora.com>
Date:   Mon Feb 3 02:46:30 2014 +0100

    drawingML export: custom geometry with cubic bezier curves
    
    When the custom shape is not a preset shape then construct a
    PolyPolygon and use DrawingML::WritePolyPolygon() to export it.
    
    Change-Id: I6598976a475bfcb92305338af9016e09df4c9456

diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx
index 5a4cf4d..293aead 100644
--- a/filter/source/msfilter/escherex.cxx
+++ b/filter/source/msfilter/escherex.cxx
@@ -1785,6 +1785,7 @@ PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno
     OUString sPolyPolygonBezier ( "PolyPolygonBezier" );
     OUString sPolyPolygon       ( "PolyPolygon" );
     OUString sPolygon           ( "Polygon" );
+    OUString sCustomShapeGeometry   ( "CustomShapeGeometry" );
 
     if ( aAny >>= aXPropSet )
     {
@@ -1793,6 +1794,8 @@ PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno
             bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolyPolygon, sal_True );
         if ( !bHasProperty )
             bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sPolygon, sal_True );
+        if ( !bHasProperty )
+            bHasProperty = EscherPropertyValueHelper::GetPropertyValue( aAny, aXPropSet, sCustomShapeGeometry, sal_True );
         if ( bHasProperty )
             aRetPolyPoly = GetPolyPolygon( aAny );
     }
@@ -1918,6 +1921,92 @@ PolyPolygon EscherPropertyContainer::GetPolyPolygon( const ::com::sun::star::uno
             }
         }
     }
+    else if ( rAny.getValueType() == ::getCppuType( ( const uno::Sequence< beans::PropertyValue >* ) 0 ) )
+    {
+        uno::Sequence< beans::PropertyValue >* pGeometrySeq =
+            (uno::Sequence< beans::PropertyValue >*)rAny.getValue();
+
+        if ( pGeometrySeq )
+        {
+            for( int i = 0; i < pGeometrySeq->getLength(); ++i )
+            {
+                const beans::PropertyValue& rProp = (*pGeometrySeq)[ i ];
+                if ( rProp.Name == "Path" )
+                {
+                    uno::Sequence<beans::PropertyValue> aPathProp;
+                    rProp.Value >>= aPathProp;
+
+                    uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
+                    uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
+                    for (int j = 0; j < aPathProp.getLength(); ++j )
+                    {
+                        const beans::PropertyValue& rPathProp = aPathProp[j];
+                        if (rPathProp.Name == "Coordinates")
+                            rPathProp.Value >>= aPairs;
+                        else if (rPathProp.Name == "Segments")
+                            rPathProp.Value >>= aSegments;
+                    }
+
+                    aPolygon = Polygon( aPairs.getLength() );
+                    for( int j = 0; j < aPairs.getLength(); ++j )
+                    {
+                        aPolygon[j] = Point( aPairs[j].First.Value.get<sal_Int32>(), aPairs[j].Second.Value.get<sal_Int32>() );
+                    }
+
+                    int nPointIndex = 0;
+                    for( int j = 0; j < aSegments.getLength(); ++j )
+                    {
+                        for ( int k = 0; k < aSegments[j].Count; ++k )
+                        {
+                            switch( aSegments[ j ].Command )
+                            {
+                                case drawing::EnhancedCustomShapeSegmentCommand::UNKNOWN: break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::MOVETO : nPointIndex++; break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::LINETO : nPointIndex++; break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::CURVETO :
+                                {
+                                    aPolygon.SetFlags( nPointIndex, POLY_CONTROL);
+                                    aPolygon.SetFlags( nPointIndex+1, POLY_CONTROL);
+                                    aPolygon.SetFlags( nPointIndex+2, POLY_CONTROL);
+                                    nPointIndex += 3;
+                                    break;
+                                }
+                                case drawing::EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
+                                case drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
+                                case drawing::EnhancedCustomShapeSegmentCommand::NOFILL :
+                                case drawing::EnhancedCustomShapeSegmentCommand::NOSTROKE :
+                                    break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+                                case drawing::EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+                                    nPointIndex += 3;
+                                    break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::ARCTO :
+                                case drawing::EnhancedCustomShapeSegmentCommand::ARC :
+                                case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+                                case drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+                                    nPointIndex += 4;
+                                    break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+                                case drawing::EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+                                    nPointIndex++;
+                                    break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::QUADRATICCURVETO :
+                                case drawing::EnhancedCustomShapeSegmentCommand::ARCANGLETO :
+                                    nPointIndex += 2;
+                                    break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::DARKEN : break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::DARKENLESS : break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::LIGHTEN : break;
+                                case drawing::EnhancedCustomShapeSegmentCommand::LIGHTENLESS : break;
+                                    break;
+                            }
+                        }
+                    }
+                    aPolyPolygon.Insert( aPolygon, POLYPOLY_APPEND );
+                }
+            }
+        }
+    }
     return aPolyPolygon;
 }
 
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 459b425..3db4c04 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1671,7 +1671,7 @@ void DrawingML::WritePolyPolygon( const PolyPolygon& rPolyPolygon )
                                    XML_y, I64S( rPoly[j].Y() - aRect.Top() ),
                                    FSEND );
 
-            if( ( flags == POLY_NORMAL || flags == POLY_SYMMTR ) && bBezier )
+            if( ( flags == POLY_NORMAL || flags == POLY_SYMMTR || j == rPoly.GetSize() - 1) && bBezier )
             {
                 mpFS->endElementNS( XML_a, XML_cubicBezTo );
                 bBezier = sal_False;
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index e55c2f3..90b7ffa 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -353,14 +353,22 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape )
     // visual shape properties
     pFS->startElementNS( mnXmlNamespace, XML_spPr, FSEND );
     WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false);
-    if( nAdjustmentValuesIndex != -1 )
+
+    if( sShapeType == "ooxml-non-primitive" ) // non-primitiv -> custom geometry
     {
-        sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
-        WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed,
-                          nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
+        WritePolyPolygon( EscherPropertyContainer::GetPolyPolygon( xShape ) );
+    }
+    else // preset geometry
+    {
+        if( nAdjustmentValuesIndex != -1 )
+        {
+            sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
+            WritePresetShape( sPresetShape, eShapeType, bPredefinedHandlesUsed,
+                              nAdjustmentsWhichNeedsToBeConverted, aGeometrySeq[ nAdjustmentValuesIndex ] );
+        }
+        else
+            WritePresetShape( sPresetShape );
     }
-    else
-        WritePresetShape( sPresetShape );
     if( rXPropSet.is() )
     {
         WriteFill( rXPropSet );
diff --git a/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx b/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx
new file mode 100644
index 0000000..baa47f4
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/dml-customgeometry-cubicbezier.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 8f1982d..239bb02 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -46,6 +46,9 @@
 #include <rtl/strbuf.hxx>
 #include <comphelper/sequenceashashmap.hxx>
 #include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
 
 #include <libxml/xpathInternals.h>
 #include <libxml/parserInternals.h>
@@ -2717,6 +2720,67 @@ DECLARE_OOXMLEXPORT_TEST(testDMLSolidfillAlpha, "dml-solidfill-alpha.docx")
     xShape.set(getShape(2), uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(sal_Int16(20), getProperty<sal_Int16>(xShape, "FillTransparence"));
 }
+
+DECLARE_OOXMLEXPORT_TEST(testDMLCustomGeometry, "dml-customgeometry-cubicbezier.docx")
+{
+
+    // The problem was that a custom shape was not exported.
+    uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(getShape(1), "CustomShapeGeometry");
+    uno::Sequence<beans::PropertyValue> aPathProps;
+    for (int i = 0; i < aProps.getLength(); ++i)
+    {
+        const beans::PropertyValue& rProp = aProps[i];
+        if (rProp.Name == "Path")
+            rProp.Value >>= aPathProps;
+    }
+    uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
+    uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
+    for (int i = 0; i < aPathProps.getLength(); ++i)
+    {
+        const beans::PropertyValue& rProp = aPathProps[i];
+        if (rProp.Name == "Coordinates")
+            rProp.Value >>= aPairs;
+        else if (rProp.Name == "Segments")
+            rProp.Value >>= aSegments;
+    }
+
+    // (a:moveTo)
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[0].Count);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::MOVETO), aSegments[0].Command );
+
+    // (a:cubicBezTo)
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(5), aSegments[1].Count);
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::CURVETO), aSegments[1].Command );
+
+    // Coordinates
+    sal_Int32 nLength = 16;
+    CPPUNIT_ASSERT_EQUAL(nLength, aPairs.getLength());
+    std::pair<sal_Int32,sal_Int32> aCoordinates[] =
+    {
+        std::pair<sal_Int32,sal_Int32>(607, 0),
+        std::pair<sal_Int32,sal_Int32>(450, 44),
+        std::pair<sal_Int32,sal_Int32>(300, 57),
+        std::pair<sal_Int32,sal_Int32>(176, 57),
+        std::pair<sal_Int32,sal_Int32>(109, 57),
+        std::pair<sal_Int32,sal_Int32>(49, 53),
+        std::pair<sal_Int32,sal_Int32>(0, 48),
+        std::pair<sal_Int32,sal_Int32>(66, 58),
+        std::pair<sal_Int32,sal_Int32>(152, 66),
+        std::pair<sal_Int32,sal_Int32>(251, 66),
+        std::pair<sal_Int32,sal_Int32>(358, 66),
+        std::pair<sal_Int32,sal_Int32>(480, 56),
+        std::pair<sal_Int32,sal_Int32>(607, 27),
+        std::pair<sal_Int32,sal_Int32>(607, 0),
+        std::pair<sal_Int32,sal_Int32>(607, 0),
+        std::pair<sal_Int32,sal_Int32>(607, 0)
+    };
+
+    for( int i = 0; i < nLength; ++i )
+    {
+        CPPUNIT_ASSERT_EQUAL(aCoordinates[i].first, aPairs[i].First.Value.get<sal_Int32>());
+        CPPUNIT_ASSERT_EQUAL(aCoordinates[i].second, aPairs[i].Second.Value.get<sal_Int32>());
+    }
+}
 #endif
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list