diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-12-04 10:42:40 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-12-04 11:25:38 +0100 |
commit | a5a836d8c43dc9cebbbf8af39bf0142de603a7c6 (patch) | |
tree | 5211f53b880421d89cfbcf36688d6ea29dcbb7be | |
parent | 5f0f3d4e91e9eb1d1f60b0cd073e7bbd8ea38c29 (diff) |
DOCX filter: effect extent should be part of the margin
OOXML has an object size (extent) a size including effects like shadow (effect
extent) and the margin (top/bottom/left/right distance). Our doc model doesn't
have an explicit "effect extent", but to have the intended layout, we at least
need the spacing of the effect around flys (even if a number of effects are not
rendered). Fix this by adding the effect extent to the margin; if we still have
the effect extent grab-bag around, then this can be undone during export.
Change-Id: I9609ce347c54588395e09ad91a84c872b9007f85
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/effectextent-margin.docx | bin | 0 -> 13219 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 10 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxsdrexport.cxx | 114 | ||||
-rw-r--r-- | writerfilter/source/dmapper/GraphicImport.cxx | 4 |
4 files changed, 72 insertions, 56 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/effectextent-margin.docx b/sw/qa/extras/ooxmlexport/data/effectextent-margin.docx Binary files differnew file mode 100644 index 000000000000..22db162a78b0 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/effectextent-margin.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 2c4f6086c603..dc5333a6f58c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -16,6 +16,7 @@ #include <com/sun/star/text/HoriOrientation.hpp> #include <com/sun/star/text/XTextRangeCompare.hpp> #include <com/sun/star/text/WritingMode2.hpp> +#include <oox/drawingml/drawingmltypes.hxx> #include <string> @@ -619,6 +620,15 @@ DECLARE_OOXMLEXPORT_TEST(testTextboxRightEdge, "textbox-right-edge.docx") // inside the draw shape. CPPUNIT_ASSERT(nShapeLeft + nShapeWidth >= nTextboxLeft + nTextboxWidth); } + +DECLARE_OOXMLEXPORT_TEST(testEffectExtentMargin, "effectextent-margin.docx") +{ + // This was 318, i.e. oox::drawingml::convertEmuToHmm(114300), effectExtent + // wasn't part of the margin, leading to the fly not taking enough space + // around itself. + CPPUNIT_ASSERT_EQUAL(oox::drawingml::convertEmuToHmm(114300+95250), getProperty<sal_Int32>(getShape(1), "LeftMargin")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx index 4b122e09d995..3e869673c772 100644 --- a/sw/source/filter/ww8/docxsdrexport.cxx +++ b/sw/source/filter/ww8/docxsdrexport.cxx @@ -319,6 +319,56 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS { isAnchor = pFrmFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR; } + + // Count effectExtent values, their value is needed before dist{T,B,L,R} is written. + SvxShadowItem aShadowItem = pFrmFmt->GetShadow(); + sal_Int32 nLeftExt = 0, nRightExt = 0, nTopExt = 0, nBottomExt = 0; + if (aShadowItem.GetLocation() != SVX_SHADOW_NONE) + { + sal_Int32 nShadowWidth(TwipsToEMU(aShadowItem.GetWidth())); + switch (aShadowItem.GetLocation()) + { + case SVX_SHADOW_TOPLEFT: + nTopExt = nLeftExt = nShadowWidth; + break; + case SVX_SHADOW_TOPRIGHT: + nTopExt = nRightExt = nShadowWidth; + break; + case SVX_SHADOW_BOTTOMLEFT: + nBottomExt = nLeftExt = nShadowWidth; + break; + case SVX_SHADOW_BOTTOMRIGHT: + nBottomExt = nRightExt = nShadowWidth; + break; + case SVX_SHADOW_NONE: + case SVX_SHADOW_END: + break; + } + } + else if (const SdrObject* pObject = pFrmFmt->FindRealSdrObject()) + { + // No shadow, but we have an idea what was the original effectExtent. + uno::Any aAny; + pObject->GetGrabBagItem(aAny); + comphelper::SequenceAsHashMap aGrabBag(aAny); + comphelper::SequenceAsHashMap::iterator it = aGrabBag.find("CT_EffectExtent"); + if (it != aGrabBag.end()) + { + comphelper::SequenceAsHashMap aEffectExtent(it->second); + for (std::pair<const OUString, uno::Any>& rDirection : aEffectExtent) + { + if (rDirection.first == "l" && rDirection.second.has<sal_Int32>()) + nLeftExt = rDirection.second.get<sal_Int32>(); + else if (rDirection.first == "t" && rDirection.second.has<sal_Int32>()) + nTopExt = rDirection.second.get<sal_Int32>(); + else if (rDirection.first == "r" && rDirection.second.has<sal_Int32>()) + nRightExt = rDirection.second.get<sal_Int32>(); + else if (rDirection.first == "b" && rDirection.second.has<sal_Int32>()) + nBottomExt = rDirection.second.get<sal_Int32>(); + } + } + } + if (isAnchor) { sax_fastparser::FastAttributeList* attrList = m_pImpl->m_pSerializer->createAttrList(); @@ -333,10 +383,10 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS lclMovePositionWithRotation(aPos, rSize, pObj->GetRotateAngle()); } attrList->add(XML_behindDoc, bOpaque ? "0" : "1"); - attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper())).getStr()); - attrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower())).getStr()); - attrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft())).getStr()); - attrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight())).getStr()); + attrList->add(XML_distT, OString::number(TwipsToEMU(pULSpaceItem.GetUpper()) - nTopExt).getStr()); + attrList->add(XML_distB, OString::number(TwipsToEMU(pULSpaceItem.GetLower()) - nBottomExt).getStr()); + attrList->add(XML_distL, OString::number(TwipsToEMU(pLRSpaceItem.GetLeft()) - nLeftExt).getStr()); + attrList->add(XML_distR, OString::number(TwipsToEMU(pLRSpaceItem.GetRight()) - nRightExt).getStr()); attrList->add(XML_simplePos, "0"); attrList->add(XML_locked, "0"); attrList->add(XML_layoutInCell, "1"); @@ -587,59 +637,11 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrmFmt* pFrmFmt, const Size& rS FSEND); // effectExtent, extent including the effect (shadow only for now) - SvxShadowItem aShadowItem = pFrmFmt->GetShadow(); - OString aLeftExt("0"), aRightExt("0"), aTopExt("0"), aBottomExt("0"); - if (aShadowItem.GetLocation() != SVX_SHADOW_NONE) - { - OString aShadowWidth(OString::number(TwipsToEMU(aShadowItem.GetWidth()))); - switch (aShadowItem.GetLocation()) - { - case SVX_SHADOW_TOPLEFT: - aTopExt = aLeftExt = aShadowWidth; - break; - case SVX_SHADOW_TOPRIGHT: - aTopExt = aRightExt = aShadowWidth; - break; - case SVX_SHADOW_BOTTOMLEFT: - aBottomExt = aLeftExt = aShadowWidth; - break; - case SVX_SHADOW_BOTTOMRIGHT: - aBottomExt = aRightExt = aShadowWidth; - break; - case SVX_SHADOW_NONE: - case SVX_SHADOW_END: - break; - } - } - else if (const SdrObject* pObject = pFrmFmt->FindRealSdrObject()) - { - // No shadow, but we have an idea what was the original effectExtent. - uno::Any aAny; - pObject->GetGrabBagItem(aAny); - comphelper::SequenceAsHashMap aGrabBag(aAny); - comphelper::SequenceAsHashMap::iterator it = aGrabBag.find("CT_EffectExtent"); - if (it != aGrabBag.end()) - { - comphelper::SequenceAsHashMap aEffectExtent(it->second); - for (std::pair<const OUString, uno::Any>& rDirection : aEffectExtent) - { - if (rDirection.first == "l" && rDirection.second.has<sal_Int32>()) - aLeftExt = OString::number(rDirection.second.get<sal_Int32>()); - else if (rDirection.first == "t" && rDirection.second.has<sal_Int32>()) - aTopExt = OString::number(rDirection.second.get<sal_Int32>()); - else if (rDirection.first == "r" && rDirection.second.has<sal_Int32>()) - aRightExt = OString::number(rDirection.second.get<sal_Int32>()); - else if (rDirection.first == "b" && rDirection.second.has<sal_Int32>()) - aBottomExt = OString::number(rDirection.second.get<sal_Int32>()); - } - } - } - m_pImpl->m_pSerializer->singleElementNS(XML_wp, XML_effectExtent, - XML_l, aLeftExt, - XML_t, aTopExt, - XML_r, aRightExt, - XML_b, aBottomExt, + XML_l, OString::number(nLeftExt), + XML_t, OString::number(nTopExt), + XML_r, OString::number(nRightExt), + XML_b, OString::number(nBottomExt), FSEND); // See if we know the exact wrap type from grab-bag. diff --git a/writerfilter/source/dmapper/GraphicImport.cxx b/writerfilter/source/dmapper/GraphicImport.cxx index f7cb766ba845..019dd5429272 100644 --- a/writerfilter/source/dmapper/GraphicImport.cxx +++ b/writerfilter/source/dmapper/GraphicImport.cxx @@ -557,15 +557,19 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue) break; case NS_ooxml::LN_CT_EffectExtent_l: m_pImpl->m_oEffectExtentLeft = nIntValue; + m_pImpl->nLeftMargin += oox::drawingml::convertEmuToHmm(nIntValue); break; case NS_ooxml::LN_CT_EffectExtent_t: m_pImpl->m_oEffectExtentTop = nIntValue; + m_pImpl->nTopMargin += oox::drawingml::convertEmuToHmm(nIntValue); break; case NS_ooxml::LN_CT_EffectExtent_r: m_pImpl->m_oEffectExtentRight = nIntValue; + m_pImpl->nRightMargin += oox::drawingml::convertEmuToHmm(nIntValue); break; case NS_ooxml::LN_CT_EffectExtent_b: m_pImpl->m_oEffectExtentBottom = nIntValue; + m_pImpl->nBottomMargin += oox::drawingml::convertEmuToHmm(nIntValue); break; case NS_ooxml::LN_CT_NonVisualDrawingProps_id:// 90650; //id of the object - ignored |