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

Mike Kaganski mike.kaganski at collabora.com
Mon Jul 24 14:31:30 UTC 2017


 sw/qa/extras/ooxmlimport/data/tdf109306.docx   |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx       |   13 +++++++++
 writerfilter/source/ooxml/OOXMLFactory.cxx     |    9 ++++++
 writerfilter/source/ooxml/OOXMLFactory.hxx     |    3 +-
 writerfilter/source/ooxml/OOXMLPropertySet.cxx |   34 +++++++++++++++++++++++++
 writerfilter/source/ooxml/OOXMLPropertySet.hxx |   17 ++++++++++++
 writerfilter/source/ooxml/factoryimpl.py       |    2 -
 writerfilter/source/ooxml/model.xml            |    6 +++-
 8 files changed, 81 insertions(+), 3 deletions(-)

New commits:
commit 8c7c72c8f8a1c8c09ee7cd4f413611c456f336b2
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Mon Jul 24 13:43:28 2017 +0300

    tdf#109306: consider percent unit specification for table sizes
    
    According to ECMA-376-1:2016, ST_MeasurementOrPercent (the type of
    "w:w" attribute of table sizes) is allowed to have this specification
    (and then is expected to be a floating-point value). First edition
    of the standard (of 2006) only defined this attribute to contain
    int32 value (of fiftieths of percent when holding relative widths).
    
    Unit test included.
    
    Change-Id: I700912e4eb07430e55fe1d169d99e8e7e0e1a00b
    Reviewed-on: https://gerrit.libreoffice.org/40361
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sw/qa/extras/ooxmlimport/data/tdf109306.docx b/sw/qa/extras/ooxmlimport/data/tdf109306.docx
new file mode 100644
index 000000000000..c13f0d6fd8e5
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf109306.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 6d1b831b8ddb..6b4dc9a81216 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1405,6 +1405,19 @@ DECLARE_OOXMLIMPORT_TEST(testTdf108849, "tdf108849.docx")
     CPPUNIT_ASSERT_EQUAL_MESSAGE("Misplaced body-level sectPr's create extra sections!", 2, getPages());
 }
 
+DECLARE_OOXMLIMPORT_TEST(testTdf109306, "tdf109306.docx")
+{
+    uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+    // Both types of relative width specification (pct): simple integers (in fiftieths of percent)
+    // and floats with "%" unit specification must be treated correctly
+    CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<bool>(xTables->getByIndex(0), "IsWidthRelative")));
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(90), getProperty<sal_Int16>(xTables->getByIndex(0), "RelativeWidth"));
+
+    CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<bool>(xTables->getByIndex(1), "IsWidthRelative")));
+    CPPUNIT_ASSERT_EQUAL(sal_Int16(80), getProperty<sal_Int16>(xTables->getByIndex(1), "RelativeWidth"));
+}
+
 // tests should only be added to ooxmlIMPORT *if* they fail round-tripping in ooxmlEXPORT
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/writerfilter/source/ooxml/OOXMLFactory.cxx b/writerfilter/source/ooxml/OOXMLFactory.cxx
index 12f6237ea996..c164ff949757 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.cxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.cxx
@@ -114,6 +114,15 @@ void OOXMLFactory::attributes(OOXMLFastContextHandler * pHandler,
                 pFactory->attributeAction(pHandler, nToken, xValue);
             }
         break;
+        case ResourceType::MeasurementOrPercent:
+            {
+                const char *pValue = "";
+                pAttribs->getAsChar(nToken, pValue);
+                OOXMLValue::Pointer_t xValue(new OOXMLMeasurementOrPercentValue(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 a3318d1da045..dce03696185c 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.hxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.hxx
@@ -52,7 +52,8 @@ enum class ResourceType {
     Math,
     Any,
     TwipsMeasure,
-    HpsMeasure
+    HpsMeasure,
+    MeasurementOrPercent
 };
 
 struct AttributeInfo
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.cxx b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
index 0b353dfb8039..b7b50d1bf20f 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.cxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
@@ -647,6 +647,40 @@ string OOXMLUniversalMeasureValue::toString() const
 }
 #endif
 
+// OOXMLMeasurementOrPercentValue
+// ECMA-376 5th ed. Part 1 , 17.18.107; 17.18.11
+OOXMLMeasurementOrPercentValue::OOXMLMeasurementOrPercentValue(const char * pValue)
+{
+    double val = rtl_str_toDouble(pValue); // will ignore the trailing unit
+
+    int nLen = strlen(pValue);
+    if (nLen > 2 &&
+        pValue[nLen - 1] == '%')
+    {
+        mnValue = static_cast<int>(val * 50);
+    }
+    else
+    {
+        // TODO: also allow units. For that, we need to know
+        // how to represent the number to converter or store
+        // the value in the type as number + unit and have
+        // getter with unit specification
+        mnValue = static_cast<int>(val);
+    }
+}
+
+int OOXMLMeasurementOrPercentValue::getInt() const
+{
+    return mnValue;
+}
+
+#ifdef DEBUG_WRITERFILTER
+string OOXMLMeasurementOrPercentValue::toString() const
+{
+    return OString::number(mnValue).getStr();
+}
+#endif
+
 /*
   class OOXMLShapeValue
  */
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.hxx b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
index 45aba15e2ccc..59df4d3ecbb2 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.hxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
@@ -261,6 +261,23 @@ typedef OOXMLNthPtMeasureValue<20> OOXMLTwipsMeasureValue;
 /// Handles OOXML's ST_HpsMeasure value.
 typedef OOXMLNthPtMeasureValue<2> OOXMLHpsMeasureValue;
 
+class OOXMLMeasurementOrPercentValue : public OOXMLValue
+{
+protected:
+    int mnValue;
+public:
+    explicit OOXMLMeasurementOrPercentValue(const char * pValue);
+
+    virtual int getInt() const override;
+    virtual OOXMLValue* clone() const override
+    {
+        return new OOXMLMeasurementOrPercentValue(*this);
+    }
+#ifdef DEBUG_WRITERFILTER
+    virtual std::string toString() const override;
+#endif
+};
+
 class OOXMLShapeValue : public OOXMLValue
 {
 protected:
diff --git a/writerfilter/source/ooxml/factoryimpl.py b/writerfilter/source/ooxml/factoryimpl.py
index d718f5a09fda..2168fff556d7 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", "TwipsMeasure", "HpsMeasure", "Boolean"]
+    resources = ["List", "Integer", "Hex", "String", "TwipsMeasure", "HpsMeasure", "Boolean", "MeasurementOrPercent"]
     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 92e8677a8ecb..49fe6f8f44ad 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -14204,6 +14204,9 @@
           <value>auto</value>
         </choice>
       </define>
+      <define name="ST_MeasurementOrPercent">
+        <data type="string"/>
+      </define>
       <define name="CT_Height">
         <attribute name="val">
           <data type="string"/>
@@ -14214,7 +14217,7 @@
       </define>
       <define name="CT_TblWidth">
         <attribute name="w">
-          <ref name="ST_DecimalNumber"/>
+          <ref name="ST_MeasurementOrPercent"/>
         </attribute>
         <attribute name="type">
           <ref name="ST_TblWidth"/>
@@ -16667,6 +16670,7 @@
       <attribute name="val" tokenid="ooxml:CT_SignedHpsMeasure_val" action="setValue"/>
       <action name="start" action="setDefaultIntegerValue"/>
     </resource>
+    <resource name="ST_MeasurementOrPercent" resource="MeasurementOrPercent"/>
     <resource name="ST_DateTime" resource="String"/>
     <resource name="CT_MacroName" resource="Value">
       <attribute name="val" tokenid="ooxml:CT_MacroName_val" action="setValue"/>


More information about the Libreoffice-commits mailing list