[Libreoffice-commits] core.git: sw/qa writerfilter/source

Mike Kaganski mike.kaganski at collabora.com
Fri Jun 9 05:46:55 UTC 2017


 sw/qa/extras/ooxmlimport/data/tdf108408.docx   |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx       |    9 +++++
 writerfilter/source/ooxml/OOXMLFactory.cxx     |   13 ++++++-
 writerfilter/source/ooxml/OOXMLFactory.hxx     |    3 +
 writerfilter/source/ooxml/OOXMLPropertySet.cxx |   41 +++++++++++++++++++------
 writerfilter/source/ooxml/OOXMLPropertySet.hxx |   24 ++++++++++++--
 writerfilter/source/ooxml/factoryimpl.py       |    2 -
 writerfilter/source/ooxml/model.xml            |    8 ++--
 8 files changed, 79 insertions(+), 21 deletions(-)

New commits:
commit ea890b1d4bcd6dd59db9f52dce1609c020804e24
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Thu Jun 8 11:55:18 2017 +0300

    tdf#108408: support unit specifications for ST_HpsMeasure
    
    w:ST_HpsMeasure is defined in ECMA-376 5th ed. Part 1, 17.18.42 as
    
      This simple type specifies that its contents contain either:
      * A positive whole number, whose contents consist of a measurement in
        half-points (equivalent to 1/144th of an inch), or
      * A positive decimal number immediately followed by a unit identifier.
      ...
      This simple type is a union of the following types:
      * The ST_PositiveUniversalMeasure simple type (§22.9.2.12).
      * The ST_UnsignedDecimalNumber simple type (§22.9.2.16).
    
    This patch generalizes OOXMLUniversalMeasureValue to handle standard-
    defined units, and introduces two typedefed specifications:
    OOXMLTwipsMeasureValue (which is used where UniversalMeasure was
    previously used), and new OOXMLHpsMeasureValue.
    
    Unit test included.
    
    Change-Id: Iccc6d46f717cb618381baf89dfd3e4bbb844b4af
    Reviewed-on: https://gerrit.libreoffice.org/38562
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sw/qa/extras/ooxmlimport/data/tdf108408.docx b/sw/qa/extras/ooxmlimport/data/tdf108408.docx
new file mode 100644
index 000000000000..dcd1ecf8bd2e
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf108408.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 9c61378ae245..2d4804e937af 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1284,6 +1284,15 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108350, "tdf108350.docx")
     CPPUNIT_ASSERT_EQUAL(double(11), getProperty<double>(xRun, "CharHeight"));
 }
 
+DECLARE_OOXMLIMPORT_TEST(testTdf108408, "tdf108408.docx")
+{
+    // Font size must consider units specifications; previously ignored and only used
+    // integer part as half-pt size, i.e. 10 pt (20 half-pt) instead of 20 pt
+    uno::Reference<text::XTextRange> xPara(getParagraph(1));
+    uno::Reference<beans::XPropertySet> xRun(getRun(xPara, 1), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(double(20), getProperty<double>(xRun, "CharHeight"));
+}
+
 
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
 
diff --git a/writerfilter/source/ooxml/OOXMLFactory.cxx b/writerfilter/source/ooxml/OOXMLFactory.cxx
index b951245ba376..3d28d2eafa4c 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.cxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.cxx
@@ -98,15 +98,24 @@ void OOXMLFactory::attributes(OOXMLFastContextHandler * pHandler,
                 pFactory->attributeAction(pHandler, nToken, xValue);
             }
             break;
-        case ResourceType::UniversalMeasure:
+        case ResourceType::TwipsMeasure:
             {
                 const char *pValue = "";
                 pAttribs->getAsChar(nToken, pValue);
-                OOXMLValue::Pointer_t xValue(new OOXMLUniversalMeasureValue(pValue));
+                OOXMLValue::Pointer_t xValue(new OOXMLTwipsMeasureValue(pValue));
                 pHandler->newProperty(nId, xValue);
                 pFactory->attributeAction(pHandler, nToken, xValue);
             }
             break;
+        case ResourceType::HpsMeasure:
+            {
+                const char *pValue = "";
+                pAttribs->getAsChar(nToken, pValue);
+                OOXMLValue::Pointer_t xValue(new OOXMLHpsMeasureValue(pValue));
+                pHandler->newProperty(nId, xValue);
+                pFactory->attributeAction(pHandler, nToken, xValue);
+            }
+        break;
         case ResourceType::List:
             {
                 sal_uInt32 nValue;
diff --git a/writerfilter/source/ooxml/OOXMLFactory.hxx b/writerfilter/source/ooxml/OOXMLFactory.hxx
index 9e4b495fd0fc..a3318d1da045 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.hxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.hxx
@@ -51,7 +51,8 @@ enum class ResourceType {
     PropertyTable,
     Math,
     Any,
-    UniversalMeasure
+    TwipsMeasure,
+    HpsMeasure
 };
 
 struct AttributeInfo
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.cxx b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
index 9a095913e082..3ef7a30b11ff 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.cxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
@@ -589,17 +589,45 @@ string OOXMLHexValue::toString() const
 #endif
 
 // OOXMLUniversalMeasureValue
-
-OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(const char * pValue)
+// ECMA-376 5th ed. Part 1 , 22.9.2.15
+OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(const char * pValue, sal_uInt32 npPt)
 {
-    mnValue = rtl_str_toInt32(pValue, 10); // will ignore the trailing 'pt'
+    double val = rtl_str_toDouble(pValue); // will ignore the trailing unit
 
     int nLen = strlen(pValue);
     if (nLen > 2 &&
         pValue[nLen-2] == 'p' &&
         pValue[nLen-1] == 't')
     {
-        mnValue = mnValue * 20;
+        mnValue = static_cast<sal_uInt32>(val * npPt);
+    }
+    else if (nLen > 2 &&
+        pValue[nLen - 2] == 'c' &&
+        pValue[nLen - 1] == 'm')
+    {
+        mnValue = static_cast<sal_uInt32>(val * npPt * 72 / 2.54);
+    }
+    else if (nLen > 2 &&
+        pValue[nLen - 2] == 'm' &&
+        pValue[nLen - 1] == 'm')
+    {
+        mnValue = static_cast<sal_uInt32>(val * npPt * 72 / 25.4);
+    }
+    else if (nLen > 2 &&
+        pValue[nLen - 2] == 'i' &&
+        pValue[nLen - 1] == 'n')
+    {
+        mnValue = static_cast<sal_uInt32>(val * npPt * 72);
+    }
+    else if (nLen > 2 &&
+        pValue[nLen - 2] == 'p' &&
+        ( pValue[nLen - 1] == 'c' || pValue[nLen - 1] == 'i' ))
+    {
+        mnValue = static_cast<sal_uInt32>(val * npPt * 12);
+    }
+    else
+    {
+        mnValue = static_cast<sal_uInt32>(val);
     }
 }
 
@@ -612,11 +640,6 @@ int OOXMLUniversalMeasureValue::getInt() const
     return mnValue;
 }
 
-OOXMLValue* OOXMLUniversalMeasureValue::clone() const
-{
-    return new OOXMLUniversalMeasureValue(*this);
-}
-
 #ifdef DEBUG_WRITERFILTER
 string OOXMLUniversalMeasureValue::toString() const
 {
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.hxx b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
index 8aa7c92a4ee3..73889a4abb9b 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.hxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
@@ -229,22 +229,38 @@ public:
     virtual OOXMLValue * clone() const override;
 };
 
-/// Handles OOXML's ST_UniversalMeasure value.
 class OOXMLUniversalMeasureValue : public OOXMLValue
 {
-protected:
+private:
     sal_uInt32 mnValue;
 public:
-    explicit OOXMLUniversalMeasureValue(const char * pValue);
+    OOXMLUniversalMeasureValue(const char * pValue, sal_uInt32 npPt);
     virtual ~OOXMLUniversalMeasureValue() override;
 
     virtual int getInt() const override;
 #ifdef DEBUG_WRITERFILTER
     virtual std::string toString() const override;
 #endif
-    virtual OOXMLValue* clone() const override;
 };
 
+/// npPt is quotient defining how much units are in 1 pt
+template <sal_uInt32 npPt> class OOXMLNthPtMeasureValue : public OOXMLUniversalMeasureValue
+{
+public:
+    explicit OOXMLNthPtMeasureValue(const char * pValue)
+        : OOXMLUniversalMeasureValue(pValue, npPt) {}
+    virtual OOXMLValue* clone() const override
+    {
+        return new OOXMLNthPtMeasureValue<npPt>(*this);
+    }
+};
+
+/// Handles OOXML's ST_TwipsMeasure value.
+typedef OOXMLNthPtMeasureValue<20> OOXMLTwipsMeasureValue;
+
+/// Handles OOXML's ST_HpsMeasure value.
+typedef OOXMLNthPtMeasureValue<2> OOXMLHpsMeasureValue;
+
 class OOXMLShapeValue : public OOXMLValue
 {
 protected:
diff --git a/writerfilter/source/ooxml/factoryimpl.py b/writerfilter/source/ooxml/factoryimpl.py
index 1e172c589ea1..d718f5a09fda 100644
--- a/writerfilter/source/ooxml/factoryimpl.py
+++ b/writerfilter/source/ooxml/factoryimpl.py
@@ -37,7 +37,7 @@ def createFastChildContextFromFactory(model):
 
             switch (nResource)
             {""")
-    resources = ["List", "Integer", "Hex", "String", "UniversalMeasure", "Boolean"]
+    resources = ["List", "Integer", "Hex", "String", "TwipsMeasure", "HpsMeasure", "Boolean"]
     for resource in [r.getAttribute("resource") for r in model.getElementsByTagName("resource")]:
         if resource not in resources:
             resources.append(resource)
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index ae89c4ba5c54..05fb53f08729 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -8236,7 +8236,7 @@
     <resource name="CT_OMathJc" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_OMathJc_val" action="setValue"/>
     </resource>
-    <resource name="ST_TwipsMeasure" resource="UniversalMeasure"/>
+    <resource name="ST_TwipsMeasure" resource="TwipsMeasure"/>
     <resource name="CT_TwipsMeasure" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_TwipsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>
@@ -16616,12 +16616,12 @@
       <action name="start" action="setDefaultIntegerValue"/>
     </resource>
     <resource name="ST_UnsignedDecimalNumber" resource="Integer"/>
-    <resource name="ST_TwipsMeasure" resource="UniversalMeasure"/>
+    <resource name="ST_TwipsMeasure" resource="TwipsMeasure"/>
     <resource name="CT_TwipsMeasure" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_TwipsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>
     </resource>
-    <resource name="ST_SignedTwipsMeasure" resource="UniversalMeasure"/>
+    <resource name="ST_SignedTwipsMeasure" resource="TwipsMeasure"/>
     <resource name="CT_SignedTwipsMeasure" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_SignedTwipsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>
@@ -16631,7 +16631,7 @@
       <attribute name="val" tokenid="ooxml:CT_PixelsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>
     </resource>
-    <resource name="ST_HpsMeasure" resource="Integer"/>
+    <resource name="ST_HpsMeasure" resource="HpsMeasure"/>
     <resource name="CT_HpsMeasure" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_HpsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>


More information about the Libreoffice-commits mailing list