Kaydet (Commit) 33a6eb3d authored tarafından Paul Trojahn's avatar Paul Trojahn Kaydeden (comit) Tamás Zolnai

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
d742c001 is no longer needed.

Change-Id: I67bba34519b3af9215fe64a71f5137aa510edf7a
Reviewed-on: https://gerrit.libreoffice.org/42250Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTamás Zolnai <tamas.zolnai@collabora.com>
üst 57d3c788
......@@ -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
......
......@@ -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
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment