oox/qa/unit/data/tdf128568_FontworkFontProperties.odt |binary
 oox/qa/unit/export.cxx                                |   34 +++++++++++++++++
 oox/source/export/vmlexport.cxx                       |   36 +++++++++++++++++-
 3 files changed, 68 insertions(+), 2 deletions(-)

New commits:
commit a6bbf5db743583e21a2af3ef5b5a608f7bd46502
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Wed Jan 25 21:32:29 2023 +0100
Commit:     Regina Henschel <rb.hensc...@t-online.de>
CommitDate: Thu Jan 26 13:00:36 2023 +0000

    tdf#128568 more font properties in VML Fontwork export
    
    When export a Fontwork shape to VML then currently only font name and
    size is exported. The patch adds style 'italic', weight 'bold' and
    the special properties 'Character spacing' and 'SameLetterHeights' of
    Fontwork shapes.
    
    Change-Id: Ifb7b42ab6c63e12f5f672e670a3bde5bcf20b1aa
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146148
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>

diff --git a/oox/qa/unit/data/tdf128568_FontworkFontProperties.odt 
b/oox/qa/unit/data/tdf128568_FontworkFontProperties.odt
new file mode 100644
index 000000000000..549d0fb029cc
Binary files /dev/null and 
b/oox/qa/unit/data/tdf128568_FontworkFontProperties.odt differ
diff --git a/oox/qa/unit/export.cxx b/oox/qa/unit/export.cxx
index 7c312798270a..f25bf4493b17 100644
--- a/oox/qa/unit/export.cxx
+++ b/oox/qa/unit/export.cxx
@@ -798,6 +798,40 @@ CPPUNIT_TEST_FIXTURE(Test, testFontworkBitmapFill)
     // in VML export.
     assertXPath(pXmlDoc, "//v:shape/v:fill", "type", "frame");
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testFontworkFontProperties)
+{
+    // The document has five Fontwork shapes. They have bitmap fill and thus 
are exported to VML.
+    // They differ in font properties e.g. font weight and character spacing.
+    loadFromURL(u"tdf128568_FontworkFontProperties.odt");
+
+    // FIXME: tdf#153183 validation error in OOXML export: Errors: 1
+    // Attribute 'ID' is not allowed to appear in element 'v:shape'.
+    skipValidation();
+
+    // Save to DOCX:
+    save("Office Open XML Text");
+
+    // Make sure the style attribute of the textpath element has the needed 
items. Without fix only
+    // font-family and font-size were written.
+    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+    OUString sStyle;
+    // bold
+    sStyle = getXPath(pXmlDoc, "(//v:shape)[1]/v:textpath", "style");
+    CPPUNIT_ASSERT(sStyle.indexOf("font-weight:bold") > -1);
+    // italic
+    sStyle = getXPath(pXmlDoc, "(//v:shape)[2]/v:textpath", "style");
+    CPPUNIT_ASSERT(sStyle.indexOf("font-style:italic") > -1);
+    // character spacing 'very loose', 150 * 655, see escherex.cxx
+    sStyle = getXPath(pXmlDoc, "(//v:shape)[3]/v:textpath", "style");
+    CPPUNIT_ASSERT(sStyle.indexOf("v-text-spacing:98250f") > -1);
+    // character spacing 'tight', 90 * 655, see escherex.cxx
+    sStyle = getXPath(pXmlDoc, "(//v:shape)[4]/v:textpath", "style");
+    CPPUNIT_ASSERT(sStyle.indexOf("v-text-spacing:58950f") > -1);
+    // same letter heights
+    sStyle = getXPath(pXmlDoc, "(//v:shape)[5]/v:textpath", "style");
+    CPPUNIT_ASSERT(sStyle.indexOf("v-same-letter-heights:t") > -1);
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/oox/source/export/vmlexport.cxx b/oox/source/export/vmlexport.cxx
index 6da57bdd8be8..62b102a8fa2d 100644
--- a/oox/source/export/vmlexport.cxx
+++ b/oox/source/export/vmlexport.cxx
@@ -32,6 +32,7 @@
 
 #include <tools/stream.hxx>
 #include <comphelper/sequenceashashmap.hxx>
+#include <svx/msdffdef.hxx>
 #include <svx/svdotext.hxx>
 #include <svx/svdograf.hxx>
 #include <svx/sdmetitm.hxx>
@@ -401,6 +402,9 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, 
const tools::Rectangle&
     }
 
     // properties
+    // The numbers of defines ESCHER_Prop_foo and DFF_Prop_foo correspond to 
the PIDs in
+    // 'Microsoft Office Drawing 97-2007 Binary Format Specification'.
+    // The property values are set by 
EscherPropertyContainer::CreateCustomShapeProperties() method.
     bool bAlreadyWritten[ 0xFFF ] = {};
     const EscherProperties &rOpts = rProps.GetOpts();
     for (auto const& opt : rOpts)
@@ -964,11 +968,38 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, 
const tools::Rectangle&
                             OUString aSize = OUString::number(nSizeF);
                             aStyle += ";font-size:" + aSize + "pt";
                         }
-                        if (IsWaterMarkShape(m_pSdrObject->GetName()))
-                            pAttrList->add(XML_trim, "t");
+
+                        sal_uInt32 nGtextFlags;
+                        if (rProps.GetOpt(DFF_Prop_gtextFStrikethrough 
/*255*/, nGtextFlags))
+                        {
+                            // The property is in fact a collection of flags. 
Two bytes contain the
+                            // fUsegtextF* flags and the other two bytes at 
same place the associated
+                            // On/Off flags. See '2.3.22.10 Geometry Text 
Boolean Properties' section
+                            // in [MS-ODRAW].
+                            if ((nGtextFlags & 0x00200020) == 0x00200020) // 
DFF_Prop_gtextFBold = 250
+                                aStyle += ";font-weight:bold";
+                            if ((nGtextFlags & 0x00100010) == 0x00100010) // 
DFF_Prop_gtextFItalic = 251
+                                aStyle += ";font-style:italic";
+                            if ((nGtextFlags & 0x00800080) == 0x00800080) // 
no DFF, PID gtextFNormalize = 248
+                                aStyle += ";v-same-letter-heights:t";
+
+                            // The value 'Fontwork character spacing' in LO is 
bound to field 'Scaling'
+                            // not to 'Spacing' in character properties. In 
fact the characters are
+                            // rendered with changed distance and width. The 
method in escherex.cxx has
+                            // put a rounded value of 'CharScaleWidth' API 
property to
+                            // DFF_Prop_gtextSpacing (=196) as integer part of 
16.16 fixed point format.
+                            // fUsegtextFTight and gtextFTight (244) of MS 
binary format are not used.
+                            sal_uInt32 nGtextSpacing;
+                            if (rProps.GetOpt(DFF_Prop_gtextSpacing, 
nGtextSpacing))
+                                aStyle += ";v-text-spacing:" + 
OUString::number(nGtextSpacing) + "f";
+                        }
 
                         if (!aStyle.isEmpty())
                             pAttrList->add(XML_style, aStyle);
+
+                        if (IsWaterMarkShape(m_pSdrObject->GetName()))
+                            pAttrList->add(XML_trim, "t");
+
                         m_pSerializer->singleElementNS(XML_v, XML_textpath, 
pAttrList);
                     }
 
@@ -1007,6 +1038,7 @@ void VMLExport::Commit( EscherPropertyContainer& rProps, 
const tools::Rectangle&
 
                     // note that XML_ID is different from XML_id (although it 
looks like a LO
                     // implementation distinction without valid justification 
to me).
+                    // FIXME: XML_ID produces invalid file, see tdf#153183
                     bAlreadyWritten[ESCHER_Prop_wzName] = true;
                 }
                 break;

Reply via email to