sw/qa/writerfilter/dmapper/FontTable.cxx         |   36 +++++++++++++++++++++++
 sw/qa/writerfilter/dmapper/data/font-family.docx |binary
 sw/source/writerfilter/dmapper/DomainMapper.cxx  |    8 +++++
 sw/source/writerfilter/dmapper/FontTable.cxx     |   27 +++++++++++++++++
 sw/source/writerfilter/dmapper/FontTable.hxx     |    3 +
 sw/source/writerfilter/dmapper/PropertyIds.cxx   |    1 
 sw/source/writerfilter/dmapper/PropertyIds.hxx   |    1 
 7 files changed, 76 insertions(+)

New commits:
commit d06de2e049761b7b9e8a95f17557d309812f7acc
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Jul 19 16:11:33 2024 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Jul 19 22:38:42 2024 +0200

    Related: tdf#162072 DOCX import: handle font family for characters
    
    Open the bugdoc, the first paragraph is meant to be sans and the second
    paragraph is meant to be serif, but both of them are serif.
    
    The bugdoc uses the fonts 'IBM Plex Sans' and 'IBM Plex Serif', which is
    not something we bundle, so the font fallback is expected, but the
    fallback should have a matching font family (roman vs swiss).
    
    Fix the problem by implementing support for <w:family w:val="..."> in
    the DOCX import, which was just ignored previously.
    
    Now the DOCX import result in on par with the ODT import result.
    
    Change-Id: I321b9fc6f63126ca5ad61af57af8a5bc7456d5b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170772
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/writerfilter/dmapper/FontTable.cxx 
b/sw/qa/writerfilter/dmapper/FontTable.cxx
index 2fe3dced2e1f..2d5a80ca0476 100644
--- a/sw/qa/writerfilter/dmapper/FontTable.cxx
+++ b/sw/qa/writerfilter/dmapper/FontTable.cxx
@@ -9,6 +9,10 @@
 
 #include <test/unoapi_test.hxx>
 
+#include <com/sun/star/awt/FontFamily.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+
 #include <vcl/embeddedfontshelper.hxx>
 
 using namespace com::sun::star;
@@ -57,6 +61,38 @@ CPPUNIT_TEST_FIXTURE(Test, testSubsettedFullEmbeddedFont)
     CPPUNIT_ASSERT(!aUrl.isEmpty());
 #endif
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFontFamily)
+{
+    // Given a document with 2 paragraphs, first is sans, second is serif:
+    // When loading that document:
+    loadFromFile(u"font-family.docx");
+
+    // Then make sure we import <w:family w:val="...">:
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY);
+    uno::Reference<container::XEnumerationAccess> 
xParaEnumAccess(xTextDocument->getText(),
+                                                                  
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xParaEnum = 
xParaEnumAccess->createEnumeration();
+    // First paragraph: sans.
+    uno::Reference<container::XEnumerationAccess> 
xPortionEnumAccess(xParaEnum->nextElement(),
+                                                                     
uno::UNO_QUERY);
+    uno::Reference<container::XEnumeration> xPortionEnum = 
xPortionEnumAccess->createEnumeration();
+    uno::Reference<beans::XPropertySet> xPortion(xPortionEnum->nextElement(), 
uno::UNO_QUERY);
+    sal_Int16 nFontFamily = awt::FontFamily::DONTKNOW;
+    xPortion->getPropertyValue(u"CharFontFamily"_ustr) >>= nFontFamily;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 5 (SWISS)
+    // - Actual  : 3 (ROMAN)
+    // i.e. the font family was not imported, all font family was roman.
+    CPPUNIT_ASSERT_EQUAL(awt::FontFamily::SWISS, nFontFamily);
+    // Second paragraph: serif.
+    xPortionEnumAccess.set(xParaEnum->nextElement(), uno::UNO_QUERY);
+    xPortionEnum = xPortionEnumAccess->createEnumeration();
+    xPortion.set(xPortionEnum->nextElement(), uno::UNO_QUERY);
+    nFontFamily = awt::FontFamily::DONTKNOW;
+    xPortion->getPropertyValue(u"CharFontFamily"_ustr) >>= nFontFamily;
+    CPPUNIT_ASSERT_EQUAL(awt::FontFamily::ROMAN, nFontFamily);
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/writerfilter/dmapper/data/font-family.docx 
b/sw/qa/writerfilter/dmapper/data/font-family.docx
new file mode 100644
index 000000000000..15bda10374ea
Binary files /dev/null and b/sw/qa/writerfilter/dmapper/data/font-family.docx 
differ
diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper.cxx
index 8854e7ed9ece..52e3eda73187 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx
@@ -418,6 +418,14 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
             if (m_pImpl->GetTopContext())
             {
                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_NAME, 
uno::Any( sStringValue ));
+
+                // Set the matching font family if we have one.
+                FontEntry::Pointer_t pFontEntry = 
m_pImpl->GetFontTable()->getFontEntryByName(sStringValue);
+                if (pFontEntry)
+                {
+                    m_pImpl->GetTopContext()->Insert(PROP_CHAR_FONT_FAMILY,
+                                                     
uno::Any(pFontEntry->m_nFontFamily));
+                }
             }
             break;
         case NS_ooxml::LN_CT_Fonts_asciiTheme:
diff --git a/sw/source/writerfilter/dmapper/FontTable.cxx 
b/sw/source/writerfilter/dmapper/FontTable.cxx
index 7cc8a39b3ef1..ebc7a7253247 100644
--- a/sw/source/writerfilter/dmapper/FontTable.cxx
+++ b/sw/source/writerfilter/dmapper/FontTable.cxx
@@ -136,7 +136,21 @@ void FontTable::lcl_sprm(Sprm& rSprm)
         case NS_ooxml::LN_CT_Font_panose1:
             break;
         case NS_ooxml::LN_CT_Font_family:
+        {
+            Value::Pointer_t pValue = rSprm.getValue();
+            sal_Int32 nIntValue = pValue ? pValue->getInt() : 0;
+            // Map OOXML's ST_FontFamily to UNO's awt::FontFamily.
+            switch (nIntValue)
+            {
+                case NS_ooxml::LN_Value_ST_FontFamily_roman:
+                    m_pImpl->pCurrentEntry->m_nFontFamily = 
awt::FontFamily::ROMAN;
+                    break;
+                case NS_ooxml::LN_Value_ST_FontFamily_swiss:
+                    m_pImpl->pCurrentEntry->m_nFontFamily = 
awt::FontFamily::SWISS;
+                    break;
+            }
             break;
+        }
         case NS_ooxml::LN_CT_Font_sig:
             break;
         case NS_ooxml::LN_CT_Font_notTrueType:
@@ -229,6 +243,19 @@ sal_uInt32 FontTable::size()
     return m_pImpl->aFontEntries.size();
 }
 
+FontEntry::Pointer_t FontTable::getFontEntryByName(std::u16string_view rName)
+{
+    for (const auto& pEntry : m_pImpl->aFontEntries)
+    {
+        if (pEntry->sFontName == rName)
+        {
+            return pEntry;
+        }
+    }
+
+    return nullptr;
+}
+
 bool FontTable::IsReadOnly() const
 {
     return m_pImpl->m_bReadOnly;
diff --git a/sw/source/writerfilter/dmapper/FontTable.hxx 
b/sw/source/writerfilter/dmapper/FontTable.hxx
index babb43d8aebb..99c23a00cb36 100644
--- a/sw/source/writerfilter/dmapper/FontTable.hxx
+++ b/sw/source/writerfilter/dmapper/FontTable.hxx
@@ -23,6 +23,7 @@
 #include <vector>
 #include "LoggedResources.hxx"
 #include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/awt/FontFamily.hpp>
 
 namespace writerfilter::dmapper
 {
@@ -33,6 +34,7 @@ struct FontEntry : public virtual SvRefBase
     typedef tools::SvRef<FontEntry> Pointer_t;
 
     OUString        sFontName;
+    sal_Int16 m_nFontFamily = css::awt::FontFamily::DONTKNOW;
     sal_Int32       nTextEncoding;
     FontEntry() :
         nTextEncoding( RTL_TEXTENCODING_DONTKNOW )
@@ -50,6 +52,7 @@ class FontTable : public LoggedProperties, public LoggedTable
 
     sal_uInt32          size();
     FontEntry::Pointer_t  getFontEntry(sal_uInt32 nIndex);
+    FontEntry::Pointer_t  getFontEntryByName(std::u16string_view rName);
 
     void addEmbeddedFont(const css::uno::Reference<css::io::XInputStream>& 
stream,
                          const OUString& fontName, std::u16string_view extra,
diff --git a/sw/source/writerfilter/dmapper/PropertyIds.cxx 
b/sw/source/writerfilter/dmapper/PropertyIds.cxx
index 394a3fd633b5..68e1e1cb8c3a 100644
--- a/sw/source/writerfilter/dmapper/PropertyIds.cxx
+++ b/sw/source/writerfilter/dmapper/PropertyIds.cxx
@@ -395,6 +395,7 @@ OUString getPropertyName( PropertyIds eId )
         { PROP_PARA_CONNECT_BORDERS, u"ParaIsConnectBorder"},
         { PROP_DECORATIVE, u"Decorative"},
         { PROP_PAPER_TRAY, u"PrinterPaperTray"},
+        { PROP_CHAR_FONT_FAMILY, u"CharFontFamily"},
     };
     auto iterator = constPropertyMap.find(eId);
     if (iterator != constPropertyMap.end())
diff --git a/sw/source/writerfilter/dmapper/PropertyIds.hxx 
b/sw/source/writerfilter/dmapper/PropertyIds.hxx
index 82ffb1ac35d4..72f3ffb149ab 100644
--- a/sw/source/writerfilter/dmapper/PropertyIds.hxx
+++ b/sw/source/writerfilter/dmapper/PropertyIds.hxx
@@ -397,6 +397,7 @@ enum PropertyIds
         ,PROP_RTL_GUTTER
         ,PROP_CURSOR_NOT_IGNORE_TABLES_IN_HF
         ,PROP_PARA_CONNECT_BORDERS
+        ,PROP_CHAR_FONT_FAMILY
     };
 
 //Returns the UNO string equivalent to eId.

Reply via email to