summaryrefslogtreecommitdiff
path: root/dviware/dvisvgm/src/TpicSpecialHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dviware/dvisvgm/src/TpicSpecialHandler.cpp')
-rw-r--r--dviware/dvisvgm/src/TpicSpecialHandler.cpp83
1 files changed, 46 insertions, 37 deletions
diff --git a/dviware/dvisvgm/src/TpicSpecialHandler.cpp b/dviware/dvisvgm/src/TpicSpecialHandler.cpp
index 47d3e46988..b611117725 100644
--- a/dviware/dvisvgm/src/TpicSpecialHandler.cpp
+++ b/dviware/dvisvgm/src/TpicSpecialHandler.cpp
@@ -2,7 +2,7 @@
** TpicSpecialHandler.cpp **
** **
** This file is part of dvisvgm -- a fast DVI to SVG converter **
-** Copyright (C) 2005-2020 Martin Gieseking <martin.gieseking@uos.de> **
+** Copyright (C) 2005-2021 Martin Gieseking <martin.gieseking@uos.de> **
** **
** This program is free software; you can redistribute it and/or **
** modify it under the terms of the GNU General Public License as **
@@ -28,6 +28,7 @@
#include "InputReader.hpp"
#include "GraphicsPath.hpp"
#include "SpecialActions.hpp"
+#include "SVGElement.hpp"
#include "SVGTree.hpp"
#include "TpicSpecialHandler.hpp"
#include "utility.hpp"
@@ -70,28 +71,32 @@ Color TpicSpecialHandler::fillColor (bool grayOnly) const {
* @param[in] penwidth pen with used to compute the stroke parameters
* @param[in] pencolor the drawing color
* @param[in] ddist dash/dot distance of line in PS point units (0:solid line, >0:dashed line, <0:dotted line) */
-static void add_stroke_attribs (XMLElement *elem, double penwidth, Color pencolor, double ddist) {
+static void add_stroke_attribs (SVGElement *elem, double penwidth, Color pencolor, double ddist) {
if (penwidth > 0) { // attributes actually required?
- elem->addAttribute("stroke", pencolor.svgColorString());
- elem->addAttribute("stroke-width", XMLString(penwidth));
+ elem->setStrokeColor(pencolor);
+ elem->setStrokeWidth(penwidth);
+ vector<double> dasharray;
if (ddist > 0)
- elem->addAttribute("stroke-dasharray", XMLString(ddist));
- else if (ddist < 0)
- elem->addAttribute("stroke-dasharray", XMLString(penwidth) + ' ' + XMLString(-ddist));
+ dasharray.push_back(ddist);
+ else if (ddist < 0) {
+ dasharray.push_back(penwidth);
+ dasharray.push_back(-ddist);
+ }
+ elem->setStrokeDash(dasharray);
}
}
-static unique_ptr<XMLElement> create_ellipse_element (double cx, double cy, double rx, double ry) {
+static unique_ptr<SVGElement> create_ellipse_element (double cx, double cy, double rx, double ry) {
bool is_circle = (rx == ry);
- auto elem = util::make_unique<XMLElement>(is_circle ? "circle" : "ellipse");
- elem->addAttribute("cx", XMLString(cx));
- elem->addAttribute("cy", XMLString(cy));
+ auto elem = util::make_unique<SVGElement>(is_circle ? "circle" : "ellipse");
+ elem->addAttribute("cx", cx);
+ elem->addAttribute("cy", cy);
if (is_circle)
- elem->addAttribute("r", XMLString(rx));
+ elem->addAttribute("r", rx);
else {
- elem->addAttribute("rx", XMLString(rx));
- elem->addAttribute("ry", XMLString(ry));
+ elem->addAttribute("rx", rx);
+ elem->addAttribute("ry", ry);
}
return elem;
}
@@ -102,7 +107,7 @@ static unique_ptr<XMLElement> create_ellipse_element (double cx, double cy, doub
* @param[in] actions object providing the actions that can be performed by the SpecialHandler */
void TpicSpecialHandler::drawLines (double ddist, SpecialActions &actions) {
if (!_points.empty() && (_penwidth > 0 || _grayLevel >= 0) && !actions.outputLocked()) {
- unique_ptr<XMLElement> elem;
+ unique_ptr<SVGElement> elem;
if (_points.size() == 1) {
const DPair &p = _points.back();
elem = create_ellipse_element(p.x()+actions.getX(), p.y()+actions.getY(), _penwidth/2.0, _penwidth/2.0);
@@ -110,26 +115,27 @@ void TpicSpecialHandler::drawLines (double ddist, SpecialActions &actions) {
}
else {
if (_points.size() == 2 || (_grayLevel < 0 && _points.front() != _points.back())) {
- elem = util::make_unique<XMLElement>("polyline");
- elem->addAttribute("fill", "none");
- elem->addAttribute("stroke-linecap", "round");
+ elem = util::make_unique<SVGElement>("polyline");
+ elem->setNoFillColor();
+ elem->setStrokeLineCap(SVGElement::LC_ROUND);
}
else {
while (_points.front() == _points.back())
_points.pop_back();
- elem = util::make_unique<XMLElement>("polygon");
- elem->addAttribute("fill", _grayLevel < 0 ? "none" : fillColor(false).svgColorString());
+ elem = util::make_unique<SVGElement>("polygon");
+ if (_grayLevel < 0)
+ elem->setNoFillColor();
+ else
+ elem->setFillColor(fillColor(false));
}
- ostringstream oss;
- for (auto it=_points.begin(); it != _points.end(); ++it) {
- if (it != _points.begin())
- oss << ' ';
- double x = it->x()+actions.getX();
- double y = it->y()+actions.getY();
- oss << XMLString(x) << ',' << XMLString(y);
+ vector<DPair> points;
+ for (const DPair &p : _points) {
+ double x = p.x()+actions.getX();
+ double y = p.y()+actions.getY();
+ points.emplace_back(x, y);
actions.embed(DPair(x, y));
}
- elem->addAttribute("points", oss.str());
+ elem->setPoints(points);
add_stroke_attribs(elem.get(), _penwidth, Color::BLACK, ddist);
}
actions.svgTree().appendToPage(std::move(elem));
@@ -175,8 +181,8 @@ void TpicSpecialHandler::drawSplines (double ddist, SpecialActions &actions) {
path.lineto(p+_points[numPoints-1]);
actions.embed(p+_points[numPoints-1]);
}
- auto pathElem = util::make_unique<XMLElement>("path");
- pathElem->addAttribute("fill", "none");
+ auto pathElem = util::make_unique<SVGElement>("path");
+ pathElem->setNoFillColor();
ostringstream oss;
path.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS);
pathElem->addAttribute("d", oss.str());
@@ -200,7 +206,7 @@ void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, do
if ((_penwidth > 0 || _grayLevel >= 0) && !actions.outputLocked()) {
cx += actions.getX();
cy += actions.getY();
- unique_ptr<XMLElement> elem;
+ unique_ptr<SVGElement> elem;
bool closed=true;
if (abs(angle2-angle1) >= math::TWO_PI) // closed ellipse?
elem = create_ellipse_element(cx, cy, rx, ry);
@@ -213,18 +219,21 @@ void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, do
path.closepath();
else
closed = false;
- elem = util::make_unique<XMLElement>("path");
+ elem = util::make_unique<SVGElement>("path");
ostringstream oss;
path.writeSVG(oss, SVGTree::RELATIVE_PATH_CMDS);
elem->addAttribute("d", oss.str());
}
if (_penwidth > 0) {
- elem->addAttribute("stroke-width", _penwidth);
- elem->addAttribute("stroke", actions.getColor().svgColorString());
+ elem->setStrokeWidth(_penwidth);
+ elem->setStrokeColor(actions.getColor());
if (!closed)
- elem->addAttribute("stroke-linecap", "round");
+ elem->setStrokeLineCap(SVGElement::LC_ROUND);
}
- elem->addAttribute("fill", _grayLevel < 0 ? "none" : fillColor(true).svgColorString());
+ if (_grayLevel < 0)
+ elem->setNoFillColor();
+ else
+ elem->setFillColor(fillColor(true));
actions.svgTree().appendToPage(std::move(elem));
double pw = _penwidth/2.0;
actions.embed(BoundingBox(cx-rx-pw, cy-ry-pw, cx+rx+pw, cy+ry+pw));
@@ -296,7 +305,7 @@ bool TpicSpecialHandler::process (const string &prefix, istream &is, SpecialActi
case cmd_id("pa"): { // add point to path
double x = ir.getDouble()*mi2bp;
double y = ir.getDouble()*mi2bp;
- _points.emplace_back(DPair(x,y));
+ _points.emplace_back(x, y);
break;
}
case cmd_id("fp"): // draw solid lines through recorded points; close and fill path if fill color was defined