include/oox/drawingml/theme.hxx               |   12 +-
 include/svx/ColorSets.hxx                     |  149 ++++++++++++++++++++++++++
 oox/inc/drawingml/textfont.hxx                |    3 
 oox/source/drawingml/textfont.cxx             |    9 +
 oox/source/drawingml/theme.cxx                |   69 +++++++++++-
 oox/source/drawingml/themeelementscontext.cxx |   23 ++--
 svx/CppunitTest_svx_unit.mk                   |    1 
 svx/qa/unit/ThemeTest.cxx                     |   40 ++++++
 8 files changed, 295 insertions(+), 11 deletions(-)

New commits:
commit d5a71bc6a28f8a3d726b2ac4688c7cef9d77ddf0
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Mon Dec 12 22:12:58 2022 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Sun Jan 1 23:34:32 2023 +0000

    oox: add support for importing font scheme into a svx::Theme
    
    Change-Id: I862256a17ce84c85174678f3fd03c8ef6661f2c5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143995
    Tested-by: Tomaž Vajngerl <qui...@gmail.com>
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/include/oox/drawingml/theme.hxx b/include/oox/drawingml/theme.hxx
index f7b4a262ffb8..ebd05957bf3b 100644
--- a/include/oox/drawingml/theme.hxx
+++ b/include/oox/drawingml/theme.hxx
@@ -35,8 +35,12 @@ namespace com::sun::star {
     namespace drawing { class XDrawPage; }
     namespace xml::dom { class XDocument; }
 }
+namespace svx {
+    class Theme;
+}
 
-namespace oox::drawingml {
+namespace oox::drawingml
+{
 
 struct EffectProperties;
 struct FillProperties;
@@ -82,6 +86,10 @@ public:
 
     FontScheme&              getFontScheme() { return maFontScheme; }
     const FontScheme&        getFontScheme() const { return maFontScheme; }
+
+    std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>>& 
getSupplementalFontMap() { return maSupplementalFontMap; }
+    std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>> const& 
getSupplementalFontMap() const { return maSupplementalFontMap; }
+
     /** Returns theme font properties by scheme type (major/minor). */
     const TextCharacterProperties*  getFontStyle( sal_Int32 nSchemeType ) 
const;
     /** Returns theme font by placeholder name, e.g. the major latin theme 
font for the font name '+mj-lt'. */
@@ -99,6 +107,7 @@ public:
     const css::uno::Reference<css::xml::dom::XDocument>& getFragment() const { 
return mxFragment; }
     void                     setFragment( const css::uno::Reference< 
css::xml::dom::XDocument>& xRef ) { mxFragment=xRef; }
 
+    std::unique_ptr<svx::Theme> createSvxTheme() const;
     void addTheme(const css::uno::Reference<css::drawing::XDrawPage>& 
xDrawPage) const;
 
 private:
@@ -111,6 +120,7 @@ private:
     LineStyleList       maLineStyleList;
     EffectStyleList     maEffectStyleList;
     FontScheme          maFontScheme;
+    std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>> 
maSupplementalFontMap;
     Shape               maSpDef;
     Shape               maLnDef;
     Shape               maTxDef;
diff --git a/include/svx/ColorSets.hxx b/include/svx/ColorSets.hxx
index 47e1d8866e5d..718b79b3e66c 100644
--- a/include/svx/ColorSets.hxx
+++ b/include/svx/ColorSets.hxx
@@ -101,6 +101,146 @@ public:
     const ColorSet& getColorSet(std::u16string_view rName);
 };
 
+struct SVXCORE_DLLPUBLIC ThemeSupplementalFont
+{
+    OUString maScript;
+    OUString maTypeface;
+};
+
+struct SVXCORE_DLLPUBLIC ThemeFont
+{
+    OUString maTypeface;
+    OUString maPanose;
+    sal_Int16 maPitch;
+    sal_Int16 maFamily;
+    sal_Int32 maCharset;
+
+    sal_Int16 getPitchFamily() const
+    {
+        return (maPitch & 0x0F) | (maFamily & 0x0F) << 4;
+    }
+};
+
+class SVXCORE_DLLPUBLIC FontScheme
+{
+private:
+    OUString maName;
+
+    ThemeFont maMinorLatin;
+    ThemeFont maMinorAsian;
+    ThemeFont maMinorComplex;
+
+    ThemeFont maMajorLatin;
+    ThemeFont maMajorAsian;
+    ThemeFont maMajorComplex;
+
+    std::vector<ThemeSupplementalFont> maMinorSupplementalFontList;
+    std::vector<ThemeSupplementalFont> maMajorSupplementalFontList;
+
+public:
+    FontScheme() = default;
+    FontScheme(OUString const& rName)
+        : maName(rName)
+    {}
+
+    const OUString& getName() const
+    {
+        return maName;
+    }
+
+    ThemeFont const& getMinorLatin() const
+    {
+        return maMinorLatin;
+    }
+    void setMinorLatin(ThemeFont const& aMinor)
+    {
+        maMinorLatin = aMinor;
+    }
+
+    ThemeFont const& getMinorAsian() const
+    {
+        return maMinorAsian;
+    }
+    void setMinorAsian(ThemeFont const& aMinor)
+    {
+        maMinorAsian = aMinor;
+    }
+
+    ThemeFont const& getMinorComplex() const
+    {
+        return maMinorComplex;
+    }
+    void setMinorComplex(ThemeFont const& aMinor)
+    {
+        maMinorComplex = aMinor;
+    }
+
+    ThemeFont const& getMajorLatin() const
+    {
+        return maMajorLatin;
+    }
+    void setMajorLatin(ThemeFont const& aMajor)
+    {
+        maMajorLatin = aMajor;
+    }
+
+    ThemeFont const& getMajorAsian() const
+    {
+        return maMajorAsian;
+    }
+    void setMajorAsian(ThemeFont const& aMajor)
+    {
+        maMajorAsian = aMajor;
+    }
+
+    ThemeFont const& getMajorComplex() const
+    {
+        return maMajorComplex;
+    }
+    void setMajorComplex(ThemeFont const& aMajor)
+    {
+        maMajorComplex = aMajor;
+    }
+
+    OUString findMinorSupplementalTypeface(std::u16string_view rScript) const
+    {
+        for (auto const& rSupplementalFont : maMinorSupplementalFontList)
+        {
+            if (rSupplementalFont.maScript == rScript)
+                return rSupplementalFont.maTypeface;
+        }
+        return OUString();
+    }
+
+    std::vector<ThemeSupplementalFont> const& getMinorSupplementalFontList() 
const
+    {
+        return maMinorSupplementalFontList;
+    }
+    void setMinorSupplementalFontList(std::vector<ThemeSupplementalFont> 
const& rSupplementalFont)
+    {
+        maMinorSupplementalFontList = rSupplementalFont;
+    }
+
+    OUString findMajorSupplementalTypeface(std::u16string_view rScript) const
+    {
+        for (auto const& rSupplementalFont : maMajorSupplementalFontList)
+        {
+            if (rSupplementalFont.maScript == rScript)
+                return rSupplementalFont.maTypeface;
+        }
+        return OUString();
+    }
+
+    std::vector<ThemeSupplementalFont> const& getMajorSupplementalFontList() 
const
+    {
+        return maMajorSupplementalFontList;
+    }
+    void setMajorSupplementalFontList(std::vector<ThemeSupplementalFont> 
const& rSupplementalFont)
+    {
+        maMajorSupplementalFontList = rSupplementalFont;
+    }
+};
+
 /// A named theme has a named color set.
 class SVXCORE_DLLPUBLIC Theme
 {
@@ -108,9 +248,18 @@ private:
     OUString maName;
     std::unique_ptr<ColorSet> mpColorSet;
 
+    FontScheme maFontScheme;
+
 public:
     Theme(OUString const& rName);
 
+    void setFontScheme(FontScheme const& rFontScheme)
+    {
+        maFontScheme = rFontScheme;
+    }
+
+    FontScheme const& getFontScheme() const { return maFontScheme; }
+
     void SetColorSet(std::unique_ptr<ColorSet> pColorSet);
     const ColorSet* GetColorSet() const;
     ColorSet* GetColorSet();
diff --git a/oox/inc/drawingml/textfont.hxx b/oox/inc/drawingml/textfont.hxx
index 231b18cffecb..3847ed8c61be 100644
--- a/oox/inc/drawingml/textfont.hxx
+++ b/oox/inc/drawingml/textfont.hxx
@@ -24,6 +24,7 @@
 
 namespace oox { class AttributeList; }
 namespace oox::core { class XmlFilterBase; }
+namespace svx { struct ThemeFont; }
 
 namespace oox::drawingml {
 
@@ -51,6 +52,8 @@ public:
                             sal_Int16& rnFontFamily,
                             const ::oox::core::XmlFilterBase& rFilter ) const;
 
+    void fillThemeFont(svx::ThemeFont& rThemeFont) const;
+
     static void resolvePitch(sal_Int32 nOoxPitch, sal_Int16& rnFontPitch, 
sal_Int16& rnFontFamily);
 
 private:
diff --git a/oox/source/drawingml/textfont.cxx 
b/oox/source/drawingml/textfont.cxx
index e5899780ad2c..c531ef7ffba6 100644
--- a/oox/source/drawingml/textfont.cxx
+++ b/oox/source/drawingml/textfont.cxx
@@ -24,6 +24,7 @@
 #include <oox/core/xmlfilterbase.hxx>
 #include <oox/helper/attributelist.hxx>
 #include <oox/token/tokens.hxx>
+#include <svx/ColorSets.hxx>
 
 using ::oox::core::XmlFilterBase;
 
@@ -90,6 +91,14 @@ bool TextFont::implGetFontData( OUString& rFontName, 
sal_Int16& rnFontPitch, sal
     return !rFontName.isEmpty();
 }
 
+void TextFont::fillThemeFont(svx::ThemeFont& rThemeFont) const
+{
+    rThemeFont.maTypeface = maTypeface;
+    rThemeFont.maPanose = maPanose;
+    rThemeFont.maCharset = mnCharset;
+    resolvePitch(mnPitchFamily, rThemeFont.maPitch, rThemeFont.maFamily);
+}
+
 void TextFont::resolvePitch(sal_Int32 nOoxPitchFamily, sal_Int16& rnFontPitch, 
sal_Int16& rnFontFamily)
 {
     rnFontPitch = lclGetFontPitch(extractValue<sal_Int16>(nOoxPitchFamily, 0, 
4));
diff --git a/oox/source/drawingml/theme.cxx b/oox/source/drawingml/theme.cxx
index 885d87b1bb0f..dfa81feaff0d 100644
--- a/oox/source/drawingml/theme.cxx
+++ b/oox/source/drawingml/theme.cxx
@@ -108,6 +108,70 @@ const TextFont* Theme::resolveFont( std::u16string_view 
rName ) const
     return nullptr;
 }
 
+std::unique_ptr<svx::Theme> Theme::createSvxTheme() const
+{
+    auto pTheme = std::make_unique<svx::Theme>(maThemeName);
+    auto pColorSet = std::make_unique<svx::ColorSet>(maClrScheme.GetName());
+    maClrScheme.fill(*pColorSet);
+    pTheme->SetColorSet(std::move(pColorSet));
+
+    svx::FontScheme aFontScheme(maFontSchemeName);
+
+    if (auto* pCharProps = getFontStyle(XML_minor))
+    {
+        svx::ThemeFont aMinorLatin;
+        pCharProps->maLatinFont.fillThemeFont(aMinorLatin);
+        aFontScheme.setMinorLatin(aMinorLatin);
+
+        svx::ThemeFont aMinorAsian;
+        pCharProps->maAsianFont.fillThemeFont(aMinorAsian);
+        aFontScheme.setMinorAsian(aMinorAsian);
+
+        svx::ThemeFont aMinorComplex;
+        pCharProps->maComplexFont.fillThemeFont(aMinorComplex);
+        aFontScheme.setMinorComplex(aMinorComplex);
+    }
+
+    if (auto* pCharProps = getFontStyle(XML_major))
+    {
+        svx::ThemeFont aMajorLatin;
+        pCharProps->maLatinFont.fillThemeFont(aMajorLatin);
+        aFontScheme.setMajorLatin(aMajorLatin);
+
+        svx::ThemeFont aMajorAsian;
+        pCharProps->maAsianFont.fillThemeFont(aMajorAsian);
+        aFontScheme.setMajorAsian(aMajorAsian);
+
+        svx::ThemeFont aMajorComplex;
+        pCharProps->maComplexFont.fillThemeFont(aMajorComplex);
+        aFontScheme.setMajorComplex(aMajorComplex);
+    }
+
+    if (maSupplementalFontMap.find(XML_minor) != maSupplementalFontMap.cend())
+    {
+        std::vector<svx::ThemeSupplementalFont> aList;
+        for (auto const& [rScript, rTypeface] : 
maSupplementalFontMap.at(XML_minor))
+        {
+            aList.push_back(svx::ThemeSupplementalFont{rScript, rTypeface});
+        }
+        aFontScheme.setMinorSupplementalFontList(aList);
+    }
+
+    if (maSupplementalFontMap.find(XML_major) != maSupplementalFontMap.cend())
+    {
+        std::vector<svx::ThemeSupplementalFont> aList;
+        for (auto const& [rScript, rTypeface] : 
maSupplementalFontMap.at(XML_major))
+        {
+            aList.push_back(svx::ThemeSupplementalFont{rScript, rTypeface});
+        }
+        aFontScheme.setMajorSupplementalFontList(aList);
+    }
+
+    pTheme->setFontScheme(aFontScheme);
+
+    return pTheme;
+}
+
 void Theme::addTheme(const css::uno::Reference<css::drawing::XDrawPage>& 
xDrawPage) const
 {
     SAL_WARN_IF(!xDrawPage.is(), "oox", "DrawPage is not set");
@@ -119,10 +183,7 @@ void Theme::addTheme(const 
css::uno::Reference<css::drawing::XDrawPage>& xDrawPa
     if (!pPage)
         return;
 
-    auto pTheme = std::make_unique<svx::Theme>(maThemeName);
-    auto pColorSet = std::make_unique<svx::ColorSet>(maClrScheme.GetName());
-    maClrScheme.fill(*pColorSet);
-    pTheme->SetColorSet(std::move(pColorSet));
+    std::unique_ptr<svx::Theme> pTheme = createSvxTheme();
 
     pPage->getSdrPageProperties().SetTheme(std::move(pTheme));
 }
diff --git a/oox/source/drawingml/themeelementscontext.cxx 
b/oox/source/drawingml/themeelementscontext.cxx
index 2cb9d12ab020..cb62f4ef0a70 100644
--- a/oox/source/drawingml/themeelementscontext.cxx
+++ b/oox/source/drawingml/themeelementscontext.cxx
@@ -145,20 +145,25 @@ namespace {
 class FontSchemeContext : public ContextHandler2
 {
 public:
-    FontSchemeContext( ContextHandler2Helper const & rParent, FontScheme& 
rFontScheme );
+    FontSchemeContext(ContextHandler2Helper const & rParent, FontScheme& 
rFontScheme,
+                      std::map<sal_Int32, std::vector<std::pair<OUString, 
OUString>>>& rSupplementalFontMap);
     virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const 
AttributeList& rAttribs ) override;
     virtual void onEndElement() override;
 
 private:
     FontScheme& mrFontScheme;
     TextCharacterPropertiesPtr mxCharProps;
+    std::map<sal_Int32, std::vector<std::pair<OUString, OUString>>>& 
mrSupplementalFontMap;
+    sal_Int32 maCurrentFont = 0;
 };
 
 }
 
-FontSchemeContext::FontSchemeContext( ContextHandler2Helper const & rParent, 
FontScheme& rFontScheme ) :
-    ContextHandler2( rParent ),
-    mrFontScheme( rFontScheme )
+FontSchemeContext::FontSchemeContext(ContextHandler2Helper const & rParent, 
FontScheme& rFontScheme,
+                                     std::map<sal_Int32, 
std::vector<std::pair<OUString, OUString>>>& rSupplementalFontMap)
+    : ContextHandler2(rParent)
+    , mrFontScheme(rFontScheme)
+    , mrSupplementalFontMap(rSupplementalFontMap)
 {
 }
 
@@ -169,12 +174,13 @@ ContextHandlerRef FontSchemeContext::onCreateContext( 
sal_Int32 nElement, const
         case A_TOKEN( majorFont ):
             mxCharProps = std::make_shared<TextCharacterProperties>();
             mrFontScheme[ XML_major ] = mxCharProps;
+            maCurrentFont = XML_major;
             return this;
         case A_TOKEN( minorFont ):
             mxCharProps = std::make_shared<TextCharacterProperties>();
             mrFontScheme[ XML_minor ] = mxCharProps;
+            maCurrentFont = XML_minor;
             return this;
-
         case A_TOKEN( latin ):
             if( mxCharProps )
                 mxCharProps->maLatinFont.setAttributes( rAttribs );
@@ -187,6 +193,11 @@ ContextHandlerRef FontSchemeContext::onCreateContext( 
sal_Int32 nElement, const
             if( mxCharProps )
                 mxCharProps->maComplexFont.setAttributes( rAttribs );
         break;
+        case A_TOKEN(font):
+            OUString aScript = rAttribs.getStringDefaulted(XML_script);
+            OUString aTypeface = rAttribs.getStringDefaulted(XML_typeface);
+            
mrSupplementalFontMap[maCurrentFont].emplace_back(std::pair<OUString, 
OUString>{aScript, aTypeface});
+        break;
     }
     return nullptr;
 }
@@ -223,7 +234,7 @@ ContextHandlerRef ThemeElementsContext::onCreateContext( 
sal_Int32 nElement, con
         {
             if (rAttribs.hasAttribute(XML_name))
                 
mrTheme.setFontSchemeName(rAttribs.getStringDefaulted(XML_name));
-            return new FontSchemeContext(*this, mrTheme.getFontScheme());
+            return new FontSchemeContext(*this, mrTheme.getFontScheme(), 
mrTheme.getSupplementalFontMap());
         }
 
         case A_TOKEN( fmtScheme ):  // CT_StyleMatrix
diff --git a/svx/CppunitTest_svx_unit.mk b/svx/CppunitTest_svx_unit.mk
index 9f22c2adba11..678a27322e02 100644
--- a/svx/CppunitTest_svx_unit.mk
+++ b/svx/CppunitTest_svx_unit.mk
@@ -33,6 +33,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,svx_unit, \
        svx/qa/unit/xoutdev \
        svx/qa/unit/xml \
        svx/qa/unit/XTableImportExportTest \
+       svx/qa/unit/ThemeTest \
 ))
 
 $(eval $(call gb_CppunitTest_use_libraries,svx_unit, \
diff --git a/svx/qa/unit/ThemeTest.cxx b/svx/qa/unit/ThemeTest.cxx
new file mode 100644
index 000000000000..757561b1bd17
--- /dev/null
+++ b/svx/qa/unit/ThemeTest.cxx
@@ -0,0 +1,40 @@
+/* -*- 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 <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <config_features.h>
+
+#include <svx/ColorSets.hxx>
+
+namespace
+{
+class ThemeTest : public CppUnit::TestFixture
+{
+};
+
+CPPUNIT_TEST_FIXTURE(ThemeTest, testPitchFamilyConversion)
+{
+    svx::ThemeFont aFont;
+    aFont.maPitch = 2;
+    aFont.maFamily = 1;
+
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(0x12), aFont.getPitchFamily());
+
+    aFont.maPitch = sal_Int16(0x7FF2); // only lower 4-bit
+    aFont.maFamily = sal_Int16(0x7FF3); // only lower 4-bit
+
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(0x32), aFont.getPitchFamily());
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to