diff options
-rw-r--r-- | include/oox/export/vmlexport.hxx | 3 | ||||
-rw-r--r-- | oox/source/export/vmlexport.cxx | 21 | ||||
-rw-r--r-- | oox/source/vml/vmlshape.cxx | 44 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/fdo67737.docx | bin | 0 -> 21349 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 24 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 5 |
6 files changed, 78 insertions, 19 deletions
diff --git a/include/oox/export/vmlexport.hxx b/include/oox/export/vmlexport.hxx index f6fcbb2f895f..7a5f7ec96351 100644 --- a/include/oox/export/vmlexport.hxx +++ b/include/oox/export/vmlexport.hxx @@ -126,6 +126,9 @@ private: /// Create an OString representing the id from a numerical id. static OString ShapeIdString( sal_uInt32 nId ); + /// Add flip X and\or flip Y + void AddFlipXY( ); + /// Add starting and ending point of a line to the m_pShapeAttrList. void AddLineDimensions( const Rectangle& rRectangle ); diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx index 0c24040f0b91..6274e19b0b5e 100644 --- a/oox/source/export/vmlexport.cxx +++ b/oox/source/export/vmlexport.cxx @@ -28,6 +28,7 @@ #include <svx/svdotext.hxx> #include <vcl/cvtgrf.hxx> #include <filter/msfilter/msdffimp.hxx> +#include <filter/msfilter/escherex.hxx> #include <com/sun/star/text/HoriOrientation.hpp> #include <com/sun/star/text/VertOrientation.hpp> @@ -795,6 +796,17 @@ OString VMLExport::ShapeIdString( sal_uInt32 nId ) return OStringBuffer( 20 ).append( "shape_" ).append( sal_Int64( nId ) ).makeStringAndClear(); } +void VMLExport::AddFlipXY( ) +{ + const sal_uInt32 nFlipHandV = SHAPEFLAG_FLIPH + SHAPEFLAG_FLIPV; + switch ( m_nShapeFlags & nFlipHandV ) + { + case SHAPEFLAG_FLIPH: m_pShapeStyle->append( ";flip:x" ); break; + case SHAPEFLAG_FLIPV: m_pShapeStyle->append( ";flip:y" ); break; + case (nFlipHandV): m_pShapeStyle->append( ";flip:xy" ); break; + } +} + void VMLExport::AddLineDimensions( const Rectangle& rRectangle ) { // style @@ -803,12 +815,7 @@ void VMLExport::AddLineDimensions( const Rectangle& rRectangle ) m_pShapeStyle->append( "position:absolute" ); - switch ( m_nShapeFlags & 0xC0 ) - { - case 0x40: m_pShapeStyle->append( ";flip:y" ); break; - case 0x80: m_pShapeStyle->append( ";flip:x" ); break; - case 0xC0: m_pShapeStyle->append( ";flip:xy" ); break; - } + AddFlipXY(); // the actual dimensions OString aLeft, aTop, aRight, aBottom; @@ -862,6 +869,8 @@ void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const Rectangle& .append( ";width:" ).append( rRectangle.Right() - rRectangle.Left() ) .append( ";height:" ).append( rRectangle.Bottom() - rRectangle.Top() ); } + + AddFlipXY(); } void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const OString& rValue ) diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 40281cf545df..e5eb0175996b 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -501,21 +501,18 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes { awt::Rectangle aShapeRect(rShapeRect); boost::optional<sal_Int32> oRotation; + bool bFlipX = false, bFlipY = false; if (!maTypeModel.maRotation.isEmpty()) oRotation.reset(maTypeModel.maRotation.toInt32()); if (!maTypeModel.maFlip.isEmpty()) { if (maTypeModel.maFlip.equalsAscii("x")) { - aShapeRect.X += aShapeRect.Width; - aShapeRect.Width *= -1; - if (oRotation) - oRotation.reset(360 - *oRotation); + bFlipX = true; } else if (maTypeModel.maFlip.equalsAscii("y")) { - aShapeRect.Y += aShapeRect.Height; - aShapeRect.Height *= -1; + bFlipY = true; } } @@ -604,12 +601,37 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes } PropertySet aPropertySet(xShape); - if (xShape.is() && oRotation) + if (xShape.is()) { - lcl_SetRotation(aPropertySet, *oRotation); - // If rotation is used, simple setPosition() is not enough. - aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) ); - aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) ); + if (oRotation) + { + lcl_SetRotation(aPropertySet, *oRotation); + // If rotation is used, simple setPosition() is not enough. + aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) ); + aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) ); + } + + // When flip has 'x' or 'y', the associated ShapeRect will be changed but direction change doesn't occur. + // It might occur internally in SdrObject of "sw" module, not here. + // The associated properties "PROP_MirroredX" and "PROP_MirroredY" have to be set here so that direction change will occur internally. + if (bFlipX || bFlipY) + { + com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aPropSequence (2); + int nPropertyIndex = 0; + if (bFlipX) + { + aPropSequence [nPropertyIndex].Name = "MirroredX"; + aPropSequence [nPropertyIndex].Value = makeAny (bFlipX); + nPropertyIndex++; + } + if (bFlipY) + { + aPropSequence [nPropertyIndex].Name = "MirroredY"; + aPropSequence [nPropertyIndex].Value = makeAny (bFlipY); + nPropertyIndex++; + } + aPropertySet.setAnyProperty(PROP_CustomShapeGeometry, makeAny( aPropSequence ) ); + } } lcl_SetAnchorType(aPropertySet, maTypeModel); diff --git a/sw/qa/extras/ooxmlexport/data/fdo67737.docx b/sw/qa/extras/ooxmlexport/data/fdo67737.docx Binary files differnew file mode 100644 index 000000000000..8be34ec7112a --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/fdo67737.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index f974d349dd48..d938671f710a 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -110,6 +110,7 @@ public: void testTableFloating(); void testTableFloatingMargins(); void testFdo44689_start_page_7(); + void testFdo67737(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -196,6 +197,7 @@ void Test::run() {"table-floating.docx", &Test::testTableFloating}, {"table-floating-margins.docx", &Test::testTableFloatingMargins}, {"fdo44689_start_page_7.docx", &Test::testFdo44689_start_page_7}, + {"fdo67737.docx", &Test::testFdo67737}, }; // Don't test the first import of these, for some reason those tests fail const char* aBlacklist[] = { @@ -1193,6 +1195,28 @@ void Test::testFdo44689_start_page_7() CPPUNIT_ASSERT_EQUAL(sal_Int16(7), getProperty<sal_Int16>(xPara, "PageNumberOffset")); } +void Test::testFdo67737() +{ + // The problem was that imported shapes did not import and render the 'flip:x' and 'flip:y' attributes + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + uno::Reference<drawing::XShape> xArrow; + xDrawPage->getByIndex(0) >>= xArrow; + uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(xArrow, "CustomShapeGeometry"); + for (int i = 0; i < aProps.getLength(); ++i) + { + const beans::PropertyValue& rProp = aProps[i]; + if (rProp.Name == "MirroredY") + { + CPPUNIT_ASSERT_EQUAL( true, bool(rProp.Value.get<sal_Bool>()) ); + return; + } + } + + // Shouldn't reach here + CPPUNIT_FAIL("Did not find MirroredY=true property"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index f9d341603825..098b6c802dcd 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -253,13 +253,14 @@ void Test::testN751117() xPropertySet->getPropertyValue("LineEndName") >>= aValue; CPPUNIT_ASSERT(aValue.indexOf("Arrow") != -1); + // Rotating & Flipping will cause the angle to change from 90 degrees to 270 degrees sal_Int32 nValue = 0; xPropertySet->getPropertyValue("RotateAngle") >>= nValue; - CPPUNIT_ASSERT_EQUAL(sal_Int32(90 * 100), nValue); + CPPUNIT_ASSERT_EQUAL(sal_Int32(270 * 100), nValue); uno::Reference<drawing::XShape> xShape(xPropertySet, uno::UNO_QUERY); awt::Size aActualSize(xShape->getSize()); - CPPUNIT_ASSERT(aActualSize.Width < 0); + CPPUNIT_ASSERT(aActualSize.Width > 0); // The second shape should be a line uno::Reference<lang::XServiceInfo> xServiceInfo(xDraws->getByIndex(1), uno::UNO_QUERY); |