[Libreoffice-commits] libvisio.git: src/lib src/test

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Tue Jul 9 20:55:21 UTC 2019


 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 <gang65 at poczta.onet.pl>
AuthorDate: Tue Jul 9 22:54:57 2019 +0200
Commit:     Bartosz Kosiorek <gang65 at 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);


More information about the Libreoffice-commits mailing list