tdf#118375, tdf#70838 correct position of rotated shape in doc
Word relates the position to the unrotated shape in legacy doc
format. Writer uses the rotated shape. The patch corrects the
difference on import and export.
Change-Id: I25537123656e62d6ffae5118ee8d621a4b5c5be0
Reviewed-on: https://gerrit.libreoffice.org/70152
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
diff --git a/sw/qa/extras/ww8export/data/tdf118375_240degClockwise.doc b/sw/qa/extras/ww8export/data/tdf118375_240degClockwise.doc
new file mode 100644
index 0000000..99d15e2
--- /dev/null
+++ b/sw/qa/extras/ww8export/data/tdf118375_240degClockwise.doc
Binary files differ
diff --git a/sw/qa/extras/ww8export/ww8export3.cxx b/sw/qa/extras/ww8export/ww8export3.cxx
index ba99e05..e62bcaf 100644
--- a/sw/qa/extras/ww8export/ww8export3.cxx
+++ b/sw/qa/extras/ww8export/ww8export3.cxx
@@ -223,6 +223,29 @@ DECLARE_WW8EXPORT_TEST(testBtlrCell, "btlr-cell.doc")
CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL, getProperty<sal_Int16>(xC1, "WritingMode"));
}
DECLARE_WW8EXPORT_TEST(testTdf118375export, "tdf118375_240degClockwise.doc")
{
// The input document has one custom shape, which is rotated 240deg. Check
// that it has the same position as in Word.
uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent,
uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_MESSAGE("Could not get XDrawPagesSupplier", xDrawPagesSupplier.is());
uno::Reference<drawing::XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages());
uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPages->getByIndex(0), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_MESSAGE("Could not get xDrawPage", xDrawPage.is());
uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get xShape", xShape.is());
uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
CPPUNIT_ASSERT_MESSAGE("Could not get the shape properties", xShapeProps.is());
sal_Int32 nPosX, nPosY;
xShapeProps->getPropertyValue("HoriOrientPosition") >>= nPosX;
xShapeProps->getPropertyValue("VertOrientPosition") >>= nPosY;
// Allow some tolerance because rounding errors through integer arithmethic
// in rotation.
CPPUNIT_ASSERT_DOUBLES_EQUAL(5200.0, static_cast<double>(nPosX), 1.0);
CPPUNIT_ASSERT_DOUBLES_EQUAL(1152.0, static_cast<double>(nPosY), 1.0);
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8esh.cxx b/sw/source/filter/ww8/wrtw8esh.cxx
index c3cb2d5..f713a9c2 100644
--- a/sw/source/filter/ww8/wrtw8esh.cxx
+++ b/sw/source/filter/ww8/wrtw8esh.cxx
@@ -659,6 +659,7 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const
WinwordAnchoring::ConvertPosition( rHOr, rVOr, rFormat );
Point aObjPos;
bool bHasHeightWidthSwapped(false);
if (RES_FLYFRMFMT == rFormat.Which())
{
SwRect aLayRect(rFormat.FindLayoutRect(false, &aObjPos));
@@ -694,6 +695,7 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const
const long nHeight = aRect.getHeight();
aRect.setWidth( nHeight );
aRect.setHeight( nWidth );
bHasHeightWidthSwapped = true;
}
}
}
@@ -755,6 +757,34 @@ void PlcDrawObj::WritePlc( WW8Export& rWrt ) const
//Nasty swap for bidi if necessary
rWrt.MiserableRTLFrameFormatHack(nLeft, nRight, rFrameFormat);
// tdf#70838. Word relates the position to the unrotated rectangle,
// Writer to the rotated one. Because the rotation is around center,
// the difference counts half.
if(pObj && pObj->GetRotateAngle())
{
SwTwips nXOff;
SwTwips nYOff;
SwTwips nSnapWidth = pObj->GetSnapRect().getWidth();
SwTwips nSnapHeight = pObj->GetSnapRect().getHeight();
SwTwips nLogicWidth = pObj->GetLogicRect().getWidth();
SwTwips nLogicHeight = pObj->GetLogicRect().getHeight();
// +1 for to compensate integer arithmetic rounding errors
if(bHasHeightWidthSwapped)
{
nXOff = (nSnapWidth - nLogicHeight + 1) / 2;
nYOff = (nSnapHeight - nLogicWidth + 1) / 2;
}
else
{
nXOff = (nSnapWidth - nLogicWidth + 1) / 2;
nYOff = (nSnapHeight - nLogicHeight + 1) / 2;
}
nLeft += nXOff;
nRight += nXOff;
nTop += nYOff;
nBottom += nYOff;
}
//xaLeft/yaTop/xaRight/yaBottom - rel. to anchor
//(most of) the border is outside the graphic is word, so
//change dimensions to fit
diff --git a/sw/source/filter/ww8/ww8graf.cxx b/sw/source/filter/ww8/ww8graf.cxx
index 8c4c573..d3d8154 100644
--- a/sw/source/filter/ww8/ww8graf.cxx
+++ b/sw/source/filter/ww8/ww8graf.cxx
@@ -2530,6 +2530,17 @@ SwFrameFormat* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
return nullptr;
}
// tdf#118375 Word relates position to the unrotated rectangle,
// Writer uses the rotated one.
if (pObject->GetRotateAngle())
{
tools::Rectangle aObjSnapRect(pObject->GetSnapRect()); // recalculates the SnapRect
pF->nXaLeft = aObjSnapRect.Left();
pF->nYaTop = aObjSnapRect.Top();
pF->nXaRight = aObjSnapRect.Right();
pF->nYaBottom = aObjSnapRect.Bottom();
}
bool bDone = false;
SdrObject* pOurNewObject = nullptr;
bool bReplaceable = false;