summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Araminowicz <g.araminowicz@gmail.com>2017-05-30 11:45:47 +0200
committerJan Holesovsky <kendy@collabora.com>2017-05-31 15:30:28 +0200
commit087537dc45bbab3db41fe6d92974cdfde59904cb (patch)
treed359f2ffc2f850ad0a511739ed9ff984517360a2
parent490e9dbade4f9d69cab4b1ec435944c9b4d2f6c2 (diff)
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@libreoffice.org> Reviewed-by: Jan Holesovsky <kendy@collabora.com>
-rw-r--r--include/oox/vml/vmlformatting.hxx12
-rw-r--r--oox/source/vml/vmlformatting.cxx25
-rw-r--r--oox/source/vml/vmlshape.cxx17
-rwxr-xr-xsw/qa/extras/ooxmlimport/data/tdf76446.docxbin0 -> 10135 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx7
5 files changed, 49 insertions, 12 deletions
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
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/tdf76446.docx
Binary files 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