src/lib/VSDContentCollector.cpp | 132 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 125 insertions(+), 7 deletions(-)
New commits: commit 53f7dacb2869feaa959f56a701f123839fbb8a80 Author: Fridrich Å trba <fridrich.st...@bluewin.ch> Date: Tue Dec 29 16:29:36 2015 +0100 Avoid equality comparison of doubles, which is prone to rounding errors Change-Id: I37ba61b95c6850ea008fd6f7ac042bea783249d7 diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index e6e3268..da6b073 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -301,7 +301,7 @@ void libvisio::VSDContentCollector::_flushCurrentPath() { if (!wasMove) { - if ((x == prevX) && (y == prevY)) + if (VSD_ALMOST_ZERO(x - prevX) && VSD_ALMOST_ZERO(y - prevY)) { if (tmpPath.back()["librevenge:path-action"]->getStr() != "Z") { @@ -332,7 +332,7 @@ void libvisio::VSDContentCollector::_flushCurrentPath() { if (!wasMove) { - if ((x == prevX) && (y == prevY)) + if (VSD_ALMOST_ZERO(x - prevX) && VSD_ALMOST_ZERO(y - prevY)) { if (tmpPath.back()["librevenge:path-action"]->getStr() != "Z") { commit d62d8b5f13b31b55706ad35fe69a871847a163e1 Author: Fridrich Å trba <fridrich.st...@bluewin.ch> Date: Tue Dec 29 16:15:48 2015 +0100 A horrendous hack to emulate line rounding property It needs some annotation not to forget the reasons behind the mess. I will do it later, since still tracking down little imperfections. Change-Id: Ic6f9d58d69047e3926cc62b899fbc379ebbd58cf diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index 1a34b51..e6e3268 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -267,7 +267,7 @@ void libvisio::VSDContentCollector::_flushCurrentPath() if (!tmpPath.empty()) { librevenge::RVNGPropertyListVector path; - _convertToPath(tmpPath, path, m_lineStyle.rounding); + _convertToPath(tmpPath, path, m_scale*m_lineStyle.rounding); m_shapeOutputDrawing->addStyle(fillPathProps); librevenge::RVNGPropertyList propList; propList.insert("svg:d", path); @@ -350,7 +350,7 @@ void libvisio::VSDContentCollector::_flushCurrentPath() if (!tmpPath.empty()) { librevenge::RVNGPropertyListVector path; - _convertToPath(tmpPath, path, m_lineStyle.rounding); + _convertToPath(tmpPath, path, m_scale*m_lineStyle.rounding); m_shapeOutputDrawing->addStyle(linePathProps); librevenge::RVNGPropertyList propList; propList.insert("svg:d", path); @@ -362,10 +362,128 @@ void libvisio::VSDContentCollector::_flushCurrentPath() } void libvisio::VSDContentCollector::_convertToPath(const std::vector<librevenge::RVNGPropertyList> &segmentVector, - librevenge::RVNGPropertyListVector &path, double /* rounding */) + librevenge::RVNGPropertyListVector &path, double rounding) { - for (unsigned i = 0; i < segmentVector.size(); ++i) - path.append(segmentVector[i]); + if (segmentVector.empty()) + return; + if (rounding > 0.0) + { + double prevX = segmentVector[0]["svg:x"] ? segmentVector[0]["svg:x"]->getDouble() : 0.0; + double prevY = segmentVector[0]["svg:y"] ? segmentVector[0]["svg:y"]->getDouble() : 0.0; + unsigned moveIndex = 0; + double maxRounding = DBL_MAX; + std::vector<librevenge::RVNGPropertyList> tmpSegment; + for (unsigned i = 0; i < segmentVector.size(); ++i) + { + if (segmentVector[i]["librevenge:path-action"] && segmentVector[i]["librevenge:path-action"]->getStr() == "M") + { + _convertToPath(tmpSegment, path, 0.0); + tmpSegment.clear(); + } + tmpSegment.push_back(segmentVector[i]); + if (segmentVector[i]["librevenge:path-action"] && segmentVector[i]["librevenge:path-action"]->getStr() == "M") + { + prevX = segmentVector[i]["svg:x"] ? segmentVector[i]["svg:x"]->getDouble() : 0.0; + prevY = segmentVector[i]["svg:y"] ? segmentVector[i]["svg:y"]->getDouble() : 0.0; + moveIndex = i; + maxRounding = DBL_MAX; + } + else if (segmentVector[i]["librevenge:path-action"] && segmentVector[i]["librevenge:path-action"]->getStr() == "L") + { + double x0 = segmentVector[i]["svg:x"] ? segmentVector[i]["svg:x"]->getDouble() : 0.0; + double y0 = segmentVector[i]["svg:y"] ? segmentVector[i]["svg:y"]->getDouble() : 0.0; + if (i+1 < segmentVector.size() && segmentVector[i+1]["librevenge:path-action"] && segmentVector[i+1]["librevenge:path-action"]->getStr() == "L") + { + double x = segmentVector[i+1]["svg:x"] ? segmentVector[i+1]["svg:x"]->getDouble() : 0.0; + double y = segmentVector[i+1]["svg:y"] ? segmentVector[i+1]["svg:y"]->getDouble() : 0.0; + if (maxRounding > rounding) + maxRounding = sqrt((y0-prevY)*(y0-prevY) + (x0-prevX)*(x0-prevX)) / 2.0; + double halfLength = sqrt((y-y0)*(y-y0)+(x-x0)*(x-x0)) / 2.0; + if (maxRounding > halfLength) + maxRounding = halfLength; + if (maxRounding > rounding) + maxRounding = rounding; + double lambda = atan2(y0-prevY, x0-prevX); + double newX0 = x0-maxRounding*cos(lambda); + double newY0 = y0-maxRounding*sin(lambda); + lambda = atan2(y-y0, x-x0); + double newX = x0+maxRounding*cos(lambda); + double newY = y0+maxRounding*sin(lambda); + tmpSegment.back().insert("svg:x", newX0); + tmpSegment.back().insert("svg:y", newY0); + librevenge::RVNGPropertyList q; + q.insert("librevenge:path-action", "Q"); + q.insert("svg:x1", x0); + q.insert("svg:y1", y0); + q.insert("svg:x", newX); + q.insert("svg:y", newY); + tmpSegment.push_back(q); + prevX = newX; + prevY = newY; + maxRounding = halfLength; + } + else if (i+1 < segmentVector.size() && segmentVector[i+1]["librevenge:path-action"] && segmentVector[i+1]["librevenge:path-action"]->getStr() == "Z") + { + if (tmpSegment.size() >= 2 && + tmpSegment[0]["librevenge:path-action"] && + tmpSegment[0]["librevenge:path-action"]->getStr() == "M" && + tmpSegment[1]["librevenge:path-action"] && + tmpSegment[1]["librevenge:path-action"]->getStr() == "L") + { + double lineX = segmentVector[moveIndex+1]["svg:x"] ? segmentVector[moveIndex+1]["svg:x"]->getDouble() : 0.0; + double lineY = segmentVector[moveIndex+1]["svg:y"] ? segmentVector[moveIndex+1]["svg:y"]->getDouble() : 0.0; + double halfLength = sqrt((lineY-y0)*(lineY-y0)+(lineX-x0)*(lineX-x0)) / 2.0; + if (maxRounding > halfLength) + maxRounding = halfLength; + if (maxRounding > rounding) + maxRounding = rounding; + double lambda = atan2(y0-prevY, x0-prevX); + double newX0 = x0-maxRounding*cos(lambda); + double newY0 = y0-maxRounding*sin(lambda); + lambda = atan2(lineY-y0, lineX-x0); + double newX = x0+maxRounding*cos(lambda); + double newY = y0+maxRounding*sin(lambda); + tmpSegment.back().insert("svg:x", newX0); + tmpSegment.back().insert("svg:y", newY0); + librevenge::RVNGPropertyList q; + q.insert("librevenge:path-action", "Q"); + q.insert("svg:x1", x0); + q.insert("svg:y1", y0); + q.insert("svg:x", newX); + q.insert("svg:y", newY); + tmpSegment.push_back(q); + tmpSegment[0].insert("svg:x", newX) ; + tmpSegment[0].insert("svg:y", newY); + prevX = newX; + prevY = newY; + maxRounding = halfLength; + } + else + maxRounding = DBL_MAX; + } + else + maxRounding = DBL_MAX; + } + else if (segmentVector[i]["librevenge:path-action"] && segmentVector[i]["librevenge:path-action"]->getStr() == "Z") + { + prevX = segmentVector[moveIndex]["svg:x"] ? segmentVector[moveIndex]["svg:x"]->getDouble() : 0.0; + prevY = segmentVector[moveIndex]["svg:y"] ? segmentVector[moveIndex]["svg:y"]->getDouble() : 0.0; + maxRounding = DBL_MAX; + } + else + { + prevX = segmentVector[i]["svg:x"] ? segmentVector[i]["svg:x"]->getDouble() : 0.0; + prevY = segmentVector[i]["svg:y"] ? segmentVector[i]["svg:y"]->getDouble() : 0.0; + maxRounding = DBL_MAX; + } + } + _convertToPath(tmpSegment, path, 0.0); + } + else + { + for (unsigned i = 0; i < segmentVector.size(); ++i) + path.append(segmentVector[i]); + } } void libvisio::VSDContentCollector::_flushText()
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits