editeng/source/items/svxfont.cxx | 6 + include/editeng/svxfont.hxx | 3 sw/qa/extras/ooxmlexport/data/tdf43767_caseMapNumbering.odt |binary sw/qa/extras/ooxmlexport/ooxmlexport21.cxx | 66 ++++++++++++ sw/source/core/text/inftxt.cxx | 3 sw/source/core/text/txtfld.cxx | 8 + 6 files changed, 85 insertions(+), 1 deletion(-)
New commits: commit 5c6c6a73e9c58ad934a4f89505d5b3e2b781e0b9 Author: Justin Luth <jl...@mail.com> AuthorDate: Mon Jun 24 13:12:59 2024 -0400 Commit: Justin Luth <jl...@mail.com> CommitDate: Fri Jun 28 01:24:36 2024 +0200 tdf#43767 mso-format layout: no smallcaps applied to numbering If the paragraph marker is formatted as Uppercase, then Uppercase is applied to that line's numbering as well. However, if the marker is formatted as SmallCaps, it MUST NOT be applied for MSO formats. Apparently MSO only supports Uppercase and SmallCaps, not Lowercase or Titlease. I don't like these adhoc exceptions, so I didn't attempt to apply them to ODF formats. Let's keep it simple for ODF - any char format that applies to the entire paragraph should apply to numbering as well (except for the existing underline/overline exceptions). - if you don't like that char attributes apply at all, blame MSO. - if you don't like that DOCX is missing your goofy formatting, blame MSO for being inconsistent. ooxmlexport12's tdf143384_tableInFoot_negativeMargins.docx is almost interesting because it applies superscript and small caps. However, the list is already uppercase, so it can't be used for the test. make CppunitTest_sw_ooxmlexport21 \ CPPUNIT_TEST_NAME=testTdf43767_caseMapNumbering Change-Id: I273baebc996adfd001e1c591dbb9aef9272a42f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169476 Reviewed-by: Justin Luth <jl...@mail.com> Tested-by: Jenkins diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx index 2df18feb449f..3bd2c8086c07 100644 --- a/editeng/source/items/svxfont.cxx +++ b/editeng/source/items/svxfont.cxx @@ -670,6 +670,12 @@ SvxFont& SvxFont::operator=( const SvxFont& rFont ) return *this; } +bool SvxFont::SvxFontSubsetEquals(const SvxFont& rFont) const +{ + return nEsc == rFont.GetEscapement() && nPropr == rFont.GetPropr() + && eCaseMap == rFont.GetCaseMap(); +} + namespace { class SvxDoGetCapitalSize : public SvxDoCapitals diff --git a/include/editeng/svxfont.hxx b/include/editeng/svxfont.hxx index 126b56f8f65f..9061ffe398d2 100644 --- a/include/editeng/svxfont.hxx +++ b/include/editeng/svxfont.hxx @@ -113,6 +113,9 @@ public: SvxFont& operator=( const SvxFont& rFont ); SvxFont& operator=( const Font& rFont ); + + // returns true if the SvxFont's own properties are equal (the SvxFont portion of an operator==) + bool SvxFontSubsetEquals(const SvxFont& rFont) const; }; #endif // INCLUDED_EDITENG_SVXFONT_HXX diff --git a/sw/qa/extras/ooxmlexport/data/tdf43767_caseMapNumbering.odt b/sw/qa/extras/ooxmlexport/data/tdf43767_caseMapNumbering.odt new file mode 100644 index 000000000000..9b9c9a299503 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf43767_caseMapNumbering.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx index 43dff8ae68cf..9ef569e47683 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx @@ -327,6 +327,72 @@ DECLARE_OOXMLEXPORT_TEST(testTdf158597, "tdf158597.docx") } } +DECLARE_OOXMLEXPORT_TEST(testTdf43767_caseMapNumbering, "tdf43767_caseMapNumbering.odt") +{ + // given a document with 2 numbered Lists [each entry restarts numbering for visual comparison] + xmlDocUniquePtr pDump = parseLayoutDump(); + + // using the relative width difference between "A)" and "a)" as the test comparison + // since ListLabelString etc. does not output the actual string that is displayed on the screen + + // When the entire paragraph has a certain character attribute, that property is also applied + // to the list numbering itself (with some differing exceptions) for both ODT and DOCX. + + // ESTABLISH A BASELINE: these baseline paragraphs have no special character attributes. + // Paragraph 1/list 1(uppercase): no formatting applied to list numbering. Width is 253 for me + const sal_Int32 nUpperCaseWidth + = getXPath(pDump, "//body/txt[1]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + // Paragraph 4/list 2(lowercase): no formatting applied to list numbering. Width is 186 for me. + const sal_Int32 nLowerCaseWidth + = getXPath(pDump, "//body/txt[5]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + + // UPPERCASE LIST + // Paragraph 2: ODF should honour "lowercase". MSO doesn't know about lowercase + sal_Int32 nWidth + = getXPath(pDump, "//body/txt[2]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT_EQUAL(isExported() ? nUpperCaseWidth : nLowerCaseWidth, nWidth); + + // Paragraph 3: ODF should honour "superscript" (for consistency). MSO ignores superscript + nWidth = getXPath(pDump, "//body/txt[3]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + if (!isExported()) + CPPUNIT_ASSERT_LESS(nLowerCaseWidth, nWidth); + else + CPPUNIT_ASSERT_EQUAL(nUpperCaseWidth, nWidth); + + // LOWERCASE LIST + //Paragraph 6: ODF should honour "titlecase". MSO doesn't know about titlecase + nWidth = getXPath(pDump, "//body/txt[6]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT_EQUAL(isExported() ? nLowerCaseWidth : nUpperCaseWidth, nWidth); + + // Paragraph 7: ODF should honour "smallcaps". MSO apparently has an exception for small caps + nWidth = getXPath(pDump, "//body/txt[7]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + if (!isExported()) + { + CPPUNIT_ASSERT_GREATER(nLowerCaseWidth, nWidth); + CPPUNIT_ASSERT_LESS(nUpperCaseWidth, nWidth); + } + else + CPPUNIT_ASSERT_EQUAL(nLowerCaseWidth, nWidth); + + // Paragraph 8: ODF should honour "uppercase". MSO also honours uppercase + nWidth = getXPath(pDump, "//body/txt[8]/SwParaPortion/SwLineLayout/SwFieldPortion"_ostr, + "width"_ostr) + .toInt32(); + CPPUNIT_ASSERT_EQUAL(nUpperCaseWidth, nWidth); +} + DECLARE_OOXMLEXPORT_TEST(testTdf156105_percentSuffix, "tdf156105_percentSuffix.odt") { // given a numbered list with a non-escaping percent symbol in the prefix and suffix diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx index a8222328e1ae..5f9ac5597934 100644 --- a/sw/source/core/text/inftxt.cxx +++ b/sw/source/core/text/inftxt.cxx @@ -2155,7 +2155,8 @@ SwFontSave::SwFontSave(const SwTextSizeInfo &rInf, SwFont *pNew, ( ! pNew->GetBackColor() && pFnt->GetBackColor() ) || ( pNew->GetBackColor() && ! pFnt->GetBackColor() ) || ( pNew->GetBackColor() && pFnt->GetBackColor() && - ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) ) + ( *pNew->GetBackColor() != *pFnt->GetBackColor() ) ) + || !pNew->GetActualFont().SvxFontSubsetEquals(pFnt->GetActualFont())) { pNew->SetTransparent( true ); pNew->SetAlign( ALIGN_BASELINE ); diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index e3abe96cab00..43e4b9e906de 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -55,6 +55,7 @@ #include <svl/grabbagitem.hxx> #include <svl/itemiter.hxx> #include <svl/whiter.hxx> +#include <editeng/cmapitem.hxx> #include <editeng/colritem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/crossedoutitem.hxx> @@ -396,6 +397,13 @@ static void checkApplyParagraphMarkFormatToNumbering(SwFont* pNumFnt, SwTextForm pCleanedSet->ClearItem(pItem->Which()); } } + else if (pItem->Which() == RES_CHRATR_CASEMAP) + { + SvxCaseMap eCaseMap = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap(); + // MS only knows about "all caps" and "small caps". Small caps is not set on numbering + if (eCaseMap == SvxCaseMap::SmallCaps) + pCleanedSet->ClearItem(pItem->Which()); + } pItem = aIter.NextItem(); };