sw/qa/extras/ooxmlexport/data/tdf166325_scheme_color.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport17.cxx | 12 ++ sw/source/filter/ww8/docxattributeoutput.cxx | 59 +++++++++----- 3 files changed, 51 insertions(+), 20 deletions(-)
New commits: commit 43b74c0037b0d1b2ea2f4dc4faa42283addcf483 Author: Aron Budea <[email protected]> AuthorDate: Wed Dec 10 13:01:58 2025 +1030 Commit: Xisco Fauli <[email protected]> CommitDate: Fri Dec 12 09:01:42 2025 +0100 tdf#166325 sw: use correct type when exporting scheme color to DOCX OOXML schemeClr element has a different type (ST_SchemeColorVal) compared to themeColor's ST_ThemeColor type, eg. dk1 instead of dark1, but commit baf179188d8b9e29188387fd4b7d887dd3168792 mapped them to the same values on export, causing some affected files to become invalid. Change-Id: Iff63aea8943be905c9afbb68012db320cc94eeb9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195346 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Jenkins Reviewed-by: Aron Budea <[email protected]> (cherry picked from commit d5136e0b6059435356351cf2c54af61401e45fc2) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195507 Reviewed-by: Xisco Fauli <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/data/tdf166325_scheme_color.docx b/sw/qa/extras/ooxmlexport/data/tdf166325_scheme_color.docx new file mode 100644 index 000000000000..76928834f205 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf166325_scheme_color.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx index 0afb04e1ca98..ca5f5d35c0fe 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx @@ -1112,6 +1112,18 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf149200) assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/w:rPr/w:color", "themeColor", u"dark1"); } +CPPUNIT_TEST_FIXTURE(Test, testTdf166325_scheme_color) +{ + createSwDoc("tdf166325_scheme_color.docx"); + save(TestFilter::DOCX); + + xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); + // Without the fix this would be "light2" (type ST_ThemeColor instead of ST_SchemeColorVal) + assertXPath(pXmlDoc, + "/w:document/w:body/w:p/w:r/w:rPr/w14:textFill/w14:solidFill/w14:schemeClr", "val", + u"lt2"); +} + DECLARE_OOXMLEXPORT_TEST(testTdf149313, "tdf149313.docx") { // only 2, but not 3 pages in document diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index f0986e3353de..3fd2af4b63ad 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -301,50 +301,69 @@ auto detachFrom(rtl::Reference<sax_fastparser::FastAttributeList>& src) return rtl::Reference(std::move(src)); } -constexpr auto constThemeColorTypeTokenMap = frozen::make_unordered_map<model::ThemeColorType, const char*>({ - { model::ThemeColorType::Dark1, "dark1" }, - { model::ThemeColorType::Light1, "light1" }, - { model::ThemeColorType::Dark2, "dark2" }, - { model::ThemeColorType::Light2, "light2" }, - { model::ThemeColorType::Accent1, "accent1" }, - { model::ThemeColorType::Accent2, "accent2" }, - { model::ThemeColorType::Accent3, "accent3" }, - { model::ThemeColorType::Accent4, "accent4" }, - { model::ThemeColorType::Accent5, "accent5" }, - { model::ThemeColorType::Accent6, "accent6" }, - { model::ThemeColorType::Hyperlink, "hyperlink" }, - { model::ThemeColorType::FollowedHyperlink, "followedHyperlink" } +struct ThemeSchemeName +{ + const char* ThemeName; + const char* SchemeName; +}; + +constexpr auto constThemeColorTypeTokenMap = frozen::make_unordered_map<model::ThemeColorType, const ThemeSchemeName>({ + { model::ThemeColorType::Dark1, { "dark1", "dk1" } }, + { model::ThemeColorType::Light1, { "light1", "lt1" } }, + { model::ThemeColorType::Dark2, {"dark2", "dk2" } }, + { model::ThemeColorType::Light2, {"light2", "lt2" } }, + { model::ThemeColorType::Accent1, {"accent1", "accent1" } }, + { model::ThemeColorType::Accent2, {"accent2", "accent2" } }, + { model::ThemeColorType::Accent3, {"accent3", "accent3" } }, + { model::ThemeColorType::Accent4, {"accent4", "accent4" } }, + { model::ThemeColorType::Accent5, {"accent5", "accent5" } }, + { model::ThemeColorType::Accent6, {"accent6", "accent6" } }, + { model::ThemeColorType::Hyperlink, {"hyperlink", "hlink" } }, + { model::ThemeColorType::FollowedHyperlink, {"followedHyperlink", "folHlink" } } }); -OString lclGetSchemeType(model::ComplexColor const& rComplexColor) +// Returns colors as OOXML ST_ThemeColor or ST_SchemeColorVal types, which are very similar +OString lclGetThemeOrSchemeType(model::ComplexColor const& rComplexColor, bool bIsTheme = true) { const auto iter = constThemeColorTypeTokenMap.find(rComplexColor.getThemeColorType()); assert(iter != constThemeColorTypeTokenMap.end()); - OString sSchemeType = iter->second; + OString sSchemeType = bIsTheme ? iter->second.ThemeName : iter->second.SchemeName; if (rComplexColor.getThemeColorUsage() == model::ThemeColorUsage::Text) { if (rComplexColor.getThemeColorType() == model::ThemeColorType::Dark1) - sSchemeType = "text1"_ostr; + sSchemeType = bIsTheme ? "text1"_ostr : "tx1"_ostr; else if (rComplexColor.getThemeColorType() == model::ThemeColorType::Dark2) - sSchemeType = "text2"_ostr; + sSchemeType = bIsTheme ? "text2"_ostr : "tx2"_ostr; } else if (rComplexColor.getThemeColorUsage() == model::ThemeColorUsage::Background) { if (rComplexColor.getThemeColorType() == model::ThemeColorType::Light1) - sSchemeType = "background1"_ostr; + sSchemeType = bIsTheme ? "background1"_ostr : "bg1"_ostr; else if (rComplexColor.getThemeColorType() == model::ThemeColorType::Light2) - sSchemeType = "background2"_ostr; + sSchemeType = bIsTheme ? "background2"_ostr : "bg2"_ostr; } return sSchemeType; } +// Returns colors as OOXML ST_ThemeColor type +OString lclGetThemeType(model::ComplexColor const& rComplexColor) +{ + return lclGetThemeOrSchemeType(rComplexColor, true); +} + +// Return colors as OOXML ST_SchemeColorVal type for Scheme Color element +OString lclGetSchemeType(model::ComplexColor const& rComplexColor) +{ + return lclGetThemeOrSchemeType(rComplexColor, false); +} + void lclAddThemeValuesToCustomAttributes( rtl::Reference<sax_fastparser::FastAttributeList>& pAttrList, model::ComplexColor const& rComplexColor, sal_Int32 nThemeAttrId, sal_Int32 nThemeTintAttrId, sal_Int32 nThemeShadeAttrId) { if (rComplexColor.isValidThemeType()) { - OString sSchemeType = lclGetSchemeType(rComplexColor); + OString sSchemeType = lclGetThemeType(rComplexColor); DocxAttributeOutput::AddToAttrList(pAttrList, FSNS(XML_w, nThemeAttrId), sSchemeType);
