diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-03-22 13:16:52 +0100 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2014-03-22 23:58:15 +0100 |
commit | c6ff03f37a6898f50a5ca07152168fb4fe911e05 (patch) | |
tree | 0f9fd1250528a867f399336b0256adb1e4d8b703 | |
parent | 1b922da415339726fb0186246dba6a03429b33bf (diff) |
fdo#70838: apply rotation transformations to DML anchor position
Used the same algorithm that we had for VML to update the position of
the DML anchor taking into account the rotation of the shape.
Complemented the unit test to check the values in the generated DML.
Change-Id: Ie0293c3cf4d1309fad58c0387f1589e69071fd9a
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 48 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.cxx | 36 |
2 files changed, 82 insertions, 2 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 918af37274c3..c8f45e3937d3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -490,6 +490,54 @@ DECLARE_OOXMLEXPORT_TEST(testFdo70838, "fdo70838.docx") if (!pXmlDocument) return; + // Check DML document + + sal_Int32 aXPos[4], aYPos[4]; + aXPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + aXPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionH/wp:posOffset").toInt32(); + + aYPos[0] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[1] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[2] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + aYPos[3] = getXPathContent(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:positionV/wp:posOffset").toInt32(); + + // TODO: compare values with a reference value extracted from the original document + // depends on fdo#75722 + // certain degree of error is tolerated due to rounding in unit conversions + CPPUNIT_ASSERT(abs(aXPos[0] - aXPos[1]) < 1000); + CPPUNIT_ASSERT(abs(aXPos[1] - aXPos[2]) < 1000); + CPPUNIT_ASSERT(abs(aXPos[2] - aXPos[3]) < 1000); + + CPPUNIT_ASSERT(abs(aYPos[0] - aYPos[1]) < 1000); + CPPUNIT_ASSERT(abs(aYPos[1] - aYPos[2]) < 1000); + CPPUNIT_ASSERT(abs(aYPos[2] - aYPos[3]) < 1000); + + sal_Int32 aHSize[4], aVSize[4]; + aHSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + aHSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cx").toInt32(); + + aVSize[0] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[1] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[2] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + aVSize[3] = getXPath(pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[4]/mc:Choice/w:drawing/wp:anchor/wp:extent", "cy").toInt32(); + + // certain degree of error is tolerated due to rounding in unit conversions + CPPUNIT_ASSERT(abs(3599280 - aHSize[0]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[1]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[2]) < 1000); + CPPUNIT_ASSERT(abs(3599280 - aHSize[3]) < 1000); + + CPPUNIT_ASSERT(abs(1799640 - aVSize[0]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[1]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[2]) < 1000); + CPPUNIT_ASSERT(abs(1799640 - aVSize[3]) < 1000); + + // Check VML document + // get styles of the four shapes OUString aStyles[4]; aStyles[0] = getXPath( pXmlDocument, "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Fallback/w:pict/v:rect", "style"); diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 4d755fc7fcde..8add83f0a628 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -86,6 +86,35 @@ OUString lclGetAnchorIdFromGrabBag(const SdrObject* pObj) return aResult; } +void lclMovePositionWithRotation(awt::Point& aPos, sal_Int64 nRotation) +{ + // code from ImplEESdrWriter::ImplFlipBoundingBox (filter/source/msfilter/eschesdo.cxx) + // TODO: refactor + + if ( nRotation == 0 ) + return; + + if ( nRotation < 0 ) + nRotation = ( 36000 + nRotation ) % 36000; + if ( nRotation % 18000 == 0 ) + nRotation = 0; + while ( nRotation > 9000 ) + nRotation = ( 18000 - ( nRotation % 18000 ) ); + + double fVal = (double) nRotation * F_PI18000; + double fCos = cos( fVal ); + double fSin = sin( fVal ); + + double nWidthHalf = (double) aPos.X / 2; + double nHeightHalf = (double) aPos.Y / 2; + + double nXDiff = fSin * nHeightHalf + fCos * nWidthHalf - nWidthHalf; + double nYDiff = fSin * nWidthHalf + fCos * nHeightHalf - nHeightHalf; + + aPos.X += nXDiff; + aPos.Y += nYDiff; +} + } ExportDataSaveRestore::ExportDataSaveRestore(DocxExport& rExport, sal_uLong nStt, sal_uLong nEnd, sw::Frame* pParentFrame) @@ -268,11 +297,14 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS { sax_fastparser::FastAttributeList* attrList = m_pImpl->m_pSerializer->createAttrList(); bool bOpaque = pFrmFmt->GetOpaque().GetValue(); + awt::Point aPos(pFrmFmt->GetHoriOrient().GetPos(), pFrmFmt->GetVertOrient().GetPos()); const SdrObject* pObj = pFrmFmt->FindRealSdrObject(); if (pObj != NULL) { // SdrObjects know their layer, consider that instead of the frame format. bOpaque = pObj->GetLayer() != pFrmFmt->GetDoc()->GetHellId() && pObj->GetLayer() != pFrmFmt->GetDoc()->GetInvisibleHellId(); + + lclMovePositionWithRotation(aPos, pObj->GetRotateAngle()); } attrList->add(XML_behindDoc, bOpaque ? "0" : "1"); attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr()); @@ -394,7 +426,7 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS else { m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND); - m_pImpl->m_pSerializer->write(TwipsToEMU(pFrmFmt->GetHoriOrient().GetPos())); + m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.X)); m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset); } m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionH); @@ -408,7 +440,7 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS else { m_pImpl->m_pSerializer->startElementNS(XML_wp, XML_posOffset, FSEND); - m_pImpl->m_pSerializer->write(TwipsToEMU(pFrmFmt->GetVertOrient().GetPos())); + m_pImpl->m_pSerializer->write(TwipsToEMU(aPos.Y)); m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_posOffset); } m_pImpl->m_pSerializer->endElementNS(XML_wp, XML_positionV); |