diff options
author | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-01-13 12:54:51 +0100 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-01-13 12:54:51 +0100 |
commit | 4d4e4e44fe790bce9e7fab4ee4aedc7b41a1a360 (patch) | |
tree | 1a9d5e5b59dcc3e30898ffc1e88b8a8976fd23b5 | |
parent | cfd630c1ba2df5d9531ccda04325a40aa33d10c4 (diff) |
Foreign rotations
-rw-r--r-- | src/lib/VSDSVGGenerator.cpp | 18 | ||||
-rw-r--r-- | src/lib/VSDXContentCollector.cpp | 125 |
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) { |