Kaydet (Commit) d3ffe3ed authored tarafından Ri GangHu's avatar Ri GangHu Kaydeden (comit) Miklos Vajna

fdo#67737 : fix for flip not being imported & rendered correctly

Signed-off-by: 's avatarAdam Co <rattles2013@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/5272

Conflicts:
	sw/qa/extras/ooxmlexport/ooxmlexport.cxx

Change-Id: I5c8440edad0381e33b64f64bb54aa8f1bc304007
üst 84184f95
...@@ -126,6 +126,9 @@ private: ...@@ -126,6 +126,9 @@ private:
/// Create an OString representing the id from a numerical id. /// Create an OString representing the id from a numerical id.
static OString ShapeIdString( sal_uInt32 nId ); 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. /// Add starting and ending point of a line to the m_pShapeAttrList.
void AddLineDimensions( const Rectangle& rRectangle ); void AddLineDimensions( const Rectangle& rRectangle );
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <svx/svdotext.hxx> #include <svx/svdotext.hxx>
#include <vcl/cvtgrf.hxx> #include <vcl/cvtgrf.hxx>
#include <filter/msfilter/msdffimp.hxx> #include <filter/msfilter/msdffimp.hxx>
#include <filter/msfilter/escherex.hxx>
#include <com/sun/star/text/HoriOrientation.hpp> #include <com/sun/star/text/HoriOrientation.hpp>
#include <com/sun/star/text/VertOrientation.hpp> #include <com/sun/star/text/VertOrientation.hpp>
...@@ -795,6 +796,17 @@ OString VMLExport::ShapeIdString( sal_uInt32 nId ) ...@@ -795,6 +796,17 @@ OString VMLExport::ShapeIdString( sal_uInt32 nId )
return OStringBuffer( 20 ).append( "shape_" ).append( sal_Int64( nId ) ).makeStringAndClear(); 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 ) void VMLExport::AddLineDimensions( const Rectangle& rRectangle )
{ {
// style // style
...@@ -803,12 +815,7 @@ void VMLExport::AddLineDimensions( const Rectangle& rRectangle ) ...@@ -803,12 +815,7 @@ void VMLExport::AddLineDimensions( const Rectangle& rRectangle )
m_pShapeStyle->append( "position:absolute" ); m_pShapeStyle->append( "position:absolute" );
switch ( m_nShapeFlags & 0xC0 ) AddFlipXY();
{
case 0x40: m_pShapeStyle->append( ";flip:y" ); break;
case 0x80: m_pShapeStyle->append( ";flip:x" ); break;
case 0xC0: m_pShapeStyle->append( ";flip:xy" ); break;
}
// the actual dimensions // the actual dimensions
OString aLeft, aTop, aRight, aBottom; OString aLeft, aTop, aRight, aBottom;
...@@ -862,6 +869,8 @@ void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const Rectangle& ...@@ -862,6 +869,8 @@ void VMLExport::AddRectangleDimensions( OStringBuffer& rBuffer, const Rectangle&
.append( ";width:" ).append( rRectangle.Right() - rRectangle.Left() ) .append( ";width:" ).append( rRectangle.Right() - rRectangle.Left() )
.append( ";height:" ).append( rRectangle.Bottom() - rRectangle.Top() ); .append( ";height:" ).append( rRectangle.Bottom() - rRectangle.Top() );
} }
AddFlipXY();
} }
void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const OString& rValue ) void VMLExport::AddShapeAttribute( sal_Int32 nAttribute, const OString& rValue )
......
...@@ -501,21 +501,18 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes ...@@ -501,21 +501,18 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
{ {
awt::Rectangle aShapeRect(rShapeRect); awt::Rectangle aShapeRect(rShapeRect);
boost::optional<sal_Int32> oRotation; boost::optional<sal_Int32> oRotation;
bool bFlipX = false, bFlipY = false;
if (!maTypeModel.maRotation.isEmpty()) if (!maTypeModel.maRotation.isEmpty())
oRotation.reset(maTypeModel.maRotation.toInt32()); oRotation.reset(maTypeModel.maRotation.toInt32());
if (!maTypeModel.maFlip.isEmpty()) if (!maTypeModel.maFlip.isEmpty())
{ {
if (maTypeModel.maFlip.equalsAscii("x")) if (maTypeModel.maFlip.equalsAscii("x"))
{ {
aShapeRect.X += aShapeRect.Width; bFlipX = true;
aShapeRect.Width *= -1;
if (oRotation)
oRotation.reset(360 - *oRotation);
} }
else if (maTypeModel.maFlip.equalsAscii("y")) else if (maTypeModel.maFlip.equalsAscii("y"))
{ {
aShapeRect.Y += aShapeRect.Height; bFlipY = true;
aShapeRect.Height *= -1;
} }
} }
...@@ -604,12 +601,37 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes ...@@ -604,12 +601,37 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes
} }
PropertySet aPropertySet(xShape); PropertySet aPropertySet(xShape);
if (xShape.is() && oRotation) if (xShape.is())
{ {
lcl_SetRotation(aPropertySet, *oRotation); if (oRotation)
// If rotation is used, simple setPosition() is not enough. {
aPropertySet.setAnyProperty(PROP_HoriOrientPosition, makeAny( aShapeRect.X ) ); lcl_SetRotation(aPropertySet, *oRotation);
aPropertySet.setAnyProperty(PROP_VertOrientPosition, makeAny( aShapeRect.Y ) ); // 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); lcl_SetAnchorType(aPropertySet, maTypeModel);
......
...@@ -110,6 +110,7 @@ public: ...@@ -110,6 +110,7 @@ public:
void testTableFloating(); void testTableFloating();
void testTableFloatingMargins(); void testTableFloatingMargins();
void testFdo44689_start_page_7(); void testFdo44689_start_page_7();
void testFdo67737();
CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST_SUITE(Test);
#if !defined(MACOSX) && !defined(WNT) #if !defined(MACOSX) && !defined(WNT)
...@@ -196,6 +197,7 @@ void Test::run() ...@@ -196,6 +197,7 @@ void Test::run()
{"table-floating.docx", &Test::testTableFloating}, {"table-floating.docx", &Test::testTableFloating},
{"table-floating-margins.docx", &Test::testTableFloatingMargins}, {"table-floating-margins.docx", &Test::testTableFloatingMargins},
{"fdo44689_start_page_7.docx", &Test::testFdo44689_start_page_7}, {"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 // Don't test the first import of these, for some reason those tests fail
const char* aBlacklist[] = { const char* aBlacklist[] = {
...@@ -1193,6 +1195,28 @@ void Test::testFdo44689_start_page_7() ...@@ -1193,6 +1195,28 @@ void Test::testFdo44689_start_page_7()
CPPUNIT_ASSERT_EQUAL(sal_Int16(7), getProperty<sal_Int16>(xPara, "PageNumberOffset")); 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_TEST_SUITE_REGISTRATION(Test);
CPPUNIT_PLUGIN_IMPLEMENT(); CPPUNIT_PLUGIN_IMPLEMENT();
......
...@@ -253,13 +253,14 @@ void Test::testN751117() ...@@ -253,13 +253,14 @@ void Test::testN751117()
xPropertySet->getPropertyValue("LineEndName") >>= aValue; xPropertySet->getPropertyValue("LineEndName") >>= aValue;
CPPUNIT_ASSERT(aValue.indexOf("Arrow") != -1); CPPUNIT_ASSERT(aValue.indexOf("Arrow") != -1);
// Rotating & Flipping will cause the angle to change from 90 degrees to 270 degrees
sal_Int32 nValue = 0; sal_Int32 nValue = 0;
xPropertySet->getPropertyValue("RotateAngle") >>= nValue; 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); uno::Reference<drawing::XShape> xShape(xPropertySet, uno::UNO_QUERY);
awt::Size aActualSize(xShape->getSize()); awt::Size aActualSize(xShape->getSize());
CPPUNIT_ASSERT(aActualSize.Width < 0); CPPUNIT_ASSERT(aActualSize.Width > 0);
// The second shape should be a line // The second shape should be a line
uno::Reference<lang::XServiceInfo> xServiceInfo(xDraws->getByIndex(1), uno::UNO_QUERY); uno::Reference<lang::XServiceInfo> xServiceInfo(xDraws->getByIndex(1), uno::UNO_QUERY);
......
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