include/oox/export/ThemeExport.hxx | 38 +++++ oox/Library_oox.mk | 1 oox/source/export/ThemeExport.cxx | 263 +++++++++++++++++++++++++++++++++++++ 3 files changed, 302 insertions(+)
New commits: commit 04bbabc89852b067b5e4461041269a50851436bb Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Mon Dec 12 22:18:43 2022 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Jan 16 05:22:06 2023 +0000 oox: add ThemeExport that exports a svx::Theme into theme.xml file Adds ThemeExport that takes a svx::Theme as input and exports that into a theme.xml file in the OOXML document. Currently supports exporting of color schemes and font schemes. Format schemes are hard-coded for now. The ThemeExport isn't yet used in any actual export functionality. Change-Id: I5ca9c256da65be77e7192be7d66c73d26d78ebd8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143996 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit 958d4667e361a1d8461889117ca830a5da85d0ee) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145398 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/include/oox/export/ThemeExport.hxx b/include/oox/export/ThemeExport.hxx new file mode 100644 index 000000000000..02f222cadafe --- /dev/null +++ b/include/oox/export/ThemeExport.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> +#include <oox/dllapi.h> +#include <oox/core/xmlfilterbase.hxx> +#include <svx/ColorSets.hxx> + +namespace oox +{ +class OOX_DLLPUBLIC ThemeExport +{ +private: + oox::core::XmlFilterBase* mpFilterBase; + +public: + ThemeExport(oox::core::XmlFilterBase* pFilterBase); + + void write(OUString const& rPath, svx::Theme const& rTheme); + +private: + static bool writeColorSet(sax_fastparser::FSHelperPtr pFS, svx::Theme const& rTheme); + static bool writeFontScheme(sax_fastparser::FSHelperPtr pFS, + svx::FontScheme const& rFontScheme); + static bool writeFormatScheme(sax_fastparser::FSHelperPtr pFS); +}; + +} // end namespace oox + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk index 7fd4d91be2e0..4f6a538860ef 100644 --- a/oox/Library_oox.mk +++ b/oox/Library_oox.mk @@ -223,6 +223,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\ oox/source/export/DMLPresetShapeExport \ oox/source/export/shapes \ oox/source/export/vmlexport \ + oox/source/export/ThemeExport \ oox/source/helper/attributelist \ oox/source/helper/binaryinputstream \ oox/source/helper/binaryoutputstream \ diff --git a/oox/source/export/ThemeExport.cxx b/oox/source/export/ThemeExport.cxx new file mode 100644 index 000000000000..f11b894f924a --- /dev/null +++ b/oox/source/export/ThemeExport.cxx @@ -0,0 +1,263 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <oox/export/ThemeExport.hxx> + +#include <oox/token/namespaces.hxx> +#include <oox/token/properties.hxx> +#include <oox/token/tokens.hxx> +#include <oox/export/utils.hxx> +#include <sax/fshelper.hxx> +#include <sax/fastattribs.hxx> +#include <unordered_map> + +namespace oox +{ +ThemeExport::ThemeExport(oox::core::XmlFilterBase* pFilterBase) + : mpFilterBase(pFilterBase) + +{ +} + +void ThemeExport::write(OUString const& rPath, svx::Theme const& rTheme) +{ + sax_fastparser::FSHelperPtr pFS = mpFilterBase->openFragmentStreamWithSerializer( + rPath, "application/vnd.openxmlformats-officedocument.theme+xml"); + + OUString aThemeName = rTheme.GetName(); + + pFS->startElementNS(XML_a, XML_theme, FSNS(XML_xmlns, XML_a), + mpFilterBase->getNamespaceURL(OOX_NS(dml)), XML_name, aThemeName); + + pFS->startElementNS(XML_a, XML_themeElements); + + const svx::ColorSet* pColorSet = rTheme.GetColorSet(); + + pFS->startElementNS(XML_a, XML_clrScheme, XML_name, pColorSet->getName()); + writeColorSet(pFS, rTheme); + pFS->endElementNS(XML_a, XML_clrScheme); + + svx::FontScheme const& rFontScheme = rTheme.getFontScheme(); + pFS->startElementNS(XML_a, XML_fontScheme, XML_name, rFontScheme.getName()); + writeFontScheme(pFS, rFontScheme); + pFS->endElementNS(XML_a, XML_fontScheme); + + pFS->startElementNS(XML_a, XML_fmtScheme); + writeFormatScheme(pFS); + pFS->endElementNS(XML_a, XML_fmtScheme); + + pFS->endElementNS(XML_a, XML_themeElements); + pFS->endElementNS(XML_a, XML_theme); + + pFS->endDocument(); +} + +namespace +{ +void fillAttrList(rtl::Reference<sax_fastparser::FastAttributeList> const& pAttrList, + svx::ThemeFont const& rThemeFont) +{ + pAttrList->add(XML_typeface, rThemeFont.maTypeface); + pAttrList->add(XML_panose, rThemeFont.maPanose); + pAttrList->add(XML_pitchFamily, OString::number(rThemeFont.getPitchFamily())); + pAttrList->add(XML_charset, OString::number(rThemeFont.maCharset)); +} + +} // end anonymous ns + +bool ThemeExport::writeFontScheme(sax_fastparser::FSHelperPtr pFS, + svx::FontScheme const& rFontScheme) +{ + pFS->startElementNS(XML_a, XML_majorFont); + + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMajorLatin()); + pFS->singleElementNS(XML_a, XML_latin, aAttrList); + } + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMajorAsian()); + pFS->singleElementNS(XML_a, XML_ea, aAttrList); + } + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMajorComplex()); + pFS->singleElementNS(XML_a, XML_cs, aAttrList); + } + + pFS->endElementNS(XML_a, XML_majorFont); + + pFS->startElementNS(XML_a, XML_minorFont); + + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMinorLatin()); + pFS->singleElementNS(XML_a, XML_latin, aAttrList); + } + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMinorAsian()); + pFS->singleElementNS(XML_a, XML_ea, aAttrList); + } + { + auto aAttrList = sax_fastparser::FastSerializerHelper::createAttrList(); + fillAttrList(aAttrList, rFontScheme.getMinorComplex()); + pFS->singleElementNS(XML_a, XML_cs, aAttrList); + } + + pFS->endElementNS(XML_a, XML_minorFont); + + return true; +} + +bool ThemeExport::writeFormatScheme(sax_fastparser::FSHelperPtr pFS) +{ + // Format Scheme: 3 or more per list but only 3 will be used currently + pFS->startElementNS(XML_a, XML_fillStyleLst); + { + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + } + pFS->endElementNS(XML_a, XML_fillStyleLst); + + pFS->startElementNS(XML_a, XML_lnStyleLst); + { + pFS->startElementNS(XML_a, XML_ln, XML_w, "6350", XML_cap, "flat", XML_cmpd, "sng", + XML_algn, "ctr"); + { + pFS->startElementNS(XML_a, XML_solidFill); + pFS->startElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->singleElementNS(XML_a, XML_shade, XML_val, "95000"); + pFS->endElementNS(XML_a, XML_schemeClr); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->singleElementNS(XML_a, XML_prstDash, XML_val, "solid"); + + pFS->singleElementNS(XML_a, XML_miter); + } + pFS->endElementNS(XML_a, XML_ln); + } + { + pFS->startElementNS(XML_a, XML_ln, XML_w, "6350", XML_cap, "flat", XML_cmpd, "sng", + XML_algn, "ctr"); + { + pFS->startElementNS(XML_a, XML_solidFill); + pFS->startElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->singleElementNS(XML_a, XML_shade, XML_val, "95000"); + pFS->endElementNS(XML_a, XML_schemeClr); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->singleElementNS(XML_a, XML_prstDash, XML_val, "solid"); + + pFS->singleElementNS(XML_a, XML_miter); + } + pFS->endElementNS(XML_a, XML_ln); + } + { + pFS->startElementNS(XML_a, XML_ln, XML_w, "6350", XML_cap, "flat", XML_cmpd, "sng", + XML_algn, "ctr"); + { + pFS->startElementNS(XML_a, XML_solidFill); + pFS->startElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->singleElementNS(XML_a, XML_shade, XML_val, "95000"); + pFS->endElementNS(XML_a, XML_schemeClr); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->singleElementNS(XML_a, XML_prstDash, XML_val, "solid"); + + pFS->singleElementNS(XML_a, XML_miter); + } + pFS->endElementNS(XML_a, XML_ln); + } + pFS->endElementNS(XML_a, XML_lnStyleLst); + + pFS->startElementNS(XML_a, XML_effectStyleLst); + { + pFS->startElementNS(XML_a, XML_effectStyle); + pFS->singleElementNS(XML_a, XML_effectLst); + pFS->endElementNS(XML_a, XML_effectStyle); + + pFS->startElementNS(XML_a, XML_effectStyle); + pFS->singleElementNS(XML_a, XML_effectLst); + pFS->endElementNS(XML_a, XML_effectStyle); + + pFS->startElementNS(XML_a, XML_effectStyle); + pFS->singleElementNS(XML_a, XML_effectLst); + pFS->endElementNS(XML_a, XML_effectStyle); + } + pFS->endElementNS(XML_a, XML_effectStyleLst); + + pFS->startElementNS(XML_a, XML_bgFillStyleLst); + { + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + + pFS->startElementNS(XML_a, XML_solidFill); + pFS->singleElementNS(XML_a, XML_schemeClr, XML_val, "phClr"); + pFS->endElementNS(XML_a, XML_solidFill); + } + pFS->endElementNS(XML_a, XML_bgFillStyleLst); + + return true; +} + +bool ThemeExport::writeColorSet(sax_fastparser::FSHelperPtr pFS, svx::Theme const& rTheme) +{ + static std::unordered_map<sal_Int32, svx::ThemeColorType> constTokenMap + = { { XML_dk1, svx::ThemeColorType::Dark1 }, + { XML_lt1, svx::ThemeColorType::Light1 }, + { XML_dk2, svx::ThemeColorType::Dark2 }, + { XML_lt2, svx::ThemeColorType::Light2 }, + { XML_accent1, svx::ThemeColorType::Accent1 }, + { XML_accent2, svx::ThemeColorType::Accent2 }, + { XML_accent3, svx::ThemeColorType::Accent3 }, + { XML_accent4, svx::ThemeColorType::Accent4 }, + { XML_accent5, svx::ThemeColorType::Accent5 }, + { XML_accent6, svx::ThemeColorType::Accent6 }, + { XML_hlink, svx::ThemeColorType::Hyperlink }, + { XML_folHlink, svx::ThemeColorType::FollowedHyperlink } }; + + static std::array<sal_Int32, 12> constTokenArray + = { XML_dk1, XML_lt1, XML_dk2, XML_lt2, XML_accent1, XML_accent2, + XML_accent3, XML_accent4, XML_accent5, XML_accent6, XML_hlink, XML_folHlink }; + + const svx::ColorSet* pColorSet = rTheme.GetColorSet(); + if (!pColorSet) + return false; + + for (auto nToken : constTokenArray) + { + svx::ThemeColorType eColorType = constTokenMap[nToken]; + Color aColor = pColorSet->getColor(eColorType); + pFS->startElementNS(XML_a, nToken); + pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(sal_Int32(aColor))); + pFS->endElementNS(XML_a, nToken); + } + + return true; +} + +} // end namespace oox + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */