summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Trojahn <paul.trojahn@gmail.com>2017-09-08 19:05:19 +0200
committerTamás Zolnai <tamas.zolnai@collabora.com>2017-09-16 17:14:38 +0200
commit33a6eb3df861009d0fe9ffee344ef00cd2906520 (patch)
tree17dec3fc32d3ab9618f38a722860ad2923fe8b0b
parent57d3c7883bc51e9aed5b4eb8f2c2d599741888ca (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.hxx2
-rw-r--r--oox/source/drawingml/shape.cxx49
-rw-r--r--sd/qa/unit/data/pptx/tdf100065.pptxbin0 -> 34359 bytes
-rwxr-xr-xsd/qa/unit/data/pptx/tdf109223.pptxbin34023 -> 0 bytes
-rw-r--r--sd/qa/unit/import-tests.cxx49
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
new file mode 100644
index 000000000000..83952dff5504
--- /dev/null
+++ b/sd/qa/unit/data/pptx/tdf100065.pptx
Binary files differ
diff --git a/sd/qa/unit/data/pptx/tdf109223.pptx b/sd/qa/unit/data/pptx/tdf109223.pptx
deleted file mode 100755
index 0f68796e8e14..000000000000
--- a/sd/qa/unit/data/pptx/tdf109223.pptx
+++ /dev/null
Binary files differ
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();