include/oox/drawingml/ThemeFilterBase.hxx | 55 + include/oox/drawingml/themefragmenthandler.hxx | 1 oox/Library_oox.mk | 1 oox/source/drawingml/ThemeFilterBase.cxx | 45 + oox/source/drawingml/themefragmenthandler.cxx | 56 - oox/source/shape/ShapeContextHandler.cxx | 4 solenv/clang-format/excludelist | 1 sw/qa/core/theme/ThemeTest.cxx | 45 + writerfilter/Library_writerfilter.mk | 3 writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 writerfilter/source/dmapper/DomainMapper.cxx | 27 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 8 writerfilter/source/dmapper/DomainMapper_Impl.hxx | 19 writerfilter/source/dmapper/ThemeHandler.cxx | 422 +++++++++ writerfilter/source/dmapper/ThemeHandler.hxx | 35 writerfilter/source/dmapper/ThemeTable.cxx | 563 ------------- writerfilter/source/dmapper/ThemeTable.hxx | 58 - writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 14 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 9 writerfilter/source/ooxml/OOXMLFactory.hxx | 2 writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.cxx | 69 + writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.hxx | 46 + writerfilter/source/ooxml/model.xml | 2 23 files changed, 812 insertions(+), 676 deletions(-)
New commits: commit 53731e084ecb5991ed02dc633f180442f91e69cf Author: Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk> AuthorDate: Tue Dec 6 17:33:44 2022 +0900 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Mon Jan 16 00:22:39 2023 +0000 sw: read theme from OOXML file and set it to the draw page This change extends writerfilter to use oox::ThemeFragmentHandler to read the theme properties, and sets that to the one and only draw page of a Writer document. This change also removes ThemeTable and replaces it with the ThemeHandler, which takes theme font data from svx::Theme instead. In addition, a test has been writen, which loads a document with a theme, and asserts the draw page has the theme and the theme properties currently supported. Change-Id: Iff0048cd21ea030ac55287707852acc463ec3cb0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143699 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> (cherry picked from commit 312100003fc7cae358038aaec853584782c698f8) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145388 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/include/oox/drawingml/ThemeFilterBase.hxx b/include/oox/drawingml/ThemeFilterBase.hxx new file mode 100644 index 000000000000..f9bbef1de11e --- /dev/null +++ b/include/oox/drawingml/ThemeFilterBase.hxx @@ -0,0 +1,55 @@ +/* -*- 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 <memory> +#include <oox/dllapi.h> +#include <oox/core/xmlfilterbase.hxx> +#include <oox/drawingml/drawingmltypes.hxx> +#include <rtl/ref.hxx> + +namespace oox::drawingml +{ +class OOX_DLLPUBLIC ThemeFilterBase final : public core::XmlFilterBase +{ +public: + typedef rtl::Reference<ThemeFilterBase> Pointer_t; + + explicit ThemeFilterBase(css::uno::Reference<css::uno::XComponentContext> const& rxContext); + + virtual ~ThemeFilterBase() override; + + /** Has to be implemented by each filter, returns the current theme. */ + virtual const oox::drawingml::Theme* getCurrentTheme() const override; + + void setCurrentTheme(const oox::drawingml::ThemePtr& pTheme); + + /** Has to be implemented by each filter to return the collection of VML shapes. */ + virtual oox::vml::Drawing* getVmlDrawing() override; + + /** Has to be implemented by each filter to return TableStyles. */ + virtual oox::drawingml::table::TableStyleListPtr getTableStyles() override; + + virtual oox::drawingml::chart::ChartConverter* getChartConverter() override; + + virtual oox::ole::VbaProject* implCreateVbaProject() const override; + + virtual bool importDocument() override { return true; } + virtual bool exportDocument() override { return false; } + +private: + virtual OUString SAL_CALL getImplementationName() override; + + oox::drawingml::ThemePtr mpTheme; +}; + +} // namespace oox::drawingml + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/oox/drawingml/themefragmenthandler.hxx b/include/oox/drawingml/themefragmenthandler.hxx index e433c350de80..918a3eb861b9 100644 --- a/include/oox/drawingml/themefragmenthandler.hxx +++ b/include/oox/drawingml/themefragmenthandler.hxx @@ -44,6 +44,7 @@ public: virtual ~ThemeFragmentHandler() override; virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; + void onStartElement(const AttributeList& rAttribs) override; private: Theme& mrTheme; diff --git a/oox/Library_oox.mk b/oox/Library_oox.mk index c88b558ec209..7fd4d91be2e0 100644 --- a/oox/Library_oox.mk +++ b/oox/Library_oox.mk @@ -211,6 +211,7 @@ $(eval $(call gb_Library_add_exception_objects,oox,\ oox/source/drawingml/themeelementscontext \ oox/source/drawingml/themefragmenthandler \ oox/source/drawingml/ThemeOverrideFragmentHandler \ + oox/source/drawingml/ThemeFilterBase \ oox/source/drawingml/transform2dcontext \ oox/source/dump/dffdumper \ oox/source/dump/dumperbase \ diff --git a/oox/source/drawingml/ThemeFilterBase.cxx b/oox/source/drawingml/ThemeFilterBase.cxx new file mode 100644 index 000000000000..b1e23de4296c --- /dev/null +++ b/oox/source/drawingml/ThemeFilterBase.cxx @@ -0,0 +1,45 @@ +/* -*- 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/drawingml/ThemeFilterBase.hxx> +#include <oox/drawingml/theme.hxx> + +using namespace css; + +namespace oox::drawingml +{ +ThemeFilterBase::ThemeFilterBase(const uno::Reference<uno::XComponentContext>& rxContext) + : XmlFilterBase(rxContext) +{ +} + +ThemeFilterBase::~ThemeFilterBase() = default; + +const oox::drawingml::Theme* ThemeFilterBase::getCurrentTheme() const { return mpTheme.get(); } + +void ThemeFilterBase::setCurrentTheme(const ::oox::drawingml::ThemePtr& pTheme) +{ + mpTheme = pTheme; +} + +oox::vml::Drawing* ThemeFilterBase::getVmlDrawing() { return nullptr; } + +oox::drawingml::table::TableStyleListPtr ThemeFilterBase::getTableStyles() +{ + return oox::drawingml::table::TableStyleListPtr(); +} + +oox::drawingml::chart::ChartConverter* ThemeFilterBase::getChartConverter() { return nullptr; } + +oox::ole::VbaProject* ThemeFilterBase::implCreateVbaProject() const { return nullptr; } + +OUString ThemeFilterBase::getImplementationName() { return OUString(); } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/themefragmenthandler.cxx b/oox/source/drawingml/themefragmenthandler.cxx index 5ab0ee1e6b21..db2d6677567d 100644 --- a/oox/source/drawingml/themefragmenthandler.cxx +++ b/oox/source/drawingml/themefragmenthandler.cxx @@ -38,41 +38,41 @@ ThemeFragmentHandler::~ThemeFragmentHandler() { } -ContextHandlerRef ThemeFragmentHandler::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs) +ContextHandlerRef ThemeFragmentHandler::onCreateContext( sal_Int32 nElement, const AttributeList& /*rAttribs*/) { // CT_OfficeStyleSheet - switch( getCurrentElement() ) + if (getCurrentElement() == A_TOKEN(theme)) { - case XML_ROOT_CONTEXT: - switch( nElement ) - { - case A_TOKEN( theme ): - { - mrTheme.setThemeName(rAttribs.getString(XML_name).get()); - return this; - } - } - break; - - case A_TOKEN( theme ): - switch( nElement ) - { - case A_TOKEN( themeElements ): // CT_BaseStyles - return new ThemeElementsContext( *this, mrTheme ); - case A_TOKEN( objectDefaults ): // CT_ObjectStyleDefaults - return new objectDefaultContext( *this, mrTheme ); - case A_TOKEN( extraClrSchemeLst ): // CT_ColorSchemeList - return nullptr; - case A_TOKEN( custClrLst ): // CustomColorList - return nullptr; - case A_TOKEN( ext ): // CT_OfficeArtExtension - return nullptr; - } - break; + switch(nElement) + { + case A_TOKEN( themeElements ): // CT_BaseStyles + return new ThemeElementsContext( *this, mrTheme ); + case A_TOKEN( objectDefaults ): // CT_ObjectStyleDefaults + return new objectDefaultContext( *this, mrTheme ); + case A_TOKEN( extraClrSchemeLst ): // CT_ColorSchemeList + return nullptr; + case A_TOKEN( custClrLst ): // CustomColorList + return nullptr; + case A_TOKEN( ext ): // CT_OfficeArtExtension + return nullptr; + } + } + else if (getCurrentElement() == XML_ROOT_CONTEXT) + { + return this; } + return nullptr; } +void ThemeFragmentHandler::onStartElement(const AttributeList& rAttribs) +{ + if (getCurrentElement() == A_TOKEN(theme)) + { + mrTheme.setThemeName(rAttribs.getStringDefaulted(XML_name)); + } +} + } // namespace oox::drawingml /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index 5404cc82fe81..09b7d8613ce9 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -282,6 +282,10 @@ void SAL_CALL ShapeContextHandler::startFastElement mxShapeFilterBase->setCurrentTheme(mpThemePtr); } } + else if (mpThemePtr && !mxShapeFilterBase->getCurrentTheme()) + { + mxShapeFilterBase->setCurrentTheme(mpThemePtr); + } createFastChildContext(Element, Attribs); } diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index e32a452a98d0..20dccb11bd8b 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -15514,7 +15514,6 @@ writerfilter/source/dmapper/TagLogger.hxx writerfilter/source/dmapper/TblStylePrHandler.cxx writerfilter/source/dmapper/TblStylePrHandler.hxx writerfilter/source/dmapper/TextEffectsHandler.cxx -writerfilter/source/dmapper/ThemeTable.cxx writerfilter/source/dmapper/TrackChangesHandler.cxx writerfilter/source/dmapper/WrapPolygonHandler.cxx writerfilter/source/ooxml/Handler.cxx diff --git a/sw/qa/core/theme/ThemeTest.cxx b/sw/qa/core/theme/ThemeTest.cxx index 356fafdb9aa4..0d3816e9a623 100644 --- a/sw/qa/core/theme/ThemeTest.cxx +++ b/sw/qa/core/theme/ThemeTest.cxx @@ -11,6 +11,11 @@ #include <memory> #include <docsh.hxx> +#include <unotxdoc.hxx> +#include <wrtsh.hxx> +#include <drawdoc.hxx> +#include <IDocumentDrawModelAccess.hxx> +#include <svx/svdpage.hxx> constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/core/theme/data/"; @@ -26,6 +31,46 @@ CPPUNIT_TEST_FIXTURE(SwCoreThemeTest, testThemeColorInHeading) CPPUNIT_ASSERT_EQUAL(sal_Int16(4), getProperty<sal_Int16>(getParagraph(1), "CharColorTheme")); } +CPPUNIT_TEST_FIXTURE(SwCoreThemeTest, testDrawPageThemeExists) +{ + SwDoc* pDoc = createSwDoc(DATA_DIRECTORY, "ThemeColorInHeading.docx"); + CPPUNIT_ASSERT(pDoc); + + SdrPage* pPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + svx::Theme* pTheme = pPage->getSdrPageProperties().GetTheme(); + CPPUNIT_ASSERT(pTheme); + CPPUNIT_ASSERT_EQUAL(OUString(u"Office Theme"), pTheme->GetName()); + + svx::ColorSet* pColorSet = pTheme->GetColorSet(); + CPPUNIT_ASSERT(pColorSet); + CPPUNIT_ASSERT_EQUAL(OUString(u"Orange"), pColorSet->getName()); + + CPPUNIT_ASSERT_EQUAL(Color(0xE48312), pTheme->GetColor(svx::ThemeColorType::Accent1)); + CPPUNIT_ASSERT_EQUAL(Color(0xBD582C), pTheme->GetColor(svx::ThemeColorType::Accent2)); + CPPUNIT_ASSERT_EQUAL(Color(0x865640), pTheme->GetColor(svx::ThemeColorType::Accent3)); + CPPUNIT_ASSERT_EQUAL(Color(0x9B8357), pTheme->GetColor(svx::ThemeColorType::Accent4)); + CPPUNIT_ASSERT_EQUAL(Color(0xC2BC80), pTheme->GetColor(svx::ThemeColorType::Accent5)); + CPPUNIT_ASSERT_EQUAL(Color(0x94A088), pTheme->GetColor(svx::ThemeColorType::Accent6)); + CPPUNIT_ASSERT_EQUAL(Color(0x000000), pTheme->GetColor(svx::ThemeColorType::Dark1)); + CPPUNIT_ASSERT_EQUAL(Color(0x637052), pTheme->GetColor(svx::ThemeColorType::Dark2)); + CPPUNIT_ASSERT_EQUAL(Color(0xFFFFFF), pTheme->GetColor(svx::ThemeColorType::Light1)); + CPPUNIT_ASSERT_EQUAL(Color(0xCCDDEA), pTheme->GetColor(svx::ThemeColorType::Light2)); + + svx::FontScheme const& rFontScheme = pTheme->getFontScheme(); + CPPUNIT_ASSERT_EQUAL(OUString(u"Calibri Light"), rFontScheme.getMajorLatin().maTypeface); + CPPUNIT_ASSERT_EQUAL(OUString(u"Calibri"), rFontScheme.getMinorLatin().maTypeface); + CPPUNIT_ASSERT_EQUAL(true, rFontScheme.getMajorAsian().maTypeface.isEmpty()); + CPPUNIT_ASSERT_EQUAL(true, rFontScheme.getMinorAsian().maTypeface.isEmpty()); + CPPUNIT_ASSERT_EQUAL(true, rFontScheme.getMajorComplex().maTypeface.isEmpty()); + CPPUNIT_ASSERT_EQUAL(true, rFontScheme.getMinorComplex().maTypeface.isEmpty()); + CPPUNIT_ASSERT_EQUAL(size_t(47), rFontScheme.getMajorSupplementalFontList().size()); + CPPUNIT_ASSERT_EQUAL(size_t(47), rFontScheme.getMinorSupplementalFontList().size()); + CPPUNIT_ASSERT_EQUAL(OUString(u"Angsana New"), + rFontScheme.findMajorSupplementalTypeface(u"Thai")); + CPPUNIT_ASSERT_EQUAL(OUString(u"Cordia New"), + rFontScheme.findMinorSupplementalTypeface(u"Thai")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk index 2b974536557b..a7e8fb756f2a 100644 --- a/writerfilter/Library_writerfilter.mk +++ b/writerfilter/Library_writerfilter.mk @@ -112,7 +112,7 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\ writerfilter/source/dmapper/TagLogger \ writerfilter/source/dmapper/TextEffectsHandler \ writerfilter/source/dmapper/TblStylePrHandler \ - writerfilter/source/dmapper/ThemeTable \ + writerfilter/source/dmapper/ThemeHandler \ writerfilter/source/dmapper/WrapPolygonHandler \ writerfilter/source/dmapper/WriteProtection \ writerfilter/source/dmapper/util \ @@ -123,6 +123,7 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\ writerfilter/source/ooxml/OOXMLDocumentImpl \ writerfilter/source/ooxml/OOXMLFactory \ writerfilter/source/ooxml/OOXMLFastContextHandler \ + writerfilter/source/ooxml/OOXMLFastContextHandlerTheme \ writerfilter/source/ooxml/OOXMLFastDocumentHandler \ writerfilter/source/ooxml/OOXMLParserState \ writerfilter/source/ooxml/OOXMLPropertySet \ diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index 1179be43c8ac..6b47ab752177 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -31,6 +31,7 @@ #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/drawing/XDrawPage.hpp> #include <oox/shape/ShapeContextHandler.hxx> +#include <oox/drawingml/theme.hxx> /** @file OOXMLDocument.hxx @@ -214,6 +215,8 @@ public: virtual const OUString & getTarget() const = 0; virtual rtl::Reference<oox::shape::ShapeContextHandler> getShapeContext( ) = 0; virtual void setShapeContext( rtl::Reference<oox::shape::ShapeContextHandler> xContext ) = 0; + virtual const oox::drawingml::ThemePtr & getTheme() const = 0; + /// Push context of drawingML shapes, so nested shapes are handled separately. virtual void pushShapeContext() = 0; /// Pop context of a previously pushed drawingML shape. diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 938fec5fe76c..555de569fc72 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -375,36 +375,36 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) } break; case NS_ooxml::LN_CT_Fonts_asciiTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeTable::getStringForTheme(nIntValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "asciiTheme", ThemeHandler::getStringForTheme(nIntValue)); if (m_pImpl->GetTopContext()) { // note: overwrite Fonts_ascii with Fonts_asciiTheme *even if* // theme font is empty - this is apparently what Word 2013 does - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); + uno::Any aPropValue = uno::makeAny( m_pImpl->getFontNameForTheme( nIntValue ) ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, aPropValue ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_ASCII, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_ASCII, uno::makeAny( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); } break; case NS_ooxml::LN_CT_Fonts_hAnsi: break;//unsupported case NS_ooxml::LN_CT_Fonts_hAnsiTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeTable::getStringForTheme(nIntValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "hAnsiTheme", ThemeHandler::getStringForTheme(nIntValue)); if (m_pImpl->GetTopContext()) - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_H_ANSI, uno::makeAny( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); break; case NS_ooxml::LN_CT_Fonts_eastAsia: if (m_pImpl->GetTopContext()) m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, uno::makeAny( sStringValue )); break; case NS_ooxml::LN_CT_Fonts_eastAsiaTheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeTable::getStringForTheme(nIntValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "eastAsiaTheme", ThemeHandler::getStringForTheme(nIntValue)); if (m_pImpl->GetTopContext()) { - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); + uno::Any aPropValue = uno::makeAny( m_pImpl->getFontNameForTheme( nIntValue ) ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_ASIAN, aPropValue ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_EAST_ASIA, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_EAST_ASIA, uno::makeAny( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); } break; case NS_ooxml::LN_CT_Fonts_cs: @@ -412,13 +412,13 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, uno::makeAny( sStringValue )); break; case NS_ooxml::LN_CT_Fonts_cstheme: - m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeTable::getStringForTheme(nIntValue)); + m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "cstheme", ThemeHandler::getStringForTheme(nIntValue)); if (m_pImpl->GetTopContext()) { - uno::Any aPropValue = uno::makeAny( m_pImpl->GetThemeTable()->getFontNameForTheme( nIntValue ) ); + uno::Any aPropValue = uno::makeAny( m_pImpl->getFontNameForTheme( nIntValue ) ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME_COMPLEX, aPropValue ); m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_FONT_NAME_CS, aPropValue, true, CHAR_GRAB_BAG ); - m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::makeAny( ThemeTable::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); + m_pImpl->GetTopContext()->Insert(PROP_CHAR_THEME_NAME_CS, uno::makeAny( ThemeHandler::getStringForTheme(nIntValue) ), true, CHAR_GRAB_BAG); } break; case NS_ooxml::LN_CT_Spacing_before: @@ -4140,11 +4140,6 @@ void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t m_pImpl->SetNumberingImport(false); } break; - case NS_ooxml::LN_THEMETABLE: - m_pImpl->GetThemeTable()->setThemeFontLangProperties( - m_pImpl->GetSettingsTable()->GetThemeFontLangProperties() ); - ref->resolve ( *m_pImpl->GetThemeTable() ); - break; case NS_ooxml::LN_settings_settings: ref->resolve ( *m_pImpl->GetSettingsTable() ); m_pImpl->ApplySettingsTable(); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index cd9ab435e23e..425febe87d18 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -8552,6 +8552,14 @@ bool DomainMapper_Impl::handlePreviousParagraphBorderInBetween() const return true; } +OUString DomainMapper_Impl::getFontNameForTheme(const Id id) +{ + auto const& pHandler = getThemeHandler(); + if (pHandler) + return pHandler->getFontNameForTheme(id); + return OUString(); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 23caabf0e254..fea4972933f7 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -33,6 +33,8 @@ #include <vector> #include <optional> +#include <ooxml/OOXMLDocument.hxx> + #include <dmapper/CommentProperties.hxx> #include "DomainMapper.hxx" @@ -43,7 +45,7 @@ #include "NumberingManager.hxx" #include "StyleSheetTable.hxx" #include "SettingsTable.hxx" -#include "ThemeTable.hxx" +#include "ThemeHandler.hxx" #include "GraphicImport.hxx" #include "OLEHandler.hxx" #include "FFDataHandler.hxx" @@ -524,10 +526,10 @@ private: ListsManager::Pointer m_pListTable; std::deque< css::uno::Reference<css::drawing::XShape> > m_aPendingShapes; StyleSheetTablePtr m_pStyleSheetTable; - ThemeTablePtr m_pThemeTable; SettingsTablePtr m_pSettingsTable; GraphicImportPtr m_pGraphicImport; + std::unique_ptr<ThemeHandler> m_pThemeHandler; PropertyMapPtr m_pTopContext; PropertyMapPtr m_pLastSectionContext; @@ -787,11 +789,14 @@ public: } OUString GetListStyleName(sal_Int32 nListId); ListsManager::Pointer const & GetListTable(); - ThemeTablePtr const & GetThemeTable() + + std::unique_ptr<ThemeHandler> const& getThemeHandler() { - if(!m_pThemeTable) - m_pThemeTable = new ThemeTable; - return m_pThemeTable; + if (!m_pThemeHandler && m_pOOXMLDocument && getDocumentReference()->getTheme()) + { + m_pThemeHandler = std::make_unique<ThemeHandler>(getDocumentReference()->getTheme(), GetSettingsTable()->GetThemeFontLangProperties()); + } + return m_pThemeHandler; } SettingsTablePtr const & GetSettingsTable() @@ -1181,6 +1186,8 @@ public: void commentProps(const OUString& sId, const CommentProperties& rProps); + OUString getFontNameForTheme(const Id id); + private: void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType); // Start a new index section; if needed, finish current paragraph diff --git a/writerfilter/source/dmapper/ThemeHandler.cxx b/writerfilter/source/dmapper/ThemeHandler.cxx new file mode 100644 index 000000000000..555a2b491fcc --- /dev/null +++ b/writerfilter/source/dmapper/ThemeHandler.cxx @@ -0,0 +1,422 @@ +/* -*- 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 "ThemeHandler.hxx" +#include <i18nlangtag/languagetag.hxx> +#include <ooxml/resourceids.hxx> + +using namespace com::sun::star; + +namespace writerfilter::dmapper +{ +namespace +{ +OUString fromLCIDToScriptTag(LanguageType lang) +{ + // conversion list from: + // http://blogs.msdn.com/b/officeinteroperability/archive/2013/04/22/office-open-xml-themes-schemes-and-fonts.aspx + switch (static_cast<sal_uInt16>(lang)) + { + case 0x429: // lidFarsi + case 0x401: // lidArabic + case 0x801: // lidIraq + case 0xc01: // lidEgyptian + case 0x1001: // lidLibya + case 0x1401: // lidAlgerian + case 0x1801: // lidMorocco + case 0x1c01: // lidTunisia + case 0x2001: // lidOman + case 0x2401: // lidYemen + case 0x2801: // lidSyria + case 0x2c01: // lidJordan + case 0x3001: // lidLebanon + case 0x3401: // lidKuwait + case 0x3801: // lidUAE + case 0x3c01: // lidBahrain + case 0x4001: // lidQatar + case 0x420: // lidUrdu + case 0x846: // lidPunjabiPakistan + case 0x859: // lidSindhiPakistan + case 0x45f: // lidTamazight + case 0x460: // lidKashmiri + case 0x463: // lidPashto + case 0x48c: // lidDari + return "Arab"; + case 0x42b: // lidArmenian + return "Armn"; + case 0x445: // lidBengali + case 0x845: // lidBengaliBangladesh + case 0x44d: // lidAssamese + case 0x458: // lidManipuri + return "Beng"; + case 0x45d: // lidInuktitut + return "Cans"; + case 0x45c: // lidCherokee + return "Cher"; + case 0x419: // lidRussian + case 0x402: // lidBulgarian + case 0x281a: // lidSerbianCyrillic + case 0x422: // lidUkranian + case 0x819: // lidRussianMoldavia + case 0xc1a: // lidSerbianCyrillicSerbMont + case 0x1c1a: // lidSerbianBosniaHerzegovinaCyrillic + case 0x201a: // lidBosnianBosniaHerzegovinaCyrillic + case 0x301a: // lidSerbianMontenegroCyrillic + case 0x423: // lidByelorussian + case 0x428: // lidTajik + case 0x82c: // lidAzeriCyrillic + case 0x42f: // lidMacedonian + case 0x43f: // lidKazakh + case 0x440: // lidKyrgyz + case 0x843: // lidUzbekCyrillic + case 0x444: // lidTatar + case 0x450: // lidMongolian + case 0x46d: // lidBashkir + case 0x485: // lidSakha + return "Cyrl"; + case 0x439: // lidHindi + case 0x44e: // lidMarathi + case 0x44f: // lidSanskrit + case 0x457: // lidKonkani + case 0x459: // lidSindhi + case 0x860: // lidKashmiriIndia + case 0x461: // lidNepali + case 0x861: // lidNepaliIndia + return "Deva"; + case 0x45e: // lidAmharic + case 0x473: // lidTigrignaEthiopic + case 0x873: // lidTigrignaEritrea + return "Ethi"; + case 0x437: // lidGeorgian + return "Geor"; + case 0x408: // lidGreek + return "Grek"; + case 0x447: // lidGujarati + return "Gujr"; + case 0x446: // lidPunjabi + return "Guru"; + case 0x412: // lidKoreanExtWansung + return "Hang"; + case 0x804: // lidChineseSimp + case 0x1004: // lidSingapore + return "Hans"; + case 0x404: // lidChineseTrad + case 0xc04: // lidHongkong + case 0x1404: // lidMacau + return "Hant"; + case 0x40d: // lidHebrew + case 0x43d: // lidYiddish + return "Hebr"; + case 0x411: // lidJapanese + return "Jpan"; + case 0x453: // lidKhmer + return "Khmr"; + case 0x44b: // lidKannada + return "Knda"; + case 0x454: // lidLao + return "Laoo"; + case 0x409: // lidAmerican + case 0xc09: // lidAustralian + case 0x809: // lidBritish + case 0x1009: // lidEnglishCanadian + case 0x403: // lidCatalan + case 0x406: // lidDanish + case 0x413: // lidDutch + case 0x813: // lidDutchBelgian + case 0x479: // lidPapiamentu + case 0x40b: // lidFinnish + case 0x40c: // lidFrench + case 0xc0c: // lidFrenchCanadian + case 0x407: // lidGerman + case 0x807: // lidSwissGerman + case 0xc07: // lidAustrianGerman + case 0x1007: // lidGermanLuxembourg + case 0x1407: // lidGermanLiechtenstein + case 0x410: // lidItalian + case 0x414: // lidNorskBokmal + case 0x814: // lidNorskNynorsk + case 0x416: // lidPortBrazil + case 0x816: // lidPortIberian + case 0x40a: // lidSpanish + case 0x41d: // lidSwedish + case 0x405: // lidCzech + case 0x40e: // lidHungarian + case 0x415: // lidPolish + case 0x41f: // lidTurkish + case 0x42d: // lidBasque + case 0x424: // lidSlovenian + case 0x426: // lidLatvian + case 0x427: // lidLithuanian + case 0x418: // lidRomanian + case 0x818: // lidRomanianMoldavia + case 0x241a: // lidSerbianLatin + case 0x41a: // lidCroatian, lidCroat + case 0x491: // lidGaelicScots + case 0x83c: // lidGaelicIrish + case 0x430: // lidSutu + case 0x431: // lidTsonga + case 0x432: // lidTswana + case 0x433: // lidVenda + case 0x434: // lidXhosa + case 0x435: // lidZulu + case 0x436: // lidAfrikaans + case 0x425: // lidEstonian + case 0x456: // lidGalician + case 0x41b: // lidSlovak + case 0x1409: // lidEnglishNewZealand + case 0x1809: // lidEnglishIreland + case 0x1c09: // lidEnglishSouthAfrica + case 0x2009: // lidEnglishJamaica + case 0x2409: // lidEnglishCaribbean + case 0x2809: // lidEnglishBelize + case 0x2c09: // lidEnglishTrinidad + case 0x3009: // lidEnglishZimbabwe + case 0x3409: // lidEnglishPhilippines + case 0x3809: // lidEnglishIndonesia + case 0x3c09: // lidEnglishHongKong + case 0x4009: // lidEnglishIndia + case 0x4409: // lidEnglishMalaysia + case 0x4809: // lidEnglishSingapore + case 0x80a: // lidSpanishMexican, lidMexican + case 0xc0a: // lidSpanishModern + case 0x100a: // lidGuatemala + case 0x140a: // lidCostaRica + case 0x180a: // lidPanama + case 0x1c0a: // lidDominicanRepublic + case 0x200a: // lidSpanishSA, lidVenezuela + case 0x240a: // lidColombia + case 0x280a: // lidPeru + case 0x2c0a: // lidArgentina + case 0x300a: // lidEcuador + case 0x340a: // lidChile + case 0x380a: // lidUruguay + case 0x3c0a: // lidParguay + case 0x400a: // lidBolivia + case 0x440a: // lidElSalvador + case 0x480a: // lidHonduras + case 0x4c0a: // lidNicaragua + case 0x500a: // lidPuertoRico + case 0x540a: // lidSpanishUS + case 0x80c: // lidFrenchBelgian + case 0x100c: // lidFrenchSwiss + case 0x140c: // lidFrenchLuxembourg + case 0x180c: // lidFrenchMonaco + case 0x1c0c: // lidFrenchWestIndies + case 0x200c: // lidFrenchReunion + case 0x240c: // lidFrenchCongoDRC, lidFrenchZaire + case 0x280c: // lidFrenchSenegal + case 0x2c0c: // lidFrenchCameroon + case 0x300c: // lidFrenchCotedIvoire + case 0x340c: // lidFrenchMali + case 0x3c0c: // lidFrenchHaiti + case 0x380c: // lidFrenchMorocco + case 0x40f: // lidIcelandic + case 0x810: // lidItalianSwiss + case 0x417: // lidRhaetoRomanic, lidRomanic + case 0x81a: // lidSerbianLatinSerbMont, lidCroatSerbo + case 0x101a: // lidBosniaHerzegovina + case 0x141a: // lidBosnianBosniaHerzegovinaLatin + case 0x181a: // lidSerbianBosniaHerzegovinaLatin + case 0x2c1a: // lidSerbianMontenegroLatin + case 0x41c: // lidAlbanian + case 0x81d: // lidSwedishFinland + case 0x421: // lidBahasa, lidIndonesian + case 0x42c: // lidAzeriLatin + case 0x42e: // lidSorbian + case 0x82e: // lidLowerSorbian + case 0x438: // lidFaeroese + case 0x43a: // lidMaltese + case 0x43b: // lidSamiLappish + case 0x83b: // lidNorthSamiSwe + case 0xc3b: // lidNorthernSamiFi + case 0x103b: // lidLuleSamiNor + case 0x143b: // lidLuleSamiSwe + case 0x183b: // lidSouthSamiNor + case 0x1c3b: // lidSouthSamiSwe + case 0x203b: // lidSkoltSami + case 0x243b: // lidInariSami + case 0x43e: // lidMalaysian + case 0x83e: // lidMalayBrunei + case 0x441: // lidSwahili + case 0x442: // lidTurkmen + case 0x443: // lidUzbekLatin + case 0x452: // lidWelsh + case 0x85d: // lidInuktitutLatin + case 0x85f: // lidTamazightLatin + case 0x462: // lidFrisian + case 0x464: // lidFilipino + case 0x466: // lidEdo + case 0x467: // lidFulfulde + case 0x468: // lidHausa + case 0x469: // lidIbibio + case 0x46a: // lidYoruba + case 0x46b: // lidQuechuaBol + case 0x86b: // lidQuechuaEcu + case 0xc6b: // lidQuechuaPe + case 0x46c: // lidSesothoSaLeboa + case 0x46e: // lidLuxembourgish + case 0x46f: // lidGreenlandic + case 0x470: // lidIgbo + case 0x471: // lidKanuri + case 0x472: // lidOromo + case 0x474: // lidGuarani + case 0x475: // lidHawaiian + case 0x476: // lidLatin + case 0x477: // lidSomali + case 0x47a: // lidMapudungun + case 0x47c: // lidMohawk + case 0x47e: // lidBreton + case 0x481: // lidMaori + case 0x482: // lidOccitan + case 0x483: // lidCorsican + case 0x484: // lidAlsatian + case 0x486: // lidKiche + case 0x487: // lidKinyarwanda + case 0x488: // lidWolof + return "Latn"; + case 0x44c: // lidMalayalam + return "Mlym"; + case 0x850: // lidMongolianMongo + return "Mong"; + case 0x455: // lidBurmese + return "Mymr"; + case 0x448: // lidOriya + return "Orya"; + case 0x45b: // lidSinhalese + return "Sinh"; + case 0x45a: // lidSyriac + return "Syrc"; + case 0x449: // lidTamil + return "Taml"; + case 0x44a: // lidTelugu + return "Telu"; + case 0x465: // lidMaldivian + return "Thaa"; + case 0x41e: // lidThai + return "Thai"; + case 0x451: // lidTibetan + case 0x851: // lidBhutanese + return "Tibt"; + case 0x480: // lidUighur + return "Uigh"; + case 0x42a: // lidVietnamese + return "Viet"; + case 0x478: // lidYi + return "Yiii"; + default: + return OUString(); + } +} + +OUString fromLocaleToScriptTag(const OUString& sLocale) +{ + return fromLCIDToScriptTag(LanguageTag::convertToLanguageType(sLocale)); +} + +OUString resolveMajorMinorTypeFace(svx::FontScheme const& rFontSheme, const Id id) +{ + switch (id) + { + case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: + return rFontSheme.getMajorAsian().maTypeface; + case NS_ooxml::LN_Value_ST_Theme_majorBidi: + return rFontSheme.getMajorComplex().maTypeface; + case NS_ooxml::LN_Value_ST_Theme_majorAscii: + case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: + return rFontSheme.getMajorLatin().maTypeface; + break; + case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: + return rFontSheme.getMinorAsian().maTypeface; + case NS_ooxml::LN_Value_ST_Theme_minorBidi: + return rFontSheme.getMinorComplex().maTypeface; + case NS_ooxml::LN_Value_ST_Theme_minorAscii: + case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: + return rFontSheme.getMinorLatin().maTypeface; + break; + default: + break; + } + return OUString(); +} + +OUString resolveSupplementalFontList(svx::FontScheme const& rFontSheme, const Id id, + std::u16string_view rLangAsia, std::u16string_view rLangBidi) +{ + switch (id) + { + case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: + return rFontSheme.findMajorSupplementalTypeface(rLangAsia); + case NS_ooxml::LN_Value_ST_Theme_majorBidi: + return rFontSheme.findMajorSupplementalTypeface(rLangBidi); + case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: + return rFontSheme.findMinorSupplementalTypeface(rLangAsia); + case NS_ooxml::LN_Value_ST_Theme_minorBidi: + return rFontSheme.findMinorSupplementalTypeface(rLangBidi); + default: + break; + } + return OUString(); +} + +} // end anonymous namespace + +ThemeHandler::ThemeHandler(oox::drawingml::ThemePtr const& pTheme, + const css::uno::Sequence<css::beans::PropertyValue>& rLangProperties) + : mpTheme(pTheme) +{ + for (const auto& rProperty : rLangProperties) + { + OUString sLocaleName; + rProperty.Value >>= sLocaleName; + if (rProperty.Name == "eastAsia") + maThemeFontLangEastAsia = fromLocaleToScriptTag(sLocaleName); + if (rProperty.Name == "bidi") + maThemeFontLangBidi = fromLocaleToScriptTag(sLocaleName); + } +} + +OUString ThemeHandler::getStringForTheme(const Id id) +{ + switch (id) + { + case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: + return "majorEastAsia"; + case NS_ooxml::LN_Value_ST_Theme_majorBidi: + return "majorBidi"; + case NS_ooxml::LN_Value_ST_Theme_majorAscii: + return "majorAscii"; + case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: + return "majorHAnsi"; + case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: + return "minorEastAsia"; + case NS_ooxml::LN_Value_ST_Theme_minorBidi: + return "minorBidi"; + case NS_ooxml::LN_Value_ST_Theme_minorAscii: + return "minorAscii"; + case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: + return "minorHAnsi"; + } + return OUString(); +} + +OUString ThemeHandler::getFontNameForTheme(const Id id) const +{ + auto pSvxTheme = mpTheme->createSvxTheme(); + svx::FontScheme const& rFontScheme = pSvxTheme->getFontScheme(); + OUString aSupplementalTypeFace = resolveSupplementalFontList( + rFontScheme, id, maThemeFontLangEastAsia, maThemeFontLangBidi); + if (!aSupplementalTypeFace.isEmpty()) + return aSupplementalTypeFace; + OUString aTypeFace = resolveMajorMinorTypeFace(rFontScheme, id); + return aTypeFace; +} + +} //namespace writerfilter + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeHandler.hxx b/writerfilter/source/dmapper/ThemeHandler.hxx new file mode 100644 index 000000000000..8d7574991b29 --- /dev/null +++ b/writerfilter/source/dmapper/ThemeHandler.hxx @@ -0,0 +1,35 @@ +/* -*- 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 <com/sun/star/beans/PropertyValue.hpp> +#include <i18nlangtag/lang.h> +#include <memory> +#include <oox/drawingml/theme.hxx> +#include <ooxml/resourceids.hxx> + +namespace writerfilter::dmapper +{ +class ThemeHandler +{ +private: + oox::drawingml::ThemePtr mpTheme; + OUString maThemeFontLangEastAsia; + OUString maThemeFontLangBidi; + +public: + ThemeHandler(oox::drawingml::ThemePtr const& pTheme, + const css::uno::Sequence<css::beans::PropertyValue>& rLangProperties); + OUString getFontNameForTheme(const Id id) const; + static OUString getStringForTheme(const Id id); +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.cxx b/writerfilter/source/dmapper/ThemeTable.cxx deleted file mode 100644 index 4d6ed2b3bc0f..000000000000 --- a/writerfilter/source/dmapper/ThemeTable.cxx +++ /dev/null @@ -1,563 +0,0 @@ -/* -*- 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/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include "TagLogger.hxx" -#include "ThemeTable.hxx" -#include <i18nlangtag/languagetag.hxx> -#include <ooxml/resourceids.hxx> - -#include <map> - -using namespace com::sun::star; - -namespace writerfilter::dmapper -{ - -struct ThemeTable_Impl -{ - ThemeTable_Impl() : - m_currentThemeFontId(0), - m_supplementalFontId(0) - {} - std::map<sal_uInt32, std::map<sal_uInt32, OUString> > m_themeFontMap; - sal_uInt32 m_currentThemeFontId; - std::map<sal_uInt32, OUString> m_currentFontThemeEntry; - OUString m_supplementalFontName; - sal_uInt32 m_supplementalFontId; - OUString m_themeFontLangEastAsia; - OUString m_themeFontLangBidi; -}; - -ThemeTable::ThemeTable() -: LoggedProperties("ThemeTable") -, LoggedTable("ThemeTable") -, m_pImpl( new ThemeTable_Impl ) -{ - -} - -ThemeTable::~ThemeTable() -{ -} - -void ThemeTable::lcl_attribute(Id Name, Value & val) -{ - OUString sValue = val.getString(); - switch(Name) - { - case NS_ooxml::LN_CT_TextFont_typeface: - if (!sValue.isEmpty()) - m_pImpl->m_currentFontThemeEntry[m_pImpl->m_currentThemeFontId] = sValue; - break; - case NS_ooxml::LN_CT_SupplementalFont_script: - if (!sValue.isEmpty()) - { - if (sValue == m_pImpl->m_themeFontLangBidi) - m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_cs; - else if (sValue == m_pImpl->m_themeFontLangEastAsia) - m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_ea; - } - break; - case NS_ooxml::LN_CT_SupplementalFont_typeface: - if (!sValue.isEmpty()) - m_pImpl->m_supplementalFontName = sValue; - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } - if(m_pImpl->m_supplementalFontId && m_pImpl->m_supplementalFontName.getLength() > 0) - { - m_pImpl->m_currentFontThemeEntry[m_pImpl->m_supplementalFontId] = m_pImpl->m_supplementalFontName; - m_pImpl->m_supplementalFontName.clear(); - m_pImpl->m_supplementalFontId = 0; - } -} - -void ThemeTable::lcl_sprm(Sprm& rSprm) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("ThemeTable.sprm"); - TagLogger::getInstance().chars(rSprm.toString()); -#endif - - m_pImpl->m_supplementalFontName.clear(); - m_pImpl->m_supplementalFontId = 0; - - sal_uInt32 nSprmId = rSprm.getId(); - switch(nSprmId) - { - case NS_ooxml::LN_CT_BaseStyles_fontScheme: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_FontScheme_majorFont: - case NS_ooxml::LN_CT_FontScheme_minorFont: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - m_pImpl->m_currentFontThemeEntry = std::map<sal_uInt32, OUString>(); - if( pProperties ) - pProperties->resolve(*this); - m_pImpl->m_themeFontMap[nSprmId] = m_pImpl->m_currentFontThemeEntry; - } - break; - case NS_ooxml::LN_CT_FontCollection_latin: - case NS_ooxml::LN_CT_FontCollection_ea: - case NS_ooxml::LN_CT_FontCollection_cs: - { - m_pImpl->m_currentThemeFontId = nSprmId; - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if( pProperties ) - pProperties->resolve(*this); - } - break; - case NS_ooxml::LN_CT_FontCollection_font: - { - writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); - if (pProperties ) - pProperties->resolve(*this); - } - break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -void ThemeTable::lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) -{ -#ifdef DBG_UTIL - TagLogger::getInstance().startElement("ThemeTable.entry"); -#endif - - ref->resolve(*this); - -#ifdef DBG_UTIL - TagLogger::getInstance().endElement(); -#endif -} - -OUString ThemeTable::getStringForTheme(const Id id) -{ - switch (id) - { - case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: - return "majorEastAsia"; - case NS_ooxml::LN_Value_ST_Theme_majorBidi: - return "majorBidi"; - case NS_ooxml::LN_Value_ST_Theme_majorAscii: - return "majorAscii"; - case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: - return "majorHAnsi"; - case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: - return "minorEastAsia"; - case NS_ooxml::LN_Value_ST_Theme_minorBidi: - return "minorBidi"; - case NS_ooxml::LN_Value_ST_Theme_minorAscii: - return "minorAscii"; - case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: - return "minorHAnsi"; - } - return OUString(); -} -OUString ThemeTable::getFontNameForTheme(const Id id) const -{ - std::map<sal_uInt32, OUString> tmpThemeFontMap; - switch (id) - { - case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: - case NS_ooxml::LN_Value_ST_Theme_majorBidi: - case NS_ooxml::LN_Value_ST_Theme_majorAscii: - case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: - tmpThemeFontMap = m_pImpl->m_themeFontMap[NS_ooxml::LN_CT_FontScheme_majorFont]; - break; - case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: - case NS_ooxml::LN_Value_ST_Theme_minorBidi: - case NS_ooxml::LN_Value_ST_Theme_minorAscii: - case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: - tmpThemeFontMap = m_pImpl->m_themeFontMap[NS_ooxml::LN_CT_FontScheme_minorFont]; - break; - default: - return OUString(); - } - - switch (id) - { - case NS_ooxml::LN_Value_ST_Theme_majorAscii: - case NS_ooxml::LN_Value_ST_Theme_majorHAnsi: - case NS_ooxml::LN_Value_ST_Theme_minorAscii: - case NS_ooxml::LN_Value_ST_Theme_minorHAnsi: - { - std::map<sal_uInt32, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_latin); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - case NS_ooxml::LN_Value_ST_Theme_majorBidi: - case NS_ooxml::LN_Value_ST_Theme_minorBidi: - { - std::map<sal_uInt32, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_cs); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - case NS_ooxml::LN_Value_ST_Theme_majorEastAsia: - case NS_ooxml::LN_Value_ST_Theme_minorEastAsia: - { - std::map<sal_uInt32, OUString>::const_iterator Iter = tmpThemeFontMap.find(NS_ooxml::LN_CT_FontCollection_ea); - if (Iter != tmpThemeFontMap.end()) - return Iter->second; - return OUString(); - } - default: - return OUString(); - } -} - -void ThemeTable::setThemeFontLangProperties(const uno::Sequence<beans::PropertyValue>& aPropSeq) -{ - for (const auto& rProp : aPropSeq) - { - OUString sLocaleName; - rProp.Value >>= sLocaleName; - if (rProp.Name == "eastAsia") - m_pImpl->m_themeFontLangEastAsia = fromLocaleToScriptTag(sLocaleName); - if (rProp.Name == "bidi") - m_pImpl->m_themeFontLangBidi = fromLocaleToScriptTag(sLocaleName); - - } -} - -OUString ThemeTable::fromLocaleToScriptTag(const OUString& sLocale) -{ - return fromLCIDToScriptTag(LanguageTag::convertToLanguageType(sLocale)); -} - -OUString ThemeTable::fromLCIDToScriptTag(LanguageType lang) -{ - // conversion list from: - // http://blogs.msdn.com/b/officeinteroperability/archive/2013/04/22/office-open-xml-themes-schemes-and-fonts.aspx - switch (static_cast<sal_uInt16>(lang)) - { - case 0x429 : // lidFarsi - case 0x401 : // lidArabic - case 0x801 : // lidIraq - case 0xc01 : // lidEgyptian - case 0x1001 : // lidLibya - case 0x1401 : // lidAlgerian - case 0x1801 : // lidMorocco - case 0x1c01 : // lidTunisia - case 0x2001 : // lidOman - case 0x2401 : // lidYemen - case 0x2801 : // lidSyria - case 0x2c01 : // lidJordan - case 0x3001 : // lidLebanon - case 0x3401 : // lidKuwait - case 0x3801 : // lidUAE - case 0x3c01 : // lidBahrain - case 0x4001 : // lidQatar - case 0x420 : // lidUrdu - case 0x846 : // lidPunjabiPakistan - case 0x859 : // lidSindhiPakistan - case 0x45f : // lidTamazight - case 0x460 : // lidKashmiri - case 0x463 : // lidPashto - case 0x48c : // lidDari - return "Arab"; - case 0x42b : // lidArmenian - return "Armn"; - case 0x445 : // lidBengali - case 0x845 : // lidBengaliBangladesh - case 0x44d : // lidAssamese - case 0x458 : // lidManipuri - return "Beng"; - case 0x45d : // lidInuktitut - return "Cans"; - case 0x45c : // lidCherokee - return "Cher"; - case 0x419 : // lidRussian - case 0x402 : // lidBulgarian - case 0x281a : // lidSerbianCyrillic - case 0x422 : // lidUkranian - case 0x819 : // lidRussianMoldavia - case 0xc1a : // lidSerbianCyrillicSerbMont - case 0x1c1a : // lidSerbianBosniaHerzegovinaCyrillic - case 0x201a : // lidBosnianBosniaHerzegovinaCyrillic - case 0x301a : // lidSerbianMontenegroCyrillic - case 0x423 : // lidByelorussian - case 0x428 : // lidTajik - case 0x82c : // lidAzeriCyrillic - case 0x42f : // lidMacedonian - case 0x43f : // lidKazakh - case 0x440 : // lidKyrgyz - case 0x843 : // lidUzbekCyrillic - case 0x444 : // lidTatar - case 0x450 : // lidMongolian - case 0x46d : // lidBashkir - case 0x485 : // lidSakha - return "Cyrl"; - case 0x439 : // lidHindi - case 0x44e : // lidMarathi - case 0x44f : // lidSanskrit - case 0x457 : // lidKonkani - case 0x459 : // lidSindhi - case 0x860 : // lidKashmiriIndia - case 0x461 : // lidNepali - case 0x861 : // lidNepaliIndia - return "Deva"; - case 0x45e : // lidAmharic - case 0x473 : // lidTigrignaEthiopic - case 0x873 : // lidTigrignaEritrea - return "Ethi"; - case 0x437 : // lidGeorgian - return "Geor"; - case 0x408 : // lidGreek - return "Grek"; - case 0x447 : // lidGujarati - return "Gujr"; - case 0x446 : // lidPunjabi - return "Guru"; - case 0x412 : // lidKoreanExtWansung - return "Hang"; - case 0x804 : // lidChineseSimp - case 0x1004 : // lidSingapore - return "Hans"; - case 0x404 : // lidChineseTrad - case 0xc04 : // lidHongkong - case 0x1404 : // lidMacau - return "Hant"; - case 0x40d : // lidHebrew - case 0x43d : // lidYiddish - return "Hebr"; - case 0x411 : // lidJapanese - return "Jpan"; - case 0x453 : // lidKhmer - return "Khmr"; - case 0x44b : // lidKannada - return "Knda"; - case 0x454 : // lidLao - return "Laoo"; - case 0x409 : // lidAmerican - case 0xc09 : // lidAustralian - case 0x809 : // lidBritish - case 0x1009 : // lidEnglishCanadian - case 0x403 : // lidCatalan - case 0x406 : // lidDanish - case 0x413 : // lidDutch - case 0x813 : // lidDutchBelgian - case 0x479 : // lidPapiamentu - case 0x40b : // lidFinnish - case 0x40c : // lidFrench - case 0xc0c : // lidFrenchCanadian - case 0x407 : // lidGerman - case 0x807 : // lidSwissGerman - case 0xc07 : // lidAustrianGerman - case 0x1007 : // lidGermanLuxembourg - case 0x1407 : // lidGermanLiechtenstein - case 0x410 : // lidItalian - case 0x414 : // lidNorskBokmal - case 0x814 : // lidNorskNynorsk - case 0x416 : // lidPortBrazil - case 0x816 : // lidPortIberian - case 0x40a : // lidSpanish - case 0x41d : // lidSwedish - case 0x405 : // lidCzech - case 0x40e : // lidHungarian - case 0x415 : // lidPolish - case 0x41f : // lidTurkish - case 0x42d : // lidBasque - case 0x424 : // lidSlovenian - case 0x426 : // lidLatvian - case 0x427 : // lidLithuanian - case 0x418 : // lidRomanian - case 0x818 : // lidRomanianMoldavia - case 0x241a : // lidSerbianLatin - case 0x41a : // lidCroatian, lidCroat - case 0x491 : // lidGaelicScots - case 0x83c : // lidGaelicIrish - case 0x430 : // lidSutu - case 0x431 : // lidTsonga - case 0x432 : // lidTswana - case 0x433 : // lidVenda - case 0x434 : // lidXhosa - case 0x435 : // lidZulu - case 0x436 : // lidAfrikaans - case 0x425 : // lidEstonian - case 0x456 : // lidGalician - case 0x41b : // lidSlovak - case 0x1409 : // lidEnglishNewZealand - case 0x1809 : // lidEnglishIreland - case 0x1c09 : // lidEnglishSouthAfrica - case 0x2009 : // lidEnglishJamaica - case 0x2409 : // lidEnglishCaribbean - case 0x2809 : // lidEnglishBelize - case 0x2c09 : // lidEnglishTrinidad - case 0x3009 : // lidEnglishZimbabwe - case 0x3409 : // lidEnglishPhilippines - case 0x3809 : // lidEnglishIndonesia - case 0x3c09 : // lidEnglishHongKong - case 0x4009 : // lidEnglishIndia - case 0x4409 : // lidEnglishMalaysia - case 0x4809 : // lidEnglishSingapore - case 0x80a : // lidSpanishMexican, lidMexican - case 0xc0a : // lidSpanishModern - case 0x100a : // lidGuatemala - case 0x140a : // lidCostaRica - case 0x180a : // lidPanama - case 0x1c0a : // lidDominicanRepublic - case 0x200a : // lidSpanishSA, lidVenezuela - case 0x240a : // lidColombia - case 0x280a : // lidPeru - case 0x2c0a : // lidArgentina - case 0x300a : // lidEcuador - case 0x340a : // lidChile - case 0x380a : // lidUruguay - case 0x3c0a : // lidParguay - case 0x400a : // lidBolivia - case 0x440a : // lidElSalvador - case 0x480a : // lidHonduras - case 0x4c0a : // lidNicaragua - case 0x500a : // lidPuertoRico - case 0x540a : // lidSpanishUS - case 0x80c : // lidFrenchBelgian - case 0x100c : // lidFrenchSwiss - case 0x140c : // lidFrenchLuxembourg - case 0x180c : // lidFrenchMonaco - case 0x1c0c : // lidFrenchWestIndies - case 0x200c : // lidFrenchReunion - case 0x240c : // lidFrenchCongoDRC, lidFrenchZaire - case 0x280c : // lidFrenchSenegal - case 0x2c0c : // lidFrenchCameroon - case 0x300c : // lidFrenchCotedIvoire - case 0x340c : // lidFrenchMali - case 0x3c0c : // lidFrenchHaiti - case 0x380c : // lidFrenchMorocco - case 0x40f : // lidIcelandic - case 0x810 : // lidItalianSwiss - case 0x417 : // lidRhaetoRomanic, lidRomanic - case 0x81a : // lidSerbianLatinSerbMont, lidCroatSerbo - case 0x101a : // lidBosniaHerzegovina - case 0x141a : // lidBosnianBosniaHerzegovinaLatin - case 0x181a : // lidSerbianBosniaHerzegovinaLatin - case 0x2c1a : // lidSerbianMontenegroLatin - case 0x41c : // lidAlbanian - case 0x81d : // lidSwedishFinland - case 0x421 : // lidBahasa, lidIndonesian - case 0x42c : // lidAzeriLatin - case 0x42e : // lidSorbian - case 0x82e : // lidLowerSorbian - case 0x438 : // lidFaeroese - case 0x43a : // lidMaltese - case 0x43b : // lidSamiLappish - case 0x83b : // lidNorthSamiSwe - case 0xc3b : // lidNorthernSamiFi - case 0x103b : // lidLuleSamiNor - case 0x143b : // lidLuleSamiSwe - case 0x183b : // lidSouthSamiNor - case 0x1c3b : // lidSouthSamiSwe - case 0x203b : // lidSkoltSami - case 0x243b : // lidInariSami - case 0x43e : // lidMalaysian - case 0x83e : // lidMalayBrunei - case 0x441 : // lidSwahili - case 0x442 : // lidTurkmen - case 0x443 : // lidUzbekLatin - case 0x452 : // lidWelsh - case 0x85d : // lidInuktitutLatin - case 0x85f : // lidTamazightLatin - case 0x462 : // lidFrisian - case 0x464 : // lidFilipino - case 0x466 : // lidEdo - case 0x467 : // lidFulfulde - case 0x468 : // lidHausa - case 0x469 : // lidIbibio - case 0x46a : // lidYoruba - case 0x46b : // lidQuechuaBol - case 0x86b : // lidQuechuaEcu - case 0xc6b : // lidQuechuaPe - case 0x46c : // lidSesothoSaLeboa - case 0x46e : // lidLuxembourgish - case 0x46f : // lidGreenlandic - case 0x470 : // lidIgbo - case 0x471 : // lidKanuri - case 0x472 : // lidOromo - case 0x474 : // lidGuarani - case 0x475 : // lidHawaiian - case 0x476 : // lidLatin - case 0x477 : // lidSomali - case 0x47a : // lidMapudungun - case 0x47c : // lidMohawk - case 0x47e : // lidBreton - case 0x481 : // lidMaori - case 0x482 : // lidOccitan - case 0x483 : // lidCorsican - case 0x484 : // lidAlsatian - case 0x486 : // lidKiche - case 0x487 : // lidKinyarwanda - case 0x488 : // lidWolof - return "Latn"; - case 0x44c : // lidMalayalam - return "Mlym"; - case 0x850 : // lidMongolianMongo - return "Mong"; - case 0x455 : // lidBurmese - return "Mymr"; - case 0x448 : // lidOriya - return "Orya"; - case 0x45b : // lidSinhalese - return "Sinh"; - case 0x45a : // lidSyriac - return "Syrc"; - case 0x449 : // lidTamil - return "Taml"; - case 0x44a : // lidTelugu - return "Telu"; - case 0x465 : // lidMaldivian - return "Thaa"; - case 0x41e : // lidThai - return "Thai"; - case 0x451 : // lidTibetan - case 0x851 : // lidBhutanese - return "Tibt"; - case 0x480 : // lidUighur - return "Uigh"; - case 0x42a : // lidVietnamese - return "Viet"; - case 0x478 : // lidYi - return "Yiii"; - default: - return OUString(); - } -} - -} //namespace writerfilter - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/ThemeTable.hxx b/writerfilter/source/dmapper/ThemeTable.hxx deleted file mode 100644 index 164f083c9ea3..000000000000 --- a/writerfilter/source/dmapper/ThemeTable.hxx +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- 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/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#pragma once - -#include "LoggedResources.hxx" -#include <com/sun/star/beans/PropertyValue.hpp> -#include <i18nlangtag/lang.h> -#include <memory> - -namespace writerfilter::dmapper -{ -struct ThemeTable_Impl; - -class ThemeTable : public LoggedProperties, public LoggedTable -{ - std::unique_ptr<ThemeTable_Impl> m_pImpl; - -public: - ThemeTable(); - virtual ~ThemeTable() override; - - OUString getFontNameForTheme(const Id id) const; - static OUString getStringForTheme(const Id id); - void setThemeFontLangProperties(const css::uno::Sequence<css::beans::PropertyValue>& aPropSeq); - -private: - // Properties - virtual void lcl_attribute(Id Name, Value& val) override; - virtual void lcl_sprm(Sprm& sprm) override; - - // Table - virtual void lcl_entry(writerfilter::Reference<Properties>::Pointer_t ref) override; - - // Helper methods - static OUString fromLocaleToScriptTag(const OUString& sLocale); - static OUString fromLCIDToScriptTag(LanguageType lang); -}; -typedef tools::SvRef<ThemeTable> ThemeTablePtr; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index 0abd516a48a2..92ddc0d79f5b 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/xml/dom/DocumentBuilder.hpp> #include <com/sun/star/graphic/GraphicMapper.hpp> #include <ooxml/resourceids.hxx> +#include <oox/drawingml/theme.hxx> #include <oox/shape/ShapeFilterBase.hxx> #include "OOXMLStreamImpl.hxx" #include "OOXMLDocumentImpl.hxx" @@ -483,6 +484,12 @@ void OOXMLDocumentImpl::resolve(Stream & rStream) resolveFastSubStream(rStream, OOXMLStream::SETTINGS); mxThemeDom = importSubStream(OOXMLStream::THEME); resolveFastSubStream(rStream, OOXMLStream::THEME); + // Convert the oox::Theme to the draw page + { + auto pThemePtr = getTheme(); + if (pThemePtr) + pThemePtr->addTheme(getDrawPage()); + } mxGlossaryDocDom = importSubStream(OOXMLStream::GLOSSARY); if (mxGlossaryDocDom.is()) resolveGlossaryStream(rStream); @@ -884,6 +891,13 @@ const rtl::Reference<oox::shape::ShapeFilterBase>& OOXMLDocumentImpl::getShapeFi return mxShapeFilterBase; } +const rtl::Reference<oox::drawingml::ThemeFilterBase>& OOXMLDocumentImpl::getThemeFilterBase() +{ + if (!mxThemeFilterBase) + mxThemeFilterBase = new oox::drawingml::ThemeFilterBase(mpStream->getContext()); + return mxThemeFilterBase; +} + OOXMLDocument * OOXMLDocumentFactory::createDocument (const OOXMLStream::Pointer_t& pStream, diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index eedf1eb12654..a9c0b6c8d80c 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/graphic/XGraphicMapper.hpp> #include <oox/drawingml/drawingmltypes.hxx> +#include <oox/drawingml/ThemeFilterBase.hxx> #include "OOXMLPropertySet.hxx" @@ -73,6 +74,7 @@ class OOXMLDocumentImpl : public OOXMLDocument // and the same is used by header and footer as well. oox::drawingml::ThemePtr mpTheme; rtl::Reference<oox::shape::ShapeFilterBase> mxShapeFilterBase; + rtl::Reference<oox::drawingml::ThemeFilterBase> mxThemeFilterBase; bool mbCommentsExtendedResolved = false; @@ -135,6 +137,10 @@ public: virtual const OUString & getTarget() const override; virtual rtl::Reference<oox::shape::ShapeContextHandler> getShapeContext( ) override; virtual void setShapeContext( rtl::Reference<oox::shape::ShapeContextHandler> xContext ) override; + virtual const oox::drawingml::ThemePtr & getTheme() const override + { + return mpTheme; + } void pushShapeContext() override; void popShapeContext() override; virtual css::uno::Reference<css::xml::dom::XDocument> getThemeDom() override; @@ -154,11 +160,10 @@ public: return mxGraphicMapper; } - const oox::drawingml::ThemePtr & getTheme() const { return mpTheme; } void setTheme(const oox::drawingml::ThemePtr& pTheme) { mpTheme = pTheme; } const rtl::Reference<oox::shape::ShapeFilterBase> & getShapeFilterBase(); - + const rtl::Reference<oox::drawingml::ThemeFilterBase> & getThemeFilterBase(); }; } diff --git a/writerfilter/source/ooxml/OOXMLFactory.hxx b/writerfilter/source/ooxml/OOXMLFactory.hxx index 4f3c82f1b070..ba2927e9b7b8 100644 --- a/writerfilter/source/ooxml/OOXMLFactory.hxx +++ b/writerfilter/source/ooxml/OOXMLFactory.hxx @@ -22,6 +22,7 @@ #include <dmapper/resourcemodel.hxx> #include "OOXMLFastContextHandler.hxx" +#include "OOXMLFastContextHandlerTheme.hxx" namespace writerfilter::ooxml { @@ -50,6 +51,7 @@ enum class ResourceType { HpsMeasure, MeasurementOrPercent, CommentEx, + Theme, }; struct AttributeInfo diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.cxx b/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.cxx new file mode 100644 index 000000000000..a976453ba911 --- /dev/null +++ b/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.cxx @@ -0,0 +1,69 @@ +/* -*- 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 <sal/log.hxx> +#include "OOXMLFastContextHandlerTheme.hxx" +#include <oox/drawingml/theme.hxx> +#include <oox/token/namespaces.hxx> + +using namespace ::com::sun::star; + +namespace writerfilter::ooxml +{ +OOXMLFastContextHandlerTheme::OOXMLFastContextHandlerTheme(OOXMLFastContextHandler* pContext) + : OOXMLFastContextHandler(pContext) +{ +} + +uno::Reference<xml::sax::XFastContextHandler> +OOXMLFastContextHandlerTheme::lcl_createFastChildContext( + Token_t Element, const uno::Reference<xml::sax::XFastAttributeList>& Attribs) +{ + if (mpThemeFragmentHandler.is()) + return mpThemeFragmentHandler->createFastChildContext(Element, Attribs); + + return this; +} + +void OOXMLFastContextHandlerTheme::lcl_startFastElement( + Token_t Element, const uno::Reference<xml::sax::XFastAttributeList>& Attribs) +{ + if (!mpThemeFragmentHandler.is()) + { + auto xThemeFilterBase = getDocument()->getThemeFilterBase(); + OUString aThemeFragmentPath + = xThemeFilterBase->getFragmentPathFromFirstTypeFromOfficeDoc(u"theme"); + auto pThemePtr = getDocument()->getTheme(); + if (!pThemePtr) + { + pThemePtr = std::make_shared<oox::drawingml::Theme>(); + getDocument()->setTheme(pThemePtr); + } + mpThemeFragmentHandler = new oox::drawingml::ThemeFragmentHandler( + *xThemeFilterBase, aThemeFragmentPath, *pThemePtr); + } + + if (mpThemeFragmentHandler.is()) + mpThemeFragmentHandler->startFastElement(Element, Attribs); +} + +void OOXMLFastContextHandlerTheme::lcl_endFastElement(Token_t Element) +{ + if (mpThemeFragmentHandler.is()) + mpThemeFragmentHandler->endFastElement(Element); +} + +void OOXMLFastContextHandlerTheme::lcl_characters(const OUString& aChars) +{ + if (mpThemeFragmentHandler.is()) + mpThemeFragmentHandler->characters(aChars); +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.hxx b/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.hxx new file mode 100644 index 000000000000..2de6b75590f0 --- /dev/null +++ b/writerfilter/source/ooxml/OOXMLFastContextHandlerTheme.hxx @@ -0,0 +1,46 @@ +/* -*- 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 <set> +#include <cppuhelper/implbase.hxx> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/xml/sax/XFastContextHandler.hpp> +#include <oox/mathml/importutils.hxx> +#include <oox/drawingml/themefragmenthandler.hxx> +#include <rtl/ref.hxx> +#include "OOXMLParserState.hxx" +#include "OOXMLPropertySet.hxx" +#include "OOXMLFastContextHandler.hxx" + +namespace writerfilter::ooxml +{ +class OOXMLFastContextHandlerTheme : public OOXMLFastContextHandler +{ + rtl::Reference<oox::drawingml::ThemeFragmentHandler> mpThemeFragmentHandler; + +public: + explicit OOXMLFastContextHandlerTheme(OOXMLFastContextHandler* pContext); + std::string getType() const override { return "Theme"; } + +protected: + void lcl_startFastElement( + Token_t Element, + const css::uno::Reference<css::xml::sax::XFastAttributeList>& Attribs) override; + void lcl_endFastElement(Token_t Element) override; + css::uno::Reference<css::xml::sax::XFastContextHandler> lcl_createFastChildContext( + Token_t Element, + const css::uno::Reference<css::xml::sax::XFastAttributeList>& Attribs) override; + virtual void lcl_characters(const OUString& aChars) override; +}; + +} // end namespace writerfilter::ooxml + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index b0dea8f744c3..b7684c564785 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -207,7 +207,7 @@ </element> </define> </grammar> - <resource name="CT_OfficeStyleSheet" resource="Table" tokenid="ooxml:THEMETABLE"/> + <resource name="CT_OfficeStyleSheet" resource="Theme" tokenid="ooxml:THEMETABLE"/> <resource name="CT_Hyperlink" resource="Properties"> <attribute name="r:id" tokenid="ooxml:CT_Hyperlink_r_id"/> </resource>