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