summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp')
-rw-r--r--Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp196
1 files changed, 0 insertions, 196 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp b/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp
deleted file mode 100644
index ce0a6d8d7ae..00000000000
--- a/Build/source/texk/dvisvgm/dvisvgm-src/src/optimizer/TransformSimplifier.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*************************************************************************
-** TransformSimplifier.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 <cmath>
-#include <cstdlib>
-#include "TransformSimplifier.hpp"
-#include "../Matrix.hpp"
-#include "../utility.hpp"
-#include "../XMLNode.hpp"
-#include "../XMLString.hpp"
-
-using namespace std;
-
-const char* TransformSimplifier::info () const {
- return "try to simplify and shorten the values of 'transform' attributes";
-}
-
-
-/** Tries to simplify the transform attributes of the context node and all its descendants. */
-void TransformSimplifier::execute (XMLElement *context) {
- if (!context)
- return;
- if (const char *transform = context->getAttributeValue("transform")) {
- Matrix matrix = Matrix::parseSVGTransform(transform);
- if (!incorporateTransform(context, matrix)) {
- string decomp = decompose(matrix);
- if (decomp.length() > matrix.toSVG().length())
- context->addAttribute("transform", matrix.toSVG());
- else {
- if (decomp.empty())
- context->removeAttribute("transform");
- else
- context->addAttribute("transform", decomp);
- }
- }
- }
- // continue with child elements
- for (XMLNode *child : *context) {
- if (XMLElement *elem = child->toElement())
- execute(elem);
- }
-}
-
-
-/** Tries to incorporate the translation and scaling components of the 'transform' attribute
- * of a given element into the positional and/or size attributes of that element. If successful,
- * the 'transform' attribute is either removed or simplified to a scale() matrix.
- * Currently, only 'image' and 'rect' elements are considered.
- * @param[in] elem element to check
- * @param[in] matrix matrix representing the 'transform' attribute of the element
- * @return true on success */
-bool TransformSimplifier::incorporateTransform (XMLElement *elem, const Matrix &matrix) {
- if ((elem->name() == "image" || elem->name() == "rect") && matrix.get(0, 1) == 0 && matrix.get(1, 0) == 0) {
- double tx = matrix.get(0, 2);
- double ty = matrix.get(1, 2);
- double sx = matrix.get(0, 0);
- double sy = matrix.get(1, 1);
- double x=0, y=0;
-
- if (const char *xstr = elem->getAttributeValue("x"))
- x = strtod(xstr, nullptr);
- if (const char *ystr = elem->getAttributeValue("y"))
- y = strtod(ystr, nullptr);
- // width and height attributes must not become negative. Hence, only apply the scaling
- // values if they are non-negative. Otherwise, keep a scaling matrix. Also retain scaling
- // transformations in image elements to avoid the need of attribute 'preseveAspectRatio'.
- if (sx < 0 || sy < 0 || elem->name() == "image") {
- x += (sx == 0 ? 0 : tx/sx);
- y += (sy == 0 ? 0 : ty/sy);
- elem->addAttribute("transform", "scale("+XMLString(sx)+","+XMLString(sy)+")");
- }
- else {
- x = x*sx + tx;
- y = y*sy + ty;
- if (const char *wstr = elem->getAttributeValue("width"))
- elem->addAttribute("width", sx*strtod(wstr, nullptr));
- if (const char *hstr = elem->getAttributeValue("height"))
- elem->addAttribute("height", sy*strtod(hstr, nullptr));
- elem->removeAttribute("transform");
- }
- elem->addAttribute("x", x); // update x attribute
- elem->addAttribute("y", y); // update y attribute
- return true;
- }
- return false;
-}
-
-
-static string translate_cmd (double dx, double dy) {
- string ret;
- XMLString dxstr(dx), dystr(dy);
- if (dxstr != "0" || dystr != "0") {
- ret = "translate("+dxstr;
- if (dystr != "0")
- ret += " "+dystr;
- ret += ')';
- }
- return ret;
-}
-
-
-static string scale_cmd (double sx, double sy) {
- string ret;
- XMLString sxstr(sx), systr(sy);
- if (sxstr != "1" || systr != "1") {
- ret = "scale("+sxstr;
- if (systr != sxstr)
- ret += " "+systr;
- ret += ')';
- }
- return ret;
-}
-
-
-static string rotate_cmd (double rad) {
- string ret;
- XMLString degstr(math::rad2deg(fmod(rad, math::TWO_PI)));
- if (degstr != "0")
- ret = "rotate("+degstr+")";
- return ret;
-}
-
-
-static string skewx_cmd (double rad) {
- string ret;
- XMLString degstr(math::rad2deg(fmod(rad, math::PI)));
- if (degstr != "0")
- ret = "skewX("+degstr+")";
- return ret;
-}
-
-
-static string skewy_cmd (double rad) {
- string ret;
- XMLString degstr(math::rad2deg(fmod(rad, math::PI)));
- if (degstr != "0")
- ret = "skewY("+degstr+")";
- return ret;
-}
-
-
-static bool not_equal (double x, double y) {
- return abs(x-y) >= 1e-6;
-}
-
-
-/** Decomposes a transformation matrix into a sequence of basic SVG transformations, i.e.
- * translation, rotation, scaling, and skewing. The algorithm (QR-based decomposition)
- * is taken from http://frederic-wang.fr/decomposition-of-2d-transform-matrices.html.
- * @param[in] matrix matrix to decompose
- * @return string containing the SVG transformation commands */
-string TransformSimplifier::decompose (const Matrix &matrix) {
- // transformation matrix [a b c d e f] according to
- // https://www.w3.org/TR/SVG11/coords.html#EstablishingANewUserSpace
- double a = matrix.get(0, 0);
- double b = matrix.get(1, 0);
- double c = matrix.get(0, 1);
- double d = matrix.get(1, 1);
- double e = matrix.get(0, 2);
- double f = matrix.get(1, 2);
- string ret = translate_cmd(e, f);
- double delta = a*d - b*c;
- if (not_equal(a, 0) || not_equal(b, 0)) {
- double r = sqrt(a*a + b*b);
- ret += rotate_cmd(b > 0 ? acos(a/r) : -acos(a/r));
- ret += scale_cmd(r, delta/r);
- ret += skewx_cmd(atan((a*c + b*d)/(r*r)));
- }
- else if (not_equal(c, 0) || not_equal(d, 0)) {
- double s = sqrt(c*c + d*d);
- ret += rotate_cmd(math::HALF_PI - (d > 0 ? acos(-c/s) : -acos(c/s)));
- ret += scale_cmd(delta/s, s);
- ret += skewy_cmd(atan((a*c + b*d)/(s*s)));
- }
- else
- ret += scale_cmd(0, 0);
- return ret;
-}
-