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.kagan...@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 <c...@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kagan...@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"/> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits