src/lib/VDXParser.cpp           |   18 ++++++++++++---
 src/lib/VSD5Parser.cpp          |    2 -
 src/lib/VSD6Parser.cpp          |    2 -
 src/lib/VSDCollector.h          |    5 ++--
 src/lib/VSDContentCollector.cpp |   47 ++++++++++++++++++++++++++++++++--------
 src/lib/VSDContentCollector.h   |   14 +++++++++--
 src/lib/VSDParser.cpp           |   10 +++++---
 src/lib/VSDStencils.cpp         |    6 +++--
 src/lib/VSDStencils.h           |    1 
 src/lib/VSDStyles.h             |   30 +++++++++++++++++--------
 src/lib/VSDStylesCollector.cpp  |    8 +++++-
 src/lib/VSDStylesCollector.h    |   11 ++++++---
 src/lib/VSDXMLParserBase.cpp    |   17 +++++++++++++-
 src/lib/VSDXParser.cpp          |   18 ++++++++++++---
 14 files changed, 146 insertions(+), 43 deletions(-)

New commits:
commit a33deeb4b905ab9bad4caa1c9393ab7af1027f69
Author:     Balazs Varga <[email protected]>
AuthorDate: Wed Sep 17 15:02:43 2025 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Fri Sep 19 10:03:45 2025 +0200

    tdf#168475 libvisio: a bit better handling of vsdx files theme import
    
    with using the correct VariationColorIndex and VariationStyleIndex
    from the xml for selecting the correct color from theme.xml.
    
    Using the default color (do not apply the theme color) is necessary
    for the first shape of the grouped "End Event" object which is a
    standard black color and cannot be changed in MS Visio. TODO: unit test
    
    Change-Id: I6da23215eb89b4177d045155cfaa8969cc85af12
    Reviewed-on: https://gerrit.libreoffice.org/c/libvisio/+/191099
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Miklos Vajna <[email protected]>

diff --git a/src/lib/VDXParser.cpp b/src/lib/VDXParser.cpp
index 99aa28f..cc18156 100644
--- a/src/lib/VDXParser.cpp
+++ b/src/lib/VDXParser.cpp
@@ -49,8 +49,10 @@ bool libvisio::VDXParser::parseMain()
       return false;
 
     VSDStyles styles = stylesCollector.getStyleSheets();
+    const std::optional<unsigned> varColInd = 
stylesCollector.getvariationColorIndex();
+    const std::optional<unsigned> varStyInd = 
stylesCollector.getvariationStyleIndex();
 
-    VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils);
+    VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils, 
varColInd, varStyInd);
     m_collector = &contentCollector;
     m_input->seek(0, librevenge::RVNG_SEEK_SET);
     if (!processXmlDocument(m_input))
@@ -459,7 +461,7 @@ void 
libvisio::VDXParser::readFillAndShadow(xmlTextReaderPtr reader)
       VSD_DEBUG_MSG(("Found stencil fill
"));
     }
     m_shape.m_fillStyle.override(VSDOptionalFillStyle(fillColourFG, 
fillColourBG, fillPattern, fillFGTransparency, fillBGTransparency,
-                                                      shadowColourFG, 
shadowPattern, shadowOffsetX, shadowOffsetY, -1, -1, 1));
+                                                      shadowColourFG, 
shadowPattern, shadowOffsetX, shadowOffsetY, -1, -1, 1, 0, 0));
   }
 }
 
@@ -734,6 +736,8 @@ void libvisio::VDXParser::readPageProps(xmlTextReaderPtr 
reader)
   double shadowOffsetY = 0.0;
   double pageScale = 1.0;
   double drawingScale = 1.0;
+  std::optional<unsigned> variationColorIndex;
+  std::optional<unsigned> variationStyleIndex;
 
   auto level = (unsigned)getElementDepth(reader);
   int ret = 1;
@@ -774,6 +778,14 @@ void libvisio::VDXParser::readPageProps(xmlTextReaderPtr 
reader)
       if (XML_READER_TYPE_ELEMENT == tokenType)
         ret = readDoubleData(drawingScale, reader);
       break;
+    case XML_VARIATIONCOLORINDEX:
+      if (XML_READER_TYPE_ELEMENT == tokenType)
+        ret = readUnsignedData(variationColorIndex, reader);
+      break;
+    case XML_VARIATIONSTYLEINDEX:
+      if (XML_READER_TYPE_ELEMENT == tokenType)
+        ret = readUnsignedData(variationStyleIndex, reader);
+      break;
     default:
       break;
     }
@@ -788,7 +800,7 @@ void libvisio::VDXParser::readPageProps(xmlTextReaderPtr 
reader)
   else if (m_isPageStarted)
   {
     double scale = drawingScale > 0 || drawingScale < 0 ? 
pageScale/drawingScale : 1.0;
-    m_collector->collectPageProps(0, level, pageWidth, pageHeight, 
shadowOffsetX, shadowOffsetY, scale, 0);
+    m_collector->collectPageProps(0, level, pageWidth, pageHeight, 
shadowOffsetX, shadowOffsetY, scale, 0, variationColorIndex, 
variationStyleIndex);
   }
 }
 
diff --git a/src/lib/VSD5Parser.cpp b/src/lib/VSD5Parser.cpp
index e86a37b..1502122 100644
--- a/src/lib/VSD5Parser.cpp
+++ b/src/lib/VSD5Parser.cpp
@@ -357,7 +357,7 @@ void 
libvisio::VSD5Parser::readFillAndShadow(librevenge::RVNGInputStream *input)
     }
     m_shape.m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, 
fillPattern, 0.0,
                                                       0.0, shfgc, 
shadowPattern, shadowOffsetX,
-                                                      shadowOffsetY, -1, -1, 
-1));
+                                                      shadowOffsetY, -1, -1, 
-1, 0, 0));
   }
 }
 
diff --git a/src/lib/VSD6Parser.cpp b/src/lib/VSD6Parser.cpp
index 4c5de78..8bc0209 100644
--- a/src/lib/VSD6Parser.cpp
+++ b/src/lib/VSD6Parser.cpp
@@ -306,7 +306,7 @@ void 
libvisio::VSD6Parser::readFillAndShadow(librevenge::RVNGInputStream *input)
     }
     m_shape.m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, 
fillPattern, fillFGTransparency,
                                                       fillBGTransparency, 
shadowFG, shadowPattern,
-                                                      shadowOffsetX, 
shadowOffsetY, -1, -1, -1));
+                                                      shadowOffsetX, 
shadowOffsetY, -1, -1, -1, 0, 0));
   }
 }
 
diff --git a/src/lib/VSDCollector.h b/src/lib/VSDCollector.h
index a4673ee..00f5756 100644
--- a/src/lib/VSDCollector.h
+++ b/src/lib/VSDCollector.h
@@ -60,9 +60,10 @@ public:
   virtual void collectTxtXForm(unsigned level, const XForm &txtxform) = 0;
   virtual void collectShapesOrder(unsigned id, unsigned level, const 
std::vector<unsigned> &shapeIds) = 0;
   virtual void collectForeignDataType(unsigned level, unsigned foreignType, 
unsigned foreignFormat, double offsetX, double offsetY, double width, double 
height) = 0;
-  virtual void collectPageProps(unsigned id, unsigned level, double pageWidth, 
double pageHeight, double shadowOffsetX, double shadowOffsetY, double scale, 
unsigned char drawingScaleUnit) = 0;
+  virtual void collectPageProps(unsigned id, unsigned level, double pageWidth, 
double pageHeight, double shadowOffsetX, double shadowOffsetY, double scale,
+                                unsigned char drawingScaleUnit, const 
std::optional<unsigned> variationColorIndex, const std::optional<unsigned> 
variationStyleIndex) = 0;
   virtual void collectPage(unsigned id, unsigned level, unsigned 
backgroundPageID, bool isBackgroundPage, const VSDName &pageName) = 0;
-  virtual void collectShape(unsigned id, unsigned level, unsigned parent, 
unsigned masterPage, unsigned masterShape, unsigned lineStyle, unsigned 
fillStyle, unsigned textStyle) = 0;
+  virtual void collectShape(unsigned id, unsigned level, unsigned parent, 
unsigned masterPage, unsigned masterShape, unsigned lineStyle, unsigned 
fillStyle, unsigned textStyle, const VSDName &aShapeType) = 0;
   virtual void collectSplineStart(unsigned id, unsigned level, double x, 
double y, double secondKnot, double firstKnot, double lastKnot, unsigned 
degree) = 0;
   virtual void collectSplineKnot(unsigned id, unsigned level, double x, double 
y, double knot) = 0;
   virtual void collectSplineEnd() = 0;
diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index 482eae7..1700740 100644
--- a/src/lib/VSDContentCollector.cpp
+++ b/src/lib/VSDContentCollector.cpp
@@ -120,14 +120,15 @@ libvisio::VSDContentCollector::VSDContentCollector(
   std::vector<std::map<unsigned, XForm> > &groupXFormsSequence,
   std::vector<std::map<unsigned, unsigned> > &groupMembershipsSequence,
   std::vector<std::list<unsigned> > &documentPageShapeOrders,
-  VSDStyles &styles, VSDStencils &stencils
+  VSDStyles &styles, VSDStencils &stencils, const std::optional<unsigned> 
&varColInd,
+  const std::optional<unsigned> &varStyInd
 ) :
   m_painter(painter), m_isPageStarted(false), m_pageWidth(0.0), 
m_pageHeight(0.0),
   m_shadowOffsetX(0.0), m_shadowOffsetY(0.0),
   m_scale(1.0), m_defaultDrawingUnit(0),
   m_x(0.0), m_y(0.0), m_originalX(0.0), m_originalY(0.0), m_xform(), 
m_txtxform(), m_misc(),
   m_currentFillGeometry(), m_currentLineGeometry(), 
m_groupXForms(groupXFormsSequence.empty() ? nullptr : &groupXFormsSequence[0]),
-  m_currentForeignData(), m_currentOLEData(), m_currentForeignProps(), 
m_currentShapeId(0), m_foreignType((unsigned)-1),
+  m_currentForeignData(), m_currentOLEData(), m_currentForeignProps(), 
m_currentShapeId(0), m_parentShapeId(0), m_foreignType((unsigned)-1),
   m_foreignFormat(0), m_foreignOffsetX(0.0), m_foreignOffsetY(0.0), 
m_foreignWidth(0.0), m_foreignHeight(0.0),
   m_noLine(false), m_noFill(false), m_noShow(false), m_fonts(),
   m_currentLevel(0), m_isShapeStarted(false),
@@ -139,11 +140,12 @@ libvisio::VSDContentCollector::VSDContentCollector(
   m_currentText(), m_names(), m_stencilNames(), m_fields(), m_stencilFields(), 
m_fieldIndex(0),
   m_charFormats(), m_paraFormats(), m_lineStyle(), m_fillStyle(), 
m_textBlockStyle(),
   m_defaultCharStyle(), m_defaultParaStyle(), m_currentStyleSheet(0), 
m_styles(styles),
+  m_variationColorIndex(varColInd), m_variationStyleIndex(varStyInd),
   m_stencils(stencils), m_stencilShape(nullptr), m_isStencilStarted(false), 
m_currentGeometryCount(0),
   m_backgroundPageID(MINUS_ONE), m_currentPageID(0), m_currentPage(), 
m_pages(), m_layerList(),
   m_splineControlPoints(), m_splineKnotVector(), m_splineX(0.0), 
m_splineY(0.0),
   m_splineLastKnot(0.0), m_splineDegree(0), m_splineLevel(0), 
m_currentShapeLevel(0),
-  m_isBackgroundPage(false), m_currentLayerList(), m_currentLayerMem(), 
m_tabSets(), m_documentTheme(nullptr)
+  m_isBackgroundPage(false), m_currentLayerList(), m_currentLayerMem(), 
m_tabSets(), m_documentTheme(nullptr), m_currentShapeType()
 {
 }
 
@@ -1693,7 +1695,8 @@ void 
libvisio::VSDContentCollector::collectFillAndShadow(unsigned level, const s
 {
   _handleLevelChange(level);
   m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, fillPattern, 
fillFGTransparency, fillBGTransparency, shfgc,
-                                            shadowPattern, shadowOffsetX, 
shadowOffsetY, qsFillColour, qsShadowColour, qsFillMatrix), m_documentTheme);
+                                            shadowPattern, shadowOffsetX, 
shadowOffsetY, qsFillColour, qsShadowColour, qsFillMatrix,
+                                            m_variationColorIndex, 
m_variationStyleIndex), !_isDefaultShapeFormat() ? m_documentTheme : nullptr);
 }
 
 void libvisio::VSDContentCollector::collectFillAndShadow(unsigned level, const 
std::optional<Colour> &colourFG, const std::optional<Colour> &colourBG,
@@ -2564,7 +2567,8 @@ void 
libvisio::VSDContentCollector::collectForeignDataType(unsigned level, unsig
 }
 
 void libvisio::VSDContentCollector::collectPageProps(unsigned /* id */, 
unsigned level, double pageWidth, double pageHeight,
-                                                     double shadowOffsetX, 
double shadowOffsetY, double scale, unsigned char drawingScaleUnit)
+                                                     double shadowOffsetX, 
double shadowOffsetY, double scale, unsigned char drawingScaleUnit,
+                                                     const 
std::optional<unsigned> variationColorIndex, const std::optional<unsigned> 
variationStyleIndex)
 {
   _handleLevelChange(level);
   m_pageWidth = pageWidth;
@@ -2573,6 +2577,8 @@ void 
libvisio::VSDContentCollector::collectPageProps(unsigned /* id */, unsigned
   m_shadowOffsetX = shadowOffsetX;
   m_shadowOffsetY = shadowOffsetY;
   m_defaultDrawingUnit = drawingScaleUnit;
+  m_variationColorIndex = variationColorIndex;
+  m_variationStyleIndex = variationStyleIndex;
 
   m_currentPage.m_pageWidth = m_scale*m_pageWidth;
   m_currentPage.m_pageHeight = m_scale*m_pageHeight;
@@ -2588,7 +2594,7 @@ void libvisio::VSDContentCollector::collectPage(unsigned 
/* id */, unsigned leve
   m_isBackgroundPage = isBackgroundPage;
 }
 
-void libvisio::VSDContentCollector::collectShape(unsigned id, unsigned level, 
unsigned /*parent*/, unsigned masterPage, unsigned masterShape, unsigned 
lineStyleId, unsigned fillStyleId, unsigned textStyleId)
+void libvisio::VSDContentCollector::collectShape(unsigned id, unsigned level, 
unsigned parent, unsigned masterPage, unsigned masterShape, unsigned 
lineStyleId, unsigned fillStyleId, unsigned textStyleId, const VSDName 
&aShapeType)
 {
   _handleLevelChange(level);
   m_currentShapeLevel = level;
@@ -2618,7 +2624,12 @@ void 
libvisio::VSDContentCollector::collectShape(unsigned id, unsigned level, un
   m_charFormats.clear();
   m_paraFormats.clear();
 
+  m_currentShapeType.clear();
+  if (aShapeType.m_data.size())
+    _convertDataToString(m_currentShapeType, aShapeType.m_data, 
aShapeType.m_format);
+
   m_currentShapeId = id;
+  m_parentShapeId = parent;
   m_pageOutputDrawing[m_currentShapeId] = VSDOutputElementList();
   m_pageOutputText[m_currentShapeId] = VSDOutputElementList();
   m_shapeOutputDrawing = &m_pageOutputDrawing[m_currentShapeId];
@@ -2678,10 +2689,11 @@ void 
libvisio::VSDContentCollector::collectShape(unsigned id, unsigned level, un
 
     m_lineStyle.override(m_stencilShape->m_lineStyle, m_documentTheme);
 
+    bool bDefault = _isDefaultShapeFormat();
     if (m_stencilShape->m_fillStyleId != MINUS_ONE)
-      
m_fillStyle.override(m_styles.getOptionalFillStyle(m_stencilShape->m_fillStyleId),
 m_documentTheme);
+      
m_fillStyle.override(m_styles.getOptionalFillStyle(m_stencilShape->m_fillStyleId),
 !bDefault ? m_documentTheme : nullptr);
 
-    m_fillStyle.override(m_stencilShape->m_fillStyle, m_documentTheme);
+    m_fillStyle.override(m_stencilShape->m_fillStyle, !bDefault ? 
m_documentTheme : nullptr);
 
     if (m_stencilShape->m_textStyleId != MINUS_ONE)
     {
@@ -2898,7 +2910,7 @@ void 
libvisio::VSDContentCollector::collectFillStyle(unsigned /* level */, const
                                                      const std::optional<long> 
&qsShadowColour, const std::optional<long> &qsFillMatrix)
 {
   VSDOptionalFillStyle fillStyle(colourFG, colourBG, fillPattern, 
fillFGTransparency, fillBGTransparency, shfgc, shadowPattern,
-                                 shadowOffsetX, shadowOffsetY, qsFillColour, 
qsShadowColour, qsFillMatrix);
+                                 shadowOffsetX, shadowOffsetY, qsFillColour, 
qsShadowColour, qsFillMatrix, m_variationColorIndex, m_variationStyleIndex);
   m_styles.addFillStyle(m_currentStyleSheet, fillStyle);
 
 }
@@ -3579,6 +3591,23 @@ void 
libvisio::VSDContentCollector::_handleLevelChange(unsigned level)
   m_currentLevel = level;
 }
 
+bool libvisio::VSDContentCollector::_isDefaultShapeFormat()
+{
+  bool bDefault = false;
+  if (m_groupMemberships != m_groupMembershipsSequence.end())
+  {
+    auto iter = m_groupMemberships->find(m_currentShapeId);
+    if (iter != m_groupMemberships->end() && m_parentShapeId == iter->second 
&& (iter == m_groupMemberships->begin() || m_parentShapeId != 
std::prev(iter)->second))
+    {
+      std::string aValue(m_currentShapeType.cstr());
+      std::size_t found = aValue.find("End Event");
+      if (found != std::string::npos)
+        bDefault = true;
+    }
+  }
+  return bDefault;
+}
+
 void libvisio::VSDContentCollector::collectMetaData(const 
librevenge::RVNGPropertyList &metaData)
 {
   m_pages.setMetaData(metaData);
diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h
index a646b4d..8651362 100644
--- a/src/lib/VSDContentCollector.h
+++ b/src/lib/VSDContentCollector.h
@@ -36,7 +36,8 @@ public:
     std::vector<std::map<unsigned, XForm> > &groupXFormsSequence,
     std::vector<std::map<unsigned, unsigned> > &groupMembershipsSequence,
     std::vector<std::list<unsigned> > &documentPageShapeOrders,
-    VSDStyles &styles, VSDStencils &stencils
+    VSDStyles &styles, VSDStencils &stencils, const std::optional<unsigned> 
&varColInd,
+    const std::optional<unsigned> &varStyInd
   );
 
   void collectDocumentTheme(const VSDXTheme *theme) override;
@@ -77,9 +78,10 @@ public:
   void collectTxtXForm(unsigned level, const XForm &txtxform) override;
   void collectShapesOrder(unsigned id, unsigned level, const 
std::vector<unsigned> &shapeIds) override;
   void collectForeignDataType(unsigned level, unsigned foreignType, unsigned 
foreignFormat, double offsetX, double offsetY, double width, double height) 
override;
-  void collectPageProps(unsigned id, unsigned level, double pageWidth, double 
pageHeight, double shadowOffsetX, double shadowOffsetY, double scale, unsigned 
char drawingScaleUnit) override;
+  void collectPageProps(unsigned id, unsigned level, double pageWidth, double 
pageHeight, double shadowOffsetX, double shadowOffsetY, double scale,
+                        unsigned char drawingScaleUnit, const 
std::optional<unsigned> variationColorIndex, const std::optional<unsigned> 
variationStyleIndex) override;
   void collectPage(unsigned id, unsigned level, unsigned backgroundPageID, 
bool isBackgroundPage, const VSDName &pageName) override;
-  void collectShape(unsigned id, unsigned level, unsigned parent, unsigned 
masterPage, unsigned masterShape, unsigned lineStyle, unsigned fillStyle, 
unsigned textStyle) override;
+  void collectShape(unsigned id, unsigned level, unsigned parent, unsigned 
masterPage, unsigned masterShape, unsigned lineStyle, unsigned fillStyle, 
unsigned textStyle, const VSDName &aShapeType) override;
   void collectSplineStart(unsigned id, unsigned level, double x, double y, 
double secondKnot, double firstKnot, double lastKnot, unsigned degree) override;
   void collectSplineKnot(unsigned id, unsigned level, double x, double y, 
double knot) override;
   void collectSplineEnd() override;
@@ -197,6 +199,7 @@ private:
   void _flushCurrentPage();
 
   void _handleLevelChange(unsigned level);
+  bool _isDefaultShapeFormat();
 
   void _handleForeignData(const librevenge::RVNGBinaryData &data);
 
@@ -253,6 +256,7 @@ private:
   librevenge::RVNGBinaryData m_currentOLEData;
   librevenge::RVNGPropertyList m_currentForeignProps;
   unsigned m_currentShapeId;
+  unsigned m_parentShapeId;
   unsigned m_foreignType;
   unsigned m_foreignFormat;
   double m_foreignOffsetX;
@@ -296,6 +300,9 @@ private:
   unsigned m_currentStyleSheet;
   VSDStyles m_styles;
 
+  std::optional<unsigned> m_variationColorIndex;
+  std::optional<unsigned> m_variationStyleIndex;
+
   VSDStencils m_stencils;
   const VSDShape *m_stencilShape;
   bool m_isStencilStarted;
@@ -323,6 +330,7 @@ private:
   std::vector<VSDTabSet> m_tabSets;
 
   const VSDXTheme *m_documentTheme;
+  librevenge::RVNGString m_currentShapeType;
 };
 
 } // namespace libvisio
diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index 757978e..4701f56 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -136,8 +136,10 @@ bool libvisio::VSDParser::parseMain()
   _handleLevelChange(0);
 
   VSDStyles styles = stylesCollector.getStyleSheets();
+  const std::optional<unsigned> varColInd = 
stylesCollector.getvariationColorIndex();
+  const std::optional<unsigned> varStyInd = 
stylesCollector.getvariationStyleIndex();
 
-  VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils);
+  VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils, 
varColInd, varStyInd);
   m_collector = &contentCollector;
   if (m_container)
     parseMetaData();
@@ -637,7 +639,7 @@ void libvisio::VSDParser::_flushShape()
   if (!m_isShapeStarted)
     return;
 
-  m_collector->collectShape(m_shape.m_shapeId, m_currentShapeLevel, 
m_shape.m_parent, m_shape.m_masterPage, m_shape.m_masterShape, 
m_shape.m_lineStyleId, m_shape.m_fillStyleId, m_shape.m_textStyleId);
+  m_collector->collectShape(m_shape.m_shapeId, m_currentShapeLevel, 
m_shape.m_parent, m_shape.m_masterPage, m_shape.m_masterShape, 
m_shape.m_lineStyleId, m_shape.m_fillStyleId, m_shape.m_textStyleId, 
m_shape.m_aName);
 
   m_collector->collectShapesOrder(0, m_currentShapeLevel+2, 
m_shape.m_shapeList.getShapesOrder());
 
@@ -1275,7 +1277,7 @@ void 
libvisio::VSDParser::readPageProps(librevenge::RVNGInputStream *input)
     m_currentStencil->m_shadowOffsetX = m_shadowOffsetX;
     m_currentStencil->m_shadowOffsetY = m_shadowOffsetY;
   }
-  m_collector->collectPageProps(m_header.id, m_header.level, pageWidth, 
pageHeight, m_shadowOffsetX, m_shadowOffsetY, scale, drawingScaleUnit);
+  m_collector->collectPageProps(m_header.id, m_header.level, pageWidth, 
pageHeight, m_shadowOffsetX, m_shadowOffsetY, scale, drawingScaleUnit, 0, 0);
 }
 
 void libvisio::VSDParser::readShape(librevenge::RVNGInputStream *input)
@@ -2143,7 +2145,7 @@ void 
libvisio::VSDParser::readFillAndShadow(librevenge::RVNGInputStream *input)
     }
     m_shape.m_fillStyle.override(VSDOptionalFillStyle(colourFG, colourBG, 
fillPattern, fillFGTransparency,
                                                       fillBGTransparency, 
shadowFG, shadowPattern,
-                                                      shadowOffsetX, 
shadowOffsetY, -1, -1, -1));
+                                                      shadowOffsetX, 
shadowOffsetY, -1, -1, -1, 0, 0));
   }
 }
 
diff --git a/src/lib/VSDStencils.cpp b/src/lib/VSDStencils.cpp
index 73af5ed..33e2d59 100644
--- a/src/lib/VSDStencils.cpp
+++ b/src/lib/VSDStencils.cpp
@@ -17,7 +17,7 @@ libvisio::VSDShape::VSDShape()
     m_textStyleId(MINUS_ONE), m_lineStyle(), m_fillStyle(), 
m_textBlockStyle(), m_charStyle(),
     m_charList(), m_paraStyle(), m_paraList(), m_tabSets(), m_text(), 
m_names(),
     m_textFormat(libvisio::VSD_TEXT_UTF16), m_nurbsData(), m_polylineData(), 
m_xform(), m_txtxform(),
-    m_xform1d(), m_misc(), m_layerMem()
+    m_xform1d(), m_misc(), m_layerMem(), m_aName()
 {
 }
 
@@ -32,7 +32,7 @@ libvisio::VSDShape::VSDShape(const libvisio::VSDShape &shape)
     m_textFormat(shape.m_textFormat), m_nurbsData(shape.m_nurbsData), 
m_polylineData(shape.m_polylineData),
     m_xform(shape.m_xform), m_txtxform(shape.m_txtxform ? new 
XForm(*(shape.m_txtxform)) : nullptr),
     m_xform1d(shape.m_xform1d ? new XForm1D(*(shape.m_xform1d)) : nullptr), 
m_misc(shape.m_misc),
-    m_layerMem(shape.m_layerMem)
+    m_layerMem(shape.m_layerMem), m_aName(shape.m_aName)
 {
 }
 
@@ -74,6 +74,7 @@ libvisio::VSDShape &libvisio::VSDShape::operator=(const 
libvisio::VSDShape &shap
     m_xform1d.reset(shape.m_xform1d ? new XForm1D(*shape.m_xform1d) : nullptr);
     m_misc = shape.m_misc;
     m_layerMem = shape.m_layerMem;
+    m_aName = shape.m_aName;
   }
   return *this;
 }
@@ -110,6 +111,7 @@ void libvisio::VSDShape::clear()
   m_textFormat = libvisio::VSD_TEXT_UTF16;
   m_misc = VSDMisc();
   m_layerMem = VSDName();
+  m_aName = VSDName();
 }
 
 libvisio::VSDStencil::VSDStencil()
diff --git a/src/lib/VSDStencils.h b/src/lib/VSDStencils.h
index 964a933..48f1ae2 100644
--- a/src/lib/VSDStencils.h
+++ b/src/lib/VSDStencils.h
@@ -57,6 +57,7 @@ public:
   std::unique_ptr<XForm1D> m_xform1d;
   VSDMisc m_misc;
   VSDName m_layerMem;
+  VSDName m_aName;
 };
 
 class VSDStencil
diff --git a/src/lib/VSDStyles.h b/src/lib/VSDStyles.h
index efc05cb..cff97d4 100644
--- a/src/lib/VSDStyles.h
+++ b/src/lib/VSDStyles.h
@@ -105,16 +105,18 @@ struct VSDOptionalFillStyle
   VSDOptionalFillStyle() :
     fgColour(), bgColour(), pattern(), fgTransparency(), bgTransparency(), 
shadowFgColour(),
     shadowPattern(), shadowOffsetX(), shadowOffsetY(), qsFillColour(), 
qsShadowColour(),
-    qsFillMatrix() {}
+    qsFillMatrix(), variationColorIndex(), variationStyleIndex() {}
   VSDOptionalFillStyle(const std::optional<Colour> &fgc, const 
std::optional<Colour> &bgc,
                        const std::optional<unsigned char> &p, const 
std::optional<double> &fga,
                        const std::optional<double> &bga, const 
std::optional<Colour> &sfgc,
                        const std::optional<unsigned char> &shp, const 
std::optional<double> &shX,
                        const std::optional<double> &shY, const 
std::optional<long> &qsFc,
-                       const std::optional<long> &qsSc, const 
std::optional<long> &qsFm) :
+                       const std::optional<long> &qsSc, const 
std::optional<long> &qsFm,
+                       const std::optional<unsigned> &vCIn, const 
std::optional<unsigned> &vSIn) :
     fgColour(fgc), bgColour(bgc), pattern(p), fgTransparency(fga), 
bgTransparency(bga),
     shadowFgColour(sfgc), shadowPattern(shp), shadowOffsetX(shX), 
shadowOffsetY(shY),
-    qsFillColour(qsFc), qsShadowColour(qsSc), qsFillMatrix(qsFm) {}
+    qsFillColour(qsFc), qsShadowColour(qsSc), qsFillMatrix(qsFm), 
variationColorIndex(vCIn),
+    variationStyleIndex(vSIn) {}
   VSDOptionalFillStyle(const VSDOptionalFillStyle &style) = default;
   ~VSDOptionalFillStyle() {}
   VSDOptionalFillStyle &operator=(const VSDOptionalFillStyle &style) = default;
@@ -132,6 +134,8 @@ struct VSDOptionalFillStyle
     ASSIGN_OPTIONAL(style.fgColour, fgColour);
     ASSIGN_OPTIONAL(style.bgColour, bgColour);
     ASSIGN_OPTIONAL(style.shadowFgColour, shadowFgColour);
+    ASSIGN_OPTIONAL(style.variationColorIndex, variationColorIndex);
+    ASSIGN_OPTIONAL(style.variationStyleIndex, variationStyleIndex);
   }
 
   std::optional<Colour> fgColour;
@@ -146,6 +150,8 @@ struct VSDOptionalFillStyle
   std::optional<long> qsFillColour;
   std::optional<long> qsShadowColour;
   std::optional<long> qsFillMatrix;
+  std::optional<unsigned> variationColorIndex;
+  std::optional<unsigned> variationStyleIndex;
 };
 
 struct VSDFillStyle
@@ -153,13 +159,15 @@ struct VSDFillStyle
   VSDFillStyle()
     : fgColour(), bgColour(0xff, 0xff, 0xff, 0), pattern(0), fgTransparency(0),
       bgTransparency(0), shadowFgColour(),  shadowPattern(0), shadowOffsetX(0),
-      shadowOffsetY(0), qsFillColour(-1), qsShadowColour(-1), qsFillMatrix(-1) 
{}
+      shadowOffsetY(0), qsFillColour(100), qsShadowColour(100), 
qsFillMatrix(-1),
+      variationColorIndex(0), variationStyleIndex(0) {}
   VSDFillStyle(const Colour &fgc, const Colour &bgc, unsigned char p,
                double fga, double bga, const Colour &sfgc, unsigned char shp,
-               double shX, double shY, long qsFc, long qsSc, long qsFm)
+               double shX, double shY, long qsFc, long qsSc, long qsFm, 
unsigned vCIn, unsigned vSIn)
     : fgColour(fgc), bgColour(bgc), pattern(p), fgTransparency(fga), 
bgTransparency(bga),
       shadowFgColour(sfgc), shadowPattern(shp), shadowOffsetX(shX), 
shadowOffsetY(shY),
-      qsFillColour(qsFc), qsShadowColour(qsSc), qsFillMatrix(qsFm) {}
+      qsFillColour(qsFc), qsShadowColour(qsSc), qsFillMatrix(qsFm), 
variationColorIndex(vCIn),
+      variationStyleIndex(vSIn) {}
   VSDFillStyle(const VSDFillStyle &style) = default;
   ~VSDFillStyle() {}
   VSDFillStyle &operator=(const VSDFillStyle &style) = default;
@@ -175,13 +183,15 @@ struct VSDFillStyle
     ASSIGN_OPTIONAL(style.qsFillColour, qsFillColour);
     ASSIGN_OPTIONAL(style.qsShadowColour, qsShadowColour);
     ASSIGN_OPTIONAL(style.qsFillMatrix, qsFillMatrix);
+    ASSIGN_OPTIONAL(style.variationColorIndex, variationColorIndex);
+    ASSIGN_OPTIONAL(style.variationStyleIndex, variationStyleIndex);
     if (theme)
     {
       // Quick Style Colour 100 is special. It is the default,
       // and it is not saved explicitely in the VSDX file.
-      ASSIGN_OPTIONAL(theme->getThemeColour(style.qsFillColour.value_or(100)), 
fgColour);
-      ASSIGN_OPTIONAL(theme->getThemeColour(style.qsFillColour.value_or(100)), 
bgColour);
-      
ASSIGN_OPTIONAL(theme->getThemeColour(style.qsShadowColour.value_or(100)), 
shadowFgColour);
+      ASSIGN_OPTIONAL(theme->getThemeColour(qsFillColour, 
variationColorIndex), fgColour);
+      ASSIGN_OPTIONAL(theme->getThemeColour(qsFillColour, 
variationColorIndex), bgColour);
+      ASSIGN_OPTIONAL(theme->getThemeColour(qsShadowColour, 
variationColorIndex), shadowFgColour);
       if (!!style.qsFillMatrix && style.qsFillMatrix.value() >= 0)
         ASSIGN_OPTIONAL(theme->getFillStyleColour(style.qsFillMatrix.value()), 
fgColour);
     }
@@ -202,6 +212,8 @@ struct VSDFillStyle
   long qsFillColour;
   long qsShadowColour;
   long qsFillMatrix;
+  unsigned variationColorIndex;
+  unsigned variationStyleIndex;
 };
 
 struct VSDOptionalCharStyle
diff --git a/src/lib/VSDStylesCollector.cpp b/src/lib/VSDStylesCollector.cpp
index ce9c656..cc6ca82 100644
--- a/src/lib/VSDStylesCollector.cpp
+++ b/src/lib/VSDStylesCollector.cpp
@@ -24,6 +24,7 @@ libvisio::VSDStylesCollector::VSDStylesCollector(
   m_groupMembershipsSequence(groupMembershipsSequence),
   m_pageShapeOrder(), m_documentPageShapeOrders(documentPageShapeOrders),
   m_groupShapeOrder(), m_shapeList(), m_currentStyleSheet(0), m_styles(),
+  m_variationColorIndex(), m_variationStyleIndex(),
   m_currentShapeLevel(0)
 {
   m_groupXFormsSequence.clear();
@@ -223,9 +224,12 @@ void 
libvisio::VSDStylesCollector::collectForeignDataType(unsigned level, unsign
 
 void libvisio::VSDStylesCollector::collectPageProps(unsigned /* id */, 
unsigned level, double /* pageWidth */, double /* pageHeight */,
                                                     double /* shadowOffsetX 
*/, double /* shadowOffsetY */, double /* scale */,
-                                                    unsigned char /* 
drawingScaleUnit */)
+                                                    unsigned char /* 
drawingScaleUnit */, const std::optional<unsigned> variationColorIndex,
+                                                    const 
std::optional<unsigned> variationStyleIndex)
 {
   _handleLevelChange(level);
+  m_variationColorIndex = variationColorIndex;
+  m_variationStyleIndex = variationStyleIndex;
 }
 
 void libvisio::VSDStylesCollector::collectPage(unsigned /* id */, unsigned 
level, unsigned /* backgroundPageID */, bool /* isBackgroundPage */, const 
VSDName & /* pageName */)
@@ -234,7 +238,7 @@ void libvisio::VSDStylesCollector::collectPage(unsigned /* 
id */, unsigned level
 }
 
 void libvisio::VSDStylesCollector::collectShape(unsigned id, unsigned level, 
unsigned parent, unsigned /*masterPage*/, unsigned /*masterShape*/,
-                                                unsigned /* lineStyle */, 
unsigned /* fillStyle */, unsigned /* textStyle */)
+                                                unsigned /* lineStyle */, 
unsigned /* fillStyle */, unsigned /* textStyle */, const VSDName & 
/*aShapeType*/)
 {
   _handleLevelChange(level);
   m_currentShapeLevel = level;
diff --git a/src/lib/VSDStylesCollector.h b/src/lib/VSDStylesCollector.h
index 9859209..0acc0bb 100644
--- a/src/lib/VSDStylesCollector.h
+++ b/src/lib/VSDStylesCollector.h
@@ -71,9 +71,10 @@ public:
   void collectTxtXForm(unsigned level, const XForm &txtxform) override;
   void collectShapesOrder(unsigned id, unsigned level, const 
std::vector<unsigned> &shapeIds) override;
   void collectForeignDataType(unsigned level, unsigned foreignType, unsigned 
foreignFormat, double offsetX, double offsetY, double width, double height) 
override;
-  void collectPageProps(unsigned id, unsigned level, double pageWidth, double 
pageHeight, double shadowOffsetX, double shadowOffsetY, double scale, unsigned 
char drawingScaleUnit) override;
+  void collectPageProps(unsigned id, unsigned level, double pageWidth, double 
pageHeight, double shadowOffsetX, double shadowOffsetY, double scale,
+                        unsigned char drawingScaleUnit, const 
std::optional<unsigned> variationColorIndex, const std::optional<unsigned> 
variationStyleIndex) override;
   void collectPage(unsigned id, unsigned level, unsigned backgroundPageID, 
bool isBackgroundPage, const VSDName &pageName) override;
-  void collectShape(unsigned id, unsigned level, unsigned parent, unsigned 
masterPage, unsigned masterShape, unsigned lineStyle, unsigned fillStyle, 
unsigned textStyle) override;
+  void collectShape(unsigned id, unsigned level, unsigned parent, unsigned 
masterPage, unsigned masterShape, unsigned lineStyle, unsigned fillStyle, 
unsigned textStyle, const VSDName &aShapeType) override;
   void collectSplineStart(unsigned id, unsigned level, double x, double y, 
double secondKnot, double firstKnot, double lastKnot, unsigned degree) override;
   void collectSplineKnot(unsigned id, unsigned level, double x, double y, 
double knot) override;
   void collectSplineEnd() override;
@@ -176,7 +177,8 @@ public:
   {
     return m_styles;
   }
-
+  const std::optional<unsigned>& getvariationColorIndex() const { return 
m_variationColorIndex; }
+  const std::optional<unsigned>& getvariationStyleIndex() const { return 
m_variationStyleIndex; }
 
 private:
   VSDStylesCollector(const VSDStylesCollector &);
@@ -204,6 +206,9 @@ private:
   unsigned m_currentStyleSheet;
   VSDStyles m_styles;
 
+  std::optional<unsigned> m_variationColorIndex;
+  std::optional<unsigned> m_variationStyleIndex;
+
   unsigned m_currentShapeLevel;
 };
 
diff --git a/src/lib/VSDXMLParserBase.cpp b/src/lib/VSDXMLParserBase.cpp
index 39290ea..6a0a4ae 100644
--- a/src/lib/VSDXMLParserBase.cpp
+++ b/src/lib/VSDXMLParserBase.cpp
@@ -939,6 +939,8 @@ void libvisio::VSDXMLParserBase::readShape(xmlTextReaderPtr 
reader)
   const shared_ptr<xmlChar> fillStyleString(xmlTextReaderGetAttribute(reader, 
BAD_CAST("FillStyle")), xmlFree);
   const shared_ptr<xmlChar> textStyleString(xmlTextReaderGetAttribute(reader, 
BAD_CAST("TextStyle")), xmlFree);
 
+  shared_ptr<xmlChar> pShapeName(xmlTextReaderGetAttribute(reader, 
BAD_CAST("NameU")), xmlFree);
+
   unsigned id = idString ? (unsigned)xmlStringToLong(idString) : MINUS_ONE;
   unsigned masterPage = masterPageString ? 
(unsigned)xmlStringToLong(masterPageString) : MINUS_ONE;
   unsigned masterShape = masterShapeString ? 
(unsigned)xmlStringToLong(masterShapeString) : MINUS_ONE;
@@ -994,6 +996,17 @@ void 
libvisio::VSDXMLParserBase::readShape(xmlTextReaderPtr reader)
   m_shape.m_masterPage = masterPage;
   m_shape.m_masterShape = masterShape;
   m_shape.m_shapeId = id;
+  if (pShapeName.get())
+  {
+      m_shape.m_aName = VSDName(
+          librevenge::RVNGBinaryData(pShapeName.get(), 
xmlStrlen(pShapeName.get())),
+                     VSD_TEXT_UTF8);
+  }
+  else if (MINUS_ONE != m_shape.m_parent && 
!m_shapeStack.top().m_aName.empty())
+  {
+      m_shape.m_aName = m_shapeStack.top().m_aName;
+  }
+
 }
 
 void libvisio::VSDXMLParserBase::initColours()
@@ -1747,7 +1760,9 @@ void libvisio::VSDXMLParserBase::_flushShape()
   if (!m_isShapeStarted)
     return;
 
-  m_collector->collectShape(m_shape.m_shapeId, m_currentShapeLevel, 
m_shape.m_parent, m_shape.m_masterPage, m_shape.m_masterShape, 
m_shape.m_lineStyleId, m_shape.m_fillStyleId, m_shape.m_textStyleId);
+  m_collector->collectShape(m_shape.m_shapeId, m_currentShapeLevel, 
m_shape.m_parent,
+                            m_shape.m_masterPage, m_shape.m_masterShape, 
m_shape.m_lineStyleId,
+                            m_shape.m_fillStyleId, m_shape.m_textStyleId, 
m_shape.m_aName);
 
   m_collector->collectShapesOrder(0, m_currentShapeLevel+2, 
m_shape.m_shapeList.getShapesOrder());
 
diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index 4f9701e..4d47f6e 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -89,8 +89,10 @@ bool libvisio::VSDXParser::parseMain() try
     return false;
 
   VSDStyles styles = stylesCollector.getStyleSheets();
+  const std::optional<unsigned> varColInd = 
stylesCollector.getvariationColorIndex();
+  const std::optional<unsigned> varStyInd = 
stylesCollector.getvariationStyleIndex();
 
-  VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils);
+  VSDContentCollector contentCollector(m_painter, groupXFormsSequence, 
groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils, 
varColInd, varStyInd);
   m_collector = &contentCollector;
   parseMetaData(m_input, rootRels);
 
@@ -610,6 +612,8 @@ void 
libvisio::VSDXParser::readPageSheetProperties(xmlTextReaderPtr reader)
   double shadowOffsetY = 0.0;
   double pageScale = 1.0;
   double drawingScale = 1.0;
+  std::optional<unsigned> variationColorIndex;
+  std::optional<unsigned> variationStyleIndex;
 
   auto level = (unsigned)getElementDepth(reader);
   int ret = 1;
@@ -650,6 +654,14 @@ void 
libvisio::VSDXParser::readPageSheetProperties(xmlTextReaderPtr reader)
       if (XML_READER_TYPE_ELEMENT == tokenType)
         ret = readDoubleData(drawingScale, reader);
       break;
+    case XML_VARIATIONCOLORINDEX:
+      if (XML_READER_TYPE_ELEMENT == tokenType)
+        ret = readUnsignedData(variationColorIndex, reader);
+      break;
+    case XML_VARIATIONSTYLEINDEX:
+      if (XML_READER_TYPE_ELEMENT == tokenType)
+        ret = readUnsignedData(variationStyleIndex, reader);
+      break;
     case XML_LAYER:
       if (XML_READER_TYPE_ELEMENT == tokenType)
         readLayer(reader);
@@ -668,7 +680,7 @@ void 
libvisio::VSDXParser::readPageSheetProperties(xmlTextReaderPtr reader)
   else if (m_isPageStarted)
   {
     double scale = drawingScale > 0 || drawingScale < 0 ? 
pageScale/drawingScale : 1.0;
-    m_collector->collectPageProps(0, level, pageWidth, pageHeight, 
shadowOffsetX, shadowOffsetY, scale, 0);
+    m_collector->collectPageProps(0, level, pageWidth, pageHeight, 
shadowOffsetX, shadowOffsetY, scale, 0, variationColorIndex, 
variationStyleIndex);
   }
 }
 
@@ -934,7 +946,7 @@ void 
libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader)
                                                       qsLineColour, 
qsLineMatrix));
     m_shape.m_fillStyle.override(VSDOptionalFillStyle(fillColourFG, 
fillColourBG, fillPattern, fillFGTransparency, fillBGTransparency,
                                                       shadowColourFG, 
shadowPattern, shadowOffsetX, shadowOffsetY,
-                                                      qsFillColour, 
qsShadowColour, qsFillMatrix));
+                                                      qsFillColour, 
qsShadowColour, qsFillMatrix, 0, 0));
     m_shape.m_textBlockStyle.override(VSDOptionalTextBlockStyle(leftMargin, 
rightMargin, topMargin, bottomMargin, verticalAlign,
                                                                 
isTextBkgndFilled, textBkgndColour, defaultTabStop, textDirection));
   }

Reply via email to