summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2012-01-13 12:54:51 +0100
committerFridrich Štrba <fridrich.strba@bluewin.ch>2012-01-13 12:54:51 +0100
commit4d4e4e44fe790bce9e7fab4ee4aedc7b41a1a360 (patch)
tree1a9d5e5b59dcc3e30898ffc1e88b8a8976fd23b5
parentcfd630c1ba2df5d9531ccda04325a40aa33d10c4 (diff)
Foreign rotations
-rw-r--r--src/lib/VSDSVGGenerator.cpp18
-rw-r--r--src/lib/VSDXContentCollector.cpp125
2 files changed, 118 insertions, 25 deletions
diff --git a/src/lib/VSDSVGGenerator.cpp b/src/lib/VSDSVGGenerator.cpp
index 29931a4..58a5a73 100644
--- a/src/lib/VSDSVGGenerator.cpp
+++ b/src/lib/VSDSVGGenerator.cpp
@@ -463,9 +463,25 @@ void libvisio::VSDSVGGenerator::drawGraphicObject(const ::WPXPropertyList &propL
if (flipY)
y = -(y + height);
+ double xmiddle = x + width / 2.0;
+ double ymiddle = y + height / 2.0;
m_outputSink << "x=\"" << doubleToString(72*x) << "\" y=\"" << doubleToString(72*y) << "\" ";
m_outputSink << "width=\"" << doubleToString(72*width) << "\" height=\"" << doubleToString(72*height) << "\" ";
- m_outputSink << "transform=\"scale(" << (flipX ? "-1" : "1") << ", " << (flipY ? "-1" : "1") << ")\" ";
+ m_outputSink << "transform=\"";
+ // rotation is around the center of the objects bounding box
+ if (propList["libwpg:rotate"])
+ {
+ double angle = propList["libwpg:rotate"]->getDouble();
+ while (angle > 180.0)
+ angle -= 360.0;
+ while (angle < -180.0)
+ angle += 360.0;
+ m_outputSink << " translate(" << doubleToString((flipX ? -1 : 1)*72*xmiddle) << ", " << doubleToString ((flipY ? -1 : 1)*72*ymiddle) << ") ";
+ m_outputSink << " rotate(" << doubleToString(angle) << ") ";
+ m_outputSink << " translate(" << doubleToString((flipX ? 1 : -1)*72*xmiddle) << ", " << doubleToString ((flipY ? 1 : -1)*72*ymiddle) << ") ";
+ }
+ m_outputSink << " scale(" << (flipX ? "-1" : "1") << ", " << (flipY ? "-1" : "1") << ") ";
+ m_outputSink << "\" ";
}
m_outputSink << "xlink:href=\"data:" << propList["libwpg:mime-type"]->getStr().cstr() << ";base64,";
m_outputSink << base64.cstr();
diff --git a/src/lib/VSDXContentCollector.cpp b/src/lib/VSDXContentCollector.cpp
index 6950320..0c3c45a 100644
--- a/src/lib/VSDXContentCollector.cpp
+++ b/src/lib/VSDXContentCollector.cpp
@@ -725,43 +725,120 @@ void libvisio::VSDXContentCollector::_flushText()
void libvisio::VSDXContentCollector::_flushCurrentForeignData()
{
- double x = m_foreignOffsetX;
- double y = m_foreignOffsetY;
- transformPoint(x,y);
- WPXPropertyList styleProps(m_styleProps);
+ double x1 = m_foreignOffsetX;
+ double y1 = m_foreignOffsetY;
+ double x2 = m_foreignOffsetX + m_foreignWidth;
+ double y2 = m_foreignOffsetY + m_foreignHeight;
+ double x3 = x1;
+ double y3 = y2;
+ double x4 = x2;
+ double y4 = y1;
+ transformPoint(x1,y1);
+ transformPoint(x2,y2);
+ transformPoint(x3,y3);
+ transformPoint(x4,y4);
+ double angle = 0.0;
+ transformAngle(angle);
+
+ double xmin = x1;
+ double xmax = x1;
+
+ if (xmin > x2)
+ xmin = x2;
+ if (xmax < x2)
+ xmax = x2;
+
+ if (xmin > x3)
+ xmin = x3;
+ if (xmax < x3)
+ xmax = x3;
+
+ if (xmin > x4)
+ xmin = x4;
+ if (xmax < x4)
+ xmax = x4;
+
+ double ymin = y1;
+ double ymax = y1;
+
+ if (ymin > y2)
+ ymin = y2;
+ if (ymax < y2)
+ ymax = y2;
+
+ if (ymin > y3)
+ ymin = y3;
+ if (ymax < y3)
+ ymax = y3;
+
+ if (ymin > y4)
+ ymin = y4;
+ if (ymax < y4)
+ ymax = y4;
+
+ double xmiddle = (xmax + xmin) / 2.0;
+ double ymiddle = (ymax + ymin) / 2.0;
+
+ bool flipX = false;
+ bool flipY = false;
- if (m_xform.flipY)
+ // If any parent group is flipped, invert flips and
+ // revert the flip information that is already incorporated
+ // in the angle.
+ unsigned shapeId = m_currentShapeId;
+ while (true)
{
- m_currentForeignProps.insert("svg:width", -m_scale*m_foreignWidth);
- m_currentForeignProps.insert("svg:height", -m_scale*m_foreignHeight);
- m_currentForeignProps.insert("svg:y", m_scale*(y + m_foreignHeight));
- if (m_xform.flipX)
+ std::map<unsigned, XForm>::iterator iterX = m_groupXForms.find(shapeId);
+ if (iterX != m_groupXForms.end())
{
- m_currentForeignProps.insert("svg:x", m_scale*x);
- styleProps.insert("style:mirror", "horizontal");
+ XForm xform = iterX->second;
+ if (xform.flipX)
+ {
+ flipX = !flipX;
+ angle = M_PI - angle;
+ }
+ if (xform.flipY)
+ {
+ flipY = !flipY;
+ angle *= -1.0;
+ }
}
else
- {
- m_currentForeignProps.insert("svg:x", m_scale*(x + m_foreignWidth));
+ break;
+ std::map<unsigned, unsigned>::iterator iter = m_groupMemberships.find(shapeId);
+ if (iter != m_groupMemberships.end())
+ shapeId = iter->second;
+ else
+ break;
+ }
+
+
+ WPXPropertyList styleProps(m_styleProps);
+
+ if (flipY)
+ {
+ m_currentForeignProps.insert("svg:x", m_scale*(xmiddle + (m_foreignWidth / 2.0)));
+ m_currentForeignProps.insert("svg:width", -m_scale*m_foreignWidth);
+ m_currentForeignProps.insert("svg:y", m_scale*(ymiddle + (m_foreignHeight / 2.0)));
+ m_currentForeignProps.insert("svg:height", -m_scale*m_foreignHeight);
+ if (flipX)
styleProps.insert("style:mirror", "none");
- }
+ else
+ styleProps.insert("style:mirror", "horizontal");
}
else
{
+ m_currentForeignProps.insert("svg:x", m_scale*(xmiddle - (m_foreignWidth / 2.0)));
m_currentForeignProps.insert("svg:width", m_scale*m_foreignWidth);
+ m_currentForeignProps.insert("svg:y", m_scale*(ymiddle - (m_foreignHeight / 2.0)));
m_currentForeignProps.insert("svg:height", m_scale*m_foreignHeight);
- m_currentForeignProps.insert("svg:y", m_scale*(y - m_foreignHeight));
- if (m_xform.flipX)
- {
- m_currentForeignProps.insert("svg:x", m_scale*(x - m_foreignWidth));
- styleProps.insert("style:mirror", "none");
- }
- else
- {
- m_currentForeignProps.insert("svg:x", m_scale*x);
+ if (flipX)
styleProps.insert("style:mirror", "horizontal");
- }
+ else
+ styleProps.insert("style:mirror", "none");
}
+ if (angle != 0.0)
+ m_currentForeignProps.insert("libwpg:rotate", angle * 180 / M_PI, WPX_GENERIC);
if (m_currentForeignData.size() && m_currentForeignProps["libwpg:mime-type"] && !m_noShow)
{