summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2011-06-27 11:30:27 +0200
committerFridrich Štrba <fridrich.strba@bluewin.ch>2011-06-27 11:30:27 +0200
commitb22faf2b1824c60496ee672d0a7ea48f053944a1 (patch)
treec902231072b5926eeefa66d62bb056b96d4da88a /src
parentf196f1d2a6266967b26d454cdd706b57ab783e6c (diff)
Process data in the Collector classes
Diffstat (limited to 'src')
-rw-r--r--src/lib/VSD11Parser.cpp35
-rw-r--r--src/lib/VSD11Parser.h2
-rw-r--r--src/lib/VSD6Parser.cpp5
-rw-r--r--src/lib/VSD6Parser.h5
-rw-r--r--src/lib/VSDXCollector.h32
-rw-r--r--src/lib/VSDXContentCollector.cpp444
-rw-r--r--src/lib/VSDXContentCollector.h31
-rw-r--r--src/lib/VSDXParser.cpp360
-rw-r--r--src/lib/VSDXParser.h36
-rw-r--r--src/lib/VSDXStylesCollector.h31
10 files changed, 652 insertions, 329 deletions
diff --git a/src/lib/VSD11Parser.cpp b/src/lib/VSD11Parser.cpp
index 7bf5a9c..a734700 100644
--- a/src/lib/VSD11Parser.cpp
+++ b/src/lib/VSD11Parser.cpp
@@ -31,7 +31,7 @@
const libvisio::VSD11Parser::StreamHandler libvisio::VSD11Parser::streamHandlers[] = {
{VSD_PAGE, "Page", &libvisio::VSD11Parser::handlePage},
- {VSD_COLORS, "Colors", &libvisio::VSD11Parser::handleColours},
+ {VSD_COLORS, "Colors", &libvisio::VSD11Parser::readColours},
{VSD_PAGES, "Pages", &libvisio::VSD11Parser::handlePages},
{0, 0, 0}
};
@@ -167,9 +167,7 @@ bool libvisio::VSD11Parser::parseDocument(WPXInputStream *input)
}
}
- // End page if one is started
- if (m_isPageStarted)
- m_painter->endGraphics();
+ m_collector->endPage();
return true;
}
@@ -275,8 +273,12 @@ void libvisio::VSD11Parser::handlePages(WPXInputStream *input)
void libvisio::VSD11Parser::handlePage(WPXInputStream *input)
{
long endPos = 0;
-
+
+#if 1
+ m_collector->pageChunkBegin(m_header.id, m_header.level);
+#else
m_groupXForms.clear();
+#endif
while (!input->atEOS())
{
@@ -296,10 +298,7 @@ void libvisio::VSD11Parser::handlePage(WPXInputStream *input)
input->seek(m_header.dataLength + m_header.trailer, WPX_SEEK_CUR);
ChunkMethod chunkHandler = chunkHandlers[index].handler;
if (chunkHandler)
- {
- m_currentShapeId = m_header.id;
(this->*chunkHandler)(input);
- }
continue;
}
@@ -312,23 +311,3 @@ void libvisio::VSD11Parser::handlePage(WPXInputStream *input)
input->seek(endPos, WPX_SEEK_SET);
}
}
-
-void libvisio::VSD11Parser::handleColours(WPXInputStream *input)
-{
- input->seek(6, WPX_SEEK_SET);
- unsigned int numColours = readU8(input);
- Colour tmpColour;
-
- input->seek(1, WPX_SEEK_CUR);
-
- for (unsigned int i = 0; i < numColours; i++)
- {
- tmpColour.r = readU8(input);
- tmpColour.g = readU8(input);
- tmpColour.b = readU8(input);
- tmpColour.a = readU8(input);
-
- m_colours.push_back(tmpColour);
- }
-}
-
diff --git a/src/lib/VSD11Parser.h b/src/lib/VSD11Parser.h
index 86af672..a8153dc 100644
--- a/src/lib/VSD11Parser.h
+++ b/src/lib/VSD11Parser.h
@@ -54,7 +54,7 @@ private:
// Stream handlers
void handlePages(WPXInputStream *input);
void handlePage(WPXInputStream *input);
- void handleColours(WPXInputStream *input);
+ void readColours(WPXInputStream *input) { VSDXParser::readColours(input); }
bool getChunkHeader(WPXInputStream *input);
};
diff --git a/src/lib/VSD6Parser.cpp b/src/lib/VSD6Parser.cpp
index 84f4675..257325e 100644
--- a/src/lib/VSD6Parser.cpp
+++ b/src/lib/VSD6Parser.cpp
@@ -33,8 +33,9 @@ const libvisio::VSD6Parser::StreamHandler libvisio::VSD6Parser::handlers[] = {
{0, 0, 0}
};
-libvisio::VSD6Parser::VSD6Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter)
- : VSDXParser(input, painter)
+libvisio::VSD6Parser::VSD6Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter) :
+ VSDXParser(input, painter), m_isPageStarted(false), m_pageWidth(0.0), m_pageHeight(0.0),
+ m_scale(1.0)
{}
libvisio::VSD6Parser::~VSD6Parser()
diff --git a/src/lib/VSD6Parser.h b/src/lib/VSD6Parser.h
index 1aa091a..4000acf 100644
--- a/src/lib/VSD6Parser.h
+++ b/src/lib/VSD6Parser.h
@@ -46,6 +46,11 @@ private:
void handlePage(WPXInputStream *input);
bool getChunkHeader(WPXInputStream *input) { return false; }
+
+ bool m_isPageStarted;
+ double m_pageWidth;
+ double m_pageHeight;
+ double m_scale;
};
} // namespace libvisio
diff --git a/src/lib/VSDXCollector.h b/src/lib/VSDXCollector.h
index b5e538b..1165571 100644
--- a/src/lib/VSDXCollector.h
+++ b/src/lib/VSDXCollector.h
@@ -21,6 +21,7 @@
#ifndef VSDXCOLLECTOR_H
#define VSDXCOLLECTOR_H
+#include <vector>
#include "VSDXParser.h"
namespace libvisio {
@@ -32,22 +33,31 @@ public:
virtual ~VSDXCollector() {}
virtual void collectEllipticalArcTo(unsigned id, unsigned level, double x3, double y3, double x2, double y2, double angle, double ecc) = 0;
- virtual void collectForeignData(unsigned id, unsigned level) = 0;
- virtual void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double bb, double cc, double dd) = 0;
+ virtual void collectForeignData(unsigned id, unsigned level, const WPXBinaryData &binaryData) = 0;
+ virtual void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double dd) = 0;
virtual void collectLine(unsigned id, unsigned level, double strokeWidth, Colour c, unsigned linePattern) = 0;
virtual void collectFillAndShadow(unsigned id, unsigned level, unsigned colourIndexFG, unsigned colourIndexBG, unsigned fillPattern) = 0;
- virtual void collectGeomList(unsigned id, unsigned level) = 0;
- virtual void collectGeometry(unsigned id, unsigned level) = 0;
- virtual void collectMoveTo(unsigned id, unsigned level) = 0;
- virtual void collectLineTo(unsigned id, unsigned level) = 0;
- virtual void collectArcTo(unsigned id, unsigned level) = 0;
- virtual void collectXFormData(unsigned id, unsigned level) = 0;
- virtual void collectShapeID(unsigned id, unsigned level) = 0;
- virtual void collectForeignDataType(unsigned id, unsigned level) = 0;
- virtual void collectPageProps(unsigned id, unsigned level) = 0;
+ virtual void collectGeomList(unsigned id, unsigned level, const std::vector<unsigned> &geometryOrder) = 0;
+ virtual void collectGeometry(unsigned id, unsigned level, unsigned geomFlags) = 0;
+ virtual void collectMoveTo(unsigned id, unsigned level, double x, double y) = 0;
+ virtual void collectLineTo(unsigned id, unsigned level, double x, double y) = 0;
+ virtual void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow) = 0;
+ virtual void collectXFormData(unsigned id, unsigned level, const XForm &xform) = 0;
+ virtual void collectShapeID(unsigned id, unsigned level, unsigned shapeId) = 0;
+ virtual void collectForeignDataType(unsigned id, unsigned level, unsigned foreignType, unsigned foreignFormat) = 0;
+ virtual void collectPageProps(unsigned id, unsigned level, double pageWidth, double pageHeight) = 0;
virtual void collectUnhandledChunk(unsigned id, unsigned level) = 0;
+ virtual void collectColours(const std::vector<Colour> &colours) = 0;
+
+ // Temporary hack
+ virtual void shapeChunkBegin(unsigned id, unsigned level) = 0;
+ virtual void shapeChunkEnd(unsigned id, unsigned level) = 0;
+ virtual void pageChunkBegin(unsigned id, unsigned level) = 0;
+ virtual void startPage() = 0;
+ virtual void endPage() = 0;
+
private:
diff --git a/src/lib/VSDXContentCollector.cpp b/src/lib/VSDXContentCollector.cpp
index da6a509..511bc04 100644
--- a/src/lib/VSDXContentCollector.cpp
+++ b/src/lib/VSDXContentCollector.cpp
@@ -22,7 +22,12 @@
#include "VSDXParser.h"
libvisio::VSDXContentCollector::VSDXContentCollector(libwpg::WPGPaintInterface *painter) :
- m_painter(painter)
+ m_painter(painter), m_isPageStarted(false), m_pageWidth(0.0), m_pageHeight(0.0),
+ m_scale(1.0), m_x(0.0), m_y(0.0), m_xform(), m_currentGeometryOrder(), m_currentGeometry(),
+ m_currentComplexGeometry(), m_groupXForms(), m_currentForeignData(), m_currentForeignProps(),
+ m_currentShapeId(0), m_foreignType(0), m_foreignFormat(0), m_styleProps(),
+ m_lineColour("black"), m_fillType("none"), m_linePattern(1), m_fillPattern(1),
+ m_gradientProps(), m_noLine(false), m_noFill(false), m_noShow(false)
{
}
@@ -62,6 +67,148 @@ void libvisio::VSDXContentCollector::flipPoint(double &x, double &y, const XForm
y = tmpY + xform.y;
}
+void libvisio::VSDXContentCollector::_flushCurrentPath()
+{
+ double startX = 0; double startY = 0;
+ double x = 0; double y = 0;
+ bool firstPoint = true;
+
+ WPXPropertyListVector path;
+ std::map<unsigned int, WPXPropertyList>::iterator iter;
+ std::map<unsigned int, WPXPropertyListVector>::iterator itervec;
+ if (m_currentGeometryOrder.size())
+ {
+ for (unsigned i = 0; i < m_currentGeometryOrder.size(); i++)
+ {
+ iter = m_currentGeometry.find(m_currentGeometryOrder[i]);
+ if (iter != m_currentGeometry.end())
+ {
+ if (firstPoint)
+ {
+ x = (iter->second)["svg:x"]->getDouble();
+ y = (iter->second)["svg:y"]->getDouble();
+ startX = x;
+ startY = y;
+ firstPoint = false;
+ }
+ else if ((iter->second)["libwpg:path-action"]->getStr() == "M")
+ {
+ if (startX == x && startY == y)
+ {
+ WPXPropertyList closedPath;
+ closedPath.insert("libwpg:path-action", "Z");
+ path.append(closedPath);
+ }
+ if (path.count() && !m_noShow)
+ {
+ m_painter->setStyle(m_styleProps, m_gradientProps);
+ m_painter->drawPath(path);
+ }
+
+ path = WPXPropertyListVector();
+ x = (iter->second)["svg:x"]->getDouble();
+ y = (iter->second)["svg:y"]->getDouble();
+ startX = x;
+ startY = y;
+ }
+ else
+ {
+ x = (iter->second)["svg:x"]->getDouble();
+ y = (iter->second)["svg:y"]->getDouble();
+ }
+ path.append(iter->second);
+ }
+ else
+ {
+ itervec = m_currentComplexGeometry.find(m_currentGeometryOrder[i]);
+ if (itervec != m_currentComplexGeometry.end())
+ {
+ WPXPropertyListVector::Iter iter2(itervec->second);
+ for (; iter2.next();)
+ {
+ if (firstPoint)
+ {
+ x = (iter2())["svg:x"]->getDouble();
+ y = (iter2())["svg:y"]->getDouble();
+ startX = x;
+ startY = y;
+ firstPoint = false;
+ }
+ else if ((iter2())["libwpg:path-action"]->getStr() == "M")
+ {
+ if (startX == x && startY == y)
+ {
+ WPXPropertyList closedPath;
+ closedPath.insert("libwpg:path-action", "Z");
+ path.append(closedPath);
+ }
+ if (path.count() && !m_noShow)
+ {
+ m_painter->setStyle(m_styleProps, m_gradientProps);
+ m_painter->drawPath(path);
+ }
+
+ path = WPXPropertyListVector();
+ x = (iter2())["svg:x"]->getDouble();
+ y = (iter2())["svg:y"]->getDouble();
+ startX = x;
+ startY = y;
+ }
+ else
+ {
+ x = (iter2())["svg:x"]->getDouble();
+ y = (iter2())["svg:y"]->getDouble();
+ }
+ path.append(iter2());
+ }
+ }
+ }
+ }
+
+ if (startX == x && startY == y && path.count())
+ {
+ WPXPropertyList closedPath;
+ closedPath.insert("libwpg:path-action", "Z");
+ path.append(closedPath);
+ }
+ if (path.count() && !m_noShow)
+ {
+ m_painter->setStyle(m_styleProps, m_gradientProps);
+ m_painter->drawPath(path);
+ }
+ }
+ else
+ {
+ for (iter=m_currentGeometry.begin(); iter != m_currentGeometry.end(); iter++)
+ path.append(iter->second);
+ for (itervec=m_currentComplexGeometry.begin(); itervec != m_currentComplexGeometry.end(); itervec++)
+ {
+ WPXPropertyListVector::Iter iter2(itervec->second);
+ for (; iter2.next();)
+ path.append(iter2());
+ }
+ if (path.count() && !m_noShow)
+ {
+ m_painter->setStyle(m_styleProps, m_gradientProps);
+ m_painter->drawPath(path);
+ }
+ }
+ m_currentGeometry.clear();
+ m_currentComplexGeometry.clear();
+ m_currentGeometryOrder.clear();
+}
+
+void libvisio::VSDXContentCollector::_flushCurrentForeignData()
+{
+ if (m_currentForeignData.size() && m_currentForeignProps["libwpg:mime-type"] && !m_noShow)
+ {
+ m_painter->setStyle(m_styleProps, m_gradientProps);
+ m_painter->drawGraphicObject(m_currentForeignProps, m_currentForeignData);
+ }
+ m_currentForeignData.clear();
+ m_currentForeignProps.clear();
+}
+
void libvisio::VSDXContentCollector::collectEllipticalArcTo(unsigned id, unsigned level, double x3, double y3, double x2, double y2, double angle, double ecc)
@@ -114,7 +261,7 @@ void libvisio::VSDXContentCollector::collectEllipticalArcTo(unsigned id, unsigne
m_currentGeometry[id] = arc;
}
-void libvisio::VSDXContentCollector::collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double bb, double cc, double dd)
+void libvisio::VSDXContentCollector::collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double dd)
{
WPXPropertyList ellipse;
ellipse.insert("svg:rx", m_scale*(aa-cx));
@@ -248,3 +395,296 @@ void libvisio::VSDXContentCollector::collectFillAndShadow(unsigned id, unsigned
m_styleProps.insert("draw:fill-color", getColourString(m_colours[colourIndexBG]));
}
}
+
+
+void libvisio::VSDXContentCollector::collectForeignData(unsigned id, unsigned level, const WPXBinaryData &binaryData)
+{
+ if (m_foreignType == 1 || m_foreignType == 4) // Image
+ {
+ // If bmp data found, reconstruct header
+ if (m_foreignType == 1 && m_foreignFormat == 0)
+ {
+ m_currentForeignData.append(0x42);
+ m_currentForeignData.append(0x4d);
+
+ m_currentForeignData.append((unsigned char)((binaryData.size() + 14) & 0x000000ff));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0x0000ff00) >> 8));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0x00ff0000) >> 16));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0xff000000) >> 24));
+
+ m_currentForeignData.append(0x00);
+ m_currentForeignData.append(0x00);
+ m_currentForeignData.append(0x00);
+ m_currentForeignData.append(0x00);
+
+ m_currentForeignData.append(0x36);
+ m_currentForeignData.append(0x00);
+ m_currentForeignData.append(0x00);
+ m_currentForeignData.append(0x00);
+ }
+ m_currentForeignData.append(binaryData);
+
+#if DUMP_BITMAP
+ if (m_foreignType == 1 || m_foreignType == 4)
+ {
+ ::WPXString filename;
+ switch(m_foreignFormat)
+ {
+ case 0:
+ filename.sprintf("binarydump%i.bmp", bitmapId++); break;
+ case 1:
+ filename.sprintf("binarydump%i.jpeg", bitmapId++); break;
+ case 2:
+ filename.sprintf("binarydump%i.gif", bitmapId++); break;
+ case 3:
+ filename.sprintf("binarydump%i.tiff", bitmapId++); break;
+ case 4:
+ filename.sprintf("binarydump%i.png", bitmapId++); break;
+ default:
+ filename.sprintf("binarydump%i.bin", bitmapId++); break;
+ }
+ FILE *f = fopen(filename.cstr(), "wb");
+ if (f)
+ {
+ const unsigned char *tmpBuffer = m_currentForeignData.getDataBuffer();
+ for (unsigned long k = 0; k < m_currentForeignData.size(); k++)
+ fprintf(f, "%c",tmpBuffer[k]);
+ fclose(f);
+ }
+ }
+#endif
+
+ m_currentForeignProps.insert("svg:width", m_scale*m_xform.width);
+ m_currentForeignProps.insert("svg:height", m_scale*m_xform.height);
+ m_currentForeignProps.insert("svg:x", m_scale*(m_xform.pinX - m_xform.pinLocX));
+ // Y axis starts at the bottom not top
+ m_currentForeignProps.insert("svg:y", m_scale*(m_pageHeight -
+ m_xform.pinY + m_xform.pinLocY - m_xform.height));
+
+ if (m_foreignType == 1)
+ {
+ switch(m_foreignFormat)
+ {
+ case 0:
+ m_currentForeignProps.insert("libwpg:mime-type", "image/bmp"); break;
+ case 1:
+ m_currentForeignProps.insert("libwpg:mime-type", "image/jpeg"); break;
+ case 2:
+ m_currentForeignProps.insert("libwpg:mime-type", "image/gif"); break;
+ case 3:
+ m_currentForeignProps.insert("libwpg:mime-type", "image/tiff"); break;
+ case 4:
+ m_currentForeignProps.insert("libwpg:mime-type", "image/png"); break;
+ }
+ }
+ else if (m_foreignType == 4)
+ {
+ const unsigned char *tmpBinData = m_currentForeignData.getDataBuffer();
+ // Check for EMF signature
+ if (tmpBinData[0x28] == 0x20 && tmpBinData[0x29] == 0x45 && tmpBinData[0x2A] == 0x4D && tmpBinData[0x2B] == 0x46)
+ {
+ m_currentForeignProps.insert("libwpg:mime-type", "image/emf");
+ }
+ else
+ {
+ m_currentForeignProps.insert("libwpg:mime-type", "image/wmf");
+ }
+ }
+ }
+}
+
+void libvisio::VSDXContentCollector::collectGeomList(unsigned id, unsigned level, const std::vector<unsigned> &geometryOrder)
+{
+ _flushCurrentPath();
+ m_currentGeometryOrder.clear();
+ for (unsigned j = 0; j< geometryOrder.size(); j++)
+ m_currentGeometryOrder.push_back(geometryOrder[j]);
+ m_noShow = false;
+}
+
+void libvisio::VSDXContentCollector::collectGeometry(unsigned id, unsigned level, unsigned geomFlags)
+{
+ m_x = 0.0; m_x = 0.0;
+ m_noFill = ((geomFlags & 1) == 1);
+ m_noLine = ((geomFlags & 2) == 2);
+ m_noShow = ((geomFlags & 4) == 4);
+ if (m_noLine || m_linePattern == 0)
+ m_styleProps.insert("svg:stroke-color", "none");
+ else
+ m_styleProps.insert("svg:stroke-color", m_lineColour);
+ if (m_noFill || m_fillPattern == 0)
+ m_styleProps.insert("svg:fill", "none");
+ else
+ m_styleProps.insert("svg:fill", m_fillType);
+ VSD_DEBUG_MSG(("Flag: %d NoFill: %d NoLine: %d NoShow: %d\n", geomFlags, m_noFill, m_noLine, m_noShow));
+}
+
+void libvisio::VSDXContentCollector::collectMoveTo(unsigned id, unsigned level, double x, double y)
+{
+ WPXPropertyList end;
+ m_x = x + m_xform.x;
+ m_y = m_xform.height - y + m_xform.y;
+ rotatePoint(m_x, m_y, m_xform);
+ flipPoint(m_x, m_y, m_xform);
+ end.insert("svg:x", m_scale*m_x);
+ end.insert("svg:y", m_scale*m_y);
+ end.insert("libwpg:path-action", "M");
+ m_currentGeometry[id] = end;
+}
+
+void libvisio::VSDXContentCollector::collectLineTo(unsigned id, unsigned level, double x, double y)
+{
+ WPXPropertyList end;
+ m_x = x + m_xform.x;
+ m_y = m_xform.height - y + m_xform.y;
+ rotatePoint(m_x, m_y, m_xform);
+ flipPoint(m_x, m_y, m_xform);
+ end.insert("svg:x", m_scale*m_x);
+ end.insert("svg:y", m_scale*m_y);
+ end.insert("libwpg:path-action", "L");
+ m_currentGeometry[id] = end;
+}
+
+void libvisio::VSDXContentCollector::collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow)
+{
+ x2 += m_xform.x;
+ y2 = m_xform.height - y2 + m_xform.y;
+ rotatePoint(x2, y2, m_xform);
+ flipPoint(x2, y2, m_xform);
+
+ if (bow == 0)
+ {
+ m_x = x2; m_y = y2;
+ WPXPropertyList end;
+ end.insert("svg:x", m_scale*m_x);
+ end.insert("svg:y", m_scale*m_y);
+ end.insert("libwpg:path-action", "L");
+ m_currentGeometry[id] = end;
+ }
+ else
+ {
+ WPXPropertyList arc;
+ double chord = sqrt(pow((y2 - m_y),2) + pow((x2 - m_x),2));
+ double radius = (4 * bow * bow + chord * chord) / (8 * fabs(bow));
+ VSD_DEBUG_MSG(("ArcTo with bow %f radius %f and chord %f\n", bow, radius, chord));
+ int largeArc = fabs(bow) > radius ? 1 : 0;
+ int sweep = bow < 0 ? 1 : 0;
+ m_x = x2; m_y = y2;
+ arc.insert("svg:rx", m_scale*radius);
+ arc.insert("svg:ry", m_scale*radius);
+ arc.insert("libwpg:rotate", m_xform.angle * (180/M_PI));
+ arc.insert("libwpg:large-arc", largeArc);
+ arc.insert("libwpg:sweep", sweep);
+ arc.insert("svg:x", m_scale*m_x);
+ arc.insert("svg:y", m_scale*m_y);
+ arc.insert("libwpg:path-action", "A");
+ m_currentGeometry[id] = arc;
+ }
+}
+
+void libvisio::VSDXContentCollector::collectXFormData(unsigned id, unsigned level, const XForm &xform)
+{
+ m_xform = xform;
+
+ std::map<unsigned int, XForm>::iterator iter = m_groupXForms.find(m_currentShapeId);
+ if (iter != m_groupXForms.end()) {
+ m_xform.pinX += iter->second.pinX;
+ m_xform.pinY += iter->second.pinY;
+ m_xform.pinLocX += iter->second.pinLocX;
+ m_xform.pinLocY += iter->second.pinLocY;
+ }
+ m_xform.x = m_xform.pinX - m_xform.pinLocX;
+ m_xform.y = m_pageHeight - m_xform.pinY + m_xform.pinLocY - m_xform.height;
+}
+
+void libvisio::VSDXContentCollector::collectShapeID(unsigned id, unsigned level, unsigned shapeId)
+{
+ m_groupXForms[shapeId] = m_xform;
+}
+
+void libvisio::VSDXContentCollector::collectForeignDataType(unsigned id, unsigned level, unsigned foreignType, unsigned foreignFormat)
+{
+ m_foreignType = foreignType;
+ m_foreignFormat = foreignFormat;
+}
+
+void libvisio::VSDXContentCollector::collectPageProps(unsigned id, unsigned level, double pageWidth, double pageHeight)
+{
+ m_pageWidth = pageWidth;
+ m_pageHeight = pageHeight;
+ WPXPropertyList pageProps;
+ pageProps.insert("svg:width", m_scale*m_pageWidth);
+ pageProps.insert("svg:height", m_scale*m_pageHeight);
+
+ if (m_isPageStarted)
+ m_painter->endGraphics();
+ m_painter->startGraphics(pageProps);
+ m_isPageStarted = true;
+}
+
+void libvisio::VSDXContentCollector::collectColours(const std::vector<Colour> &colours)
+{
+ m_colours.clear();
+ m_colours.reserve(colours.size());
+ for (unsigned i = 0; i < colours.size(); i++)
+ m_colours.push_back(colours[i]);
+}
+
+
+// TEMPORARY HACKS
+
+void libvisio::VSDXContentCollector::shapeChunkBegin(unsigned id, unsigned level)
+{
+ _flushCurrentPath();
+ _flushCurrentForeignData();
+
+ m_gradientProps = WPXPropertyListVector();
+ m_foreignType = 0; // Tracks current foreign data type
+ m_foreignFormat = 0; // Tracks foreign data format
+
+ m_x = 0; m_y = 0;
+ m_xform = XForm();
+
+ // Geometry flags
+ m_noLine = false;
+ m_noFill = false;
+ m_noShow = false;
+
+ // Save line colour and pattern, fill type and pattern
+ m_lineColour = "black";
+ m_fillType = "none";
+ m_linePattern = 1; // same as "solid"
+ m_fillPattern = 1; // same as "solid"
+
+ // Reset style
+ m_styleProps.clear();
+ m_styleProps.insert("svg:stroke-width", m_scale*0.0138889);
+ m_styleProps.insert("svg:stroke-color", m_lineColour);
+ m_styleProps.insert("draw:fill", m_fillType);
+ m_styleProps.insert("svg:stroke-dasharray", "solid");
+
+ m_currentShapeId = id;
+}
+
+void libvisio::VSDXContentCollector::shapeChunkEnd(unsigned id, unsigned level)
+{
+ _flushCurrentPath();
+ _flushCurrentForeignData();
+ m_x = 0; m_y = 0;
+}
+
+void libvisio::VSDXContentCollector::startPage()
+{
+}
+
+void libvisio::VSDXContentCollector::endPage()
+{
+ // End page if one is started
+ if (m_isPageStarted)
+ m_painter->endGraphics();
+}
+
+void libvisio::VSDXContentCollector::pageChunkBegin(unsigned id, unsigned level)
+{
+ m_groupXForms.clear();
+}
diff --git a/src/lib/VSDXContentCollector.h b/src/lib/VSDXContentCollector.h
index 406c463..39fc903 100644
--- a/src/lib/VSDXContentCollector.h
+++ b/src/lib/VSDXContentCollector.h
@@ -40,22 +40,31 @@ public:
virtual ~VSDXContentCollector() {};
void collectEllipticalArcTo(unsigned id, unsigned level, double x3, double y3, double x2, double y2, double angle, double ecc);
- void collectForeignData(unsigned id, unsigned level) {}
- void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double bb, double cc, double dd);
+ void collectForeignData(unsigned id, unsigned level, const WPXBinaryData &binaryData);
+ void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double dd);
void collectLine(unsigned id, unsigned level, double strokeWidth, Colour c, unsigned linePattern);
void collectFillAndShadow(unsigned id, unsigned level, unsigned colourIndexFG, unsigned colourIndexBG, unsigned fillPattern);
- void collectGeomList(unsigned id, unsigned level) {}
- void collectGeometry(unsigned id, unsigned level) {}
- void collectMoveTo(unsigned id, unsigned level) {}
- void collectLineTo(unsigned id, unsigned level) {}
- void collectArcTo(unsigned id, unsigned level) {}
- void collectXFormData(unsigned id, unsigned level) {}
- void collectShapeID(unsigned id, unsigned level) {}
- void collectForeignDataType(unsigned id, unsigned level) {}
- void collectPageProps(unsigned id, unsigned level) {}
+ void collectGeomList(unsigned id, unsigned level, const std::vector<unsigned> &geometryOrder);
+ void collectGeometry(unsigned id, unsigned level, unsigned geomFlags);
+ void collectMoveTo(unsigned id, unsigned level, double x, double y);
+ void collectLineTo(unsigned id, unsigned level, double x, double y);
+ void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow);
+ void collectXFormData(unsigned id, unsigned level, const XForm &xform);
+ void collectShapeID(unsigned id, unsigned level, unsigned shapeId);
+ void collectForeignDataType(unsigned id, unsigned level, unsigned foreignType, unsigned foreignFormat);
+ void collectPageProps(unsigned id, unsigned level, double pageWidth, double pageHeight);
void collectUnhandledChunk(unsigned id, unsigned level) {}
+ void collectColours(const std::vector<Colour> &colours);
+
+ // Temporary hack
+ void shapeChunkBegin(unsigned id, unsigned level);
+ void shapeChunkEnd(unsigned id, unsigned level);
+ void pageChunkBegin(unsigned id, unsigned level);
+ void startPage();
+ void endPage();
+
private:
VSDXContentCollector(const VSDXContentCollector&);
diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index fdca3ba..13d99f5 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -41,199 +41,13 @@ static unsigned bitmapId = 0;
#endif
libvisio::VSDXParser::VSDXParser(WPXInputStream *input, libwpg::WPGPaintInterface *painter)
- : m_input(input), m_painter(painter), m_isPageStarted(false), m_pageWidth(0.0),
- m_pageHeight(0.0), m_scale(1.0), m_x(0.0), m_y(0.0), m_xform(), m_header(),
- m_currentGeometryOrder(), m_currentGeometry(), m_currentComplexGeometry(),
- m_groupXForms(), m_currentForeignData(), m_currentForeignProps(), m_currentShapeId(0),
- m_foreignType(0), m_foreignFormat(0), m_styleProps(), m_lineColour("black"),
- m_fillType("none"), m_linePattern(1), m_fillPattern(1), m_gradientProps(), m_noLine(false),
- m_noFill(false), m_noShow(false), m_collector(0)
+ : m_input(input), m_painter(painter), m_header(), m_collector(0)
{}
libvisio::VSDXParser::~VSDXParser()
{}
-const ::WPXString libvisio::VSDXParser::getColourString(const struct Colour &c) const
-{
- ::WPXString sColour;
- sColour.sprintf("#%.2x%.2x%.2x", c.r, c.g, c.b);
- return sColour;
-}
-
-void libvisio::VSDXParser::rotatePoint(double &x, double &y, const XForm &xform)
-{
- if (xform.angle == 0.0) return;
-
- // Calculate co-ordinates using pin position as origin
- double tmpX = x - xform.pinX;
- double tmpY = (m_pageHeight - y) - xform.pinY; // Start from bottom left
-
- // Rotate around pin and move back to bottom left as origin
- x = (tmpX * cos(xform.angle)) - (tmpY * sin(xform.angle)) + xform.pinX;
- y = (tmpX * sin(xform.angle)) + (tmpY * cos(xform.angle)) + xform.pinY;
- y = m_pageHeight - y; // Flip Y for screen co-ordinate
-}
-
-void libvisio::VSDXParser::flipPoint(double &x, double &y, const XForm &xform)
-{
- if (!xform.flipX && !xform.flipY) return;
-
- double tmpX = x - xform.x;
- double tmpY = y - xform.y;
-
- if (xform.flipX)
- tmpX = xform.width - tmpX;
- if (xform.flipY)
- tmpY = xform.height - tmpY;
- x = tmpX + xform.x;
- y = tmpY + xform.y;
-}
-
-void libvisio::VSDXParser::_flushCurrentPath()
-{
- double startX = 0; double startY = 0;
- double x = 0; double y = 0;
- bool firstPoint = true;
-
- WPXPropertyListVector path;
- std::map<unsigned int, WPXPropertyList>::iterator iter;
- std::map<unsigned int, WPXPropertyListVector>::iterator itervec;
- if (m_currentGeometryOrder.size())
- {
- for (unsigned i = 0; i < m_currentGeometryOrder.size(); i++)
- {
- iter = m_currentGeometry.find(m_currentGeometryOrder[i]);
- if (iter != m_currentGeometry.end())
- {
- if (firstPoint)
- {
- x = (iter->second)["svg:x"]->getDouble();
- y = (iter->second)["svg:y"]->getDouble();
- startX = x;
- startY = y;
- firstPoint = false;
- }
- else if ((iter->second)["libwpg:path-action"]->getStr() == "M")
- {
- if (startX == x && startY == y)
- {
- WPXPropertyList closedPath;
- closedPath.insert("libwpg:path-action", "Z");
- path.append(closedPath);
- }
- if (path.count() && !m_noShow)
- {
- m_painter->setStyle(m_styleProps, m_gradientProps);
- m_painter->drawPath(path);
- }
-
- path = WPXPropertyListVector();
- x = (iter->second)["svg:x"]->getDouble();
- y = (iter->second)["svg:y"]->getDouble();
- startX = x;
- startY = y;
- }
- else
- {
- x = (iter->second)["svg:x"]->getDouble();
- y = (iter->second)["svg:y"]->getDouble();
- }
- path.append(iter->second);
- }
- else
- {
- itervec = m_currentComplexGeometry.find(m_currentGeometryOrder[i]);
- if (itervec != m_currentComplexGeometry.end())
- {
- WPXPropertyListVector::Iter iter2(itervec->second);
- for (; iter2.next();)
- {
- if (firstPoint)
- {
- x = (iter2())["svg:x"]->getDouble();
- y = (iter2())["svg:y"]->getDouble();
- startX = x;
- startY = y;
- firstPoint = false;
- }
- else if ((iter2())["libwpg:path-action"]->getStr() == "M")
- {
- if (startX == x && startY == y)
- {
- WPXPropertyList closedPath;
- closedPath.insert("libwpg:path-action", "Z");
- path.append(closedPath);
- }
- if (path.count() && !m_noShow)
- {
- m_painter->setStyle(m_styleProps, m_gradientProps);
- m_painter->drawPath(path);
- }
-
- path = WPXPropertyListVector();
- x = (iter2())["svg:x"]->getDouble();
- y = (iter2())["svg:y"]->getDouble();
- startX = x;
- startY = y;
- }
- else
- {
- x = (iter2())["svg:x"]->getDouble();
- y = (iter2())["svg:y"]->getDouble();
- }
- path.append(iter2());
- }
- }
- }
- }
-
- if (startX == x && startY == y && path.count())
- {
- WPXPropertyList closedPath;
- closedPath.insert("libwpg:path-action", "Z");
- path.append(closedPath);
- }
- if (path.count() && !m_noShow)
- {
- m_painter->setStyle(m_styleProps, m_gradientProps);
- m_painter->drawPath(path);
- }
- }
- else
- {
- for (iter=m_currentGeometry.begin(); iter != m_currentGeometry.end(); iter++)
- path.append(iter->second);
- for (itervec=m_currentComplexGeometry.begin(); itervec != m_currentComplexGeometry.end(); itervec++)
- {
- WPXPropertyListVector::Iter iter2(itervec->second);
- for (; iter2.next();)
- path.append(iter2());
- }
- if (path.count() && !m_noShow)
- {
- m_painter->setStyle(m_styleProps, m_gradientProps);
- m_painter->drawPath(path);
- }
- }
- m_currentGeometry.clear();
- m_currentComplexGeometry.clear();
- m_currentGeometryOrder.clear();
-}
-
-void libvisio::VSDXParser::_flushCurrentForeignData()
-{
- if (m_currentForeignData.size() && m_currentForeignProps["libwpg:mime-type"] && !m_noShow)
- {
- m_painter->setStyle(m_styleProps, m_gradientProps);
- m_painter->drawGraphicObject(m_currentForeignProps, m_currentForeignData);
- }
- m_currentForeignData.clear();
- m_currentForeignProps.clear();
-}
-
-
-
// --- READERS ---
void libvisio::VSDXParser::readEllipticalArcTo(WPXInputStream *input)
@@ -251,8 +65,8 @@ void libvisio::VSDXParser::readEllipticalArcTo(WPXInputStream *input)
input->seek(1, WPX_SEEK_CUR);
double ecc = readDouble(input); // Eccentricity
-#if 0
- m_collector->collectEllipticalArcTo(x3, y3, x2, y2, angle, ecc, m_header.id);
+#if 1
+ m_collector->collectEllipticalArcTo(m_header.id, m_header.level, x3, y3, x2, y2, angle, ecc);
#else
x3 += m_xform.x;
y3 = m_xform.height - y3 + m_xform.y;
@@ -306,20 +120,26 @@ void libvisio::VSDXParser::readEllipticalArcTo(WPXInputStream *input)
void libvisio::VSDXParser::readForeignData(WPXInputStream *input)
{
+ unsigned long tmpBytesRead = 0;
+ const unsigned char *buffer = input->read(m_header.dataLength, tmpBytesRead);
+ if (m_header.dataLength != tmpBytesRead)
+ return;
+ WPXBinaryData binaryData(buffer, tmpBytesRead);
+#if 1
+ m_collector->collectForeignData(m_header.id, m_header.level, binaryData);
+#else
if (m_foreignType == 1 || m_foreignType == 4) // Image
{
- unsigned long tmpBytesRead = 0;
- const unsigned char *buffer = input->read(m_header.dataLength, tmpBytesRead);
// If bmp data found, reconstruct header
if (m_foreignType == 1 && m_foreignFormat == 0)
{
m_currentForeignData.append(0x42);
m_currentForeignData.append(0x4d);
- m_currentForeignData.append((unsigned char)((tmpBytesRead + 14) & 0x000000ff));
- m_currentForeignData.append((unsigned char)(((tmpBytesRead + 14) & 0x0000ff00) >> 8));
- m_currentForeignData.append((unsigned char)(((tmpBytesRead + 14) & 0x00ff0000) >> 16));
- m_currentForeignData.append((unsigned char)(((tmpBytesRead + 14) & 0xff000000) >> 24));
+ m_currentForeignData.append((unsigned char)((binaryData.size() + 14) & 0x000000ff));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0x0000ff00) >> 8));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0x00ff0000) >> 16));
+ m_currentForeignData.append((unsigned char)(((binaryData.size() + 14) & 0xff000000) >> 24));
m_currentForeignData.append(0x00);
m_currentForeignData.append(0x00);
@@ -331,7 +151,7 @@ void libvisio::VSDXParser::readForeignData(WPXInputStream *input)
m_currentForeignData.append(0x00);
m_currentForeignData.append(0x00);
}
- m_currentForeignData.append(buffer, tmpBytesRead);
+ m_currentForeignData.append(binaryData);
#if DUMP_BITMAP
if (m_foreignType == 1 || m_foreignType == 4)
@@ -400,6 +220,7 @@ void libvisio::VSDXParser::readForeignData(WPXInputStream *input)
}
}
}
+#endif
}
void libvisio::VSDXParser::readEllipse(WPXInputStream *input)
@@ -417,8 +238,8 @@ void libvisio::VSDXParser::readEllipse(WPXInputStream *input)
input->seek(1, WPX_SEEK_CUR);
double dd = readDouble(input);
-#if 0
- m_collector->collectEllipse(cx, cy, aa, bb, cc, dd);
+#if 1
+ m_collector->collectEllipse(m_header.id, m_header.level, cx, cy, aa, dd);
#else
WPXPropertyList ellipse;
ellipse.insert("svg:rx", m_scale*(aa-cx));
@@ -446,8 +267,8 @@ void libvisio::VSDXParser::readLine(WPXInputStream *input)
c.a = readU8(input);
unsigned linePattern = readU8(input);
-#if 0
- m_collector->collectLine(strokeWidth, c, linePattern);
+#if 1
+ m_collector->collectLine(m_header.id, m_header.level, strokeWidth, c, linePattern);
#else
m_linePattern = linePattern;
m_styleProps.insert("svg:stroke-width", m_scale*strokeWidth);
@@ -494,8 +315,8 @@ void libvisio::VSDXParser::readFillAndShadow(WPXInputStream *input)
input->seek(4, WPX_SEEK_CUR);
unsigned fillPattern = readU8(input);
-#if 0
- m_collector->collectFillAndShadow(colourIndexFG, colourIndexBG, fillPattern);
+#if 1
+ m_collector->collectFillAndShadow(m_header.id, m_header.level, colourIndexFG, colourIndexBG, fillPattern);
#else
m_fillPattern = fillPattern;
if (m_fillPattern == 0)
@@ -584,16 +405,30 @@ void libvisio::VSDXParser::readGeomList(WPXInputStream *input)
uint32_t subHeaderLength = readU32(input);
uint32_t childrenListLength = readU32(input);
input->seek(subHeaderLength, WPX_SEEK_CUR);
- _flushCurrentPath();
+ std::vector<unsigned> geometryOrder;
+ geometryOrder.reserve(childrenListLength / sizeof(uint32_t));
for (unsigned i = 0; i < (childrenListLength / sizeof(uint32_t)); i++)
- m_currentGeometryOrder.push_back(readU32(input));
+ geometryOrder.push_back(readU32(input));
+
+#if 1
+ m_collector->collectGeomList(m_header.id, m_header.level, geometryOrder);
+#else
+ _flushCurrentPath();
+ m_currentGeometryOrder.clear();
+ for (unsigned j = 0; j< geometryOrder.size(); j++)
+ m_currentGeometryOrder.push_back(geometryOrder[j]);
m_noShow = false;
+#endif
}
void libvisio::VSDXParser::readGeometry(WPXInputStream *input)
{
+ unsigned geomFlags = readU8(input);
+
+#if 1
+ m_collector->collectGeometry(m_header.id, m_header.level, geomFlags);
+#else
m_x = 0.0; m_x = 0.0;
- unsigned int geomFlags = readU8(input);
m_noFill = ((geomFlags & 1) == 1);
m_noLine = ((geomFlags & 2) == 2);
m_noShow = ((geomFlags & 4) == 4);
@@ -606,15 +441,22 @@ void libvisio::VSDXParser::readGeometry(WPXInputStream *input)
else
m_styleProps.insert("svg:fill", m_fillType);
VSD_DEBUG_MSG(("Flag: %d NoFill: %d NoLine: %d NoShow: %d\n", geomFlags, m_noFill, m_noLine, m_noShow));
+#endif
}
void libvisio::VSDXParser::readMoveTo(WPXInputStream *input)
{
- WPXPropertyList end;
input->seek(1, WPX_SEEK_CUR);
- m_x = readDouble(input) + m_xform.x;
+ double x = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_y = (m_xform.height - readDouble(input)) + m_xform.y;
+ double y = readDouble(input);
+
+#if 1
+ m_collector->collectMoveTo(m_header.id, m_header.level, x, y);
+#else
+ WPXPropertyList end;
+ m_x = x + m_xform.x;
+ m_y = m_xform.height - y + m_xform.y;
rotatePoint(m_x, m_y, m_xform);
flipPoint(m_x, m_y, m_xform);
@@ -622,33 +464,45 @@ void libvisio::VSDXParser::readMoveTo(WPXInputStream *input)
end.insert("svg:y", m_scale*m_y);
end.insert("libwpg:path-action", "M");
m_currentGeometry[m_header.id] = end;
+#endif
}
void libvisio::VSDXParser::readLineTo(WPXInputStream *input)
{
- WPXPropertyList end;
input->seek(1, WPX_SEEK_CUR);
- m_x = readDouble(input) + m_xform.x;
+ double x = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_y = (m_xform.height - readDouble(input)) + m_xform.y;
+ double y = readDouble(input);
+
+#if 1
+ m_collector->collectLineTo(m_header.id, m_header.level, x, y);
+#else
+ WPXPropertyList end;
+ m_x = x + m_xform.x;
+ m_y = m_xform.height - y + m_xform.y;
rotatePoint(m_x, m_y, m_xform);
flipPoint(m_x, m_y, m_xform);
-
end.insert("svg:x", m_scale*m_x);
end.insert("svg:y", m_scale*m_y);
end.insert("libwpg:path-action", "L");
m_currentGeometry[m_header.id] = end;
+#endif
}
void libvisio::VSDXParser::readArcTo(WPXInputStream *input)
{
input->seek(1, WPX_SEEK_CUR);
- double x2 = readDouble(input) + m_xform.x;
+ double x2 = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- double y2 = (m_xform.height - readDouble(input)) + m_xform.y;
+ double y2 = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
double bow = readDouble(input);
+#if 1
+ m_collector->collectArcTo(m_header.id, m_header.level, x2, y2, bow);
+#else
+ x2 += m_xform.x;
+ y2 = m_xform.height - y2 + m_xform.y;
rotatePoint(x2, y2, m_xform);
flipPoint(x2, y2, m_xform);
@@ -680,26 +534,33 @@ void libvisio::VSDXParser::readArcTo(WPXInputStream *input)
arc.insert("libwpg:path-action", "A");
m_currentGeometry[m_header.id] = arc;
}
+#endif
}
void libvisio::VSDXParser::readXFormData(WPXInputStream *input)
{
+ XForm xform;
input->seek(1, WPX_SEEK_CUR);
- m_xform.pinX = readDouble(input);
+ xform.pinX = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.pinY = readDouble(input);
+ xform.pinY = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.width = readDouble(input);
+ xform.width = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.height = readDouble(input);
+ xform.height = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.pinLocX = readDouble(input);
+ xform.pinLocX = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.pinLocY = readDouble(input);
+ xform.pinLocY = readDouble(input);
input->seek(1, WPX_SEEK_CUR);
- m_xform.angle = readDouble(input);
- m_xform.flipX = (readU8(input) != 0);
- m_xform.flipY = (readU8(input) != 0);
+ xform.angle = readDouble(input);
+ xform.flipX = (readU8(input) != 0);
+ xform.flipY = (readU8(input) != 0);
+
+#if 1
+ m_collector->collectXFormData(m_header.id, m_header.level, xform);
+#else
+ m_xform = xform;
std::map<unsigned int, XForm>::iterator iter = m_groupXForms.find(m_currentShapeId);
if (iter != m_groupXForms.end()) {
@@ -710,11 +571,17 @@ void libvisio::VSDXParser::readXFormData(WPXInputStream *input)
}
m_xform.x = m_xform.pinX - m_xform.pinLocX;
m_xform.y = m_pageHeight - m_xform.pinY + m_xform.pinLocY - m_xform.height;
+#endif
}
void libvisio::VSDXParser::readShapeID(WPXInputStream *input)
{
- m_groupXForms[readU32(input)] = m_xform;
+ unsigned shapeId = readU32(input);
+#if 1
+ m_collector->collectShapeID(m_header.id, m_header.level, shapeId);
+#else
+ m_groupXForms[shapeId] = m_xform;
+#endif
}
void libvisio::VSDXParser::readForeignDataType(WPXInputStream *input)
@@ -725,9 +592,13 @@ void libvisio::VSDXParser::readForeignDataType(WPXInputStream *input)
unsigned foreignFormat = readU32(input);
VSD_DEBUG_MSG(("Found foreign data, type %d format %d\n", foreignType, foreignFormat));
-
+
+#if 1
+ m_collector->collectForeignDataType(m_header.id, m_header.level, foreignType, foreignFormat);
+#else
m_foreignType = foreignType;
m_foreignFormat = foreignFormat;
+#endif
}
void libvisio::VSDXParser::readPageProps(WPXInputStream *input)
@@ -740,6 +611,9 @@ void libvisio::VSDXParser::readPageProps(WPXInputStream *input)
input->seek(19, WPX_SEEK_CUR);
/* m_scale = */ readDouble(input);
+#if 1
+ m_collector->collectPageProps(m_header.id, m_header.level, pageWidth, pageHeight);
+#else
m_pageWidth = pageWidth;
m_pageHeight = pageHeight;
WPXPropertyList pageProps;
@@ -750,21 +624,46 @@ void libvisio::VSDXParser::readPageProps(WPXInputStream *input)
m_painter->endGraphics();
m_painter->startGraphics(pageProps);
m_isPageStarted = true;
+#endif
+}
+
+void libvisio::VSDXParser::readColours(WPXInputStream *input)
+{
+ input->seek(6, WPX_SEEK_SET);
+ unsigned int numColours = readU8(input);
+ Colour tmpColour;
+
+ input->seek(1, WPX_SEEK_CUR);
+
+ std::vector<Colour> colours;
+
+ for (unsigned int i = 0; i < numColours; i++)
+ {
+ tmpColour.r = readU8(input);
+ tmpColour.g = readU8(input);
+ tmpColour.b = readU8(input);
+ tmpColour.a = readU8(input);
+
+ colours.push_back(tmpColour);
+ }
+ m_collector->collectColours(colours);
}
void libvisio::VSDXParser::shapeChunk(WPXInputStream *input)
{
long endPos = 0;
+#if 1
+ m_collector->shapeChunkBegin(m_header.id, m_header.level);
+#else
+ _flushCurrentPath();
+ _flushCurrentForeignData();
m_gradientProps = WPXPropertyListVector();
m_foreignType = 0; // Tracks current foreign data type
m_foreignFormat = 0; // Tracks foreign data format
- _flushCurrentPath();
- _flushCurrentForeignData();
m_x = 0; m_y = 0;
m_xform = XForm();
- m_header = ChunkHeader();
// Geometry flags
m_noLine = false;
@@ -783,6 +682,7 @@ void libvisio::VSDXParser::shapeChunk(WPXInputStream *input)
m_styleProps.insert("svg:stroke-color", m_lineColour);
m_styleProps.insert("draw:fill", m_fillType);
m_styleProps.insert("svg:stroke-dasharray", "solid");
+#endif
while (!input->atEOS())
{
@@ -843,8 +743,12 @@ void libvisio::VSDXParser::shapeChunk(WPXInputStream *input)
input->seek(endPos, WPX_SEEK_SET);
}
+#if 1
+ m_collector->shapeChunkEnd(m_header.id, m_header.level);
+#else
_flushCurrentPath();
_flushCurrentForeignData();
m_x = 0; m_y = 0;
+#endif
}
diff --git a/src/lib/VSDXParser.h b/src/lib/VSDXParser.h
index 8ba9511..9dd08b1 100644
--- a/src/lib/VSDXParser.h
+++ b/src/lib/VSDXParser.h
@@ -56,50 +56,16 @@ protected:
void readShapeID(WPXInputStream *input);
void readForeignDataType(WPXInputStream *input);
void readPageProps(WPXInputStream *input);
-
- void rotatePoint(double &x, double &y, const XForm &xform);
- void flipPoint(double &x, double &y, const XForm &xform);
-
- void _flushCurrentPath();
- void _flushCurrentForeignData();
+ void readColours(WPXInputStream *input);
// Chunk handlers
void shapeChunk(WPXInputStream *input);
virtual bool getChunkHeader(WPXInputStream *input) = 0;
- const ::WPXString getColourString(const Colour& c) const;
-
WPXInputStream *m_input;
libwpg::WPGPaintInterface *m_painter;
- bool m_isPageStarted;
- double m_pageWidth;
- double m_pageHeight;
- double m_scale;
- double m_x;
- double m_y;
- XForm m_xform;
ChunkHeader m_header;
- std::vector<unsigned> m_currentGeometryOrder;
- std::map<unsigned, WPXPropertyList> m_currentGeometry;
- std::map<unsigned, WPXPropertyListVector> m_currentComplexGeometry;
- std::map<unsigned, XForm> m_groupXForms;
- WPXBinaryData m_currentForeignData;
- WPXPropertyList m_currentForeignProps;
- unsigned m_currentShapeId;
- unsigned m_foreignType;
- unsigned m_foreignFormat;
- WPXPropertyList m_styleProps;
- ::WPXString m_lineColour;
- ::WPXString m_fillType;
- unsigned m_linePattern;
- unsigned m_fillPattern;
- WPXPropertyListVector m_gradientProps;
- bool m_noLine;
- bool m_noFill;
- bool m_noShow;
- std::vector<Colour> m_colours;
-
VSDXCollector *m_collector;
};
diff --git a/src/lib/VSDXStylesCollector.h b/src/lib/VSDXStylesCollector.h
index ce24a24..2409f7d 100644
--- a/src/lib/VSDXStylesCollector.h
+++ b/src/lib/VSDXStylesCollector.h
@@ -33,21 +33,30 @@ public:
virtual ~VSDXStylesCollector() {};
void collectEllipticalArcTo(unsigned id, unsigned level, double x3, double y3, double x2, double y2, double angle, double ecc) {}
- void collectForeignData(unsigned id, unsigned level) {}
- void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double bb, double cc, double dd) {}
+ void collectForeignData(unsigned id, unsigned level, const WPXBinaryData &binaryData) {}
+ void collectEllipse(unsigned id, unsigned level, double cx, double cy, double aa, double dd) {}
void collectLine(unsigned id, unsigned level, double strokeWidth, Colour c, unsigned linePattern) {}
void collectFillAndShadow(unsigned id, unsigned level, unsigned colourIndexFG, unsigned colourIndexBG, unsigned fillPattern) {}
- void collectGeomList(unsigned id, unsigned level) {}
- void collectGeometry(unsigned id, unsigned level) {}
- void collectMoveTo(unsigned id, unsigned level) {}
- void collectLineTo(unsigned id, unsigned level) {}
- void collectArcTo(unsigned id, unsigned level) {}
- void collectXFormData(unsigned id, unsigned level) {}
- void collectShapeID(unsigned id, unsigned level) {}
- void collectForeignDataType(unsigned id, unsigned level) {}
- void collectPageProps(unsigned id, unsigned level) {}
+ void collectGeomList(unsigned id, unsigned level, const std::vector<unsigned> &geometryOrder) {}
+ void collectGeometry(unsigned id, unsigned level, unsigned geomFlags) {}
+ void collectMoveTo(unsigned id, unsigned level, double x, double y) {}
+ void collectLineTo(unsigned id, unsigned level, double x, double y) {}
+ void collectArcTo(unsigned id, unsigned level, double x2, double y2, double bow) {}
+ void collectXFormData(unsigned id, unsigned level, const XForm &xform) {}
+ void collectShapeID(unsigned id, unsigned level, unsigned shapeId) {}
+ void collectForeignDataType(unsigned id, unsigned level, unsigned foreignType, unsigned foreignFormat) {}
+ void collectPageProps(unsigned id, unsigned level, double pageWidth, double pageHeight) {}
void collectUnhandledChunk(unsigned id, unsigned level) {}
+
+ void collectColours(const std::vector<Colour> &colours) {}
+
+ // Temporary hack
+ void shapeChunkBegin(unsigned id, unsigned level) {}
+ void shapeChunkEnd(unsigned id, unsigned level) {}
+ void pageChunkBegin(unsigned id, unsigned level) {}
+ void startPage() {}
+ void endPage() {}
private: