src/lib/VSD5Parser.cpp | 2 src/lib/VSD6Parser.cpp | 6 - src/lib/VSDCollector.h | 2 src/lib/VSDContentCollector.cpp | 5 - src/lib/VSDContentCollector.h | 2 src/lib/VSDDocumentStructure.h | 51 +++++++++++++ src/lib/VSDFieldList.cpp | 104 ++++++++++++++++++++++++--- src/lib/VSDFieldList.h | 9 +- src/lib/VSDParser.cpp | 6 - src/lib/VSDStylesCollector.cpp | 2 src/lib/VSDStylesCollector.h | 2 src/test/data/Visio11TextFieldsWithUnits.vsd |binary src/test/data/Visio6TextFieldsWithUnits.vsd |binary src/test/importtest.cpp | 11 ++ 14 files changed, 176 insertions(+), 26 deletions(-)
New commits: commit 9bf6a30786fb75cb725fe038d77ef03e1ebc4bc0 Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Tue Jul 9 22:54:57 2019 +0200 Commit: Bartosz Kosiorek <gan...@poczta.onet.pl> CommitDate: Tue Jul 9 22:54:57 2019 +0200 tdf#126292 Fix unit conversion Change-Id: I88711a1bf1bfd6078dc6948194449bcc91f34cce diff --git a/src/lib/VSD5Parser.cpp b/src/lib/VSD5Parser.cpp index f16160e..c918510 100644 --- a/src/lib/VSD5Parser.cpp +++ b/src/lib/VSD5Parser.cpp @@ -464,7 +464,7 @@ void libvisio::VSD5Parser::readTextField(librevenge::RVNGInputStream *input) else { double numericValue = readDouble(input); - m_shape.m_fields.addNumericField(m_header.id, m_header.level, VSD_FIELD_FORMAT_Unknown, numericValue, 0xffff); + m_shape.m_fields.addNumericField(m_header.id, m_header.level, VSD_FIELD_FORMAT_Unknown, UNIT_NoCast, numericValue, 0xffff); } } diff --git a/src/lib/VSD6Parser.cpp b/src/lib/VSD6Parser.cpp index d2dd941..012528e 100644 --- a/src/lib/VSD6Parser.cpp +++ b/src/lib/VSD6Parser.cpp @@ -337,7 +337,7 @@ void libvisio::VSD6Parser::readTextField(librevenge::RVNGInputStream *input) unsigned long initialPosition = input->tell(); input->seek(7, librevenge::RVNG_SEEK_CUR); unsigned char unit = readU8(input); - if (unit == 0xe8) + if (unit == UNIT_StringWithoutUnit) { int nameId = readS32(input); input->seek(6, librevenge::RVNG_SEEK_CUR); @@ -391,13 +391,13 @@ void libvisio::VSD6Parser::readTextField(librevenge::RVNGInputStream *input) if (blockIdx != 2) { - if (unit == 0x28) + if (unit == UNIT_Date) formatNumber = VSD_FIELD_FORMAT_MsoDateShort; else formatNumber = VSD_FIELD_FORMAT_Unknown; } - m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, numericValue, formatStringId); + m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, unit, numericValue, formatStringId); } } diff --git a/src/lib/VSDCollector.h b/src/lib/VSDCollector.h index 7286d1c..11fd25e 100644 --- a/src/lib/VSDCollector.h +++ b/src/lib/VSDCollector.h @@ -150,7 +150,7 @@ public: // Field list virtual void collectFieldList(unsigned id, unsigned level) = 0; virtual void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId) = 0; - virtual void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) = 0; + virtual void collectNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) = 0; // Metadata virtual void collectMetaData(const librevenge::RVNGPropertyList &metaData) = 0; diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index e15b4d9..e808b21 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -3436,7 +3436,7 @@ void libvisio::VSDContentCollector::collectTextField(unsigned id, unsigned level } } -void libvisio::VSDContentCollector::collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) +void libvisio::VSDContentCollector::collectNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) { _handleLevelChange(level); VSDFieldListElement *pElement = m_stencilFields.getElement(m_fields.size()); @@ -3446,6 +3446,7 @@ void libvisio::VSDContentCollector::collectNumericField(unsigned id, unsigned le if (element) { element->setValue(number); + element->setUnit(unit); if (format == VSD_FIELD_FORMAT_Unknown) { std::map<unsigned, librevenge::RVNGString>::const_iterator iter = m_names.find(formatStringId); @@ -3460,7 +3461,7 @@ void libvisio::VSDContentCollector::collectNumericField(unsigned id, unsigned le } else { - VSDNumericField tmpField(id, level, format, number, formatStringId); + VSDNumericField tmpField(id, level, format, unit, number, formatStringId); m_fields.push_back(tmpField.getString(m_names)); } } diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h index 1252afe..58993d2 100644 --- a/src/lib/VSDContentCollector.h +++ b/src/lib/VSDContentCollector.h @@ -170,7 +170,7 @@ public: // Field list void collectFieldList(unsigned id, unsigned level) override; void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId) override; - void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) override; + void collectNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) override; void startPage(unsigned pageId) override; void endPage() override; diff --git a/src/lib/VSDDocumentStructure.h b/src/lib/VSDDocumentStructure.h index 4fd8b61..0d10b91 100644 --- a/src/lib/VSDDocumentStructure.h +++ b/src/lib/VSDDocumentStructure.h @@ -126,6 +126,57 @@ #define VSD_FONTFACE 0xd7 #define VSD_FONTFACES 0xd8 +// Unit conversions: +#define UNIT_Number 32 +#define UNIT_Percent 33 +#define UNIT_Acre 36 +#define UNIT_Hectare 37 +#define UNIT_Date 40 +#define UNIT_DurationUnits 42 +#define UNIT_ElapsedWeek 43 +#define UNIT_ElapsedDay 44 +#define UNIT_ElapsedHour 45 +#define UNIT_ElapsedMin 46 +#define UNIT_ElapsedSec 47 +#define UNIT_TypeUnits 48 +#define UNIT_PicasAndPoints 49 +#define UNIT_Points 50 +#define UNIT_Picas 51 +#define UNIT_CicerosAndDidots 52 +#define UNIT_Didots 53 +#define UNIT_Ciceros 54 +#define UNIT_PageUnits 63 +#define UNIT_DrawingUnits 64 +#define UNIT_Inches 65 +#define UNIT_Feet 66 +#define UNIT_FeetAndInches 67 +#define UNIT_Centimeters 69 +#define UNIT_Miles 68 +#define UNIT_Millimeters 70 +#define UNIT_Meters 71 +#define UNIT_Kilometers 72 +#define UNIT_InchFractions 73 +#define UNIT_MileFractions 74 +#define UNIT_Yards 75 +#define UNIT_NauticalMiles 76 +#define UNIT_AngleUnits 80 +#define UNIT_Degrees 81 +#define UNIT_DegreeMinuteSecond 82 +#define UNIT_Radians 83 +#define UNIT_Minutes 84 +#define UNIT_Sec 85 +#define UNIT_GUID 95 +#define UNIT_Currency 111 +#define UNIT_NURBS 138 +#define UNIT_Polyline 139 +#define UNIT_Point 225 +#define UNIT_String 231 +#define UNIT_StringWithoutUnit 232 +#define UNIT_Multidimensional 233 // like Acre, square meters, sq. inches, hectare, sq. yards +#define UNIT_Color 251 +#define UNIT_NoCast 252 // No unit conversion +#define UNIT_Invalid 255 + // Field formats #define VSD_FIELD_FORMAT_NumGenNoUnits 0 diff --git a/src/lib/VSDFieldList.cpp b/src/lib/VSDFieldList.cpp index f6fc62d..7b6d058 100644 --- a/src/lib/VSDFieldList.cpp +++ b/src/lib/VSDFieldList.cpp @@ -44,12 +44,12 @@ void libvisio::VSDTextField::setNameId(int nameId) void libvisio::VSDNumericField::handle(VSDCollector *collector) const { - collector->collectNumericField(m_id, m_level, m_format, m_number, m_formatStringId); + collector->collectNumericField(m_id, m_level, m_format, m_unit, m_number, m_formatStringId); } libvisio::VSDFieldListElement *libvisio::VSDNumericField::clone() { - return new VSDNumericField(m_id, m_level, m_format, m_number, m_formatStringId); + return new VSDNumericField(m_id, m_level, m_format, m_unit, m_number, m_formatStringId); } #define MAX_BUFFER 1024 @@ -95,6 +95,85 @@ static librevenge::RVNGString doubleToString(const double value, const char* for return librevenge::RVNGString(stringValue.c_str()); } +double convertNumber(const unsigned short unit, const double number) +{ + switch (unit) + { + case UNIT_Percent: + return number*100.0; + + case UNIT_Points: + return number*72.0; + case UNIT_Picas: + return number*6.0; + case UNIT_Didots: + return number*67.37400530504; + case UNIT_Ciceros: + return number*5.62984854; + case UNIT_Inches: + return number; + case UNIT_Feet: + return number*0.0833333333; + case UNIT_Centimeters: + return number*2.54; + case UNIT_Miles: + return number*63360; + case UNIT_Millimeters: + return number*25.4; + case UNIT_Meters: + return number*0.0254; + case UNIT_Kilometers: + return number*0.0000254; + default: + return number; + } +} + +librevenge::RVNGString getUnitString(const unsigned short unit) +{ + switch (unit) + { + case UNIT_Number: + case UNIT_Date: // TODO + case UNIT_String: + case UNIT_StringWithoutUnit: + case UNIT_NoCast: + case UNIT_Invalid: + return ""; + case UNIT_Percent: + return "%"; + case UNIT_Acre: + return "acres"; + case UNIT_Hectare: + return "ha"; + + case UNIT_Points: + return "pt"; + case UNIT_Picas: + return "p"; + case UNIT_Didots: + return "d"; + case UNIT_Ciceros: + return "c"; + case UNIT_Inches: + return "in"; + case UNIT_Feet: + return "ft"; + case UNIT_Centimeters: + return "cm"; + case UNIT_Miles: + return "mi"; + case UNIT_Millimeters: + return "mm"; + case UNIT_Meters: + return "m"; + case UNIT_Kilometers: + return "km"; + default: + return ""; + } +} + librevenge::RVNGString libvisio::VSDNumericField::getString(const std::map<unsigned, librevenge::RVNGString> &) { if (m_format == VSD_FIELD_FORMAT_Unknown) @@ -106,15 +185,14 @@ librevenge::RVNGString libvisio::VSDNumericField::getString(const std::map<unsig { // 0 Format string: 0.#### Example: 30060.9167 // 1 Format string: 0.#### u Example: 30060.9167 cm - return doubleToString(m_number, "%.4g"); + return doubleToString(convertNumber(m_unit, m_number), "%.4g"); } case VSD_FIELD_FORMAT_0PlNoUnits: case VSD_FIELD_FORMAT_0PlDefUnits: { // 2 Format string: 0 Example: 30061 // 3 Format string: 0 u Example: 30061 cm - std::unique_ptr<librevenge::RVNGProperty> pProp{librevenge::RVNGPropertyFactory::newIntProp(m_number)}; - return pProp ? pProp->getStr() : librevenge::RVNGString(); + return doubleToString(convertNumber(m_unit, m_number), "%.0f"); } case VSD_FIELD_FORMAT_1PlNoUnits: @@ -122,7 +200,7 @@ librevenge::RVNGString libvisio::VSDNumericField::getString(const std::map<unsig { // 4 Format string: 0.0 Example: 30060.9 // 5 Format string: 0.0 u Example: 30060.9 cm - return doubleToString(m_number, "%.1f"); + return doubleToString(convertNumber(m_unit, m_number), "%.1f"); } case VSD_FIELD_FORMAT_2PlNoUnits: @@ -130,7 +208,7 @@ librevenge::RVNGString libvisio::VSDNumericField::getString(const std::map<unsig { // 6 Format string: 0.00 Example: 30061.92 // 7 Format string: 0.00 u Example: 30061.92 cm - return doubleToString(m_number, "%.2f"); + return doubleToString(convertNumber(m_unit, m_number), "%.2f"); } case VSD_FIELD_FORMAT_3PlNoUnits: @@ -138,7 +216,7 @@ librevenge::RVNGString libvisio::VSDNumericField::getString(const std::map<unsig { // 8 Format string: 0.000 Example: 30061.916 // 9 Format string: 0.000 u Example: 30061.916 cm - return doubleToString(m_number, "%.3f"); + return doubleToString(convertNumber(m_unit, m_number), "%.3f"); } //TODO VSD_FIELD_FORMAT_FeetAndInches 10 Format string: <,FEET/INCH>0.000 u //TODO VSD_FIELD_FORMAT_Radians 11 Format string: <,rad>0.#### u @@ -301,6 +379,12 @@ void libvisio::VSDNumericField::setFormat(unsigned short format) { m_format = format; } + +void libvisio::VSDNumericField::setUnit(unsigned short unit) +{ + m_unit = unit; +} + void libvisio::VSDNumericField::setValue(double number) { m_number = number; @@ -362,10 +446,10 @@ void libvisio::VSDFieldList::addTextField(unsigned id, unsigned level, int nameI m_elements[id] = make_unique<VSDTextField>(id, level, nameId, formatStringId); } -void libvisio::VSDFieldList::addNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) +void libvisio::VSDFieldList::addNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) { if (m_elements.find(id) == m_elements.end()) - m_elements[id] = make_unique<VSDNumericField>(id, level, format, number, formatStringId); + m_elements[id] = make_unique<VSDNumericField>(id, level, format, unit, number, formatStringId); } void libvisio::VSDFieldList::handle(VSDCollector *collector) const diff --git a/src/lib/VSDFieldList.h b/src/lib/VSDFieldList.h index 9d47bb3..9fe2951 100644 --- a/src/lib/VSDFieldList.h +++ b/src/lib/VSDFieldList.h @@ -32,6 +32,7 @@ public: virtual librevenge::RVNGString getString(const std::map<unsigned, librevenge::RVNGString> &) = 0; virtual void setNameId(int) = 0; virtual void setFormat(unsigned short) = 0; + virtual void setUnit(unsigned short) = 0; virtual void setValue(double) = 0; }; @@ -49,6 +50,7 @@ public: librevenge::RVNGString getString(const std::map<unsigned, librevenge::RVNGString> &strVec) override; void setNameId(int nameId) override; void setFormat(unsigned short) override {} + void setUnit(unsigned short) override {} void setValue(double) override {} private: unsigned m_id, m_level; @@ -58,10 +60,11 @@ private: class VSDNumericField : public VSDFieldListElement { public: - VSDNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) + VSDNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) : m_id(id), m_level(level), m_format(format), + m_unit(unit), m_number(number), m_formatStringId(formatStringId) {} ~VSDNumericField() override {} @@ -70,11 +73,13 @@ public: librevenge::RVNGString getString(const std::map<unsigned, librevenge::RVNGString> &) override; void setNameId(int) override {} void setFormat(unsigned short format) override; + void setUnit(unsigned short unit) override; void setValue(double number) override; private: librevenge::RVNGString datetimeToString(const char *format, double datetime); unsigned m_id, m_level; unsigned short m_format; + unsigned short m_unit; double m_number; int m_formatStringId; }; @@ -89,7 +94,7 @@ public: void setElementsOrder(const std::vector<unsigned> &m_elementsOrder); void addFieldList(unsigned id, unsigned level); void addTextField(unsigned id, unsigned level, int nameId, int formatStringId); - void addNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId); + void addNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId); void addClonedField(unsigned id); void handle(VSDCollector *collector) const; void clear(); diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp index cc0bb96..980a4ca 100644 --- a/src/lib/VSDParser.cpp +++ b/src/lib/VSDParser.cpp @@ -2173,7 +2173,7 @@ void libvisio::VSDParser::readTextField(librevenge::RVNGInputStream *input) unsigned long initialPosition = input->tell(); input->seek(7, librevenge::RVNG_SEEK_CUR); unsigned char unit = readU8(input); - if (unit == 0xe8) + if (unit == UNIT_StringWithoutUnit) { int nameId = readS32(input); input->seek(6, librevenge::RVNG_SEEK_CUR); @@ -2227,13 +2227,13 @@ void libvisio::VSDParser::readTextField(librevenge::RVNGInputStream *input) if (blockIdx != 2) { - if (unit == 0x28) + if (unit == UNIT_Date) formatNumber = VSD_FIELD_FORMAT_MsoDateShort; else formatNumber = VSD_FIELD_FORMAT_Unknown; } - m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, numericValue, formatStringId); + m_shape.m_fields.addNumericField(m_header.id, m_header.level, formatNumber, unit, numericValue, formatStringId); } } diff --git a/src/lib/VSDStylesCollector.cpp b/src/lib/VSDStylesCollector.cpp index cc8021f..5503ede 100644 --- a/src/lib/VSDStylesCollector.cpp +++ b/src/lib/VSDStylesCollector.cpp @@ -408,7 +408,7 @@ void libvisio::VSDStylesCollector::collectTextField(unsigned /* id */, unsigned _handleLevelChange(level); } -void libvisio::VSDStylesCollector::collectNumericField(unsigned /* id */, unsigned level, unsigned short /* format */, double /* number */, int /* formatStringId */) +void libvisio::VSDStylesCollector::collectNumericField(unsigned /* id */, unsigned level, unsigned short /* format */, unsigned short /* unit */, double /* number */, int /* formatStringId */) { _handleLevelChange(level); } diff --git a/src/lib/VSDStylesCollector.h b/src/lib/VSDStylesCollector.h index b18fdd6..6da8f2c 100644 --- a/src/lib/VSDStylesCollector.h +++ b/src/lib/VSDStylesCollector.h @@ -163,7 +163,7 @@ public: // Field list void collectFieldList(unsigned id, unsigned level) override; void collectTextField(unsigned id, unsigned level, int nameId, int formatStringId) override; - void collectNumericField(unsigned id, unsigned level, unsigned short format, double number, int formatStringId) override; + void collectNumericField(unsigned id, unsigned level, unsigned short format, unsigned short unit, double number, int formatStringId) override; void collectMetaData(const librevenge::RVNGPropertyList &) override { } diff --git a/src/test/data/Visio11TextFieldsWithUnits.vsd b/src/test/data/Visio11TextFieldsWithUnits.vsd new file mode 100644 index 0000000..be927c5 Binary files /dev/null and b/src/test/data/Visio11TextFieldsWithUnits.vsd differ diff --git a/src/test/data/Visio6TextFieldsWithUnits.vsd b/src/test/data/Visio6TextFieldsWithUnits.vsd new file mode 100644 index 0000000..dbbf103 Binary files /dev/null and b/src/test/data/Visio6TextFieldsWithUnits.vsd differ diff --git a/src/test/importtest.cpp b/src/test/importtest.cpp index 100338d..6ced876 100644 --- a/src/test/importtest.cpp +++ b/src/test/importtest.cpp @@ -153,7 +153,7 @@ xmlDocPtr parse(const char *filename, xmlBufferPtr buffer) xmlTextWriterEndDocument(writer); xmlFreeTextWriter(writer); - //std::cerr << "XML is '" << (const char *)xmlBufferContent(buffer) << "'" << std::endl; + std::cerr << "XML is '" << (const char *)xmlBufferContent(buffer) << "'" << std::endl; return xmlParseMemory((const char *)xmlBufferContent(buffer), xmlBufferLength(buffer)); } @@ -178,6 +178,7 @@ class ImportTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(testVsdTextBlockWithoutBgColor); CPPUNIT_TEST(testVsdNumericFormat); CPPUNIT_TEST(testVsdDateTimeFormatting); + CPPUNIT_TEST(testVsd11TextfieldsWithUnits); CPPUNIT_TEST(testBmpFileHeader); CPPUNIT_TEST(testBmpFileHeader2); CPPUNIT_TEST_SUITE_END(); @@ -192,6 +193,7 @@ class ImportTest : public CPPUNIT_NS::TestFixture void testVsdTextBlockWithoutBgColor(); void testVsdNumericFormat(); void testVsdDateTimeFormatting(); + void testVsd11TextfieldsWithUnits(); void testBmpFileHeader(); void testBmpFileHeader2(); @@ -333,6 +335,13 @@ void ImportTest::testVsdDateTimeFormatting() assertXPathContent(m_doc, "/document/page/textObject/paragraph/span/insertText", "11/30/2005"); } +// tdf#126292 +void ImportTest::testVsd11TextfieldsWithUnits() +{ + m_doc = parse("Visio11TextFieldsWithUnits.vsd", m_buffer); + assertXPathContent(m_doc, "/document/page/textObject/paragraph/span/insertText", "11/30/2005"); +} + void ImportTest::testBmpFileHeader() { m_doc = parse("bitmaps.vsd", m_buffer); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits