summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2017-06-08 11:55:18 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2017-06-09 07:46:34 +0200
commitea890b1d4bcd6dd59db9f52dce1609c020804e24 (patch)
treec3eb894389ae12d36d7815670c591e5cccffe9c0
parentfdfdea4d5af51a68f2d497cc5c3359d74c385fd5 (diff)
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@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--sw/qa/extras/ooxmlimport/data/tdf108408.docxbin0 -> 1298 bytes
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx9
-rw-r--r--writerfilter/source/ooxml/OOXMLFactory.cxx13
-rw-r--r--writerfilter/source/ooxml/OOXMLFactory.hxx3
-rw-r--r--writerfilter/source/ooxml/OOXMLPropertySet.cxx41
-rw-r--r--writerfilter/source/ooxml/OOXMLPropertySet.hxx24
-rw-r--r--writerfilter/source/ooxml/factoryimpl.py2
-rw-r--r--writerfilter/source/ooxml/model.xml8
8 files changed, 79 insertions, 21 deletions
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
--- /dev/null
+++ b/sw/qa/extras/ooxmlimport/data/tdf108408.docx
Binary files 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"/>