diff options
author | Paul Trojahn <paul.trojahn@gmail.com> | 2017-09-08 19:05:19 +0200 |
---|---|---|
committer | Tamás Zolnai <tamas.zolnai@collabora.com> | 2017-09-16 17:14:38 +0200 |
commit | 33a6eb3df861009d0fe9ffee344ef00cd2906520 (patch) | |
tree | 17dec3fc32d3ab9618f38a722860ad2923fe8b0b | |
parent | 57d3c7883bc51e9aed5b4eb8f2c2d599741888ca (diff) |
tdf#100065 PPTX Fix import of custom shapes in groups
A negative scale of the parent matrix indicates that the shape needs to
be flipped. This commit fixes text rotation as well, so
d742c0019435d0bc90c9342492583636099a057f is no longer needed.
Change-Id: I67bba34519b3af9215fe64a71f5137aa510edf7a
Reviewed-on: https://gerrit.libreoffice.org/42250
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tamás Zolnai <tamas.zolnai@collabora.com>
-rw-r--r-- | include/oox/drawingml/shape.hxx | 2 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 49 | ||||
-rw-r--r-- | sd/qa/unit/data/pptx/tdf100065.pptx | bin | 0 -> 34359 bytes | |||
-rwxr-xr-x | sd/qa/unit/data/pptx/tdf109223.pptx | bin | 34023 -> 0 bytes | |||
-rw-r--r-- | sd/qa/unit/import-tests.cxx | 49 |
5 files changed, 48 insertions, 52 deletions
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx index 7c3a8934e42a..6028a11c2bc0 100644 --- a/include/oox/drawingml/shape.hxx +++ b/include/oox/drawingml/shape.hxx @@ -139,7 +139,6 @@ public: sal_Int32 getRotation() const { return mnRotation; } void setDiagramRotation( sal_Int32 nRotation ) { mnDiagramRotation = nRotation; } void setFlip( bool bFlipH, bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; } - void applyParentTextFlipV(bool bTextFlipV) { mbInheritedTextFlipV = bTextFlipV; } void addChild( const ShapePtr& rChildPtr ) { maChildren.push_back( rChildPtr ); } std::vector< ShapePtr >& getChildren() { return maChildren; } @@ -317,7 +316,6 @@ private: sal_Int32 mnDiagramRotation; // rotates shape prior to sizing, does not affect text rotation bool mbFlipH; bool mbFlipV; - bool mbInheritedTextFlipV; // Used by group shapes only bool mbHidden; bool mbHiddenMasterShape; // master shapes can be hidden in layout slides // we need separate flag because we don't want diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 8e418d19e22a..e75f6e8ca3d1 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -116,7 +116,6 @@ Shape::Shape( const sal_Char* pServiceName, bool bDefaultHeight ) , mnDiagramRotation( 0 ) , mbFlipH( false ) , mbFlipV( false ) -, mbInheritedTextFlipV(false) , mbHidden( false ) , mbHiddenMasterShape( false ) , mbLockedCanvas( false ) @@ -160,7 +159,6 @@ Shape::Shape( const ShapePtr& pSourceShape ) , mnDiagramRotation( pSourceShape->mnDiagramRotation ) , mbFlipH( pSourceShape->mbFlipH ) , mbFlipV( pSourceShape->mbFlipV ) -, mbInheritedTextFlipV(pSourceShape->mbInheritedTextFlipV) , mbHidden( pSourceShape->mbHidden ) , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape ) , mbLockedCanvas( pSourceShape->mbLockedCanvas ) @@ -317,7 +315,6 @@ void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText ) mnRotation = rReferencedShape.mnRotation; mbFlipH = rReferencedShape.mbFlipH; mbFlipV = rReferencedShape.mbFlipV; - mbInheritedTextFlipV = rReferencedShape.mbInheritedTextFlipV; mbHidden = rReferencedShape.mbHidden; } @@ -391,7 +388,6 @@ void Shape::addChildren( std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() ); while( aIter != rMaster.maChildren.end() ) { (*aIter)->setMasterTextListStyle( mpMasterTextListStyle ); - (*aIter)->applyParentTextFlipV(mbInheritedTextFlipV != mbFlipV); (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), pShapeMap ); } } @@ -492,7 +488,8 @@ Reference< XShape > const & Shape::createAndInsert( maSize.Height ? maSize.Height : 1.0 ); } - if( mbFlipH || mbFlipV || mnRotation != 0) + bool bInGroup = !aParentTransformation.isIdentity(); + if( mbFlipH || mbFlipV || mnRotation != 0 || bInGroup ) { // calculate object's center basegfx::B2DPoint aCenter(0.5, 0.5); @@ -507,30 +504,33 @@ Reference< XShape > const & Shape::createAndInsert( aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 ); } - if( bUseRotationTransform && mnRotation != 0 ) + if( bUseRotationTransform ) { // OOXML flips shapes before rotating them. - sal_Int32 nRotation = mnRotation; - if(bIsCustomShape) + double fRotation = F_PI180 * ( (double)mnRotation / 60000.0 ); + if( bIsCustomShape ) { - if(mbFlipH) + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aParentTransformation.decompose(aScale, aTranslate, fRotate, fShearX); + // A negative scale means that the shape needs to be flipped + if(aScale.getX() < 0) { - nRotation = nRotation * -1 + 60000*360; + mbFlipH = !mbFlipH; } - if(mbFlipV) + if(aScale.getY() < 0) { - nRotation = nRotation * -1 + 60000*360; + mbFlipV = !mbFlipV; } } // rotate around object's center - aTransformation.rotate( F_PI180 * ( (double)nRotation / 60000.0 ) ); + aTransformation.rotate( fRotation ); } // move object back from center aTransformation.translate( aCenter.getX(), aCenter.getY() ); } - bool bInGroup = !aParentTransformation.isIdentity(); if( maPosition.X != 0 || maPosition.Y != 0) { // if global position is used, add it to transformation @@ -544,6 +544,25 @@ Reference< XShape > const & Shape::createAndInsert( aParentTransformation = aTransformation; aTransformation.scale(1/double(EMU_PER_HMM), 1/double(EMU_PER_HMM)); + if( bIsCustomShape ) + { + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aTransformation.decompose(aScale, aTranslate, fRotate, fShearX); + + // OOXML rotates shapes before flipping them, so the rotation needs to be inverted. + if( mbFlipH != mbFlipV) + { + // calculate object's center + basegfx::B2DPoint aCenter(0.5, 0.5); + aCenter *= aTransformation; + + aTransformation.translate( -aCenter.getX(), -aCenter.getY() ); + aTransformation.rotate( fRotate * -2.0 ); + aTransformation.translate( aCenter.getX(), aCenter.getY() ); + } + } + // special for lineshape if ( aServiceName == "com.sun.star.drawing.LineShape" ) { @@ -1093,8 +1112,6 @@ Reference< XShape > const & Shape::createAndInsert( if( getTextBody() ) { sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) ); - if(mbInheritedTextFlipV) - nTextRotateAngle -= 180 * 60000; nTextRotateAngle -= mnDiagramRotation; /* OOX measures text rotation clockwise in 1/60000th degrees, relative to the containing shape. setTextRotateAngle wants diff --git a/sd/qa/unit/data/pptx/tdf100065.pptx b/sd/qa/unit/data/pptx/tdf100065.pptx Binary files differnew file mode 100644 index 000000000000..83952dff5504 --- /dev/null +++ b/sd/qa/unit/data/pptx/tdf100065.pptx diff --git a/sd/qa/unit/data/pptx/tdf109223.pptx b/sd/qa/unit/data/pptx/tdf109223.pptx Binary files differdeleted file mode 100755 index 0f68796e8e14..000000000000 --- a/sd/qa/unit/data/pptx/tdf109223.pptx +++ /dev/null diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx index 9975f16e87ef..f49fd62881ff 100644 --- a/sd/qa/unit/import-tests.cxx +++ b/sd/qa/unit/import-tests.cxx @@ -162,9 +162,9 @@ public: void testTdf89064(); void testTdf108925(); void testTdf109067(); - void testTdf109223(); void testTdf109187(); void testTdf108926(); + void testTdf100065(); bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected); void testPatternImport(); @@ -235,9 +235,9 @@ public: CPPUNIT_TEST(testTdf89064); CPPUNIT_TEST(testTdf108925); CPPUNIT_TEST(testTdf109067); - CPPUNIT_TEST(testTdf109223); CPPUNIT_TEST(testTdf109187); CPPUNIT_TEST(testTdf108926); + CPPUNIT_TEST(testTdf100065); CPPUNIT_TEST_SUITE_END(); }; @@ -2234,38 +2234,6 @@ void SdImportTest::testTdf109067() xDocShRef->DoClose(); } -void SdImportTest::testTdf109223() -{ - // In the test document flipV attribute is defined for a group shape - // This transformation is not applied on child shapes - // To make the text direction right at least I added an additional text rotation when parent shape is flipped. - sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109223.pptx"), PPTX); - uno::Reference< container::XIndexAccess > xGroupShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW); - uno::Reference< beans::XPropertySet > xShape(xGroupShape->getByIndex(1), uno::UNO_QUERY); - - // Check the shape text to make sure we test the right shape - OUString sText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY)->getString(); - CPPUNIT_ASSERT_EQUAL(OUString("Tested child shape"), sText); - - // Check the attribute inherited from parent shape - bool bAttributeFound = false; - uno::Sequence<beans::PropertyValue> aProps; - CPPUNIT_ASSERT(xShape->getPropertyValue("CustomShapeGeometry") >>= aProps); - for (sal_Int32 i = 0; i < aProps.getLength(); ++i) - { - const beans::PropertyValue& rProp = aProps[i]; - if (rProp.Name == "TextPreRotateAngle") - { - CPPUNIT_ASSERT_EQUAL(sal_Int32(180), rProp.Value.get<sal_Int32>()); - bAttributeFound = true; - break; - } - } - - CPPUNIT_ASSERT_EQUAL(true, bAttributeFound); - xDocShRef->DoClose(); -} - void SdImportTest::testTdf109187() { sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109187.pptx"), PPTX); @@ -2298,6 +2266,19 @@ void SdImportTest::testTdf108926() xDocShRef->DoClose(); } +void SdImportTest::testTdf100065() +{ + sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100065.pptx"), PPTX); + uno::Reference< container::XIndexAccess > xGroupShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW); + uno::Reference< beans::XPropertySet > xShape(xGroupShape->getByIndex(1), uno::UNO_QUERY_THROW); + + sal_Int32 nAngle; + CPPUNIT_ASSERT(xShape->getPropertyValue("RotateAngle") >>= nAngle); + CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), nAngle); + + xDocShRef->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest); CPPUNIT_PLUGIN_IMPLEMENT(); |