summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp263
1 files changed, 0 insertions, 263 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp
deleted file mode 100644
index 95dc58a4ec4..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/src/EmSpecialHandler.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*************************************************************************
-** EmSpecialHandler.cpp **
-** **
-** This file is part of dvisvgm -- a fast DVI to SVG converter **
-** 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 **
-** published by the Free Software Foundation; either version 3 of **
-** the License, or (at your option) any later version. **
-** **
-** This program is distributed in the hope that it will be useful, but **
-** WITHOUT ANY WARRANTY; without even the implied warranty of **
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
-** GNU General Public License for more details. **
-** **
-** You should have received a copy of the GNU General Public License **
-** along with this program; if not, see <http://www.gnu.org/licenses/>. **
-*************************************************************************/
-
-#include <sstream>
-#include "EmSpecialHandler.hpp"
-#include "InputBuffer.hpp"
-#include "InputReader.hpp"
-#include "Length.hpp"
-#include "SpecialActions.hpp"
-#include "SVGTree.hpp"
-#include "XMLNode.hpp"
-#include "XMLString.hpp"
-
-using namespace std;
-
-
-/** Computes the "cut vector" that is used to compute the line shape.
- * Because each line has a width > 0 the actual shape of the line is a tetragon.
- * The 4 vertices can be influenced by the cut parameter c that specifies
- * a horizontal, vertical or orthogonal cut of a line end. Depending on c and the
- * line's slope a cut vector v can be computed that, relatively to endpoint p, denotes
- * the 2 vertices of that line end: v1=p+v and v2=p-v.
- * @param[in] cuttype character identifying the cut direction ('h', 'v' or 'p')
- * @param[in] linedir direction vector of line to be drawn
- * @param[in] lw width of line to be drawn
- * @return the "cut vector" */
-static DPair cut_vector (char cuttype, const DPair &linedir, double linewidth) {
- DPair cut;
- switch (cuttype) {
- case 'v': // vertical
- if (linedir.x() != 0) {
- double slope = linedir.y()/linedir.x();
- double h = sqrt(linewidth*linewidth*(1+slope*slope));
- cut.y(h/2);
- }
- break;
- case 'h': // horizontal
- if (linedir.y() != 0) {
- double slope = linedir.x()/linedir.y();
- double h = sqrt(linewidth*linewidth*(1+slope*slope));
- double sgn = slope < 0 ? 1.0 : -1.0;
- cut.x(h*sgn/2);
- }
- break;
- default: // c == 'p': perpendicular to the line vector
- if (linedir.x() != 0 && linedir.y() != 0)
- return linedir.ortho()/linedir.length() * (linewidth/2);
- }
- return cut;
-}
-
-
-/** Creates the SVG element that will a the line.
- * @param[in] p1 first endpoint in PS point units
- * @param[in] p2 second endpoint in PS point units
- * @param[in] c1 cut method of first endpoint ('h', 'v' or 'p')
- * @param[in] c2 cut method of second endpoint ('h', 'v' or 'p')
- * @param[in] lw line width in PS point units
- * @param[in] actions object providing the actions that can be performed by the SpecialHandler */
-static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions &actions) {
- if (actions.outputLocked())
- return;
- unique_ptr<XMLElement> node;
- DPair dir = p2-p1;
- if (dir.x() == 0 || dir.y() == 0 || (c1 == 'p' && c2 == 'p')) {
- // draw regular line
- node = util::make_unique<XMLElement>("line");
- node->addAttribute("x1", p1.x());
- node->addAttribute("y1", p1.y());
- node->addAttribute("x2", p2.x());
- node->addAttribute("y2", p2.y());
- node->addAttribute("stroke-width", lw);
- node->addAttribute("stroke", actions.getColor().svgColorString());
- // update bounding box
- DPair cv = cut_vector('p', dir, lw);
- actions.embed(p1+cv);
- actions.embed(p1-cv);
- actions.embed(p2+cv);
- actions.embed(p2-cv);
- }
- else {
- // draw polygon
- DPair cv1 = cut_vector(c1, dir, lw);
- DPair cv2 = cut_vector(c2, dir, lw);
- DPair q11 = p1+cv1, q12 = p1-cv1;
- DPair q21 = p2+cv2, q22 = p2-cv2;
- ostringstream oss;
- oss << XMLString(q11.x()) << ',' << XMLString(q11.y()) << ' '
- << XMLString(q12.x()) << ',' << XMLString(q12.y()) << ' '
- << XMLString(q22.x()) << ',' << XMLString(q22.y()) << ' '
- << XMLString(q21.x()) << ',' << XMLString(q21.y());
- node = util::make_unique<XMLElement>("polygon");
- node->addAttribute("points", oss.str());
- if (actions.getColor() != Color::BLACK)
- node->addAttribute("fill", actions.getColor().svgColorString());
- // update bounding box
- actions.embed(q11);
- actions.embed(q12);
- actions.embed(q21);
- actions.embed(q22);
- }
- actions.svgTree().appendToPage(std::move(node));
-}
-
-
-/** Reads a length (value + unit) and returns its value in PS points (bp).
- * If no unit is specified, TeX points are assumed. */
-static double read_length (InputReader &in) {
- double val = in.getDouble();
- string unitstr;
- if (isalpha(in.peek())) unitstr += char(in.get());
- if (isalpha(in.peek())) unitstr += char(in.get());
- Length::Unit unit = Length::Unit::PT;
- try {
- unit = Length::stringToUnit(unitstr);
- }
- catch (UnitException &e) {
- }
- return Length(val, unit).bp();
-}
-
-
-bool EmSpecialHandler::process (const string &prefix, istream &is, SpecialActions &actions) {
- // em:moveto => move graphic cursor to dvi position
- // em:lineto => draw line from graphic cursor to dvi cursor, then move graphic cursor to dvi position
- // em:linewidth <w> => set line width to <w>
- // em:point <n>[,<x>[,<y>]] => defines point <n> as (<x>,<y>); if <x> and/or <y> is missing,
- // the corresponding dvi cursor coordinate is inserted
- // <x> and <y> are lengths
- // em:line <n>[h|v|p], <m>[h|v|p] [,<w>] => draws line of width <w> from point #<n> to point #<m>
- // point number suffixes:
- // h: cut line horizontally
- // v: cut line vertically
- // p: cut line orthogonally to line direction (default)
- // if <w> is omitted, the global line width is used
- //
- // supported length units: pt, pc, in, bp, cm, mm, dd, cc, sp
- // default line width: 0.4pt
- struct Command {
- const char *name;
- void (EmSpecialHandler::*handler)(InputReader&, SpecialActions&);
- } commands[] = {
- {"point", &EmSpecialHandler::point},
- {"line", &EmSpecialHandler::line},
- {"moveto", &EmSpecialHandler::moveto},
- {"lineto", &EmSpecialHandler::lineto},
- {"linewidth", &EmSpecialHandler::linewidth},
- {nullptr, nullptr}
- };
-
- StreamInputReader ir(is);
- const string cmdstr = ir.getWord();
- for (Command *cmd=commands; cmd->name; cmd++) {
- if (cmdstr == cmd->name) {
- (this->*cmd->handler)(ir, actions);
- break;
- }
- }
- return true;
-}
-
-
-/** Handles the "moveto" command that sets the drawing position to the current DVI position. */
-void EmSpecialHandler::moveto (InputReader&, SpecialActions &actions) {
- _pos.x(actions.getX());
- _pos.y(actions.getY());
-}
-
-
-/** Handles the "lineto" command that sraws a straight line from the current drawing position
- * to the current DVI position, and sets the drawing position to the DVI position afterwards. */
-void EmSpecialHandler::lineto (InputReader&, SpecialActions &actions) {
- DPair currpos(actions.getX(), actions.getY());
- create_line(_pos, currpos, 'p', 'p', _linewidth, actions);
- _pos = currpos;
-}
-
-
-/** Handles the "linewidth" command that changes the line width which affects all following
- * drawing commands. */
-void EmSpecialHandler::linewidth (InputReader &ir, SpecialActions&) {
- _linewidth = read_length(ir);
-}
-
-
-/** Handles the "point" command that adds a point to the point list. */
-void EmSpecialHandler::point (InputReader &ir, SpecialActions &actions) {
- DPair pos(actions.getX(), actions.getY());
- int n = ir.getInt();
- if (ir.getPunct() == ',') {
- pos.x(ir.getDouble());
- if (ir.getPunct() == ',')
- pos.y(ir.getDouble());
- }
- _points[n] = pos;
-}
-
-
-/** Handles the "line" command that draws a straight line between two points
- * from the point list. */
-void EmSpecialHandler::line (InputReader &ir, SpecialActions& actions) {
- int pointnum1 = ir.getInt();
- int cut1 = 'p';
- if (isalpha(ir.peek()))
- cut1 = ir.get();
- ir.getPunct();
- int pointnum2 = ir.getInt();
- int cut2 = 'p';
- if (isalpha(ir.peek()))
- cut2 = ir.get();
- double linewidth = _linewidth;
- if (ir.getPunct() == ',')
- linewidth = read_length(ir);
- auto it1=_points.find(pointnum1);
- auto it2=_points.find(pointnum2);
- if (it1 != _points.end() && it2 != _points.end())
- create_line(it1->second, it2->second, char(cut1), char(cut2), linewidth, actions);
- else {
- // Line endpoints don't necessarily have to be defined before
- // a line definition. If a point isn't defined yet, we put the line
- // in a wait list and process the lines at the end of the page.
- _lines.emplace_back(Line(pointnum1, pointnum2, char(cut1), char(cut2), linewidth));
- }
-}
-
-
-/** This method is called at the end of a DVI page. Here we have to draw all pending
- * lines that are still in the line list. All line endpoints must be defined until here. */
-void EmSpecialHandler::dviEndPage (unsigned pageno, SpecialActions &actions) {
- for (const Line &line : _lines) {
- auto pit1=_points.find(line.p1);
- auto pit2=_points.find(line.p2);
- if (pit1 != _points.end() && pit2 != _points.end())
- create_line(pit1->second, pit2->second, line.c1, line.c2, line.width, actions);
- // all lines with still undefined points are ignored
- }
- // line and point definitions are local to a page
- _lines.clear();
- _points.clear();
-}
-
-
-vector<const char*> EmSpecialHandler::prefixes() const {
- vector<const char*> pfx {"em:"};
- return pfx;
-}