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 a6c0b1a2b7c8d29bf3561fff472a4b5684e4967b Author: Mike Kaganski <[email protected]> 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. Reviewed-on: https://gerrit.libreoffice.org/38562 Tested-by: Jenkins <[email protected]> Reviewed-by: Mike Kaganski <[email protected]> (cherry picked from commit ea890b1d4bcd6dd59db9f52dce1609c020804e24) Change-Id: Iccc6d46f717cb618381baf89dfd3e4bbb844b4af Reviewed-on: https://gerrit.libreoffice.org/38591 Reviewed-by: Mike Kaganski <[email protected]> Tested-by: Mike Kaganski <[email protected]> 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 4d027678f098..ec80bb6cb561 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -1388,6 +1388,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 4227ae21aa07..b30b8adf3dba 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 RT_UniversalMeasure: + case RT_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 RT_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 RT_List: { sal_uInt32 nValue; diff --git a/writerfilter/source/ooxml/OOXMLFactory.hxx b/writerfilter/source/ooxml/OOXMLFactory.hxx index e1f7a63c6c66..1527be15c0d6 100644 --- a/writerfilter/source/ooxml/OOXMLFactory.hxx +++ b/writerfilter/source/ooxml/OOXMLFactory.hxx @@ -53,7 +53,8 @@ enum ResourceType_t { RT_PropertyTable, RT_Math, RT_Any, - RT_UniversalMeasure + RT_TwipsMeasure, + RT_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 dbb391c60066..92fe4ddddeee 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 b79f290cfc9d..d132f03ed72f 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 [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
