include/xmloff/XMLFontAutoStylePool.hxx                   |   24 -
 include/xmloff/xmlexp.hxx                                 |   25 +
 sc/inc/xmlwrap.hxx                                        |    2 
 sc/source/filter/xml/xmlexprt.hxx                         |    6 
 sc/source/filter/xml/xmlfonte.cxx                         |   29 --
 sc/source/filter/xml/xmlwrap.cxx                          |    2 
 sd/source/filter/xml/sdxmlwrp.cxx                         |   12 
 sw/qa/extras/odfexport/data/font_used_in_header_only.fodt |   45 +++
 sw/qa/extras/odfexport/odfexport2.cxx                     |   42 ++
 sw/qa/extras/uiwriter/uiwriter6.cxx                       |  157 +++++-----
 sw/source/filter/xml/wrtxml.cxx                           |    8 
 sw/source/filter/xml/wrtxml.hxx                           |    5 
 sw/source/filter/xml/xmlexp.hxx                           |    5 
 sw/source/filter/xml/xmlfonte.cxx                         |   46 +--
 xmloff/source/draw/sdxmlexp.cxx                           |   61 +---
 xmloff/source/draw/sdxmlexp_impl.hxx                      |   11 
 xmloff/source/style/XMLFontAutoStylePool.cxx              |  202 ++++++--------
 17 files changed, 392 insertions(+), 290 deletions(-)

New commits:
commit 7a3d121a6bdeb8d3c3ff68cf08394d9889a6bca3
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat May 24 01:32:06 2025 +0500
Commit:     Michael Stahl <michael.st...@collabora.com>
CommitDate: Thu Aug 7 13:50:15 2025 +0200

    Related: tdf#166627 Write font-face-src for each mention of embedded font
    
    Before commit e61a179b4ff8ce2072c3c0780628eb38c7a43529 (tdf#166627: embed
    fonts everywhere we emit font data, 2025-05-23),  embedding of fonts only
    happened during export of content.xml, to avoid complexity of shared data
    between different instances of SvXMLExport, created separately per stream.
    
    The said commit introduced a way to pass the data between these instances,
    and embedding now is done by any SvXMLExport instance  that needs to emit
    font-face-decls. Currently, only the first declaration of a used embedded
    font gets its font-face-src.
    
    But this is wrong, when the same embedded font in another stream, where it
    is also used, does not reference its files.  This patch allows all streams
    to emit font-face-src for all fonts used in it. File duplication in ZIP is
    avoided by passing the embedded file information between SvXMLExport, with
    font file hash and its path in ZIP, instead of font names.
    
    Change-Id: I7a62e50c086d8741dbc8aadf61d0f008bad916ff
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185720
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189033
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Michael Stahl <michael.st...@collabora.com>

diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index 7e4b74ef9a47..9ac58acbe00c 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -165,9 +165,8 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public 
cppu::WeakImplHelper<
 
     const OUString               msWS;           // " "
 
+    // A map of font hashes and names that were already embedded, including 
previous passes
     std::unordered_map<OString, OUString> m_aEmbeddedFontFiles;
-    // A list of font names that were already embedded, including previous 
passes
-    std::unordered_set<OUString> m_aEmbeddedFontNames;
 
     // Shapes in Writer cannot be named via context menu (#i51726#)
     SvtModuleOptions::EFactory meModelType;
@@ -318,8 +317,8 @@ public:
     // doesn't handle some style-specific content like headers/footers. These 
methods are for
     // passing the "already embedded" information from one instance to another.
 
-    std::vector<OUString> getEmbeddedFontNames() const;
-    void setEmbeddedFontNames(const std::vector<OUString>&);
+    std::unordered_map<OString, OUString> getEmbeddedFontFiles() const;
+    void setEmbeddedFontFiles(const std::unordered_map<OString, OUString>&);
 
     // XExporter
     virtual void SAL_CALL setSourceDocument( const css::uno::Reference< 
css::lang::XComponent >& xDoc ) override;
diff --git a/sc/inc/xmlwrap.hxx b/sc/inc/xmlwrap.hxx
index 29b867251490..9a192bc01e81 100644
--- a/sc/inc/xmlwrap.hxx
+++ b/sc/inc/xmlwrap.hxx
@@ -63,7 +63,7 @@ class ScXMLImportWrapper
     SfxMedium*      pMedium;
     css::uno::Reference< css::embed::XStorage > xStorage;
 
-    std::vector<OUString> maEmbeddedFontNames;
+    std::unordered_map<OString, OUString> maEmbeddedFontFiles;
 
     css::uno::Reference< css::task::XStatusIndicator> GetStatusIndicator() 
const;
 
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
index 1116d015ac8c..2c3ac3d823f1 100644
--- a/sc/source/filter/xml/xmlwrap.cxx
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -650,7 +650,7 @@ bool ScXMLImportWrapper::ExportToComponent(const 
uno::Reference<uno::XComponentC
         ScXMLExport* pExport = 
static_cast<ScXMLExport*>(dynamic_cast<SvXMLExport*>(xFilter.get()));
         assert(pExport && "can only succeed");
         pExport->SetSharedData(std::move(pSharedData));
-        pExport->setEmbeddedFontNames(maEmbeddedFontNames);
+        pExport->setEmbeddedFontFiles(maEmbeddedFontFiles);
 
         // if there are sheets to copy, get the source stream
         if ( sName == "content.xml" && lcl_HasValidStream(rDoc) && ( 
pExport->getExportFlags() & SvXMLExportFlags::OASIS ) )
@@ -698,7 +698,7 @@ bool ScXMLImportWrapper::ExportToComponent(const 
uno::Reference<uno::XComponentC
         else
             bRet = xFilter->filter( aDescriptor );
 
-        maEmbeddedFontNames = pExport->getEmbeddedFontNames();
+        maEmbeddedFontFiles = pExport->getEmbeddedFontFiles();
         pSharedData = pExport->ReleaseSharedData();
     }
 
diff --git a/sd/source/filter/xml/sdxmlwrp.cxx 
b/sd/source/filter/xml/sdxmlwrp.cxx
index d8cd04671945..caf15884c10f 100644
--- a/sd/source/filter/xml/sdxmlwrp.cxx
+++ b/sd/source/filter/xml/sdxmlwrp.cxx
@@ -896,7 +896,7 @@ bool SdXMLFilter::Export()
             aServices[i].mpStream  = nullptr;
 
             XML_SERVICEMAP* pServices = aServices;
-            std::vector<OUString> aEmbeddedFontNames;
+            std::unordered_map<OString, OUString> maEmbeddedFontFiles;
 
             // doc export
             do
@@ -954,13 +954,13 @@ bool SdXMLFilter::Export()
                         auto pFilter = 
dynamic_cast<SvXMLExport*>(xFilter.get());
                         if (pFilter)
                         {
-                            pFilter->setEmbeddedFontNames(aEmbeddedFontNames);
+                            pFilter->setEmbeddedFontFiles(maEmbeddedFontFiles);
                         }
                         // outputstream will be closed by SAX parser
                         bDocRet = xFilter->filter( aDescriptor );
                         if (pFilter)
                         {
-                            aEmbeddedFontNames = 
pFilter->getEmbeddedFontNames();
+                            maEmbeddedFontFiles = 
pFilter->getEmbeddedFontFiles();
                         }
                     }
                 }
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index df064b740cb7..c61469e6a637 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -2329,7 +2329,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
         assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 2']", 1);
     }
 
-    // Check content - No font-face-src nodes should be present
+    // Check content - font-face-src should be present for all fonts
     pXmlDoc = parseExport(u"content.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
 
@@ -2339,7 +2339,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
     {
         OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
         assertXPath(pXmlDoc, prefix + "['CASE 2']");
-        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 2']", 0);
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 2']", 1);
     }
 
     // CASE 3 - font embedding enabled, embed only used fonts enabled
@@ -2391,19 +2391,19 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
         assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 1);
     }
 
-    // Check content - font-face-src should be present only for Carlito fonts
+    // Check content - font-face-src should be present only for Carlito and 
Liberation Serif fonts
+    // Note that the used sets of fonts are different for styles.xml and 
content.xml
     pXmlDoc = parseExport(u"content.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
 
     assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face['CASE 3']", 6);
-    for (auto fontName : { "Caladea", "Liberation Sans", "Liberation Sans1", 
"Liberation Serif",
-                           "Liberation Serif1" })
+    for (auto fontName : { "Caladea", "Liberation Sans", "Liberation Sans1" })
     {
         OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
         assertXPath(pXmlDoc, prefix + "['CASE 3']");
         assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 0);
     }
-    for (auto fontName : { "Carlito" })
+    for (auto fontName : { "Carlito", "Liberation Serif", "Liberation Serif1" 
})
     {
         OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
         assertXPath(pXmlDoc, prefix + "['CASE 3']");
diff --git a/sw/source/filter/xml/wrtxml.cxx b/sw/source/filter/xml/wrtxml.cxx
index 66faa6342428..2f5e049ea581 100644
--- a/sw/source/filter/xml/wrtxml.cxx
+++ b/sw/source/filter/xml/wrtxml.cxx
@@ -579,12 +579,12 @@ bool SwXMLWriter::WriteThroughComponent(
     if (pFilter)
     {
         pFilter->SetLibreOfficeKitNotifier(SfxViewShell::Current());
-        pFilter->setEmbeddedFontNames(maEmbeddedFontNames);
+        pFilter->setEmbeddedFontFiles(maEmbeddedFontFiles);
     }
     bool result = xFilter->filter( rMediaDesc );
     if (pFilter)
     {
-        maEmbeddedFontNames = pFilter->getEmbeddedFontNames();
+        maEmbeddedFontFiles = pFilter->getEmbeddedFontFiles();
     }
     return result;
 }
diff --git a/sw/source/filter/xml/wrtxml.hxx b/sw/source/filter/xml/wrtxml.hxx
index fa5e2a6f327b..cf45481cf933 100644
--- a/sw/source/filter/xml/wrtxml.hxx
+++ b/sw/source/filter/xml/wrtxml.hxx
@@ -57,7 +57,7 @@ public:
     virtual ErrCodeMsg Write( SwPaM&, SfxMedium&, const OUString* ) override;
 
 private:
-    std::vector<OUString> maEmbeddedFontNames;
+    std::unordered_map<OString, OUString> maEmbeddedFontFiles;
 
     // helper methods to write XML streams
 
diff --git a/xmloff/source/style/XMLFontAutoStylePool.cxx 
b/xmloff/source/style/XMLFontAutoStylePool.cxx
index e2050423b047..3034aef14ee9 100644
--- a/xmloff/source/style/XMLFontAutoStylePool.cxx
+++ b/xmloff/source/style/XMLFontAutoStylePool.cxx
@@ -425,10 +425,8 @@ void SvXMLExport::exportFonts(const 
std::vector<XMLFontAutoStylePoolEntry_Impl*>
 
         SvXMLElementExport aElement(*this, XML_NAMESPACE_STYLE, XML_FONT_FACE, 
true, true);
 
-        // When embedding is requested, and embedded only is not set or font 
is used, and the font
-        // was not embedded already in a different pass
-        if (bEmbedFonts && (!bEmbedUsedOnly || 
aUsedFontNames.contains(pEntry->GetFamilyName()))
-            && !m_aEmbeddedFontNames.contains(pEntry->GetName()))
+        // When embedding is requested, and embedded only is not set or font 
is used
+        if (bEmbedFonts && (!bEmbedUsedOnly || 
aUsedFontNames.contains(pEntry->GetFamilyName())))
         {
             const bool bExportFlat(getExportFlags() & 
SvXMLExportFlags::EMBEDDED);
 
@@ -467,7 +465,6 @@ void SvXMLExport::exportFonts(const 
std::vector<XMLFontAutoStylePoolEntry_Impl*>
             }
             if (!aEmbeddedFonts.empty())
             {
-                m_aEmbeddedFontNames.insert(pEntry->GetName());
                 SvXMLElementExport fontFaceSrc(*this, XML_NAMESPACE_SVG, 
XML_FONT_FACE_SRC, true, true);
                 for (EmbeddedFontInfo const & rEmbeddedFont : aEmbeddedFonts)
                 {
@@ -516,15 +513,14 @@ void SvXMLExport::exportFonts(const 
std::vector<XMLFontAutoStylePoolEntry_Impl*>
     }
 }
 
-std::vector<OUString> SvXMLExport::getEmbeddedFontNames() const
+std::unordered_map<OString, OUString> SvXMLExport::getEmbeddedFontFiles() const
 {
-    return std::vector(m_aEmbeddedFontNames.begin(), 
m_aEmbeddedFontNames.end());
+    return m_aEmbeddedFontFiles;
 }
 
-void SvXMLExport::setEmbeddedFontNames(const std::vector<OUString>& newNames)
+void SvXMLExport::setEmbeddedFontFiles(const std::unordered_map<OString, 
OUString>& value)
 {
-    m_aEmbeddedFontNames.clear();
-    m_aEmbeddedFontNames.insert(newNames.begin(), newNames.end());
+    m_aEmbeddedFontFiles = value;
 }
 
 void XMLFontAutoStylePool::exportXML()
commit eba7d8df443289ea38552560301dedf3d7a14b01
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri May 23 12:14:27 2025 +0500
Commit:     Michael Stahl <michael.st...@collabora.com>
CommitDate: Thu Aug 7 13:50:05 2025 +0200

    tdf#166627: embed fonts everywhere we emit font data
    
    Commit 69ed893087f89d176a5ec4b263ce8d75774be72b (tdf#160253: fix list
    identifier export decision code) made a large change to the autostyle
    collection procedure, which became more precise. It turns out, that
    before that change, exporting content.xml gathered autostyles from
    page definitions, too, meaning that the fonts used there were marked
    as used in that pass. After the change, that pass doesn't look into
    the page styles and their content, and the fonts that are only used
    in headers/footers aren't seen as used in that pass.
    
    The font embedding procedure was previously implemented to only do
    the embedding during content.xml export, to avoid duplicating font
    files from each pass. Since each stream was exported by a separate
    instance of SvXMLExport, it was considered difficult to maintain the
    already embedded fonts list across all passes. It assumed that the
    export of content.xml sees all used fonts.
    
    But after the described change, this assumption doesn't hold anymore.
    We need to make sure to embed all fonts found in all passes.
    
    This change introduces such state, implemented as set of font names
    maintained in the object that exports all the streams, creating an
    exporter for each. Using a new set of function to set and get the
    "already embedded" font list in SvXMLExport, the outer object passes
    that list to each created SvXMLExport instance, and after the call
    to `filter`, retrieves the updated list, to pass it to the next one.
    
    The change required to move some members from XMLFontAutoStylePool
    to SvXMLExport, to avoid additional complexity of passing the list
    from SvXMLExport to XMLFontAutoStylePool. The implementations of
    the moved methods are kept in XMLFontAutoStylePool.cxx, because the
    internal structs used in the methods are defined there.
    
    After the change, some of the embedded font file references, that
    previously appeared in content.xml, will now be in styles.xml.
    
    Change-Id: Iaa26f1d1d623dee5a5c43600ea5fd2af1d04b46f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185704
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189032
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Michael Stahl <michael.st...@collabora.com>

diff --git a/include/xmloff/XMLFontAutoStylePool.hxx 
b/include/xmloff/XMLFontAutoStylePool.hxx
index 569f1443ab14..427ad6dac79f 100644
--- a/include/xmloff/XMLFontAutoStylePool.hxx
+++ b/include/xmloff/XMLFontAutoStylePool.hxx
@@ -40,23 +40,12 @@ private:
 
     std::unique_ptr<XMLFontAutoStylePool_Impl> m_pFontAutoStylePool;
     std::set<OUString> m_aNames;
-    bool m_bTryToEmbedFonts;
-    std::unordered_map<OString, OUString> m_aEmbeddedFontFiles;
-
-    OUString embedFontFile(OUString const & rFileUrl, OUString const & 
rFamilyName);
-
-    std::unordered_set<OUString> getUsedFontList();
 
 protected:
-    bool m_bEmbedUsedOnly;
-    bool m_bEmbedLatinScript;
-    bool m_bEmbedAsianScript;
-    bool m_bEmbedComplexScript;
-
     SvXMLExport& GetExport() { return m_rExport; }
 
 public:
-    XMLFontAutoStylePool( SvXMLExport& rExport, bool tryToEmbedFonts = false );
+    XMLFontAutoStylePool(SvXMLExport& rExport);
     virtual ~XMLFontAutoStylePool() override;
 
     OUString Add(
@@ -74,17 +63,6 @@ public:
             rtl_TextEncoding eEnc )const;
 
     void exportXML();
-
-    void setEmbedOnlyUsedFonts(bool bEmbedUsedOnly)
-    {
-        m_bEmbedUsedOnly = bEmbedUsedOnly;
-    }
-    void setEmbedFontScripts(bool bEmbedLatinScript, bool bEmbedAsianScript, 
bool bEmbedComplexScript)
-    {
-        m_bEmbedLatinScript = bEmbedLatinScript;
-        m_bEmbedAsianScript = bEmbedAsianScript;
-        m_bEmbedComplexScript = bEmbedComplexScript;
-    }
 };
 
 #endif // INCLUDED_XMLOFF_XMLFONTAUTOSTYLEPOOL_HXX
diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index 4ff51e19bc50..7e4b74ef9a47 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -51,6 +51,8 @@
 
 #include <vector>
 #include <memory>
+#include <unordered_map>
+#include <unordered_set>
 #include <o3tl/typed_flags_set.hxx>
 
 namespace com::sun::star::beans { class XPropertySet; }
@@ -72,6 +74,7 @@ class SvtSecurityMapPersonalInfo;
 class SvXMLExport_Impl;
 class ProgressBarHelper;
 class XMLEventExport;
+class XMLFontAutoStylePoolEntry_Impl;
 class XMLImageMapExport;
 class XMLErrors;
 class LanguageTag;
@@ -162,6 +165,10 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public 
cppu::WeakImplHelper<
 
     const OUString               msWS;           // " "
 
+    std::unordered_map<OString, OUString> m_aEmbeddedFontFiles;
+    // A list of font names that were already embedded, including previous 
passes
+    std::unordered_set<OUString> m_aEmbeddedFontNames;
+
     // Shapes in Writer cannot be named via context menu (#i51726#)
     SvtModuleOptions::EFactory meModelType;
     SAL_DLLPRIVATE void DetermineModelType_();
@@ -177,6 +184,9 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public 
cppu::WeakImplHelper<
     virtual void SetBodyAttributes();
     void 
GetViewSettingsAndViews(css::uno::Sequence<css::beans::PropertyValue>& rProps);
 
+    OUString embedFontFile(OUString const& rFileUrl, OUString const& 
rFamilyName);
+    std::unordered_set<OUString> getUsedFontList();
+
 protected:
     void setExportFlags( SvXMLExportFlags nExportFlags ) { mnExportFlags = 
nExportFlags; }
 
@@ -229,6 +239,12 @@ protected:
     virtual void 
GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps);
     virtual void 
GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps);
 
+    virtual bool getEmbedFonts() { return false; }
+    virtual bool getEmbedOnlyUsedFonts() { return false; }
+    virtual bool getEmbedLatinScript() { return true; }
+    virtual bool getEmbedAsianScript() { return true; }
+    virtual bool getEmbedComplexScript() { return true; }
+
     struct SettingsGroup
     {
         ::xmloff::token::XMLTokenEnum                     eGroupName;
@@ -294,6 +310,16 @@ public:
     virtual ~SvXMLExport() override;
 
     virtual void collectAutoStyles();
+    void exportFonts(const std::vector<XMLFontAutoStylePoolEntry_Impl*>& 
rFonts);
+
+    // We write font info to both content.xml and styles.xml, but they are 
written by different
+    // SvXMLExport instances, and would therefore embed each font file twice, 
if done naively. On
+    // the other hand, we can't limit the embedding only to content.xml phase, 
because there it
+    // doesn't handle some style-specific content like headers/footers. These 
methods are for
+    // passing the "already embedded" information from one instance to another.
+
+    std::vector<OUString> getEmbeddedFontNames() const;
+    void setEmbeddedFontNames(const std::vector<OUString>&);
 
     // XExporter
     virtual void SAL_CALL setSourceDocument( const css::uno::Reference< 
css::lang::XComponent >& xDoc ) override;
diff --git a/sc/inc/xmlwrap.hxx b/sc/inc/xmlwrap.hxx
index bfae5363cfbd..29b867251490 100644
--- a/sc/inc/xmlwrap.hxx
+++ b/sc/inc/xmlwrap.hxx
@@ -63,6 +63,8 @@ class ScXMLImportWrapper
     SfxMedium*      pMedium;
     css::uno::Reference< css::embed::XStorage > xStorage;
 
+    std::vector<OUString> maEmbeddedFontNames;
+
     css::uno::Reference< css::task::XStatusIndicator> GetStatusIndicator() 
const;
 
     ErrCodeMsg ImportFromComponent(const 
css::uno::Reference<css::uno::XComponentContext>& xContext,
diff --git a/sc/source/filter/xml/xmlexprt.hxx 
b/sc/source/filter/xml/xmlexprt.hxx
index d7ad2c726187..0ff2e453f400 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -227,6 +227,12 @@ protected:
     virtual XMLPageExport* CreatePageExport() override;
     virtual XMLShapeExport* CreateShapeExport() override;
     virtual XMLFontAutoStylePool* CreateFontAutoStylePool() override;
+    virtual bool getEmbedFonts() override;
+    virtual bool getEmbedOnlyUsedFonts() override;
+    virtual bool getEmbedLatinScript() override;
+    virtual bool getEmbedAsianScript() override;
+    virtual bool getEmbedComplexScript() override;
+
 public:
     ScXMLExport(
         const css::uno::Reference< css::uno::XComponentContext >& rContext,
diff --git a/sc/source/filter/xml/xmlfonte.cxx 
b/sc/source/filter/xml/xmlfonte.cxx
index 55d0eee18f4e..3b71077614fa 100644
--- a/sc/source/filter/xml/xmlfonte.cxx
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -41,7 +41,7 @@ private:
     void AddFontItems(const sal_uInt16* pWhichIds, sal_uInt8 nIdCount, const 
SfxItemPool* pItemPool, const bool bExportDefaults);
 
 public:
-    ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, ScXMLExport& rExport, bool 
bEmbedFonts);
+    ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, ScXMLExport& rExport);
 };
 
 }
@@ -71,8 +71,8 @@ void ScXMLFontAutoStylePool_Impl::AddFontItems(const 
sal_uInt16* pWhichIds, sal_
     }
 }
 
-ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, 
ScXMLExport& rExportP, bool bEmbedFonts)
-    : XMLFontAutoStylePool(rExportP, bEmbedFonts)
+ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, 
ScXMLExport& rExportP)
+    : XMLFontAutoStylePool(rExportP)
 {
     if (!pDoc)
         return;
@@ -92,11 +92,6 @@ 
ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, ScXML
 
     std::unique_ptr<SfxStyleSheetIterator> pItr = 
pDoc->GetStyleSheetPool()->CreateIterator(SfxStyleFamily::Page);
 
-    m_bEmbedUsedOnly = pDoc->IsEmbedUsedFontsOnly();
-    m_bEmbedLatinScript = pDoc->IsEmbedFontScriptLatin();
-    m_bEmbedAsianScript = pDoc->IsEmbedFontScriptAsian();
-    m_bEmbedComplexScript = pDoc->IsEmbedFontScriptComplex();
-
     if(!pItr)
         return;
 
@@ -148,17 +143,13 @@ 
ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScDocument* pDoc, ScXML
 
 XMLFontAutoStylePool* ScXMLExport::CreateFontAutoStylePool()
 {
-    bool blockFontEmbedding = false;
-    // We write font info to both content.xml and styles.xml, but they are both
-    // written by different ScXMLExport instance, and would therefore write 
each
-    // font file twice without complicated checking for duplicates, so handle
-    // the embedding only in one of them.
-    if(!( getExportFlags() & SvXMLExportFlags::CONTENT ))
-        blockFontEmbedding = true;
-    ScDocument* pDoc = GetDocument();
-    if (pDoc && !pDoc->IsEmbedFonts())
-        blockFontEmbedding = true;
-    return new ScXMLFontAutoStylePool_Impl(pDoc, *this, !blockFontEmbedding);
+    return new ScXMLFontAutoStylePool_Impl(GetDocument(), *this);
 }
 
+bool ScXMLExport::getEmbedFonts() { return GetDocument()->IsEmbedFonts(); }
+bool ScXMLExport::getEmbedOnlyUsedFonts() { return 
GetDocument()->IsEmbedUsedFontsOnly(); }
+bool ScXMLExport::getEmbedLatinScript() { return 
GetDocument()->IsEmbedFontScriptLatin(); }
+bool ScXMLExport::getEmbedAsianScript() { return 
GetDocument()->IsEmbedFontScriptAsian(); }
+bool ScXMLExport::getEmbedComplexScript() { return 
GetDocument()->IsEmbedFontScriptComplex(); }
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
index bf4e055440db..1116d015ac8c 100644
--- a/sc/source/filter/xml/xmlwrap.cxx
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -650,6 +650,7 @@ bool ScXMLImportWrapper::ExportToComponent(const 
uno::Reference<uno::XComponentC
         ScXMLExport* pExport = 
static_cast<ScXMLExport*>(dynamic_cast<SvXMLExport*>(xFilter.get()));
         assert(pExport && "can only succeed");
         pExport->SetSharedData(std::move(pSharedData));
+        pExport->setEmbeddedFontNames(maEmbeddedFontNames);
 
         // if there are sheets to copy, get the source stream
         if ( sName == "content.xml" && lcl_HasValidStream(rDoc) && ( 
pExport->getExportFlags() & SvXMLExportFlags::OASIS ) )
@@ -697,6 +698,7 @@ bool ScXMLImportWrapper::ExportToComponent(const 
uno::Reference<uno::XComponentC
         else
             bRet = xFilter->filter( aDescriptor );
 
+        maEmbeddedFontNames = pExport->getEmbeddedFontNames();
         pSharedData = pExport->ReleaseSharedData();
     }
 
diff --git a/sd/source/filter/xml/sdxmlwrp.cxx 
b/sd/source/filter/xml/sdxmlwrp.cxx
index 8bf962a7ede0..d8cd04671945 100644
--- a/sd/source/filter/xml/sdxmlwrp.cxx
+++ b/sd/source/filter/xml/sdxmlwrp.cxx
@@ -38,6 +38,7 @@
 #include <svx/dialmgr.hxx>
 #include <svx/strings.hrc>
 #include <svx/xmlgrhlp.hxx>
+#include <xmloff/xmlexp.hxx>
 
 #include <DrawDocShell.hxx>
 
@@ -895,6 +896,7 @@ bool SdXMLFilter::Export()
             aServices[i].mpStream  = nullptr;
 
             XML_SERVICEMAP* pServices = aServices;
+            std::vector<OUString> aEmbeddedFontNames;
 
             // doc export
             do
@@ -948,8 +950,18 @@ bool SdXMLFilter::Export()
                     if( xExporter.is() )
                     {
                         xExporter->setSourceDocument( mxModel );
+
+                        auto pFilter = 
dynamic_cast<SvXMLExport*>(xFilter.get());
+                        if (pFilter)
+                        {
+                            pFilter->setEmbeddedFontNames(aEmbeddedFontNames);
+                        }
                         // outputstream will be closed by SAX parser
                         bDocRet = xFilter->filter( aDescriptor );
+                        if (pFilter)
+                        {
+                            aEmbeddedFontNames = 
pFilter->getEmbeddedFontNames();
+                        }
                     }
                 }
 
diff --git a/sw/qa/extras/odfexport/data/font_used_in_header_only.fodt 
b/sw/qa/extras/odfexport/data/font_used_in_header_only.fodt
new file mode 100644
index 000000000000..17f7feed9e93
--- /dev/null
+++ b/sw/qa/extras/odfexport/data/font_used_in_header_only.fodt
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<office:document 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:ooo="http://openoffice.org/2004/office"; 
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" 
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" 
xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" 
office:version="1.4" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:settings>
+  <config:config-item-set config:name="ooo:configuration-settings">
+   <config:config-item config:name="EmbedFonts" 
config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedOnlyUsedFonts" 
config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedLatinScriptFonts" 
config:type="boolean">true</config:config-item>
+   <config:config-item config:name="EmbedAsianScriptFonts" 
config:type="boolean">false</config:config-item>
+   <config:config-item config:name="EmbedComplexScriptFonts" 
config:type="boolean">false</config:config-item>
+  </config:config-item-set>
+ </office:settings>
+ <office:font-face-decls>
+  <style:font-face style:name="Liberation Sans" 
svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" 
style:font-pitch="variable"/>
+  <style:font-face style:name="Liberation Serif" 
svg:font-family="&apos;Liberation Serif&apos;" 
style:font-family-generic="roman" style:font-pitch="variable"/>
+ </office:font-face-decls>
+ <office:styles>
+  <style:default-style style:family="paragraph">
+   <style:text-properties style:font-name="Liberation Serif" 
fo:font-size="12pt" fo:language="en" fo:country="US"/>
+  </style:default-style>
+  <style:style style:name="Standard" style:family="paragraph" 
style:class="text"/>
+ </office:styles>
+ <office:automatic-styles>
+  <style:style style:name="P1" style:family="paragraph" 
style:parent-style-name="Standard">
+   <style:text-properties style:font-name="Liberation Sans"/>
+  </style:style>
+  <style:page-layout style:name="pm1">
+   <style:header-style>
+    <style:header-footer-properties fo:min-height="0" fo:margin-left="0" 
fo:margin-right="0" fo:margin-bottom="5mm"/>
+   </style:header-style>
+  </style:page-layout>
+ </office:automatic-styles>
+ <office:master-styles>
+  <style:master-page style:name="Standard" style:page-layout-name="pm1">
+   <style:header>
+    <text:p text:style-name="P1">Header: Liberation Sans</text:p>
+   </style:header>
+  </style:master-page>
+ </office:master-styles>
+ <office:body>
+  <office:text>
+   <text:p>Body: Liberation Serif</text:p>
+  </office:text>
+ </office:body>
+</office:document>
\ No newline at end of file
diff --git a/sw/qa/extras/odfexport/odfexport2.cxx 
b/sw/qa/extras/odfexport/odfexport2.cxx
index b2c844e91f81..85991c7570f5 100644
--- a/sw/qa/extras/odfexport/odfexport2.cxx
+++ b/sw/qa/extras/odfexport/odfexport2.cxx
@@ -18,6 +18,7 @@
 #include <com/sun/star/linguistic2/XHyphenator.hpp>
 #include <com/sun/star/style/VerticalAlignment.hpp>
 #include <com/sun/star/text/ColumnSeparatorStyle.hpp>
+#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
 #include <com/sun/star/text/XBookmarksSupplier.hpp>
 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
 #include <com/sun/star/text/XDocumentIndex.hpp>
@@ -61,7 +62,7 @@ CPPUNIT_TEST_FIXTURE(Test, testEmbeddedFontProps)
 #if !defined(MACOSX)
     // Test that font style/weight of embedded fonts is exposed.
     // Test file is a normal ODT, except EmbedFonts is set to true in 
settings.xml.
-    xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
+    xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
     // These failed, the attributes were missing.
     assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation 
Serif']/svg:font-face-src/svg:font-face-uri[1]", "font-style", u"normal");
     assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation 
Serif']/svg:font-face-src/svg:font-face-uri[1]", "font-weight", u"normal");
@@ -74,6 +75,45 @@ CPPUNIT_TEST_FIXTURE(Test, testEmbeddedFontProps)
 #endif
 }
 
+CPPUNIT_TEST_FIXTURE(Test, tdf166627)
+{
+    loadAndReload("font_used_in_header_only.fodt");
+    // Liberation Sans wasn't embedded before fix, because it was only seen 
used in header
+
+    xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
+
+    // There should be four files embedded for the font
+    assertXPath(
+        pXmlDoc,
+        "//style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src/svg:font-face-uri", 4);
+
+    uno::Reference<container::XNameAccess> xZipNames(
+        
packages::zip::ZipFileAccess::createWithURL(comphelper::getProcessComponentContext(),
+                                                    maTempFile.GetURL()),
+        uno::UNO_SET_THROW);
+
+    OUString url = getXPath(
+        pXmlDoc,
+        "//style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src/svg:font-face-uri[1]",
+        "href");
+    CPPUNIT_ASSERT(xZipNames->hasByName(url));
+    url = getXPath(
+        pXmlDoc,
+        "//style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src/svg:font-face-uri[2]",
+        "href");
+    CPPUNIT_ASSERT(xZipNames->hasByName(url));
+    url = getXPath(
+        pXmlDoc,
+        "//style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src/svg:font-face-uri[3]",
+        "href");
+    CPPUNIT_ASSERT(xZipNames->hasByName(url));
+    url = getXPath(
+        pXmlDoc,
+        "//style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src/svg:font-face-uri[4]",
+        "href");
+    CPPUNIT_ASSERT(xZipNames->hasByName(url));
+}
+
 DECLARE_ODFEXPORT_TEST(testTdf100492, "tdf100492.odt")
 {
     CPPUNIT_ASSERT_EQUAL(2, getShapes());
diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx 
b/sw/qa/extras/uiwriter/uiwriter6.cxx
index af5c132f880a..df064b740cb7 100644
--- a/sw/qa/extras/uiwriter/uiwriter6.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter6.cxx
@@ -2230,6 +2230,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
     createSwDoc("testFontEmbedding.odt");
 
     OString 
aContentBaseXpath("/office:document-content/office:font-face-decls"_ostr);
+    OString 
aStylesBaseXpath("/office:document-styles/office:font-face-decls"_ostr);
     OString aSettingsBaseXpath(
         
"/office:document-settings/office:settings/config:config-item-set"_ostr);
 
@@ -2261,36 +2262,31 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
     assertXPathContent(
         pXmlDoc, aSettingsBaseXpath + 
"/config:config-item[@config:name='EmbedFonts']", u"false");
 
+    // Check styles - No font-face-src nodes should be present
+    pXmlDoc = parseExport(u"styles.xml"_ustr);
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    assertXPath(pXmlDoc, aStylesBaseXpath + "/style:font-face['CASE 1']", 6);
+    for (auto fontName : { "Caladea", "Carlito", "Liberation Sans", 
"Liberation Sans1",
+                           "Liberation Serif", "Liberation Serif1" })
+    {
+        OString prefix = aStylesBaseXpath + "/style:font-face[@style:name='" + 
fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 1']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 1']", 0);
+    }
+
     // Check content - No font-face-src nodes should be present
     pXmlDoc = parseExport(u"content.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
 
-    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face", 6);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans']");
-    assertXPath(
-        pXmlDoc,
-        aContentBaseXpath + "/style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src", 0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Sans1']/svg:font-face-src",
-                0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif']/svg:font-face-src",
-                0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif1']/svg:font-face-src",
-                0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']/svg:font-face-src", 0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']/svg:font-face-src", 0);
+    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face['CASE 1']", 6);
+    for (auto fontName : { "Caladea", "Carlito", "Liberation Sans", 
"Liberation Sans1",
+                           "Liberation Serif", "Liberation Serif1" })
+    {
+        OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 1']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 1']", 0);
+    }
 
     // CASE 2 - font embedding enabled, but embed used fonts disabled
 
@@ -2302,7 +2298,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
     save(u"writer8"_ustr);
     CPPUNIT_ASSERT(maTempFile.IsValid());
 
-    // Check setting - font embedding should be enabled + embed only used 
fonts and scripts
+    // Check setting - font embedding should be enabled
     pXmlDoc = parseExport(u"settings.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
     assertXPathContent(
@@ -2320,37 +2316,31 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
         pXmlDoc, aSettingsBaseXpath + 
"/config:config-item[@config:name='EmbedComplexScriptFonts']",
         u"true");
 
-    // Check content - font-face-src should be present only for "Liberation 
Sans" fonts
+    // Check styles - font-face-src should be present for all fonts
+    pXmlDoc = parseExport(u"styles.xml"_ustr);
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    assertXPath(pXmlDoc, aStylesBaseXpath + "/style:font-face['CASE 2']", 6);
+    for (auto fontName : { "Caladea", "Carlito", "Liberation Sans", 
"Liberation Sans1",
+                           "Liberation Serif", "Liberation Serif1" })
+    {
+        OString prefix = aStylesBaseXpath + "/style:font-face[@style:name='" + 
fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 2']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 2']", 1);
+    }
 
+    // Check content - No font-face-src nodes should be present
     pXmlDoc = parseExport(u"content.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
 
-    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face", 6);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans']");
-    assertXPath(
-        pXmlDoc,
-        aContentBaseXpath + "/style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src", 1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Sans1']/svg:font-face-src",
-                1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif']/svg:font-face-src",
-                1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif1']/svg:font-face-src",
-                1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']/svg:font-face-src", 1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']/svg:font-face-src", 1);
+    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face['CASE 2']", 6);
+    for (auto fontName : { "Caladea", "Carlito", "Liberation Sans", 
"Liberation Sans1",
+                           "Liberation Serif", "Liberation Serif1" })
+    {
+        OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 2']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 2']", 0);
+    }
 
     // CASE 3 - font embedding enabled, embed only used fonts enabled
 
@@ -2383,37 +2373,42 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testFontEmbedding)
         pXmlDoc, aSettingsBaseXpath + 
"/config:config-item[@config:name='EmbedComplexScriptFonts']",
         u"true");
 
-    // Check content - font-face-src should be present only for "Liberation 
Sans" fonts
+    // Check styles - font-face-src should be present only for "Liberation 
Serif" fonts
+    pXmlDoc = parseExport(u"styles.xml"_ustr);
+    CPPUNIT_ASSERT(pXmlDoc);
+
+    assertXPath(pXmlDoc, aStylesBaseXpath + "/style:font-face['CASE 3']", 6);
+    for (auto fontName : { "Caladea", "Carlito", "Liberation Sans", 
"Liberation Sans1" })
+    {
+        OString prefix = aStylesBaseXpath + "/style:font-face[@style:name='" + 
fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 3']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 0);
+    }
+    for (auto fontName : { "Liberation Serif", "Liberation Serif1" })
+    {
+        OString prefix = aStylesBaseXpath + "/style:font-face[@style:name='" + 
fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 3']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 1);
+    }
 
+    // Check content - font-face-src should be present only for Carlito fonts
     pXmlDoc = parseExport(u"content.xml"_ustr);
     CPPUNIT_ASSERT(pXmlDoc);
 
-    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face", 6);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans']");
-    assertXPath(
-        pXmlDoc,
-        aContentBaseXpath + "/style:font-face[@style:name='Liberation 
Sans']/svg:font-face-src", 0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Sans1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Sans1']/svg:font-face-src",
-                0);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif']/svg:font-face-src",
-                1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Liberation Serif1']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath
-                    + "/style:font-face[@style:name='Liberation 
Serif1']/svg:font-face-src",
-                1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Carlito']/svg:font-face-src", 1);
-    assertXPath(pXmlDoc, aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']");
-    assertXPath(pXmlDoc,
-                aContentBaseXpath + 
"/style:font-face[@style:name='Caladea']/svg:font-face-src", 0);
+    assertXPath(pXmlDoc, aContentBaseXpath + "/style:font-face['CASE 3']", 6);
+    for (auto fontName : { "Caladea", "Liberation Sans", "Liberation Sans1", 
"Liberation Serif",
+                           "Liberation Serif1" })
+    {
+        OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 3']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 0);
+    }
+    for (auto fontName : { "Carlito" })
+    {
+        OString prefix = aContentBaseXpath + "/style:font-face[@style:name='" 
+ fontName + "']";
+        assertXPath(pXmlDoc, prefix + "['CASE 3']");
+        assertXPath(pXmlDoc, prefix + "/svg:font-face-src['CASE 3']", 1);
+    }
 #endif
 }
 
diff --git a/sw/source/filter/xml/wrtxml.cxx b/sw/source/filter/xml/wrtxml.cxx
index 01d0bd2b682e..66faa6342428 100644
--- a/sw/source/filter/xml/wrtxml.cxx
+++ b/sw/source/filter/xml/wrtxml.cxx
@@ -579,8 +579,14 @@ bool SwXMLWriter::WriteThroughComponent(
     if (pFilter)
     {
         pFilter->SetLibreOfficeKitNotifier(SfxViewShell::Current());
+        pFilter->setEmbeddedFontNames(maEmbeddedFontNames);
     }
-    return xFilter->filter( rMediaDesc );
+    bool result = xFilter->filter( rMediaDesc );
+    if (pFilter)
+    {
+        maEmbeddedFontNames = pFilter->getEmbeddedFontNames();
+    }
+    return result;
 }
 
 void GetXMLWriter(
diff --git a/sw/source/filter/xml/wrtxml.hxx b/sw/source/filter/xml/wrtxml.hxx
index abbdd7aa7bde..fa5e2a6f327b 100644
--- a/sw/source/filter/xml/wrtxml.hxx
+++ b/sw/source/filter/xml/wrtxml.hxx
@@ -25,6 +25,8 @@
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <shellio.hxx>
 
+#include <vector>
+
 class SwPaM;
 class SfxMedium;
 
@@ -55,6 +57,7 @@ public:
     virtual ErrCodeMsg Write( SwPaM&, SfxMedium&, const OUString* ) override;
 
 private:
+    std::vector<OUString> maEmbeddedFontNames;
 
     // helper methods to write XML streams
 
@@ -73,7 +76,7 @@ private:
 
     // write a single output stream
     // (to be called either directly or by WriteThroughComponent(...))
-    static bool WriteThroughComponent(
+    bool WriteThroughComponent(
         const css::uno::Reference<css::io::XOutputStream> & xOutputStream,
         const css::uno::Reference<css::lang::XComponent> & xComponent,
         const css::uno::Reference<css::uno::XComponentContext> & rFactory,
diff --git a/sw/source/filter/xml/xmlexp.hxx b/sw/source/filter/xml/xmlexp.hxx
index 6e095396db61..780ff0c8ddd7 100644
--- a/sw/source/filter/xml/xmlexp.hxx
+++ b/sw/source/filter/xml/xmlexp.hxx
@@ -112,6 +112,11 @@ protected:
     virtual XMLPageExport* CreatePageExport() override;
     virtual XMLShapeExport* CreateShapeExport() override;
     virtual XMLFontAutoStylePool* CreateFontAutoStylePool() override;
+    virtual bool getEmbedFonts() override;
+    virtual bool getEmbedOnlyUsedFonts() override;
+    virtual bool getEmbedLatinScript() override;
+    virtual bool getEmbedAsianScript() override;
+    virtual bool getEmbedComplexScript() override;
 
 public:
     SwXMLExport(
diff --git a/sw/source/filter/xml/xmlfonte.cxx 
b/sw/source/filter/xml/xmlfonte.cxx
index 8c521e5fe293..974542f1d4e0 100644
--- a/sw/source/filter/xml/xmlfonte.cxx
+++ b/sw/source/filter/xml/xmlfonte.cxx
@@ -33,7 +33,7 @@ namespace {
 class SwXMLFontAutoStylePool_Impl: public XMLFontAutoStylePool
 {
 public:
-    SwXMLFontAutoStylePool_Impl(SwXMLExport& rExport, bool bFontEmbedding);
+    SwXMLFontAutoStylePool_Impl(SwXMLExport& rExport);
 };
 
 }
@@ -56,8 +56,8 @@ sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB)
 }
 }
 
-SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& 
_rExport, bool bFontEmbedding)
-    : XMLFontAutoStylePool(_rExport, bFontEmbedding)
+SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport)
+    : XMLFontAutoStylePool(_rExport)
 {
     TypedWhichId<SvxFontItem> const aWhichIds[3] = { RES_CHRATR_FONT, 
RES_CHRATR_CJK_FONT,
                                       RES_CHRATR_CTL_FONT };
@@ -110,28 +110,32 @@ 
SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport,
         Add(pFont->GetFamilyName(), pFont->GetStyleName(), pFont->GetFamily(), 
pFont->GetPitch(),
             pFont->GetCharSet());
     }
-
-    auto const pDocument = _rExport.getDoc();
-
-    m_bEmbedUsedOnly = 
pDocument->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_USED_FONTS);
-    m_bEmbedLatinScript = 
pDocument->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_LATIN_SCRIPT_FONTS);
-    m_bEmbedAsianScript = 
pDocument->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_ASIAN_SCRIPT_FONTS);
-    m_bEmbedComplexScript = 
pDocument->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_COMPLEX_SCRIPT_FONTS);
-
 }
 
 XMLFontAutoStylePool* SwXMLExport::CreateFontAutoStylePool()
 {
-    bool blockFontEmbedding = false;
-    // We write font info to both content.xml and styles.xml, but they are both
-    // written by different SwXMLExport instance, and would therefore write 
each
-    // font file twice without complicated checking for duplicates, so handle
-    // the embedding only in one of them.
-    if( !( getExportFlags() & SvXMLExportFlags::CONTENT) )
-        blockFontEmbedding = true;
-    if( !getDoc()->getIDocumentSettingAccess().get( 
DocumentSettingId::EMBED_FONTS ))
-        blockFontEmbedding = true;
-    return new SwXMLFontAutoStylePool_Impl( *this, !blockFontEmbedding );
+    return new SwXMLFontAutoStylePool_Impl(*this);
+}
+
+bool SwXMLExport::getEmbedFonts()
+{
+    return 
getDoc()->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_FONTS);
+}
+bool SwXMLExport::getEmbedOnlyUsedFonts()
+{
+    return 
getDoc()->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_USED_FONTS);
+}
+bool SwXMLExport::getEmbedLatinScript()
+{
+    return 
getDoc()->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_LATIN_SCRIPT_FONTS);
+}
+bool SwXMLExport::getEmbedAsianScript()
+{
+    return 
getDoc()->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_ASIAN_SCRIPT_FONTS);
+}
+bool SwXMLExport::getEmbedComplexScript()
+{
+    return 
getDoc()->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_COMPLEX_SCRIPT_FONTS);
 }
 
 void SwXMLImport::NotifyContainsEmbeddedFont()
diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx
index 74ee70aa6a33..93b88d8abb40 100644
--- a/xmloff/source/draw/sdxmlexp.cxx
+++ b/xmloff/source/draw/sdxmlexp.cxx
@@ -2774,47 +2774,36 @@ 
com_sun_star_comp_Impress_XMLClipboardExporter_get_implementation(
 
 XMLFontAutoStylePool* SdXMLExport::CreateFontAutoStylePool()
 {
-    bool bEmbedFonts = false;
-    bool bEmbedUsedOnly = false;
-    bool bEmbedLatinScript = true;
-    bool bEmbedAsianScript = true;
-    bool bEmbedComplexScript = true;
-
-    if (getExportFlags() & SvXMLExportFlags::CONTENT)
+    try
     {
-        try
-        {
-            Reference<lang::XMultiServiceFactory> xFactory(GetModel(), 
UNO_QUERY);
-            Reference<beans::XPropertySet> xProps;
-            Reference<beans::XPropertySetInfo> xInfo;
-
-            if (xFactory.is())
-                
xProps.set(xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), 
UNO_QUERY);
-            if (xProps.is())
-                xInfo =  xProps->getPropertySetInfo();
-            if (xInfo.is() && xProps.is())
-            {
-                if (xInfo->hasPropertyByName(u"EmbedFonts"_ustr))
-                    xProps->getPropertyValue(u"EmbedFonts"_ustr) >>= 
bEmbedFonts;
-                if (xInfo->hasPropertyByName(u"EmbedOnlyUsedFonts"_ustr))
-                    xProps->getPropertyValue(u"EmbedOnlyUsedFonts"_ustr) >>= 
bEmbedUsedOnly;
-                if (xInfo->hasPropertyByName(u"EmbedLatinScriptFonts"_ustr))
-                    xProps->getPropertyValue(u"EmbedLatinScriptFonts"_ustr) 
>>= bEmbedLatinScript;
-                if (xInfo->hasPropertyByName(u"EmbedAsianScriptFonts"_ustr))
-                    xProps->getPropertyValue(u"EmbedAsianScriptFonts"_ustr) 
>>= bEmbedAsianScript;
-                if (xInfo->hasPropertyByName(u"EmbedComplexScriptFonts"_ustr))
-                    xProps->getPropertyValue(u"EmbedComplexScriptFonts"_ustr) 
>>= bEmbedComplexScript;
-            }
-        } catch(...)
+        Reference<lang::XMultiServiceFactory> xFactory(GetModel(), UNO_QUERY);
+        Reference<beans::XPropertySet> xProps;
+        Reference<beans::XPropertySetInfo> xInfo;
+
+        if (xFactory.is())
+            
xProps.set(xFactory->createInstance(u"com.sun.star.document.Settings"_ustr), 
UNO_QUERY);
+        if (xProps.is())
+            xInfo =  xProps->getPropertySetInfo();
+        if (xInfo.is() && xProps.is())
         {
-            // clipboard document doesn't have shell so throws from 
getPropertyValue
-            // gallery elements may not support com.sun.star.document.Settings 
so throws from createInstance
+            if (xInfo->hasPropertyByName(u"EmbedFonts"_ustr))
+                xProps->getPropertyValue(u"EmbedFonts"_ustr) >>= mbEmbedFonts;
+            if (xInfo->hasPropertyByName(u"EmbedOnlyUsedFonts"_ustr))
+                xProps->getPropertyValue(u"EmbedOnlyUsedFonts"_ustr) >>= 
mbEmbedUsedOnly;
+            if (xInfo->hasPropertyByName(u"EmbedLatinScriptFonts"_ustr))
+                xProps->getPropertyValue(u"EmbedLatinScriptFonts"_ustr) >>= 
mbEmbedLatinScript;
+            if (xInfo->hasPropertyByName(u"EmbedAsianScriptFonts"_ustr))
+                xProps->getPropertyValue(u"EmbedAsianScriptFonts"_ustr) >>= 
mbEmbedAsianScript;
+            if (xInfo->hasPropertyByName(u"EmbedComplexScriptFonts"_ustr))
+                xProps->getPropertyValue(u"EmbedComplexScriptFonts"_ustr) >>= 
mbEmbedComplexScript;
         }
+    } catch(...)
+    {
+        // clipboard document doesn't have shell so throws from 
getPropertyValue
+        // gallery elements may not support com.sun.star.document.Settings so 
throws from createInstance
     }
 
-    XMLFontAutoStylePool *pPool = new XMLFontAutoStylePool( *this, bEmbedFonts 
);
-    pPool->setEmbedOnlyUsedFonts(bEmbedUsedOnly);
-    pPool->setEmbedFontScripts(bEmbedLatinScript, bEmbedAsianScript, 
bEmbedComplexScript);
+    XMLFontAutoStylePool* pPool = new XMLFontAutoStylePool(*this);
 
     Reference< beans::XPropertySet > xProps( GetModel(), UNO_QUERY );
     if ( xProps.is() ) {
diff --git a/xmloff/source/draw/sdxmlexp_impl.hxx 
b/xmloff/source/draw/sdxmlexp_impl.hxx
index 8207d64e3b9e..ab79e5590f71 100644
--- a/xmloff/source/draw/sdxmlexp_impl.hxx
+++ b/xmloff/source/draw/sdxmlexp_impl.hxx
@@ -109,6 +109,12 @@ class SdXMLExport : public SvXMLExport
 
     bool            mbIsDraw;
 
+    bool mbEmbedFonts = false;
+    bool mbEmbedUsedOnly = false;
+    bool mbEmbedLatinScript = true;
+    bool mbEmbedAsianScript = true;
+    bool mbEmbedComplexScript = true;
+
     virtual void ExportStyles_(bool bUsed) override;
     virtual void ExportAutoStyles_() override;
     virtual void ExportFontDecls_() override;
@@ -150,6 +156,11 @@ protected:
     virtual void 
GetViewSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) override;
     virtual void 
GetConfigurationSettings(css::uno::Sequence<css::beans::PropertyValue>& aProps) 
override;
     virtual XMLFontAutoStylePool* CreateFontAutoStylePool() override;
+    virtual bool getEmbedFonts() override { return mbEmbedFonts; }
+    virtual bool getEmbedOnlyUsedFonts() override { return mbEmbedUsedOnly; }
+    virtual bool getEmbedLatinScript() override { return mbEmbedLatinScript; }
+    virtual bool getEmbedAsianScript() override { return mbEmbedAsianScript; }
+    virtual bool getEmbedComplexScript() override { return 
mbEmbedComplexScript; }
 
 public:
     SdXMLExport(
diff --git a/xmloff/source/style/XMLFontAutoStylePool.cxx 
b/xmloff/source/style/XMLFontAutoStylePool.cxx
index 363b4a575e8e..e2050423b047 100644
--- a/xmloff/source/style/XMLFontAutoStylePool.cxx
+++ b/xmloff/source/style/XMLFontAutoStylePool.cxx
@@ -49,8 +49,6 @@ using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
 using namespace ::xmloff::token;
 
-namespace {
-
 class XMLFontAutoStylePoolEntry_Impl
 {
     OUString    sName;
@@ -85,8 +83,6 @@ public:
     rtl_TextEncoding GetEncoding() const { return eEnc; }
 };
 
-}
-
 inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
         OUString aName,
         OUString aFamilyName,
@@ -150,14 +146,9 @@ class XMLFontAutoStylePool_Impl : public 
o3tl::sorted_vector<std::unique_ptr<XML
 {
 };
 
-XMLFontAutoStylePool::XMLFontAutoStylePool(SvXMLExport& rExp, bool 
bTryToEmbedFonts) :
+XMLFontAutoStylePool::XMLFontAutoStylePool(SvXMLExport& rExp) :
     m_rExport( rExp ),
-    m_pFontAutoStylePool( new XMLFontAutoStylePool_Impl ),
-    m_bTryToEmbedFonts( bTryToEmbedFonts ),
-    m_bEmbedUsedOnly(false),
-    m_bEmbedLatinScript(true),
-    m_bEmbedAsianScript(true),
-    m_bEmbedComplexScript(true)
+    m_pFontAutoStylePool( new XMLFontAutoStylePool_Impl )
 {
 }
 
@@ -255,14 +246,6 @@ OUString lcl_checkFontFile( const OUString &fileUrl )
     return OUString();
 }
 
-/// Contains information about a single variant of an embedded font.
-struct EmbeddedFontInfo
-{
-    OUString aURL;
-    FontWeight eWeight = WEIGHT_NORMAL;
-    FontItalic eItalic = ITALIC_NONE;
-};
-
 /// Converts FontWeight to CSS-compatible string representation.
 OUString FontWeightToString(FontWeight eWeight)
 {
@@ -301,11 +284,11 @@ OUString FontItalicToString(FontItalic eWeight)
 
 }
 
-std::unordered_set<OUString> XMLFontAutoStylePool::getUsedFontList()
+std::unordered_set<OUString> SvXMLExport::getUsedFontList()
 {
     std::unordered_set<OUString> aReturnSet;
 
-    uno::Reference<style::XStyleFamiliesSupplier> 
xFamiliesSupp(GetExport().GetModel(), UNO_QUERY);
+    uno::Reference<style::XStyleFamiliesSupplier> xFamiliesSupp(GetModel(), 
UNO_QUERY);
     if (!xFamiliesSupp.is())
         return aReturnSet;
 
@@ -313,6 +296,9 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
     uno::Reference<container::XNameAccess> 
xFamilies(xFamiliesSupp->getStyleFamilies());
     if (xFamilies.is())
     {
+        const bool bEmbedLatinScript = getEmbedLatinScript();
+        const bool bEmbedAsianScript = getEmbedAsianScript();
+        const bool bEmbedComplexScript = getEmbedComplexScript();
         const uno::Sequence<OUString> aFamilyNames = 
xFamilies->getElementNames();
         for (OUString const & sFamilyName : aFamilyNames)
         {
@@ -332,7 +318,7 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
                         uno::Reference<beans::XPropertySetInfo> 
xInfo(xPropertySet ? xPropertySet->getPropertySetInfo() : nullptr);
                         if (xInfo)
                         {
-                            if (m_bEmbedLatinScript && 
xInfo->hasPropertyByName(u"CharFontName"_ustr))
+                            if (bEmbedLatinScript && 
xInfo->hasPropertyByName(u"CharFontName"_ustr))
                             {
                                 OUString sCharFontName;
                                 Any aFontAny = 
xPropertySet->getPropertyValue(u"CharFontName"_ustr);
@@ -340,7 +326,7 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
                                 if (!sCharFontName.isEmpty())
                                     aReturnSet.insert(sCharFontName);
                             }
-                            if (m_bEmbedAsianScript && 
xInfo->hasPropertyByName(u"CharFontNameAsian"_ustr))
+                            if (bEmbedAsianScript && 
xInfo->hasPropertyByName(u"CharFontNameAsian"_ustr))
                             {
                                 OUString sCharFontNameAsian;
                                 Any aFontAny = 
xPropertySet->getPropertyValue(u"CharFontNameAsian"_ustr);
@@ -348,7 +334,7 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
                                 if (!sCharFontNameAsian.isEmpty())
                                     aReturnSet.insert(sCharFontNameAsian);
                             }
-                            if (m_bEmbedComplexScript && 
xInfo->hasPropertyByName(u"CharFontNameComplex"_ustr))
+                            if (bEmbedComplexScript && 
xInfo->hasPropertyByName(u"CharFontNameComplex"_ustr))
                             {
                                 OUString sCharFontNameComplex;
                                 Any aFontAny = 
xPropertySet->getPropertyValue(u"CharFontNameComplex"_ustr);
@@ -364,10 +350,10 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
     }
 
     // make sure auto-styles are collected
-    GetExport().collectAutoStyles();
+    collectAutoStyles();
 
     // Check auto-styles for fonts
-    std::vector<xmloff::AutoStyleEntry> aAutoStyleEntries = 
GetExport().GetAutoStylePool()->GetAutoStyleEntries();
+    std::vector<xmloff::AutoStyleEntry> aAutoStyleEntries = 
GetAutoStylePool()->GetAutoStyleEntries();
     for (auto const & rAutoStyleEntry : aAutoStyleEntries)
     {
         for (auto const & rPair : rAutoStyleEntry.m_aXmlProperties)
@@ -389,103 +375,85 @@ std::unordered_set<OUString> 
XMLFontAutoStylePool::getUsedFontList()
     return aReturnSet;
 }
 
-void XMLFontAutoStylePool::exportXML()
+void SvXMLExport::exportFonts(const 
std::vector<XMLFontAutoStylePoolEntry_Impl*>& rFonts)
 {
-    SvXMLElementExport aElem(GetExport(), XML_NAMESPACE_OFFICE,
-                             XML_FONT_FACE_DECLS,
-                             true, true);
+    SvXMLElementExport aElem(*this, XML_NAMESPACE_OFFICE, XML_FONT_FACE_DECLS, 
true, true);
+
     Any aAny;
     OUString sTmp;
     XMLFontFamilyNamePropHdl aFamilyNameHdl;
     XMLFontFamilyPropHdl aFamilyHdl;
     XMLFontPitchPropHdl aPitchHdl;
     XMLFontEncodingPropHdl aEncHdl;
-    const SvXMLUnitConverter& rUnitConv = GetExport().GetMM100UnitConverter();
+    const bool bEmbedFonts = getEmbedFonts();
+    const bool bEmbedUsedOnly = bEmbedFonts && getEmbedOnlyUsedFonts();
 
     std::map<OUString, OUString> fontFilesMap; // our url to document url
 
     std::unordered_set<OUString> aUsedFontNames;
-    if (m_bEmbedUsedOnly)
+    if (bEmbedUsedOnly)
         aUsedFontNames = getUsedFontList();
 
-    // Sort <style:font-face> elements based on their style:name attribute.
-    std::vector<XMLFontAutoStylePoolEntry_Impl*> aFontAutoStyles;
-    for (const auto& pEntry : *m_pFontAutoStylePool)
+    for (const auto& pEntry : rFonts)
     {
-        aFontAutoStyles.push_back(pEntry.get());
-    }
-    std::sort(
-        aFontAutoStyles.begin(), aFontAutoStyles.end(),
-        [](const XMLFontAutoStylePoolEntry_Impl* pA, 
XMLFontAutoStylePoolEntry_Impl* pB) -> bool {
-            return pA->GetName() < pB->GetName();
-        });
-
-    for (const auto& pEntry : aFontAutoStyles)
-    {
-        GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, 
pEntry->GetName());
+        AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, pEntry->GetName());
 
         aAny <<= pEntry->GetFamilyName();
-        if (aFamilyNameHdl.exportXML(sTmp, aAny, rUnitConv))
-            GetExport().AddAttribute(XML_NAMESPACE_SVG,
-                                     XML_FONT_FAMILY, sTmp);
+        if (aFamilyNameHdl.exportXML(sTmp, aAny, GetMM100UnitConverter()))
+            AddAttribute(XML_NAMESPACE_SVG, XML_FONT_FAMILY, sTmp);
 
         const OUString& rStyleName = pEntry->GetStyleName();
         if (!rStyleName.isEmpty())
-            GetExport().AddAttribute(XML_NAMESPACE_STYLE,
-                                     XML_FONT_ADORNMENTS,
-                                     rStyleName);
+            AddAttribute(XML_NAMESPACE_STYLE, XML_FONT_ADORNMENTS, rStyleName);
 
         aAny <<= static_cast<sal_Int16>(pEntry->GetFamily());
-        if (aFamilyHdl.exportXML(sTmp, aAny, rUnitConv))
+        if (aFamilyHdl.exportXML(sTmp, aAny, GetMM100UnitConverter()))
         {
-            GetExport().AddAttribute(XML_NAMESPACE_STYLE,
-                                     XML_FONT_FAMILY_GENERIC, sTmp);
+            AddAttribute(XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC, sTmp);
         }
         aAny <<= static_cast<sal_Int16>(pEntry->GetPitch());
-        if (aPitchHdl.exportXML(sTmp, aAny, rUnitConv))
+        if (aPitchHdl.exportXML(sTmp, aAny, GetMM100UnitConverter()))
         {
-            GetExport().AddAttribute(XML_NAMESPACE_STYLE,
-                                     XML_FONT_PITCH, sTmp);
+            AddAttribute(XML_NAMESPACE_STYLE, XML_FONT_PITCH, sTmp);
         }
 
         aAny <<= static_cast<sal_Int16>(pEntry->GetEncoding());
-        if (aEncHdl.exportXML( sTmp, aAny, rUnitConv))
+        if (aEncHdl.exportXML(sTmp, aAny, GetMM100UnitConverter()))
         {
-            GetExport().AddAttribute(XML_NAMESPACE_STYLE,
-                                     XML_FONT_CHARSET, sTmp);
+            AddAttribute(XML_NAMESPACE_STYLE, XML_FONT_CHARSET, sTmp);
         }
 
-        SvXMLElementExport aElement(GetExport(), XML_NAMESPACE_STYLE,
-                                    XML_FONT_FACE, true, true);
+        SvXMLElementExport aElement(*this, XML_NAMESPACE_STYLE, XML_FONT_FACE, 
true, true);
 
-        if (m_bTryToEmbedFonts)
+        // When embedding is requested, and embedded only is not set or font 
is used, and the font
+        // was not embedded already in a different pass
+        if (bEmbedFonts && (!bEmbedUsedOnly || 
aUsedFontNames.contains(pEntry->GetFamilyName()))
+            && !m_aEmbeddedFontNames.contains(pEntry->GetName()))
         {
-            const bool bExportFlat(GetExport().getExportFlags() & 
SvXMLExportFlags::EMBEDDED);
-            std::vector<EmbeddedFontInfo> aEmbeddedFonts;
-            static const std::vector<std::pair<FontWeight, FontItalic>> 
aCombinations =
+            const bool bExportFlat(getExportFlags() & 
SvXMLExportFlags::EMBEDDED);
+
+            /// Contains information about a single variant of an embedded 
font.
+            struct EmbeddedFontInfo
             {
-                { WEIGHT_NORMAL, ITALIC_NONE },
-                { WEIGHT_BOLD,   ITALIC_NONE },
-                { WEIGHT_NORMAL, ITALIC_NORMAL },
-                { WEIGHT_BOLD,   ITALIC_NORMAL },
+                OUString aURL;
+                FontWeight eWeight;
+                FontItalic eItalic;
             };
+            std::vector<EmbeddedFontInfo> aEmbeddedFonts;
 
-            for (auto const & aCombinationPair : aCombinations)
+            for (FontItalic fontItalic : { ITALIC_NONE, ITALIC_NORMAL })
             {
-                // Embed font if at least viewing is allowed (in which case 
the opening app must check
-                // the font license rights too and open either read-only or 
not use the font for editing).
-                OUString sFileUrl = EmbeddedFontsHelper::fontFileUrl(
-                                        pEntry->GetFamilyName(), 
pEntry->GetFamily(),
-                                        aCombinationPair.second, 
aCombinationPair.first, pEntry->GetPitch(),
-                                        
EmbeddedFontsHelper::FontRights::ViewingAllowed);
-                if (sFileUrl.isEmpty())
-                    continue;
-
-                // When embedded only is not set or font is used
-                if (!m_bEmbedUsedOnly ||
-                    aUsedFontNames.find(pEntry->GetFamilyName()) != 
aUsedFontNames.end())
+                for (FontWeight fontWeight : { WEIGHT_NORMAL, WEIGHT_BOLD })
                 {
-                    if (!fontFilesMap.count(sFileUrl))
+                    // Embed font if at least viewing is allowed (in which 
case the opening app must check
+                    // the font license rights too and open either read-only 
or not use the font for editing).
+                    OUString sFileUrl = EmbeddedFontsHelper::fontFileUrl(
+                        pEntry->GetFamilyName(), pEntry->GetFamily(), 
fontItalic, fontWeight,
+                        pEntry->GetPitch(), 
EmbeddedFontsHelper::FontRights::ViewingAllowed);
+                    if (sFileUrl.isEmpty())
+                        continue;
+
+                    if (!fontFilesMap.contains(sFileUrl))
                     {
                         const OUString docUrl = bExportFlat ?
                                                     
lcl_checkFontFile(sFileUrl) : embedFontFile(sFileUrl, pEntry->GetFamilyName());
@@ -494,45 +462,42 @@ void XMLFontAutoStylePool::exportXML()
                         else
                             continue; // --> failed to embed
                     }
-                    EmbeddedFontInfo aEmbeddedFont;
-                    aEmbeddedFont.aURL = sFileUrl;
-                    aEmbeddedFont.eWeight = aCombinationPair.first;
-                    aEmbeddedFont.eItalic = aCombinationPair.second;
-                    aEmbeddedFonts.push_back(aEmbeddedFont);
+                    aEmbeddedFonts.push_back({ sFileUrl, fontWeight, 
fontItalic });
                 }
             }
             if (!aEmbeddedFonts.empty())
             {
-                SvXMLElementExport fontFaceSrc(GetExport(), XML_NAMESPACE_SVG, 
XML_FONT_FACE_SRC, true, true);
+                m_aEmbeddedFontNames.insert(pEntry->GetName());
+                SvXMLElementExport fontFaceSrc(*this, XML_NAMESPACE_SVG, 
XML_FONT_FACE_SRC, true, true);
                 for (EmbeddedFontInfo const & rEmbeddedFont : aEmbeddedFonts)
                 {
-                    if (fontFilesMap.count(rEmbeddedFont.aURL))
+                    if (fontFilesMap.contains(rEmbeddedFont.aURL))
                     {
                         if (!bExportFlat)
                         {
-                            GetExport().AddAttribute(XML_NAMESPACE_XLINK, 
XML_HREF,
-                                                     
fontFilesMap[rEmbeddedFont.aURL]);
-                            GetExport().AddAttribute(XML_NAMESPACE_XLINK, 
XML_TYPE, u"simple"_ustr);
+                            AddAttribute(XML_NAMESPACE_XLINK, XML_HREF,
+                                         fontFilesMap[rEmbeddedFont.aURL]);
+                            AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, 
u"simple"_ustr);
                         }
 
                         // Help consumers of our output by telling them which
                         // font file is which one.
-                        GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, 
XML_FONT_STYLE,
-                                                 
FontItalicToString(rEmbeddedFont.eItalic));
-                        GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, 
XML_FONT_WEIGHT,
-                                                 
FontWeightToString(rEmbeddedFont.eWeight));
+                        AddAttribute(XML_NAMESPACE_LO_EXT, XML_FONT_STYLE,
+                                     
FontItalicToString(rEmbeddedFont.eItalic));
+                        AddAttribute(XML_NAMESPACE_LO_EXT, XML_FONT_WEIGHT,
+                                     
FontWeightToString(rEmbeddedFont.eWeight));
 
-                        SvXMLElementExport fontFaceUri(GetExport(), 
XML_NAMESPACE_SVG,
+                        SvXMLElementExport fontFaceUri(*this, 
XML_NAMESPACE_SVG,
                                                        XML_FONT_FACE_URI, 
true, true);
 
                         if (bExportFlat)
                         {
                             const uno::Reference<ucb::XSimpleFileAccess> 
xFileAccess(
-                                
ucb::SimpleFileAccess::create(GetExport().getComponentContext()));
+                                
ucb::SimpleFileAccess::create(getComponentContext()));
                             try
                             {
                                 const uno::Reference<io::XInputStream> 
xInput(xFileAccess->openFileRead(fontFilesMap[rEmbeddedFont.aURL]));
-                                XMLBase64Export aBase64Exp(GetExport());
+                                XMLBase64Export aBase64Exp(*this);
                                 
aBase64Exp.exportOfficeBinaryDataElement(xInput);
                             }
                             catch (const uno::Exception &)
@@ -541,8 +506,8 @@ void XMLFontAutoStylePool::exportXML()
                             }
                         }
 
-                        GetExport().AddAttribute(XML_NAMESPACE_SVG, 
XML_STRING, u"truetype"_ustr);
-                        SvXMLElementExport fontFaceFormat(GetExport(), 
XML_NAMESPACE_SVG,
+                        AddAttribute(XML_NAMESPACE_SVG, XML_STRING, 
u"truetype"_ustr);
+                        SvXMLElementExport fontFaceFormat(*this, 
XML_NAMESPACE_SVG,
                                                           
XML_FONT_FACE_FORMAT, true, true);
                     }
                 }
@@ -551,6 +516,33 @@ void XMLFontAutoStylePool::exportXML()
     }
 }
 
+std::vector<OUString> SvXMLExport::getEmbeddedFontNames() const
+{
+    return std::vector(m_aEmbeddedFontNames.begin(), 
m_aEmbeddedFontNames.end());
+}
+
+void SvXMLExport::setEmbeddedFontNames(const std::vector<OUString>& newNames)
+{
+    m_aEmbeddedFontNames.clear();
+    m_aEmbeddedFontNames.insert(newNames.begin(), newNames.end());
+}
+
+void XMLFontAutoStylePool::exportXML()
+{
+    // Sort <style:font-face> elements based on their style:name attribute.
+    std::vector<XMLFontAutoStylePoolEntry_Impl*> aFontAutoStyles;
+    for (const auto& pEntry : *m_pFontAutoStylePool)
+    {
+        aFontAutoStyles.push_back(pEntry.get());
+    }
+    std::sort(
+        aFontAutoStyles.begin(), aFontAutoStyles.end(),
+        [](const XMLFontAutoStylePoolEntry_Impl* pA, 
XMLFontAutoStylePoolEntry_Impl* pB) -> bool {
+            return pA->GetName() < pB->GetName();
+        });
+    GetExport().exportFonts(aFontAutoStyles);
+}
+
 static OUString getFreeFontName(uno::Reference<embed::XStorage> const & 
rxStorage, OUString const & rFamilyName)
 {
     OUString sName;
@@ -609,7 +601,7 @@ static OString getFileHash(OUString const & rFileUrl)
     return convertToHashString(aHashEngine.finalize());
 }
 
-OUString XMLFontAutoStylePool::embedFontFile(OUString const & fileUrl, 
OUString const & rFamilyName)
+OUString SvXMLExport::embedFontFile(OUString const& fileUrl, OUString const& 
rFamilyName)
 {
     try
     {
@@ -621,11 +613,11 @@ OUString XMLFontAutoStylePool::embedFontFile(OUString 
const & fileUrl, OUString
         if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
             return OUString();
 
-        if ( !GetExport().GetTargetStorage().is() )
+        if ( !GetTargetStorage().is() )
             return OUString();
 
         uno::Reference< embed::XStorage > storage;
-        storage.set( GetExport().GetTargetStorage()->openStorageElement( 
u"Fonts"_ustr,
+        storage.set( GetTargetStorage()->openStorageElement( u"Fonts"_ustr,
             ::embed::ElementModes::WRITE ), uno::UNO_SET_THROW );
 
         OUString name = getFreeFontName(storage, rFamilyName);

Reply via email to