sw/qa/extras/ooxmlexport/data/tdf112287.docx |binary sw/qa/extras/ooxmlexport/data/tdf112287B.docx |binary sw/qa/extras/ooxmlexport/data/tdf154129_framePr1.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport18.cxx | 19 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx | 10 sw/qa/extras/rtfexport/data/tdf154129_transparentFrame.rtf | 3 sw/qa/extras/rtfexport/rtfexport3.cxx | 6 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 383 ++++++------- 8 files changed, 219 insertions(+), 202 deletions(-)
New commits: commit 5d619635512519ef7b3b53af4fbbf3666578d7f7 Author: Justin Luth <justin.l...@collabora.com> AuthorDate: Sat Mar 11 11:36:59 2023 -0500 Commit: Justin Luth <jl...@mail.com> CommitDate: Fri May 19 18:41:13 2023 +0200 tdf#154129 writerfilter framePr: check whole style inheritance (and dedup) The fixes related to this bug were broken up into numerous commits, but all combined into one patch for backporting. This is a squashed commit that includes: commit 1519ae101abf32187db983c8a08f7bf1899d5d22 tdf#154129 writerfilter framePr: check whole style inheritance: HAnchor commit b2d754c49b7351f7b2663bb249b4b2f663ef3786 tdf#154129 writerfilter framePr: address nit about nSafetyLimit commit c253fc3877fd91f4345feb60dacb6565f9a2509b tdf#154129 writerfilter framePr: check whole style inheritance: VAnchor commit b1696d2a3e2015b60fc04a785e6a9f7925f4232e tdf#154129 writerfilter framePr: check whole style inheritance: Y/YAlign commit 630732bfd8ed531e9d412a36a083f33763def054 tdf#112287 tdf#154129 writerfilter framePr: fix vAnchor default commit 1bc004f67feb51beb00113cedd5f98a1e6e2bcdd tdf#154129 writerfilter framePr: check whole style inheritance: X/XAlign commit 2571b39158c679a42a68bea5f219e29a42f4e6a6 tdf#154129 writerfilter framePr: check whole style inheritance: W/H commit 6f1052da8d145b1176186024dc4745cbd561fe36 tdf#154129 writerfilter framePr: check whole style inheritance: hRule commit 44837a12d12be3e525fa48b37c3dd2553cc97d94 tdf#154129 writerfilter framePr: check whole style inheritance: wrap commit 2ab9a2e4166264be83300e7ed038be1b803a5ac8 tdf#154129 writerfilter framePr: check whole style inheritance: v/hSpace commit 6eb483d3f27e3ee8c56d422fb96f83844370d325 tdf#154129 writerfilter framePr: remove last use of pParaStyle commit fb8522e457b098b5ade98a4a4babbc8704d3fad4 NFC tdf#154129 writerfilter framePr: deduplicate Hori/VertOrient commit 1a12246fc1deaaf1e2c723c0c541de85cf88101e NFC tdf#154129 writerfilter framePr: deduplicate w:w commit af8f05f859a1fb61d88dfe558d1bc7a8282c792a tdf#154129 writerfilter framePr: deduplicate w:h commit f2a10d9e751bdbc4ba981b6ca9d0dc127439a3c2 tdf#154129 writerfilter framePr: nhRule obey comment instructions commit 1188fa78d0e7b5fd8f4c7c207fd4ec9ced666c12 tdf#154129 writerfilter framePr: deduplicate w:x commit 611288b64548762e0731ed6323e1653e4fca2317 tdf#154129 writerfilter framePr: deduplicate w:y commit 070e62bad980cbe15dfbe9096a5e5d962a70f07c tdf#154129 writerfilter framePr: deduplicate w:hAnchor commit2d331e6bfe8c9ca31f1a4e092dbcffb8919b8655 tdf#154129 writerfilter framePr: deduplicate w:vAnchor commit 33ce22f080bbedfde78fdc907b0d4d5bd0f68f14 tdf#154129 writerfilter framePr: deduplicate w:wrap commit 4237db7f43c08efbf166a2bfa8a0c99d1c5f04a4 NFC tdf#154129 writerfilter framePr: deduplicate lcl.. call commit a777dab7544bd11c26ae26c40cce49ab976dab2d tdf#154129 tdf#73546 writerfilter framePr: fix/deduplicate w:v/hSpace commit d21ba804040bdb275234254fbbe742ce830420c2 tdf#154129 tdf#97128 writerfilter framePr: deduplicate PopFrameDirection commit b1194e42dde6e3749631a6510d9e7b969e5eae8e tdf#154129 writerfilter framePr: deduplicate BackColorTransparency commit 97b84d31a1db2ec690d180effad307f331d62fb9 tdf#154129 tdf#78590 writerfilter framePr: deduplicate grabbag Change-Id: I32eabc6c1090dbc2c467da74fe32c6377e9a3875 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148686 Tested-by: Jenkins Reviewed-by: Justin Luth <jl...@mail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151987 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sw/qa/extras/ooxmlexport/data/tdf112287.docx b/sw/qa/extras/ooxmlexport/data/tdf112287.docx index 3464e28985da..ca22693186e0 100644 Binary files a/sw/qa/extras/ooxmlexport/data/tdf112287.docx and b/sw/qa/extras/ooxmlexport/data/tdf112287.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/tdf112287B.docx b/sw/qa/extras/ooxmlexport/data/tdf112287B.docx new file mode 100644 index 000000000000..945d3d026b19 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf112287B.docx differ diff --git a/sw/qa/extras/ooxmlexport/data/tdf154129_framePr1.docx b/sw/qa/extras/ooxmlexport/data/tdf154129_framePr1.docx new file mode 100644 index 000000000000..27ba6055c287 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf154129_framePr1.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx index a62c144938e1..8c14caaf2768 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx @@ -16,6 +16,7 @@ #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/text/GraphicCrop.hpp> +#include <com/sun/star/text/RelOrientation.hpp> #include <com/sun/star/text/WritingMode2.hpp> #include <com/sun/star/text/XFootnotesSupplier.hpp> #include <com/sun/star/text/XTextDocument.hpp> @@ -133,15 +134,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf104394_lostTextbox, "tdf104394_lostTextbox.docx" CPPUNIT_ASSERT_EQUAL(2, getPages()); } -DECLARE_OOXMLEXPORT_TEST(testTdf146984_anchorInShape, "tdf146984_anchorInShape.docx") +DECLARE_OOXMLEXPORT_TEST(testTdf154129_framePr1, "tdf154129_framePr1.docx") { - // This was only one page b/c the page break was missing. - CPPUNIT_ASSERT_EQUAL(2, getPages()); - - const auto& pLayout = parseLayoutDump(); - // There are shapes on both pages - these should be non-zero numbers - //assertXPath(pLayout, "//page[1]//anchored", 3); - //assertXPath(pLayout, "//page[2]//anchored", 2); + for (size_t i = 1; i < 4; ++i) + { + uno::Reference<drawing::XShape> xTextFrame = getShape(i); + // The anchor is defined in the style, and only the first style was checked, not the parents + auto nAnchor = getProperty<sal_Int16>(xTextFrame, "HoriOrientRelation"); + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, nAnchor); + nAnchor = getProperty<sal_Int16>(xTextFrame, "VertOrientRelation"); + CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, nAnchor); + } } DECLARE_OOXMLEXPORT_TEST(testTdf153613_anchoredAfterPgBreak, "tdf153613_anchoredAfterPgBreak.docx") diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx index d8be5e39ba93..ceb6bdff9c06 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx @@ -1424,10 +1424,20 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf112287) xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml"); assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","vAnchor","margin"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","hAnchor","text"); assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","xAlign","center"); assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","yAlign","bottom"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf112287B) +{ + loadAndSave("tdf112287B.docx"); + xmlDocUniquePtr pXmlDocument = parseExport("word/document.xml"); + + assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","vAnchor","text"); + assertXPath(pXmlDocument, "/w:document/w:body/w:p[1]/w:pPr/w:framePr","hAnchor","text"); +} + CPPUNIT_TEST_FIXTURE(Test, testZOrderInHeader) { loadAndSave("tdf120760_ZOrderInHeader.docx"); diff --git a/sw/qa/extras/rtfexport/data/tdf154129_transparentFrame.rtf b/sw/qa/extras/rtfexport/data/tdf154129_transparentFrame.rtf new file mode 100644 index 000000000000..29cece2af5c8 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf154129_transparentFrame.rtf @@ -0,0 +1,3 @@ +{\rtf1\ansi\ansicpg1252\deff0\deflang1033 +\paperw7920\paperh6120\margl360\margr360\margt360\margb302\gutter0 \windowctrl\ftnbj\viewkind1\viewscale100 \sectd \linex0 +{\pard \pvpg\phcol\posx2204\posy3791\absw1772\absh-230\overlay {\pard \cf1 \f0 \b \pvpg\phcol\posx2204\posy3791\absw1772\absh-220\overlay VISIBLE\par}\par}\sect } diff --git a/sw/qa/extras/rtfexport/rtfexport3.cxx b/sw/qa/extras/rtfexport/rtfexport3.cxx index 6260da4a58a4..00f553a499b0 100644 --- a/sw/qa/extras/rtfexport/rtfexport3.cxx +++ b/sw/qa/extras/rtfexport/rtfexport3.cxx @@ -110,6 +110,12 @@ DECLARE_RTFEXPORT_TEST(testTdf130817, "tdf130817.rtf") CPPUNIT_ASSERT_EQUAL(OUString("$"), xEndnote1->getAnchor()->getString()); } +DECLARE_RTFEXPORT_TEST(testTdf154129_transparentFrame, "tdf154129_transparentFrame.rtf") +{ + // Without the fix, this was zero, and the text frame with "Visible" just looks white. + CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(getShape(1), "FillTransparence")); +} + DECLARE_RTFEXPORT_TEST(testTdf137683_charHighlightNone, "tdf137683_charHighlightNone.rtf") { uno::Reference<beans::XPropertySet> xRun(getRun(getParagraph(1), 1), uno::UNO_QUERY_THROW); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 5f83bed4c58f..f599764c291d 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -1584,224 +1584,219 @@ void DomainMapper_Impl::CheckUnregisteredFrameConversion( ) return; try { - StyleSheetEntryPtr pParaStyle = - GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(rAppendContext.pLastParagraphProperties->GetParaStyleName()); + // A paragraph's properties come from direct formatting or somewhere in the style hierarchy + std::vector<const ParagraphProperties*> vProps; + vProps.emplace_back(rAppendContext.pLastParagraphProperties.get()); + sal_Int8 nSafetyLimit = 16; + StyleSheetEntryPtr pStyle = GetStyleSheetTable()->FindStyleSheetByConvertedStyleName( + rAppendContext.pLastParagraphProperties->GetParaStyleName()); + while (nSafetyLimit-- && pStyle && pStyle->m_pProperties) + { + vProps.emplace_back(&pStyle->m_pProperties->props()); + assert(pStyle->m_sBaseStyleIdentifier != pStyle->m_sStyleName); + if (pStyle->m_sBaseStyleIdentifier.isEmpty()) + break; + pStyle = GetStyleSheetTable()->FindStyleSheetByISTD(pStyle->m_sBaseStyleIdentifier); + } + SAL_WARN_IF(!nSafetyLimit,"writerfilter.dmapper","Inherited style loop likely: early exit"); std::vector<beans::PropertyValue> aFrameProperties; - if ( pParaStyle ) + sal_Int32 nWidth = -1; + for (const auto pProp : vProps) { - const StyleSheetPropertyMap* pStyleProperties = pParaStyle->m_pProperties.get(); - if (!pStyleProperties) - return; - sal_Int32 nWidth = - rAppendContext.pLastParagraphProperties->Getw() > 0 ? - rAppendContext.pLastParagraphProperties->Getw() : - pStyleProperties->props().Getw(); - bool bAutoWidth = nWidth < 1; - if( bAutoWidth ) - nWidth = DEFAULT_FRAME_MIN_WIDTH; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH), nWidth)); - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEIGHT), - rAppendContext.pLastParagraphProperties->Geth() > 0 ? - rAppendContext.pLastParagraphProperties->Geth() : - pStyleProperties->props().Geth() > 0 ? pStyleProperties->props().Geth() : DEFAULT_FRAME_MIN_HEIGHT)); - - sal_Int16 nhRule = sal_Int16( - rAppendContext.pLastParagraphProperties->GethRule() >= 0 ? - rAppendContext.pLastParagraphProperties->GethRule() : - pStyleProperties->props().GethRule()); - if ( nhRule < 0 ) - { - if ( rAppendContext.pLastParagraphProperties->Geth() >= 0 || - pStyleProperties->props().GethRule() >= 0 ) - { - // [MS-OE376] Word uses a default value of "atLeast" for - // this attribute when the value of the h attribute is not 0. - nhRule = text::SizeType::MIN; - } - else - { - nhRule = text::SizeType::VARIABLE; - } - } - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), nhRule)); - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX)); - - if (const std::optional<sal_Int16> nDirection = PopFrameDirection()) - { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_FRM_DIRECTION), *nDirection)); - } + if (pProp->Getw() < 0) + continue; + nWidth = pProp->Getw(); + break; + } + bool bAutoWidth = nWidth < 1; + if (bAutoWidth) + nWidth = DEFAULT_FRAME_MIN_WIDTH; + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_WIDTH), nWidth)); + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), + bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX)); + + bool bValidH = false; + sal_Int32 nHeight = DEFAULT_FRAME_MIN_HEIGHT; + for (const auto pProp : vProps) + { + if (pProp->Geth() < 0) + continue; + nHeight = pProp->Geth(); + bValidH = true; + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_HEIGHT), nHeight)); - sal_Int16 nHoriOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetxAlign() : - pStyleProperties->props().GetxAlign() >= 0 ? pStyleProperties->props().GetxAlign() : text::HoriOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT), nHoriOrient)); - - //set a non negative default value - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_POSITION), - rAppendContext.pLastParagraphProperties->IsxValid() ? - rAppendContext.pLastParagraphProperties->Getx() : - pStyleProperties->props().IsxValid() - ? pStyleProperties->props().Getx() : DEFAULT_VALUE)); - - //Default the anchor in case FramePr_hAnchor is missing ECMA 17.3.1.11 - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GethAnchor() : - pStyleProperties->props().GethAnchor() >=0 ? pStyleProperties->props().GethAnchor() : text::RelOrientation::FRAME ))); - - sal_Int16 nVertOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetyAlign() : - pStyleProperties->props().GetyAlign() >= 0 ? pStyleProperties->props().GetyAlign() : text::VertOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT), nVertOrient)); - - //set a non negative default value - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_POSITION), - rAppendContext.pLastParagraphProperties->IsyValid() ? - rAppendContext.pLastParagraphProperties->Gety() : - pStyleProperties->props().IsyValid() - ? pStyleProperties->props().Gety() : DEFAULT_VALUE)); - - //Default the anchor in case FramePr_vAnchor is missing ECMA 17.3.1.11 - if (rAppendContext.pLastParagraphProperties->GetWrap() == text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE && - pStyleProperties->props().GetWrap() - == text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE) + sal_Int16 nhRule = -1; + for (const auto pProp : vProps) + { + if (pProp->GethRule() < 0) + continue; + nhRule = pProp->GethRule(); + break; + } + if (nhRule < 0) + { + if (bValidH && nHeight) { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvAnchor() : - pStyleProperties->props().GetvAnchor() >= 0 ? pStyleProperties->props().GetvAnchor() : text::RelOrientation::FRAME))); + // [MS-OE376] Word uses a default value of "atLeast" for + // this attribute when the value of the h attribute is not 0. + nhRule = text::SizeType::MIN; } else { - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_RELATION), sal_Int16( - rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvAnchor() : - pStyleProperties->props().GetvAnchor() >= 0 ? pStyleProperties->props().GetvAnchor() : text::RelOrientation::PAGE_PRINT_AREA))); + nhRule = text::SizeType::VARIABLE; } - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SURROUND), - rAppendContext.pLastParagraphProperties->GetWrap() != text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE - ? rAppendContext.pLastParagraphProperties->GetWrap() - : pStyleProperties->props().GetWrap() - != text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE - ? pStyleProperties->props().GetWrap() - : text::WrapTextMode_NONE )); - - /** FDO#73546 : distL & distR should be unsigned integers <Ecma 20.4.3.6> - Swapped the array elements 11,12 & 13,14 since 11 & 12 are - LEFT & RIGHT margins and 13,14 are TOP and BOTTOM margins respectively. - */ - sal_Int32 nRightDist; - sal_Int32 nLeftDist = nRightDist = - rAppendContext.pLastParagraphProperties->GethSpace() >= 0 ? - rAppendContext.pLastParagraphProperties->GethSpace() : - pStyleProperties->props().GethSpace() >= 0 - ? pStyleProperties->props().GethSpace() : 0; - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LEFT_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_RIGHT_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist)); - - sal_Int32 nBottomDist; - sal_Int32 nTopDist = nBottomDist = - rAppendContext.pLastParagraphProperties->GetvSpace() >= 0 ? - rAppendContext.pLastParagraphProperties->GetvSpace() : - pStyleProperties->props().GetvSpace() >= 0 - ? pStyleProperties->props().GetvSpace() : 0; - - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_TOP_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BOTTOM_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist)); - // If there is no fill, the Word default is 100% transparency. - // Otherwise CellColorHandler has priority, and this setting - // will be ignored. - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BACK_COLOR_TRANSPARENCY), sal_Int32(100))); - - uno::Sequence<beans::PropertyValue> aGrabBag( comphelper::InitPropertySequence({ - { "ParaFrameProperties", uno::Any(rAppendContext.pLastParagraphProperties->IsFrameMode()) } - })); - aFrameProperties.push_back(comphelper::makePropertyValue("FrameInteropGrabBag", aGrabBag)); - - lcl_MoveBorderPropertiesToFrame(aFrameProperties, - rAppendContext.pLastParagraphProperties->GetStartingRange(), - rAppendContext.pLastParagraphProperties->GetEndingRange()); } - else - { - sal_Int32 nWidth = rAppendContext.pLastParagraphProperties->Getw(); - bool bAutoWidth = nWidth < 1; - if( bAutoWidth ) - nWidth = DEFAULT_FRAME_MIN_WIDTH; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH), nWidth)); + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), nhRule)); - sal_Int16 nhRule = sal_Int16(rAppendContext.pLastParagraphProperties->GethRule()); - if ( nhRule < 0 ) - { - if ( rAppendContext.pLastParagraphProperties->Geth() >= 0 ) - { - // [MS-OE376] Word uses a default value of atLeast for - // this attribute when the value of the h attribute is not 0. - nhRule = text::SizeType::MIN; - } - else - { - nhRule = text::SizeType::VARIABLE; - } - } - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_SIZE_TYPE), nhRule)); + bool bValidX = false; + sal_Int32 nX = DEFAULT_VALUE; + for (const auto pProp : vProps) + { + bValidX = pProp->IsxValid(); + if (!bValidX) + continue; + nX = pProp->Getx(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_POSITION), nX)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_WIDTH_TYPE), bAutoWidth ? text::SizeType::MIN : text::SizeType::FIX)); + sal_Int16 nHoriOrient = text::HoriOrientation::NONE; + for (const auto pProp : vProps) + { + if (pProp->GetxAlign() < 0) + continue; + nHoriOrient = pProp->GetxAlign(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT), nHoriOrient)); - sal_Int16 nHoriOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetxAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetxAlign() : - text::HoriOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT), nHoriOrient)); + //Default the anchor in case FramePr_hAnchor is missing ECMA 17.3.1.11 + sal_Int16 nHAnchor = text::RelOrientation::FRAME; // 'text' + for (const auto pProp : vProps) + { + if (pProp->GethAnchor() < 0) + continue; + nHAnchor = pProp->GethAnchor(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_RELATION), nHAnchor)); - sal_Int16 nVertOrient = sal_Int16( - rAppendContext.pLastParagraphProperties->GetyAlign() >= 0 ? - rAppendContext.pLastParagraphProperties->GetyAlign() : - text::VertOrientation::NONE ); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT), nVertOrient)); + bool bValidY = false; + sal_Int32 nY = DEFAULT_VALUE; + for (const auto pProp : vProps) + { + bValidY = pProp->IsyValid(); + if (!bValidY) + continue; + nY = pProp->Gety(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_POSITION), nY)); - sal_Int32 nVertDist = rAppendContext.pLastParagraphProperties->GethSpace(); - if( nVertDist < 0 ) - nVertDist = 0; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_LEFT_MARGIN), nVertOrient == text::VertOrientation::TOP ? 0 : nVertDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_RIGHT_MARGIN), nVertOrient == text::VertOrientation::BOTTOM ? 0 : nVertDist)); + sal_Int16 nVertOrient = text::VertOrientation::NONE; + for (const auto pProp : vProps) + { + if (pProp->GetyAlign() < 0) + continue; + nVertOrient = pProp->GetyAlign(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT), nVertOrient)); - sal_Int32 nHoriDist = rAppendContext.pLastParagraphProperties->GetvSpace(); - if( nHoriDist < 0 ) - nHoriDist = 0; - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_TOP_MARGIN), nHoriOrient == text::HoriOrientation::LEFT ? 0 : nHoriDist)); - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_BOTTOM_MARGIN), nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nHoriDist)); + //Default the anchor in case FramePr_vAnchor is missing ECMA 17.3.1.11 + sal_Int16 nVAnchor = text::RelOrientation::FRAME; // 'text' + // vAlign is ignored if vAnchor is set to 'text'. So, if w:y is not defined, + // but there is a defined vAlign, then a missing vAnchor should become 'margin'. + if (!bValidY && nVertOrient) + { + nVAnchor = text::RelOrientation::PAGE_PRINT_AREA; // 'margin' + } + for (const auto pProp : vProps) + { + if (pProp->GetvAnchor() < 0) + continue; + nVAnchor = pProp->GetvAnchor(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_RELATION), nVAnchor)); - if( rAppendContext.pLastParagraphProperties->Geth() > 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HEIGHT), rAppendContext.pLastParagraphProperties->Geth())); + text::WrapTextMode nWrap = text::WrapTextMode_NONE; + for (const auto pProp : vProps) + { + if (pProp->GetWrap() == text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE) + continue; + nWrap = pProp->GetWrap(); + break; + } + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_SURROUND), nWrap)); - if( rAppendContext.pLastParagraphProperties->IsxValid() ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_HORI_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Getx())); + sal_Int32 nRightDist = 0; + sal_Int32 nLeftDist = 0; + for (const auto pProp : vProps) + { + if (pProp->GethSpace() < 0) + continue; + nLeftDist = nRightDist = pProp->GethSpace(); + break; + } + aFrameProperties.push_back(comphelper::makePropertyValue( + getPropertyName(PROP_LEFT_MARGIN), + nHoriOrient == text::HoriOrientation::LEFT ? 0 : nLeftDist)); + aFrameProperties.push_back(comphelper::makePropertyValue( + getPropertyName(PROP_RIGHT_MARGIN), + nHoriOrient == text::HoriOrientation::RIGHT ? 0 : nRightDist)); - if( rAppendContext.pLastParagraphProperties->GethAnchor() >= 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue("HoriOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GethAnchor()))); + sal_Int32 nBottomDist = 0; + sal_Int32 nTopDist = 0; + for (const auto pProp : vProps) + { + if (pProp->GetvSpace() < 0) + continue; + nTopDist = nBottomDist = pProp->GetvSpace(); + break; + } + aFrameProperties.push_back(comphelper::makePropertyValue( + getPropertyName(PROP_TOP_MARGIN), + nVertOrient == text::VertOrientation::TOP ? 0 : nTopDist)); + aFrameProperties.push_back(comphelper::makePropertyValue( + getPropertyName(PROP_BOTTOM_MARGIN), + nVertOrient == text::VertOrientation::BOTTOM ? 0 : nBottomDist)); - if( rAppendContext.pLastParagraphProperties->IsyValid() ) - aFrameProperties.push_back(comphelper::makePropertyValue(getPropertyName(PROP_VERT_ORIENT_POSITION), rAppendContext.pLastParagraphProperties->Gety())); + if (const std::optional<sal_Int16> nDirection = PopFrameDirection()) + { + aFrameProperties.push_back( + comphelper::makePropertyValue(getPropertyName(PROP_FRM_DIRECTION), *nDirection)); + } - if( rAppendContext.pLastParagraphProperties->GetvAnchor() >= 0 ) - aFrameProperties.push_back(comphelper::makePropertyValue("VertOrientRelation", sal_Int16(rAppendContext.pLastParagraphProperties->GetvAnchor()))); + // If there is no fill, the Word default is 100% transparency. + // Otherwise CellColorHandler has priority, and this setting + // will be ignored. + aFrameProperties.push_back(comphelper::makePropertyValue( + getPropertyName(PROP_BACK_COLOR_TRANSPARENCY), sal_Int32(100))); - if( rAppendContext.pLastParagraphProperties->GetWrap() >= text::WrapTextMode_NONE ) - aFrameProperties.push_back(comphelper::makePropertyValue("Surround", rAppendContext.pLastParagraphProperties->GetWrap())); + uno::Sequence<beans::PropertyValue> aGrabBag(comphelper::InitPropertySequence( + { { "ParaFrameProperties", + uno::Any(rAppendContext.pLastParagraphProperties->IsFrameMode()) } })); + aFrameProperties.push_back(comphelper::makePropertyValue("FrameInteropGrabBag", aGrabBag)); - lcl_MoveBorderPropertiesToFrame(aFrameProperties, - rAppendContext.pLastParagraphProperties->GetStartingRange(), - rAppendContext.pLastParagraphProperties->GetEndingRange()); - } + lcl_MoveBorderPropertiesToFrame(aFrameProperties, + rAppendContext.pLastParagraphProperties->GetStartingRange(), + rAppendContext.pLastParagraphProperties->GetEndingRange()); //frame conversion has to be executed after table conversion RegisterFrameConversion(