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

Grzegorz Araminowicz g.araminowicz at gmail.com
Wed May 31 13:31:15 UTC 2017


 include/oox/vml/vmlformatting.hxx           |   12 ++++++++++++
 oox/source/vml/vmlformatting.cxx            |   25 +++++++++++++++++++++++++
 oox/source/vml/vmlshape.cxx                 |   17 +++++------------
 sw/qa/extras/ooxmlimport/data/tdf76446.docx |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx    |    7 +++++++
 5 files changed, 49 insertions(+), 12 deletions(-)

New commits:
commit 087537dc45bbab3db41fe6d92974cdfde59904cb
Author: Grzegorz Araminowicz <g.araminowicz at gmail.com>
Date:   Tue May 30 11:45:47 2017 +0200

    tdf#76446 GSoC: incorrect rotation of VML shapes
    
    * support poorly documented 'fd' suffix in rotation attribute
    * allow non-integer rotation
    
    Change-Id: I3d72f2a708e6585597db09366c00c50038abc9c1
    Reviewed-on: https://gerrit.libreoffice.org/38207
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/include/oox/vml/vmlformatting.hxx b/include/oox/vml/vmlformatting.hxx
index efb0e6606887..b07d8b01899a 100644
--- a/include/oox/vml/vmlformatting.hxx
+++ b/include/oox/vml/vmlformatting.hxx
@@ -75,6 +75,18 @@ namespace ConversionHelper
                             const OUString& rValue,
                             double fDefValue );
 
+    /** Converts the passed VML rotation value to degrees.
+        See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation
+        angles are clockwise, we have them as counter-clockwise.
+        Additionally, VML type is 0..360, our is 0..36000.
+
+        @param rValue  The VML rotation value. This is a floating-point value
+            with optional 'fd' suffix. If the suffix is missing, the floating
+            point value will be returned unmodified. If the 'fd' suffix is
+            present, the value will be divided by 65536.
+    */
+    OOX_DLLPUBLIC sal_Int32    decodeRotation( const OUString& rValue );
+
     /** Converts the passed VML measure string to EMU (English Metric Units).
 
         @param rGraphicHelper  The graphic helper needed to perform pixel
diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx
index c2e2d139c0d6..6b9d1a9c654d 100644
--- a/oox/source/vml/vmlformatting.cxx
+++ b/oox/source/vml/vmlformatting.cxx
@@ -34,6 +34,7 @@
 #include "oox/helper/graphichelper.hxx"
 #include <oox/token/properties.hxx>
 #include <oox/token/tokens.hxx>
+#include <svx/svdtrans.hxx>
 
 namespace oox {
 namespace vml {
@@ -109,6 +110,30 @@ double ConversionHelper::decodePercent( const OUString& rValue, double fDefValue
     return fDefValue;
 }
 
+sal_Int32 ConversionHelper::decodeRotation( const OUString& rValue )
+{
+    if( rValue.isEmpty() )
+        return 0;
+
+    double fValue = 0.0;
+    double fRotation = 0.0;
+    sal_Int32 nEndPos = 0;
+    if( !lclExtractDouble(fValue, nEndPos, rValue) )
+        return 0;
+
+    if( nEndPos == rValue.getLength() )
+        fRotation = fValue;
+    else if( (nEndPos + 2 == rValue.getLength()) && (rValue[nEndPos] == 'f') && (rValue[nEndPos+1] == 'd') )
+        fRotation = fValue / 65536.0;
+    else
+    {
+        OSL_FAIL("ConversionHelper::decodeRotation - unknown measure unit");
+        return 0;
+    }
+
+    return NormAngle360(fRotation * -100);
+}
+
 sal_Int64 ConversionHelper::decodeMeasureToEmu( const GraphicHelper& rGraphicHelper,
         const OUString& rValue, sal_Int32 nRefValue, bool bPixelX, bool bDefaultAsPixel )
 {
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index 7c78234e511f..f7d6c6908b8f 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -372,7 +372,7 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS
                     }
 
                     if(!(maTypeModel.maRotation).isEmpty())
-                        aGrabBag.push_back(comphelper::makePropertyValue("mso-rotation-angle", sal_Int32(NormAngle360((maTypeModel.maRotation.toInt32()) * -100))));
+                        aGrabBag.push_back(comphelper::makePropertyValue("mso-rotation-angle", ConversionHelper::decodeRotation(maTypeModel.maRotation)));
                     propertySet->setPropertyValue("FrameInteropGrabBag", uno::makeAny(comphelper::containerToSequence(aGrabBag)));
                     sal_Int32 backColorTransparency = 0;
                     propertySet->getPropertyValue("BackColorTransparency")
@@ -620,20 +620,13 @@ void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel,
     lcl_setSurround( rPropSet, rTypeModel, rGraphicHelper );
 }
 
-void lcl_SetRotation(PropertySet& rPropSet, const sal_Int32 nRotation)
-{
-    // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise.
-    // Additionally, VML type is 0..360, our is 0..36000.
-    rPropSet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360(nRotation * -100))));
-}
-
 Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const awt::Rectangle& rShapeRect ) const
 {
     awt::Rectangle aShapeRect(rShapeRect);
     boost::optional<sal_Int32> oRotation;
     bool bFlipX = false, bFlipY = false;
     if (!maTypeModel.maRotation.isEmpty())
-        oRotation.reset(maTypeModel.maRotation.toInt32());
+        oRotation.reset(ConversionHelper::decodeRotation(maTypeModel.maRotation));
     if (!maTypeModel.maFlip.isEmpty())
     {
         if (maTypeModel.maFlip == "x")
@@ -786,7 +779,7 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
     {
         if (oRotation)
         {
-            lcl_SetRotation(aPropertySet, *oRotation);
+            aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(*oRotation));
             uno::Reference<lang::XServiceInfo> xServiceInfo(rxShapes, uno::UNO_QUERY);
             if (!xServiceInfo->supportsService("com.sun.star.drawing.GroupShape"))
             {
@@ -844,7 +837,7 @@ Reference< XShape > SimpleShape::createPictureObject( const Reference< XShapes >
         }
         // fdo#70457: preserve rotation information
         if ( !maTypeModel.maRotation.isEmpty() )
-            lcl_SetRotation( aPropSet, maTypeModel.maRotation.toInt32() );
+            aPropSet.setAnyProperty(PROP_RotateAngle, makeAny(ConversionHelper::decodeRotation(maTypeModel.maRotation)));
 
         const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
         lcl_SetAnchorType(aPropSet, maTypeModel, rGraphicHelper);
@@ -1288,7 +1281,7 @@ Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes >
     const GraphicHelper& rGraphicHelper = mrDrawing.getFilter().getGraphicHelper();
     lcl_SetAnchorType(aPropertySet, maTypeModel, rGraphicHelper);
     if (!maTypeModel.maRotation.isEmpty())
-        lcl_SetRotation(aPropertySet, maTypeModel.maRotation.toInt32());
+        aPropertySet.setAnyProperty(PROP_RotateAngle, makeAny(ConversionHelper::decodeRotation(maTypeModel.maRotation)));
     return xGroupShape;
 }
 
diff --git a/sw/qa/extras/ooxmlimport/data/tdf76446.docx b/sw/qa/extras/ooxmlimport/data/tdf76446.docx
new file mode 100755
index 000000000000..7ba6db35f146
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf76446.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index dee3ad3d3596..ebebedda914b 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1280,6 +1280,13 @@ DECLARE_OOXMLIMPORT_TEST(testTdf100072, "tdf100072.docx")
     CPPUNIT_ASSERT_MESSAGE("Shape line width does not match", abs(nFirstEnd - nSecondEnd) < 10);
 }
 
+DECLARE_OOXMLIMPORT_TEST(testTdf76446, "tdf76446.docx")
+{
+    uno::Reference<drawing::XShape> xShape = getShape(1);
+    sal_Int64 nRot = getProperty<sal_Int64>(xShape, "RotateAngle");
+    CPPUNIT_ASSERT_EQUAL(sal_Int64(3128), nRot);
+}
+
 
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
 


More information about the Libreoffice-commits mailing list