diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-0.8.7/src')
121 files changed, 17008 insertions, 0 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.cpp new file mode 100644 index 00000000000..2cd78531312 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.cpp @@ -0,0 +1,37 @@ +/************************************************************************* +** BgColorSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "BgColorSpecialHandler.h" +#include "ColorSpecialHandler.h" +#include "SpecialActions.h" + +using namespace std; + + +bool BgColorSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + ColorSpecialHandler csh; + return csh.process(prefix, is, actions); +} + + +const char** BgColorSpecialHandler::prefixes () const { + static const char *pfx[] = {"background", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.h new file mode 100644 index 00000000000..4c76c7f59ec --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BgColorSpecialHandler.h @@ -0,0 +1,34 @@ +/************************************************************************* +** BgColorSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef BGCOLORSPECIALHANDLER_H +#define BGCOLORSPECIALHANDLER_H + +#include "SpecialManager.h" + +struct BgColorSpecialHandler : SpecialHandler +{ + const char* info () const {return "background color special";} + const char* name () const {return "bgcolor";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.cpp new file mode 100644 index 00000000000..f6859e24083 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.cpp @@ -0,0 +1,123 @@ +/************************************************************************* +** Bitmap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <iostream> +#include "Bitmap.h" +#include "macros.h" + +using namespace std; + +Bitmap::Bitmap () : _rows(0), _cols(0), _xshift(0), _yshift(0), _bpr(0), _bytes(0) +{ +} + + +/** Constructs a Bitmap */ +Bitmap::Bitmap (int minx, int maxx, int miny , int maxy) { + resize(minx, maxx, miny, maxy); +} + + +/** Resizes the bitmap and clears all pixels. + * @param[in] minx index of leftmost pixel column + * @param[in] maxx index of rightmost pixel column + * @param[in] miny index of bottom row + * @param[in] maxy index of top row */ +void Bitmap::resize (int minx, int maxx, int miny , int maxy) { + _rows = abs(maxy-miny)+1; + _cols = abs(maxx-minx)+1; + _xshift = minx; + _yshift = miny; + _bpr = _cols/8 + (_cols % 8 ? 1 : 0); // bytes per row + _bytes.resize(_rows*_bpr); + FORALL(_bytes, vector<UInt8>::iterator, it) + *it = 0; +} + + +/** Sets n pixels of row r to 1 starting at pixel c. + * @param[in] r number of row + * @param[in] c number of column (pixel) + * @param[in] n number of bits to be set */ +void Bitmap::setBits (int r, int c, int n) { + r -= _yshift; + c -= _xshift; + UInt8 *byte = &_bytes[r*_bpr + c/8];// + (c%8 ? 1 : 0); + while (n > 0) { + int b = 7 - c%8; // number of leftmost bit in current byte to be set + int m = min(n, b+1); // number of bits to be set in current byte + Int16 bitseq = (1 << m)-1; // sequence of n set bits (bits 0..n-1 are set) + bitseq <<= b-m+1; // move bit sequence so that bit b is the leftmost set bit + *byte |= bitseq; // apply bit sequence to current byte + byte++; + n -= m; + c += m; + } +} + + +void Bitmap::forAllPixels (ForAllData &data) const { + for (int r=_rows-1; r >= 0 ; r--) { + for (int c=0; c < _bpr; c++) { + UInt8 byte = _bytes[r*_bpr+c]; + for (int b=7; b >= 0; b--) { + data.pixel(8*c+(7-b), r, byte & (1 << b), *this); + } + } + } +} + + +struct BBoxData : public Bitmap::ForAllData +{ + BBoxData () : maxx(0), maxy(0) {} + void pixel (int x, int y, bool set, const Bitmap &bm) { + if (set) { + maxx = max(maxx, x); + maxy = max(maxy, y); + } + } + int maxx, maxy; +}; + + +void Bitmap::bbox (int &w, int &h) const { + BBoxData data; + forAllPixels(data); + w = data.maxx+1; + h = data.maxy+1; +} + + +ostream& Bitmap::write (ostream &os) const { +#if 0 + for (int r=_rows-1; r >= 0 ; r--) { + for (int c=0; c < _bpr; c++) { + UInt8 byte = _bytes[r*_bpr+c]; + for (int b=128; b; b>>=1) + os << (byte & b ? '*' : '-'); + os << ' '; + } + os << endl; + } +#endif + return os; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.h new file mode 100644 index 00000000000..f67a017e1f4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Bitmap.h @@ -0,0 +1,109 @@ +/************************************************************************* +** Bitmap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef BITMAP_H +#define BITMAP_H + +#include <ostream> +#include <vector> +#include "types.h" + + +class Bitmap +{ + public: + struct ForAllData { + virtual ~ForAllData() {} + virtual void pixel (int x, int y, bool set, Bitmap &bm) {} + virtual void pixel (int x, int y, bool set, const Bitmap &bm) {} + }; + + public: + Bitmap (); + Bitmap (int minx, int maxx, int miny , int maxy); + void resize (int minx, int maxx, int miny , int maxy); + void setBits(int r, int c, int n); + const UInt8* operator[] (int r) const {return &_bytes[r*_bpr];} + int height () const {return _rows;} + int width () const {return _cols;} + int xshift () const {return _xshift;} + int yshift () const {return _yshift;} + int bytesPerRow () const {return _bpr;} + bool empty () const {return (!_rows && !_cols) || _bytes.empty();} + void bbox (int &w, int &h) const; + void forAllPixels (ForAllData &data) const; + + template <typename T> + int copy (std::vector<T> &target, bool vflip=false) const; + +// template <typename T> +// void write (std::ostream &os, const std::vector<T> &v) const; + + std::ostream& write (std::ostream &os) const; + + private: + int _rows, _cols; ///< number of rows, columns + int _xshift, _yshift; ///< horizontal/vertical shift + int _bpr; ///< number of bytes per row + std::vector<UInt8> _bytes; +}; + + +/** Copies the bitmap to a new target area and reorganize the bits. + * @param[out] target points to first T of new bitmap (must be deleted after usage) + * @param[in] vflip true if the new bitmap should be flipped vertically + * @return number of Ts per row */ +template <typename T> +int Bitmap::copy (std::vector<T> &target, bool vflip) const { + const int s = sizeof(T); + const int tpr = _bpr/s + (_bpr%s ? 1 : 0); // number of Ts per row + target.resize(_rows*tpr); + for (int r=0; r < _rows; r++) { + int targetrow = vflip ? _rows-r-1 : r; + for (int b=0; b < _bpr; b++) { + T &t = target[targetrow*tpr + b/s]; + T chunk = (T)_bytes[r*_bpr+b] << (8*(s-1-b%s)); + if (b % s == 0) + t = chunk; + else + t |= chunk; + } + } + return tpr; +} + + +/* +template <typename T> +void Bitmap::write (std::ostream &os, const std::vector<T> &v) const { + const int s = sizeof(T); + const int tpr = _bpr/s + (_bpr%s ? 1 : 0); // number of Ts per row + for (int r=_rows-1; r >= 0; r--) { + for (int t=0; t < tpr; t++) { + for (T b=(T)1<<(8*s-1); b; b>>=1) + os << ((v[r*tpr+t] & b) ? '*' : '-'); + os << ' '; + } + os << std::endl; + } +}*/ + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.cpp new file mode 100644 index 00000000000..73afd92a016 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.cpp @@ -0,0 +1,189 @@ +/************************************************************************* +** BoundingBox.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <algorithm> +#include <sstream> +#include <string> +#include "BoundingBox.h" +#include "Matrix.h" + +using namespace std; + + +BoundingBox::BoundingBox () + : ulx(0), uly(0), lrx(0), lry(0), _valid(false), _locked(false) +{ +} + + +BoundingBox::BoundingBox (double ulxx, double ulyy, double lrxx, double lryy) + : ulx(min(ulxx,lrxx)), uly(min(ulyy,lryy)), + lrx(max(ulxx,lrxx)), lry(max(ulyy,lryy)), + _valid(true), _locked(false) +{ +} + + +BoundingBox::BoundingBox (const DPair &p1, const DPair &p2) + : ulx(min(p1.x(), p2.x())), uly(min(p1.y(), p2.y())), + lrx(max(p1.x(), p2.x())), lry(max(p1.y(), p2.y())), + _valid(true), _locked(false) +{ +} + + +BoundingBox::BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy) + : ulx(min(ulxx.pt(),lrxx.pt())), uly(min(ulyy.pt(),lryy.pt())), + lrx(max(ulxx.pt(),lrxx.pt())), lry(max(ulyy.pt(),lryy.pt())), + _valid(true), _locked(false) +{ +} + + +void BoundingBox::set (const string &boxstr) { + Length coord[4]; + const size_t len = boxstr.length(); + size_t l=0; + for (int i=0; i < 4; i++) { + while (l < len && isspace(boxstr[l])) + l++; + size_t r=l; + while (r < len && !isspace(boxstr[r]) && boxstr[r] != ',') + r++; + string lenstr = boxstr.substr(l, r-l); + coord[i].set(lenstr); + if (boxstr[r] == ',') + r++; + l = r; + if ((l == len && i < 3) || lenstr.empty()) + throw BoundingBoxException("four length parameters expected"); + } + ulx = min(coord[0].pt(), coord[2].pt()); + uly = min(coord[1].pt(), coord[3].pt()); + lrx = max(coord[0].pt(), coord[2].pt()); + lry = max(coord[1].pt(), coord[3].pt()); +} + + +/** Enlarges the box so that point (x,y) is enclosed. */ +void BoundingBox::embed (double x, double y) { + if (!_locked) { + if (_valid) { + if (x < ulx) + ulx = x; + else if (x > lrx) + lrx = x; + if (y < uly) + uly = y; + else if (y > lry) + lry = y; + } + else { + ulx = lrx = x; + uly = lry = y; + _valid = true; + } + } +} + + +/** Enlarges the box so that box bb is enclosed. */ +void BoundingBox::embed (const BoundingBox &bb) { + if (!_locked && bb._valid) { + if (_valid) { + embed(bb.ulx, bb.uly); + embed(bb.lrx, bb.lry); + } + else { + ulx = bb.ulx; + uly = bb.uly; + lrx = bb.lrx; + lry = bb.lry; + _valid = true; + } + } +} + + +void BoundingBox::embed (const DPair &c, double r) { + embed(BoundingBox(c.x()-r, c.y()-r, c.x()+r, c.y()+r)); +} + + +void BoundingBox::expand (double m) { + if (!_locked) { + ulx -= m; + uly -= m; + lrx += m; + lry += m; + } +} + + +/** Intersects the current box with bbox and applies the result to *this. + * If both boxes are disjoint, *this is not altered. + * @param[in] bbox box to intersect with + * @return false if *this is locked or both boxes are disjoint */ +bool BoundingBox::intersect (const BoundingBox &bbox) { + if (_locked || lrx < bbox.ulx || lry < bbox.uly || ulx > bbox.lrx || uly > bbox.lry) + return false; + ulx = max(ulx, bbox.ulx); + uly = max(uly, bbox.uly); + lrx = min(lrx, bbox.lrx); + lry = min(lry, bbox.lry); + return true; +} + + +void BoundingBox::operator += (const BoundingBox &bb) { + if (!_locked) { + ulx += bb.ulx; + uly += bb.uly; + lrx += bb.lrx; + lry += bb.lry; + } +} + + +void BoundingBox::transform (const Matrix &tm) { + if (!_locked) { + DPair ul = tm * DPair(lrx, lry); + DPair lr = tm * DPair(ulx, uly); + DPair ll = tm * DPair(ulx, lry); + DPair ur = tm * DPair(lrx, uly); + ulx = min(min(ul.x(), lr.x()), min(ur.x(), ll.x())); + uly = min(min(ul.y(), lr.y()), min(ur.y(), ll.y())); + lrx = max(max(ul.x(), lr.x()), max(ur.x(), ll.x())); + lry = max(max(ul.y(), lr.y()), max(ur.y(), ll.y())); + } +} + + +string BoundingBox::toSVGViewBox () const { + ostringstream oss; + oss << ulx << ' ' << uly << ' ' << width() << ' ' << height(); + return oss.str(); +} + + +ostream& BoundingBox::write (ostream &os) const { + return os << '(' << ulx << ", " << uly + << ", " << lrx << ", " << lry << ')'; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.h new file mode 100644 index 00000000000..82dc527d163 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/BoundingBox.h @@ -0,0 +1,79 @@ +/************************************************************************* +** BoundingBox.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef BOUNDINGBOX_H +#define BOUNDINGBOX_H + +#include <ostream> +#include <string> +#include "Length.h" +#include "MessageException.h" +#include "Pair.h" +#include "macros.h" +#include "types.h" + + +class Matrix; + + +struct BoundingBoxException : MessageException +{ + BoundingBoxException (const string &msg) : MessageException(msg) {} +}; + + +class BoundingBox +{ + public: + BoundingBox (); + BoundingBox (double ulxx, double ulyy, double lrxx, double lryy); + BoundingBox (const DPair &p1, const DPair &p2); + BoundingBox (const Length &ulxx, const Length &ulyy, const Length &lrxx, const Length &lryy); + BoundingBox (const string &boxstr) {set(boxstr);} + void set (const string &boxstr); + void embed (double x, double y); + void embed (const BoundingBox &bb); + void embed (const DPair &p) {embed(p.x(), p.y());} + void embed (const DPair &c, double r); + void expand (double m); + bool intersect (const BoundingBox &bbox); + double minX () const {return ulx;} + double minY () const {return uly;} + double maxX () const {return lrx;} + double maxY () const {return lry;} + double width () const {return lrx-ulx;} + double height () const {return lry-uly;} + void lock () {_locked = true;} + void unlock () {_locked = false;} + void operator += (const BoundingBox &bb); + void transform (const Matrix &tm); + std::string toSVGViewBox () const; + std::ostream& write (std::ostream &os) const; + + private: + double ulx, uly; ///< coordinates of upper left vertex (in TeX point units) + double lrx, lry; ///< coordinates of lower right vertex (in TeX point unitx) + bool _valid : 1; ///< true if the box coordinates are properly set + bool _locked : 1; ///< if true, the box data is read-only +}; + +IMPLEMENT_OUTPUT_OPERATOR(BoundingBox) + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.cpp new file mode 100644 index 00000000000..6d9b603bee6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.cpp @@ -0,0 +1,178 @@ +/************************************************************************* +** Calculator.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <sstream> +#include "Calculator.h" + +using namespace std; + +// token types +const char END = 0; +const char NUMBER = 1; +const char NAME = 2; + + +#include <iostream> + + +/** Evaluates a given arithmetic expressions and returns its value. + * The evaluator is implemented as a recursive descendent parser. + * @param[in] is reads expression from this stream + * @return expression value */ +double Calculator::eval (istream &is) { + double ret = expr(is, false); + if (lookAhead(is) > 0) + throw CalculatorException("expression syntax error"); + return ret; +} + + +/** Evaluates a given arithmetic expressions and returns its value. + * @param[in] expr expression to evaluate + * @return expression value */ +double Calculator::eval (const string &expr) { + istringstream iss; + iss.str(expr); + return eval(iss); +} + + +/** Evaluates the root rule of the expression grammar. */ +double Calculator::expr (istream &is, bool skip) { // expr: + double left = term(is, skip); + while (1) + switch (lookAhead(is)) { + case '+': left += term(is, true); break; // term '+' term => $1 + $3 + case '-': left -= term(is, true); break; // term '-' term => $1 - $3 + default : return left; // term => $1 + } +} + + +double Calculator::term (istream &is, bool skip) { // term: + double left = prim(is, skip); + while (1) + switch (lookAhead(is)) { + case '*': left *= prim(is, true); break; // prim '*' prim => $1 * $3 + case '/': { // prim '/' prim => $1 / $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left /= denom; + break; + } + case '%': { // prim '%' prim => $1 mod $3 + double denom = prim(is, true); + if (denom == 0) + throw CalculatorException("division by zero"); + left -= denom*floor(left/denom); + break; + } + default: // prim => $1 + return left; + } +} + + +double Calculator::prim (istream &is, bool skip) { // prim: + if (skip) + lex(is); + switch (lookAhead(is)) { + case NUMBER: { // NUMBER => $1 + lex(is); + double ret = numValue; + if (lookAhead(is) == NAME) { // NUMBER NAME => $1 * $2 + lex(is); + ret *= getVariable(strValue); + } + return ret; + } + case NAME: { // NAME => getVariable($1) + lex(is); + return getVariable(strValue); + } + case '-': // '-' prim => -$2 + return -prim(is, true); + case '(': { // '(' expr ')' => $2 + double e = expr(is, true); + if (lookAhead(is) != ')') + throw CalculatorException("')' expected"); + lex(is); + return e; + } + default: + throw CalculatorException("primary expression expected"); + } +} + + +/** Determines type of next token without swallowing it. That means + * the same token will be read again next time. */ +char Calculator::lookAhead (istream &is) { + while (isspace(is.peek())) // skip whitespace + is.get(); + if (is.eof()) + return END; + char c = is.peek(); + if (isdigit(c) || c == '.') + return NUMBER; + if (isalpha(c)) + return NAME; + return c; +} + + +/** Reads next token and returns its type. The token value is either assigned + * to the object members numValue or strValue depending on the type. The token + * type is represented by a unique integer. In contrast to method 'lookAhead' + * lex consumes the read token. + * @param[in] is next token is read from this stream + * @return token type */ +char Calculator::lex (istream &is) { + char tokenType = lookAhead(is); + switch (tokenType) { + case NUMBER: + is >> numValue; + break; + case NAME: { + strValue.clear(); + while (isalpha(is.peek())) + strValue += char(is.get()); + break; + } + default: + tokenType = is.get(); + } + return tokenType; +} + + +/** Returns the value of a previously defined variable. If there + * is no variable of the given name, a CalculatorException is thrown. + * @param[in] name name of variable + * @return assigned value */ +double Calculator::getVariable (const string &name) const { + map<string,double>::const_iterator it = variables.find(name); + if (it == variables.end()) + throw CalculatorException("undefined variable '" + name + "'"); + return it->second; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.h new file mode 100644 index 00000000000..a8673a99c1f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Calculator.h @@ -0,0 +1,59 @@ +/************************************************************************* +** Calculator.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef CALCULATOR_H +#define CALCULATOR_H + +#include <istream> +#include <map> +#include <string> +#include "MessageException.h" + +using std::istream; +using std::map; +using std::string; + +struct CalculatorException : public MessageException +{ + CalculatorException (const string &msg) : MessageException(msg) {} +}; + +class Calculator +{ + public: + double eval (istream &is); + double eval (const string &expr); + void setVariable (const string &name, double value) {variables[name] = value;} + double getVariable (const string &name) const; + + protected: + double expr (istream &is, bool skip); + double term (istream &is, bool skip); + double prim (istream &is, bool skip); + char lex (istream &is); + char lookAhead (istream &is); + + private: + map<string,double> variables; + double numValue; + string strValue; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.cpp new file mode 100644 index 00000000000..54875d928a5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.cpp @@ -0,0 +1,87 @@ +/************************************************************************* +** CharmapTranslator.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <fstream> +#include "CharmapTranslator.h" +#include "Font.h" +#include "FontEngine.h" +#include "FileFinder.h" +#include "macros.h" + +using namespace std; + +/** Returns true if 'unicode' is a valid unicode value in XML documents. + * XML version 1.0 doesn't allow various unicode character references + * ( for example). */ +static bool valid_unicode (UInt32 unicode) { + UInt32 ranges[] = { + 0x0000, 0x0020, + 0x007f, 0x0084, + 0x0086, 0x009f, + 0xfdd0, 0xfddf + }; + for (int i=0; i < 4; i++) + if (unicode >= ranges[2*i] && unicode <= ranges[2*i+1]) + return false; + return true; +} + + +CharmapTranslator::CharmapTranslator (const Font *font) { + setFont(font); +} + + +CharmapTranslator::CharmapTranslator (const FontEngine &fe) { + fe.buildTranslationMap(translationMap); +} + + +void CharmapTranslator::setFont (const Font *font) { + translationMap.clear(); + + const PhysicalFont *pf = dynamic_cast<const PhysicalFont*>(font); + if (pf && pf->type() != PhysicalFont::MF) { + const char *path = font->path(); + FontEngine fe; + if (fe.setFont(path)) + fe.buildTranslationMap(translationMap); + } +} + + +UInt32 CharmapTranslator::unicode (UInt32 customCode) const { + ConstIterator it = translationMap.find(customCode); + if (it != translationMap.end()) + return it->second; + + // No unicode equivalent found in font file. + // Now we should look for a smart alternative but at the moment + // it's sufficient to simply choose a valid unused unicode value... + map<UInt32,UInt32> reverseMap; + FORALL(translationMap, ConstIterator, i) + reverseMap[i->second] = i->first; + // can we use charcode itself as unicode replacement? + if (valid_unicode(customCode) && (reverseMap.empty() || reverseMap.find(customCode) != reverseMap.end())) + return customCode; + // @@ this should be optimized :-) + return 0x3400+customCode; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.h new file mode 100644 index 00000000000..99cbfdeb702 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CharmapTranslator.h @@ -0,0 +1,50 @@ +/************************************************************************* +** CharmapTranslator.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef CHARMAPTRANSLATOR_H +#define CHARMAPTRANSLATOR_H + +#include <map> +#include <string> +#include "types.h" + +using std::map; +using std::string; + +class FileFinder; +class Font; +class FontEngine; + +class CharmapTranslator +{ + typedef map<UInt32,UInt32>::iterator Iterator; + typedef map<UInt32,UInt32>::const_iterator ConstIterator; + public: + CharmapTranslator () {} + CharmapTranslator (const Font *font); + CharmapTranslator (const FontEngine &fe); + void setFont (const Font *font); + UInt32 unicode (UInt32 customCode) const; + + private: + map<UInt32,UInt32> translationMap; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.cpp new file mode 100644 index 00000000000..c1020748c4b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.cpp @@ -0,0 +1,269 @@ +/************************************************************************* +** CmdLineParserBase.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include <iostream> +#include "CmdLineParserBase.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "Message.h" + +using namespace std; + +void CmdLineParserBase::init () { + _error = false; + _files.clear(); +} + +/** Parses all options given on the command line. + * @param[in] printErrors enable/disable printing of error messages */ +void CmdLineParserBase::parse (int argc, char **argv, bool printErrors) { + init(); + _printErrors = printErrors; + bool filesOnly = false; // + for (int i=1; i < argc; i++) { + CharInputBuffer ib(argv[i], strlen(argv[i])); + BufferInputReader ir(ib); + if (filesOnly || ir.peek() != '-') + _files.push_back(argv[i]); + else { + ir.get(); + if (ir.peek() == '-') { + // scan long option + ir.get(); + if (ir.eof()) // "--" only + filesOnly = true; // treat all following options as filenames + else { + string longname; + while (isalnum(ir.peek()) || ir.peek() == '-') + longname += ir.get(); + if (const Option *opt = option(longname)) + (*opt->handler)(this, ir, *opt, true); + else if (!_error) { + if (printErrors) + Message::estream(false) << "unknown option --" << longname << endl; + _error = true; + } + } + } + else { + // scan short option(s) + bool combined = false; // multiple short options combined, e.g -abc + do { + int shortname = ir.get(); + if (const Option *opt = option(shortname)) { + if (!combined || opt->argmode == 0) { + if (opt->argmode == 'r' && strlen(argv[i]) == 2) { // required argument separated by whitespace? + if (i+1 < argc && argv[i+1][0] != '-') + ib.assign(argv[++i]); + } + (*opt->handler)(this, ir, *opt, false); + if (opt->argmode == 0) + combined = true; + } + else { + if (printErrors) + Message::estream(false) << "option -" << char(shortname) << " must be given separately\n"; + _error = true; + } + } + else if (shortname > 0) { + if (printErrors) + Message::estream(false) << "unknown option -" << shortname << endl; + _error = true; + } + } + while (!_error && combined && !ir.eof()); + } + } + } +} + + +/** Prints an error message to stdout. + * @param[in] opt error occurred in this option + * @param[in] longopt the long option name was scanned + * @param[in] msg message to be printed */ +void CmdLineParserBase::error (const Option &opt, bool longopt, const char *msg) const { + if (_printErrors) { + Message::estream(false) << "option "; + if (longopt) + Message::estream(false) << "--" << opt.longname; + else + Message::estream(false) << '-' << opt.shortname; + Message::estream(false) << ": " << msg << endl; + } + _error = true; +} + + +/** Lists the scanned filenames. Just for debugging purposes. */ +void CmdLineParserBase::status () const { + cout << "file names:\n"; + for (size_t i=0; i < _files.size(); i++) + cout << " " << _files[i] << endl; + cout << endl; +} + + +/** Returns the option information of a given short option name. + * If the option name can't be found 0 is returned. + * @param[in] longname long version of the option without leading hyphen (e.g. p, not -p) */ +const CmdLineParserBase::Option* CmdLineParserBase::option (char shortname) const { + const Option *opts = options(); + for (int i=0; i < numOptions(); i++) + if (opts[i].shortname == shortname) + return &opts[i]; + return 0; +} + + +/** Returns the option information of a given long option name. + * Parameter 'longname' hasn't to be the complete long option name. The function looks up + * all options that start with 'longname'. If a unique or an exact match was found, it's returned. + * Otherwise, the return value is 0. + * @param[in] longname long version of the option without leading hyphens (e.g. param, not --param) */ +const CmdLineParserBase::Option* CmdLineParserBase::option (const string &longname) const { + const Option *opts = options(); + vector<const Option*> matches; // all matching options + size_t len = longname.length(); + for (int i=0; i < numOptions(); i++) { + if (string(opts[i].longname, len) == longname) { + if (len == strlen(opts[i].longname)) // exact match? + return &opts[i]; + matches.push_back(&opts[i]); + } + } + switch (matches.size()) { + default: + if (_printErrors) { + Message::estream(false) << "option --" << longname << " is ambiguous ("; + for (size_t i=0; i < matches.size(); i++) { + if (i > 0) + Message::estream(false) << ", "; + Message::estream(false) << matches[i]->longname; + } + Message::estream(false) << ")\n"; + } + _error = true; + + case 0 : return 0; + case 1 : return matches[0]; + } +} + + +/** Returns true if a valid separator between option and argument was found. + * Arguments of long options are preceded by a '='. The argument of a short option + * directly follows the option without a separation character. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given */ +bool CmdLineParserBase::checkArgPrefix (InputReader &ir, const Option &opt, bool longopt) const { + if (longopt) { + if (ir.peek() == '=') + ir.get(); + else { + error(opt, longopt, "'=' expected"); + return false; + } + } + return true; +} + + +/** Returns true if a given option has no argument, .e.g. -p or --param. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given */ +bool CmdLineParserBase::checkNoArg (InputReader &ir, const Option &opt, bool longopt) const { + if (ir.eof()) + return true; + error(opt, longopt, "no argument expected"); + return false; +} + + +/** Gets an integer argument of a given option, e.g. -p5 or --param=5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getIntArg (InputReader &ir, const Option &opt, bool longopt, int &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseInt(arg) && ir.eof()) + return true; + error(opt, longopt, "integer value expected"); + } + return false; +} + + +/** Gets an unsigned integer argument of a given option, e.g. -p5 or --param=5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getUIntArg (InputReader &ir, const Option &opt, bool longopt, unsigned &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseUInt(arg) && ir.eof()) + return true; + error(opt, longopt, "unsigned integer value expected"); + } + return false; +} + + +/** Gets a double (floating point) argument of a given option, e.g. -p=2.5 or --param=2.5. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getDoubleArg (InputReader &ir, const Option &opt, bool longopt, double &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + if (ir.parseDouble(arg) != 0 && ir.eof()) + return true; + error(opt, longopt, "floating point value expected"); + } + return false; +} + + +/** Gets a string argument of a given option, e.g. -pstr or --param=str. + * @param[in] ir argument is read from this InputReader + * @param[in] opt scans argument of this option + * @param[in] longopt true if the long option name was given + * @param[out] arg the scanned option argument + * @return true if argument could be scanned without errors */ +bool CmdLineParserBase::getStringArg (InputReader &ir, const Option &opt, bool longopt, string &arg) const { + if (checkArgPrefix(ir, opt, longopt)) { + arg.clear(); + while (!ir.eof()) + arg += ir.get(); + if (!arg.empty()) + return true; + error(opt, longopt, "string argument expected"); + } + return false; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.h new file mode 100644 index 00000000000..24aaffbc132 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CmdLineParserBase.h @@ -0,0 +1,93 @@ +/************************************************************************* +** CmdLineParserBase.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef CMDLINEPARSERBASE_H +#define CMDLINEPARSERBASE_H + +#include <string> +#include <vector> + +class InputReader; + +class CmdLineParserBase +{ + protected: + struct Option; + + struct OptionHandler { + virtual void operator () (CmdLineParserBase *obj, InputReader &ir, const Option &opt, bool longopt) const=0; + }; + + template <typename T> + class OptionHandlerImpl : public OptionHandler { + protected: + typedef void (T::*LocalHandler)(InputReader &ir, const Option &opt, bool longopt); + + public: + OptionHandlerImpl (LocalHandler handler) : _handler(handler) {} + + void operator () (CmdLineParserBase *obj, InputReader &ir, const Option &opt, bool longopt) const { + if (T *tobj = dynamic_cast<T*>(obj)) + (tobj->*_handler)(ir, opt, longopt); + } + + private: + LocalHandler _handler; + }; + + struct Option { + ~Option () {delete handler;} + char shortname; + const char *longname; + char argmode; // mode of option argument: '\0'=none, 'o'=optional, 'r'=required + const OptionHandler *handler; + }; + + public: + virtual void parse (int argc, char **argv, bool printErrors=true); + virtual void help () const {} + virtual int numOptions () const {return 0;} + virtual int numFiles () const {return _files.size();} + virtual const char* file (size_t n) {return (n >= 0 && n < _files.size()) ? _files[n].c_str() : 0;} + virtual void status () const; + virtual bool error () const {return _error;} + + protected: + CmdLineParserBase () : _error(false) {} + CmdLineParserBase (const CmdLineParserBase &cmd) {} + virtual void init (); + virtual void error (const Option &opt, bool longopt, const char *msg) const; + bool checkArgPrefix (InputReader &ir, const Option &opt, bool longopt) const; + bool checkNoArg (InputReader &ir, const Option &opt, bool longopt) const; + bool getIntArg (InputReader &ir, const Option &opt, bool longopt, int &arg) const; + bool getUIntArg (InputReader &ir, const Option &opt, bool longopt, unsigned &arg) const; + bool getDoubleArg (InputReader &ir, const Option &opt, bool longopt, double &arg) const; + bool getStringArg (InputReader &ir, const Option &opt, bool longopt, std::string &arg) const; + const Option* option (char shortname) const; + const Option* option (const std::string &longname) const; + virtual const Option* options () const {return 0;} + + private: + bool _printErrors; ///< if true, print error messages + mutable bool _error; ///< error occured while parsing options + std::vector<std::string> _files; ///< filename parameters +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.cpp new file mode 100644 index 00000000000..7a85eadd79b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.cpp @@ -0,0 +1,126 @@ +/************************************************************************* +** Color.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iomanip> +#include <sstream> +#include "Color.h" + +using namespace std; + + + +const Color Color::BLACK(0); +const Color Color::WHITE(UInt8(255), UInt8(255), UInt8(255)); + + +static inline UInt8 float_to_byte (float v) { + return floor(255*v+0.5); +} + + +void Color::set (float r, float g, float b) { + set(float_to_byte(r), float_to_byte(g), float_to_byte(b)); +} + + +void Color::setHSB (float h, float s, float b) { + vector<float> hsb(3), rgb(3); + hsb[0] = h; + hsb[1] = s; + hsb[2] = b; + HSB2RGB(hsb, rgb); + set(rgb[0], rgb[1], rgb[2]); +} + + +void Color::setCMYK (float c, float m, float y, float k) { + vector<float> cmyk(4), rgb(3); + cmyk[0] = c; + cmyk[1] = m; + cmyk[2] = y; + cmyk[3] = k; + CMYK2RGB(cmyk, rgb); + set(rgb[0], rgb[1], rgb[2]); +} + + +void Color::operator *= (double c) { + UInt32 rgb=0; + for (int i=0; i < 3; i++) { + rgb |= UInt32(floor((_rgb & 0xff)*c+0.5)) << (8*i); + _rgb >>= 8; + } + _rgb = rgb; +} + + +string Color::rgbString () const { + ostringstream oss; + oss << '#'; + for (int i=2; i >= 0; i--) { + oss << setbase(16) << setfill('0') << setw(2) + << (((_rgb >> (8*i)) & 0xff)); + } + return oss.str(); +} + + +/** Approximates a CMYK color by an RGB triple. The component values + * are expected to be normalized, i.e. 0 <= cmyk[i],rgb[j] <= 1. + * @param[in] cmyk color in CMYK space + * @param[out] rgb RGB approximation */ +void Color::CMYK2RGB (const vector<float> &cmyk, vector<float> &rgb) { + for (int i=0; i < 3; i++) + rgb[i] = 1.0-min(1.0f, cmyk[i]+cmyk[3]); +} + + +/** Converts a color given in HSB coordinates to RGB. + * @param[in] hsb color in HSB space + * @param[out] rgb color in RGB space */ +void Color::HSB2RGB (const vector<float> &hsb, vector<float> &rgb) { + if (hsb[1] == 0) + rgb[0] = rgb[1] = rgb[2] = hsb[2]; + else { + float h = hsb[0]-floor(hsb[0]); + int i = 6*h; + float f = 6*h-i; + float p = hsb[2]*(1-hsb[1]); + float q = hsb[2]*(1-hsb[1]*f); + float t = hsb[2]*(1-hsb[1]*(1-f)); + switch (i) { + case 0 : rgb[0]=hsb[2]; rgb[1]=t; rgb[2]=p; break; + case 1 : rgb[0]=q; rgb[1]=hsb[2]; rgb[2]=p; break; + case 2 : rgb[0]=p; rgb[1]=hsb[2]; rgb[2]=t; break; + case 3 : rgb[0]=p; rgb[1]=q; rgb[2]=hsb[2]; break; + case 4 : rgb[0]=t; rgb[1]=p; rgb[2]=hsb[2]; break; + case 5 : rgb[0]=hsb[2]; rgb[1]=p; rgb[2]=q; break; + default: ; // prevent compiler warning + } + } +} + + +void Color::getRGB (float &r, float &g, float &b) const { + r = ((_rgb >> 16) & 255) / 255.0; + g = ((_rgb >> 8) & 255) / 255.0; + b = (_rgb & 255) / 255.0; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.h new file mode 100644 index 00000000000..51f8733c58b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Color.h @@ -0,0 +1,59 @@ +/************************************************************************* +** Color.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef COLOR_H +#define COLOR_H + +#include <string> +#include <vector> +#include "types.h" + +class Color +{ + public: + static const Color BLACK; + static const Color WHITE; + + public: + Color () : _rgb(0) {} + Color (UInt32 rgb) : _rgb(rgb) {} + Color (UInt8 r, UInt8 g, UInt8 b) {set(r,g,b);} + Color (float r, float g, float b) {set(r,g,b);} + Color (const std::vector<float> &rgb) {set(rgb[0], rgb[1], rgb[2]);} + operator UInt32 () const {return _rgb;} + bool operator == (const Color &c) {return _rgb == c._rgb;} + bool operator != (const Color &c) {return _rgb != c._rgb;} + void set (UInt8 r, UInt8 g, UInt8 b) {_rgb = (r << 16) | (g << 8) | b;} + void set (float r, float g, float b); + void setGray (UInt8 g) {set(g,g,g);} + void setGray (float g) {set(g,g,g);} + void setHSB (float h, float s, float b); + void setCMYK (float c, float m, float y, float k); + void getRGB (float &r, float &g, float &b) const; + void operator *= (double c); + std::string rgbString () const; + static void CMYK2RGB (const std::vector<float> &cmyk, std::vector<float> &rgb); + static void HSB2RGB (const std::vector<float> &hsb, std::vector<float> &rgb); + + private: + UInt32 _rgb; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.cpp new file mode 100644 index 00000000000..99a25820092 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.cpp @@ -0,0 +1,269 @@ +/************************************************************************* +** ColorSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <algorithm> +#include <cmath> +#include <cstring> +#include <iomanip> +#include <sstream> +#include <vector> +#include "ColorSpecialHandler.h" +#include "SpecialActions.h" + +using namespace std; + + + +/** Approximates a CMYK color by an RGB triple. The component values + * are expected to be normalized, i.e. 0 <= cmyk[i],rgb[j] <= 1. + * @param[in] cmyk color in CMYK space + * @param[out] rgb RGB approximation */ +static void cmyk_to_rgb (const vector<float> &cmyk, vector<float> &rgb) { + for (int i=0; i < 3; i++) + rgb[i] = 1.0-min(1.0f, cmyk[i]+cmyk[3]); +} + + +/** Converts a color given in HSB coordinates to RGB. + * @param[in] hsb color in HSB space + * @param[out] rgb color in RGB space */ +static void hsb_to_rgb (const vector<float> &hsb, vector<float> &rgb) { + if (hsb[1] == 0) + rgb[0] = rgb[1] = rgb[2] = hsb[2]; + else { + float h = hsb[0]-floor(hsb[0]); + int i = 6*h; + float f = 6*h-i; + float p = hsb[2]*(1-hsb[1]); + float q = hsb[2]*(1-hsb[1]*f); + float t = hsb[2]*(1-hsb[1]*(1-f)); + switch (i) { + case 0 : rgb[0]=hsb[2]; rgb[1]=t; rgb[2]=p; break; + case 1 : rgb[0]=q; rgb[1]=hsb[2]; rgb[2]=p; break; + case 2 : rgb[0]=p; rgb[1]=hsb[2]; rgb[2]=t; break; + case 3 : rgb[0]=p; rgb[1]=q; rgb[2]=hsb[2]; break; + case 4 : rgb[0]=t; rgb[1]=p; rgb[2]=hsb[2]; break; + case 5 : rgb[0]=hsb[2]; rgb[1]=p; rgb[2]=q; break; + default: ; // prevent compiler warning + } + } +} + + +/** Converts a gray value to RGB. + * @param[in] gray normalized gray value (0 <= gray <= 1) + * @param[out] rgb resulting RGB triple */ +static void gray_to_rgb (const float gray, vector<float> &rgb) { + for (int i=0; i < 3; i++) + rgb[i] = gray; +} + + +static float read_float (istream &is) { + is.clear(); + float v; + is >> v; + if (is.fail()) + throw SpecialException("number expected"); + return v; +} + + +/** Reads multiple float values from a given stream. The number of + * values read is determined by the size of the result vector. + * @param[in] is stream to be read from + * @param[out] v the resulting floats */ +static void read_floats (istream &is, vector<float> &v) { + for (size_t i=0; i < v.size(); i++) + v[i] = read_float(is); +} + + +static bool color_constant (const string &c, vector<float> &rgb) { + // converted color constants from color.pro + const struct { + const char *name; + const float rgb[3]; + } + constants[] = { + {"Apricot", {1, 0.68, 0.48}}, + {"Aquamarine", {0.18, 1, 0.7}}, + {"Bittersweet", {0.76, 0.01, 0}}, + {"Black", {0, 0, 0}}, + {"Blue", {0, 0, 1}}, + {"BlueGreen", {0.15, 1, 0.67}}, + {"BlueViolet", {0.1, 0.05, 0.96}}, + {"BrickRed", {0.72, 0, 0}}, + {"Brown", {0.4, 0, 0}}, + {"BurntOrange", {1, 0.49, 0}}, + {"CadetBlue", {0.38, 0.43, 0.77}}, + {"CarnationPink", {1, 0.37, 1}}, + {"Cerulean", {0.06, 0.89, 1}}, + {"CornflowerBlue", {0.35, 0.87, 1}}, + {"Cyan", {0, 1, 1}}, + {"Dandelion", {1, 0.71, 0.16}}, + {"DarkOrchid", {0.6, 0.2, 0.8}}, + {"Emerald", {0, 1, 0.5}}, + {"ForestGreen", {0, 0.88, 0}}, + {"Fuchsia", {0.45, 0.01, 0.92}}, + {"Goldenrod", {1, 0.9, 0.16}}, + {"Gray", {0.5, 0.5, 0.5}}, + {"Green", {0, 1, 0}}, + {"GreenYellow", {0.85, 1, 0.31}}, + {"JungleGreen", {0.01, 1, 0.48}}, + {"Lavender", {1, 0.52, 1}}, + {"LimeGreen", {0.5, 1, 0}}, + {"Magenta", {1, 0, 1}}, + {"Mahogany", {0.65, 0, 0}}, + {"Maroon", {0.68, 0, 0}}, + {"Melon", {1, 0.54, 0.5}}, + {"MidnightBlue", {0, 0.44, 0.57}}, + {"Mulberry", {0.64, 0.08, 0.98}}, + {"NavyBlue", {0.06, 0.46, 1}}, + {"OliveGreen", {0, 0.6, 0}}, + {"Orange", {1, 0.39, 0.13}}, + {"OrangeRed", {1, 0, 0.5}}, + {"Orchid", {0.68, 0.36, 1}}, + {"Peach", {1, 0.5, 0.3}}, + {"Periwinkle", {0.43, 0.45, 1}}, + {"PineGreen", {0, 0.75, 0.16}}, + {"Plum", {0.5, 0, 1}}, + {"ProcessBlue", {0.04, 1, 1}}, + {"Purple", {0.55, 0.14, 1}}, + {"RawSienna", {0.55, 0, 0}}, + {"Red", {1, 0, 0}}, + {"RedOrange", {1, 0.23, 0.13}}, + {"RedViolet", {0.59, 0, 0.66}}, + {"Rhodamine", {1, 0.18, 1}}, + {"RoyalBlue", {0, 0.5, 1}}, + {"RoyalPurple", {0.25, 0.1, 1}}, + {"RubineRed", {1, 0, 0.87}}, + {"Salmon", {1, 0.47, 0.62}}, + {"SeaGreen", {0.31, 1, 0.5}}, + {"Sepia", {0.3, 0, 0}}, + {"SkyBlue", {0.38, 1, 0.88}}, + {"SpringGreen", {0.74, 1, 0.24}}, + {"Tan", {0.86, 0.58, 0.44}}, + {"TealBlue", {0.12, 0.98, 0.64}}, + {"Thistle", {0.88, 0.41, 1}}, + {"Turquoise", {0.15, 1, 0.8}}, + {"Violet", {0.21, 0.12, 1}}, + {"VioletRed", {1, 0.19, 1}}, + {"White", {1, 1, 1}}, + {"WildStrawberry", {1, 0.04, 0.61}}, + {"Yellow", {1, 1, 0}}, + {"YellowGreen", {0.56, 1, 0.26}}, + {"YellowOrange", {1, 0.58, 0}} + }; + // binary search + int first=0, last=68-1; + while (first <= last) { + int mid = first+(last-first)/2; + int cmp = strcmp(constants[mid].name, c.c_str()); + if (cmp > 0) + last = mid-1; + else if (cmp < 0) + first = mid+1; + else { + rgb[0] = constants[mid].rgb[0]; + rgb[1] = constants[mid].rgb[1]; + rgb[2] = constants[mid].rgb[2]; + return true; + } + } + return false; +} + + +/** Reads a color statement from an input stream and converts it to RGB. + * A color statement has the following syntax: + * <color model> <component values> + * Currently, the following color models are supported: rgb, cmyk, hsb and gray. + * Examples: rgb 1 0.5 0, gray 0.5 + * @param[in] model if model != "" this value specifies the model, otherwise it's read from the stream + * @param[in] is stream to be read from + * @param[out] resulting RGB triple + * @return true if statement has successfully been read */ +static void read_color (string model, istream &is, vector<float> &rgb) { + if (model.empty()) + is >> model; + if (model == "rgb") + read_floats(is, rgb); + else if (model == "cmyk") { + vector<float> cmyk(4); + read_floats(is, cmyk); + cmyk_to_rgb(cmyk, rgb); + } + else if (model == "hsb") { + vector<float> hsb(3); + read_floats(is, hsb); + hsb_to_rgb(hsb, rgb); + } + else if (model == "gray") + gray_to_rgb(read_float(is), rgb); + else if (!color_constant(model, rgb)) + throw SpecialException("unknown color statement"); + if (rgb[0] > 1 || rgb[1] > 1 || rgb[2] > 1) { + ostringstream oss; + oss << "invalid RGB value (" << rgb[0] << ',' << rgb[1] << ',' << rgb[2] << ')'; + throw SpecialException(oss.str()); + } +} + + +bool ColorSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + vector<float> rgb(3); + if (prefix && strcmp(prefix, "background") == 0) { + read_color("", is, rgb); + actions->setBgColor(rgb); + } + else { + string cmd; + is >> cmd; + if (cmd == "push") { // color push <model> <params> + read_color("", is, rgb); + _colorStack.push(rgb); + } + else if (cmd == "pop") { + if (!_colorStack.empty()) // color pop + _colorStack.pop(); + } + else { // color <model> <params> + read_color(cmd, is, rgb); + while (!_colorStack.empty()) + _colorStack.pop(); + _colorStack.push(rgb); + } + if (actions) { + if (_colorStack.empty()) + actions->setColor(Color::BLACK); + else + actions->setColor(_colorStack.top()); + } + } + return true; +} + + +const char** ColorSpecialHandler::prefixes () const { + static const char *pfx[] = {"color", 0}; + return pfx; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.h new file mode 100644 index 00000000000..6ee202e479b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ColorSpecialHandler.h @@ -0,0 +1,43 @@ +/************************************************************************* +** ColorSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef COLORSPECIALHANDLER_H +#define COLORSPECIALHANDLER_H + +#include <stack> +#include <vector> +#include "SpecialHandler.h" + + +class ColorSpecialHandler : public SpecialHandler +{ + typedef std::vector<float> RGB; + + public: + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + const char* name () const {return "color";} + const char* info () const {return "complete support of color specials";} + const char** prefixes () const; + + private: + std::stack<RGB> _colorStack; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.cpp new file mode 100644 index 00000000000..49279eb71ce --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.cpp @@ -0,0 +1,262 @@ +// This file was automatically generated by opt2cpp. +// It is part of the dvisvgm package and published under the terms +// of the GNU General Public License version 3 or later. +// See file COPYING for further details. +// (C) 2009 Martin Gieseking <martin.gieseking@uos.de> + +#include <cstdio> +#include <iostream> +#include <iomanip> +#include "InputReader.h" +#include "CommandLine.h" + +using namespace std; + +const CmdLineParserBase::Option CommandLine::_options[] = { + {'b', "bbox", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_bbox)}, + {'C', "cache", 'o', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_cache)}, + {'h', "help", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_help)}, + {'l', "list-specials", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_list_specials)}, + {'M', "mag", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_mag)}, + {'m', "map-file", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_map_file)}, + {'n', "no-fonts", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_fonts)}, + {'\0', "no-mktexmf", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_mktexmf)}, + {'S', "no-specials", 'o', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_specials)}, + {'\0', "no-styles", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_no_styles)}, + {'o', "output", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_output)}, + {'p', "page", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_page)}, + {'P', "progress", 'o', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_progress)}, + {'r', "rotate", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_rotate)}, + {'c', "scale", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_scale)}, + {'s', "stdout", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_stdout)}, + {'a', "trace-all", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_trace_all)}, + {'T', "transform", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_transform)}, + {'t', "translate", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_translate)}, + {'v', "verbosity", 'r', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_verbosity)}, + {'V', "version", 0, new OptionHandlerImpl<CommandLine>(&CommandLine::handle_version)}, + {'z', "zip", 'o', new OptionHandlerImpl<CommandLine>(&CommandLine::handle_zip)}, +}; + +void CommandLine::init () { + CmdLineParserBase::init(); + _bbox_given = false; + _cache_given = false; + _help_given = false; + _list_specials_given = false; + _mag_given = false; + _map_file_given = false; + _no_fonts_given = false; + _no_mktexmf_given = false; + _no_specials_given = false; + _no_styles_given = false; + _output_given = false; + _page_given = false; + _progress_given = false; + _rotate_given = false; + _scale_given = false; + _stdout_given = false; + _trace_all_given = false; + _transform_given = false; + _translate_given = false; + _verbosity_given = false; + _version_given = false; + _zip_given = false; + + _bbox_arg = "min"; + _cache_arg.clear(); + _mag_arg = 4; + _map_file_arg.clear(); + _no_specials_arg.clear(); + _output_arg.clear(); + _page_arg = 1; + _progress_arg = 100; + _rotate_arg = 0; + _scale_arg.clear(); + _transform_arg.clear(); + _translate_arg.clear(); + _verbosity_arg = 7; + _zip_arg = 9; +} + +void CommandLine::help () const { + puts("This program converts DVI files, as created by TeX/LaTeX to\nthe XML-based scalable vector graphics format SVG.\n\nUsage: dvisvgm [options] dvifile\n"); + puts("Input options:"); + puts(" -p, --page=number choose page to convert (default: 1)"); + puts(" -m, --map-file=[+]filename set [additional] font map file name"); + puts("\nSVG output options:"); + puts(" -b, --bbox=fmt set format or size of bounding box (default: min)"); + puts(" -o, --output=filename set name of output file"); + puts(" -s, --stdout write SVG output to stdout"); + puts(" -n, --no-fonts draw glyphs by using path elements"); + puts(" --no-styles don't use styles to reference fonts"); + puts(" -z, --zip[=level] create compressed .svgz file (default: 9)"); + puts("\nSVG transformations:"); + puts(" -r, --rotate=angle rotate page content clockwise"); + puts(" -c, --scale=sx[,sy] scale page content"); + puts(" -t, --translate=tx[,ty] shift page content"); + puts(" -T, --transform=commands transform page content"); + puts("\nProcessing options:"); + puts(" -C, --cache[=dir] set/print path of cache directory"); + puts(" -M, --mag=factor magnification of Metafont output (default: 4)"); + puts(" --no-mktexmf don't try to create missing fonts"); + puts(" -S, --no-specials[=prefixes] don't process [selected] specials"); + puts(" -a, --trace-all trace all glyphs of used bitmap fonts"); + puts("\nMessage options:"); + puts(" -h, --help print this help and exit"); + puts(" -l, --list-specials print supported special sets and exit"); + puts(" -P, --progress[=skip] enable progess indicator (default: 100)"); + puts(" -v, --verbosity=level set verbosity level (0-7) (default: 7)"); + puts(" -V, --version print version and exit"); +} + + +void CommandLine::handle_bbox(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _bbox_arg)) + _bbox_given = true; +} + + +void CommandLine::handle_cache(InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getStringArg(ir, opt, longopt, _cache_arg)) + _cache_given = true; +} + + +void CommandLine::handle_help(InputReader &ir, const Option &opt, bool longopt) { + _help_given = true; +} + + +void CommandLine::handle_list_specials(InputReader &ir, const Option &opt, bool longopt) { + _list_specials_given = true; +} + + +void CommandLine::handle_mag(InputReader &ir, const Option &opt, bool longopt) { + if (getDoubleArg(ir, opt, longopt, _mag_arg)) + _mag_given = true; +} + + +void CommandLine::handle_map_file(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _map_file_arg)) + _map_file_given = true; +} + + +void CommandLine::handle_no_fonts(InputReader &ir, const Option &opt, bool longopt) { + _no_fonts_given = true; +} + + +void CommandLine::handle_no_mktexmf(InputReader &ir, const Option &opt, bool longopt) { + _no_mktexmf_given = true; +} + + +void CommandLine::handle_no_specials(InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getStringArg(ir, opt, longopt, _no_specials_arg)) + _no_specials_given = true; +} + + +void CommandLine::handle_no_styles(InputReader &ir, const Option &opt, bool longopt) { + _no_styles_given = true; +} + + +void CommandLine::handle_output(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _output_arg)) + _output_given = true; +} + + +void CommandLine::handle_page(InputReader &ir, const Option &opt, bool longopt) { + if (getUIntArg(ir, opt, longopt, _page_arg)) + _page_given = true; +} + + +void CommandLine::handle_progress(InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getUIntArg(ir, opt, longopt, _progress_arg)) + _progress_given = true; +} + + +void CommandLine::handle_rotate(InputReader &ir, const Option &opt, bool longopt) { + if (getDoubleArg(ir, opt, longopt, _rotate_arg)) + _rotate_given = true; +} + + +void CommandLine::handle_scale(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _scale_arg)) + _scale_given = true; +} + + +void CommandLine::handle_stdout(InputReader &ir, const Option &opt, bool longopt) { + _stdout_given = true; +} + + +void CommandLine::handle_trace_all(InputReader &ir, const Option &opt, bool longopt) { + _trace_all_given = true; +} + + +void CommandLine::handle_transform(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _transform_arg)) + _transform_given = true; +} + + +void CommandLine::handle_translate(InputReader &ir, const Option &opt, bool longopt) { + if (getStringArg(ir, opt, longopt, _translate_arg)) + _translate_given = true; +} + + +void CommandLine::handle_verbosity(InputReader &ir, const Option &opt, bool longopt) { + if (getUIntArg(ir, opt, longopt, _verbosity_arg)) + _verbosity_given = true; +} + + +void CommandLine::handle_version(InputReader &ir, const Option &opt, bool longopt) { + _version_given = true; +} + + +void CommandLine::handle_zip(InputReader &ir, const Option &opt, bool longopt) { + if (ir.eof() || getIntArg(ir, opt, longopt, _zip_arg)) + _zip_given = true; +} + + +void CommandLine::status () const { + cout << 'b'<< setw(20) << "bbox " << bbox_given() << setw(10) << bbox_arg() << endl; + cout << 'C'<< setw(20) << "cache " << cache_given() << setw(10) << cache_arg() << endl; + cout << 'h'<< setw(20) << "help " << help_given() << endl; + cout << 'l'<< setw(20) << "list-specials " << list_specials_given() << endl; + cout << 'M'<< setw(20) << "mag " << mag_given() << setw(10) << mag_arg() << endl; + cout << 'm'<< setw(20) << "map-file " << map_file_given() << setw(10) << map_file_arg() << endl; + cout << 'n'<< setw(20) << "no-fonts " << no_fonts_given() << endl; + cout << ' '<< setw(20) << "no-mktexmf " << no_mktexmf_given() << endl; + cout << 'S'<< setw(20) << "no-specials " << no_specials_given() << setw(10) << no_specials_arg() << endl; + cout << ' '<< setw(20) << "no-styles " << no_styles_given() << endl; + cout << 'o'<< setw(20) << "output " << output_given() << setw(10) << output_arg() << endl; + cout << 'p'<< setw(20) << "page " << page_given() << setw(10) << page_arg() << endl; + cout << 'P'<< setw(20) << "progress " << progress_given() << setw(10) << progress_arg() << endl; + cout << 'r'<< setw(20) << "rotate " << rotate_given() << setw(10) << rotate_arg() << endl; + cout << 'c'<< setw(20) << "scale " << scale_given() << setw(10) << scale_arg() << endl; + cout << 's'<< setw(20) << "stdout " << stdout_given() << endl; + cout << 'a'<< setw(20) << "trace-all " << trace_all_given() << endl; + cout << 'T'<< setw(20) << "transform " << transform_given() << setw(10) << transform_arg() << endl; + cout << 't'<< setw(20) << "translate " << translate_given() << setw(10) << translate_arg() << endl; + cout << 'v'<< setw(20) << "verbosity " << verbosity_given() << setw(10) << verbosity_arg() << endl; + cout << 'V'<< setw(20) << "version " << version_given() << endl; + cout << 'z'<< setw(20) << "zip " << zip_given() << setw(10) << zip_arg() << endl; + CmdLineParserBase::status(); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.h new file mode 100644 index 00000000000..91874d97bf9 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/CommandLine.h @@ -0,0 +1,123 @@ +// This file was automatically generated by opt2cpp. +// It is part of the dvisvgm package and published under the terms +// of the GNU General Public License version 3 or later. +// See file COPYING for further details. +// (C) 2009 Martin Gieseking <martin.gieseking@uos.de> + +#ifndef COMMANDLINE_H +#define COMMANDLINE_H + +#include "CmdLineParserBase.h" + +class CommandLine : public CmdLineParserBase +{ + public: + CommandLine () {init();} + CommandLine (int argc, char **argv, bool printErrors) {parse(argc, argv, printErrors);} + void help () const; + void status () const; + int numOptions () const {return 22;} + bool page_given () const {return _page_given;} + unsigned page_arg () const {return _page_arg;} + bool map_file_given () const {return _map_file_given;} + const std::string& map_file_arg () const {return _map_file_arg;} + bool bbox_given () const {return _bbox_given;} + const std::string& bbox_arg () const {return _bbox_arg;} + bool output_given () const {return _output_given;} + const std::string& output_arg () const {return _output_arg;} + bool stdout_given () const {return _stdout_given;} + bool no_fonts_given () const {return _no_fonts_given;} + bool no_styles_given () const {return _no_styles_given;} + bool zip_given () const {return _zip_given;} + int zip_arg () const {return _zip_arg;} + bool rotate_given () const {return _rotate_given;} + double rotate_arg () const {return _rotate_arg;} + bool scale_given () const {return _scale_given;} + const std::string& scale_arg () const {return _scale_arg;} + bool translate_given () const {return _translate_given;} + const std::string& translate_arg () const {return _translate_arg;} + bool transform_given () const {return _transform_given;} + const std::string& transform_arg () const {return _transform_arg;} + bool cache_given () const {return _cache_given;} + const std::string& cache_arg () const {return _cache_arg;} + bool mag_given () const {return _mag_given;} + double mag_arg () const {return _mag_arg;} + bool no_mktexmf_given () const {return _no_mktexmf_given;} + bool no_specials_given () const {return _no_specials_given;} + const std::string& no_specials_arg () const {return _no_specials_arg;} + bool trace_all_given () const {return _trace_all_given;} + bool help_given () const {return _help_given;} + bool list_specials_given () const {return _list_specials_given;} + bool progress_given () const {return _progress_given;} + unsigned progress_arg () const {return _progress_arg;} + bool verbosity_given () const {return _verbosity_given;} + unsigned verbosity_arg () const {return _verbosity_arg;} + bool version_given () const {return _version_given;} + + protected: + void init (); + const CmdLineParserBase::Option* options () const {return _options;} + void handle_page (InputReader &ir, const Option &opt, bool longopt); + void handle_map_file (InputReader &ir, const Option &opt, bool longopt); + void handle_bbox (InputReader &ir, const Option &opt, bool longopt); + void handle_output (InputReader &ir, const Option &opt, bool longopt); + void handle_stdout (InputReader &ir, const Option &opt, bool longopt); + void handle_no_fonts (InputReader &ir, const Option &opt, bool longopt); + void handle_no_styles (InputReader &ir, const Option &opt, bool longopt); + void handle_zip (InputReader &ir, const Option &opt, bool longopt); + void handle_rotate (InputReader &ir, const Option &opt, bool longopt); + void handle_scale (InputReader &ir, const Option &opt, bool longopt); + void handle_translate (InputReader &ir, const Option &opt, bool longopt); + void handle_transform (InputReader &ir, const Option &opt, bool longopt); + void handle_cache (InputReader &ir, const Option &opt, bool longopt); + void handle_mag (InputReader &ir, const Option &opt, bool longopt); + void handle_no_mktexmf (InputReader &ir, const Option &opt, bool longopt); + void handle_no_specials (InputReader &ir, const Option &opt, bool longopt); + void handle_trace_all (InputReader &ir, const Option &opt, bool longopt); + void handle_help (InputReader &ir, const Option &opt, bool longopt); + void handle_list_specials (InputReader &ir, const Option &opt, bool longopt); + void handle_progress (InputReader &ir, const Option &opt, bool longopt); + void handle_verbosity (InputReader &ir, const Option &opt, bool longopt); + void handle_version (InputReader &ir, const Option &opt, bool longopt); + + private: + static const CmdLineParserBase::Option _options[]; + bool _page_given; + unsigned _page_arg; + bool _map_file_given; + std::string _map_file_arg; + bool _bbox_given; + std::string _bbox_arg; + bool _output_given; + std::string _output_arg; + bool _stdout_given; + bool _no_fonts_given; + bool _no_styles_given; + bool _zip_given; + int _zip_arg; + bool _rotate_given; + double _rotate_arg; + bool _scale_given; + std::string _scale_arg; + bool _translate_given; + std::string _translate_arg; + bool _transform_given; + std::string _transform_arg; + bool _cache_given; + std::string _cache_arg; + bool _mag_given; + double _mag_arg; + bool _no_mktexmf_given; + bool _no_specials_given; + std::string _no_specials_arg; + bool _trace_all_given; + bool _help_given; + bool _list_specials_given; + bool _progress_given; + unsigned _progress_arg; + bool _verbosity_given; + unsigned _verbosity_arg; + bool _version_given; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.cpp new file mode 100644 index 00000000000..4cde80af936 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.cpp @@ -0,0 +1,57 @@ +/************************************************************************* +** DLLoader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "DLLoader.h" + + +DLLoader::DLLoader (const char *dlname) { +#ifdef __WIN32__ + _handle = LoadLibrary(dlname); +#else + _handle = dlopen(dlname, RTLD_LAZY); +#endif +} + + +DLLoader::~DLLoader () { + if (_handle) { +#ifdef __WIN32__ + FreeLibrary(_handle); +#else + dlclose(_handle); +#endif + } +} + + +void* DLLoader::loadFunction (const char *name) { + if (_handle) { +#ifdef __WIN32__ + return (void*)GetProcAddress(_handle, name); +#else + return dlsym(_handle, name); +#endif + } + return 0; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.h new file mode 100644 index 00000000000..97af3d739d7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DLLoader.h @@ -0,0 +1,52 @@ +/************************************************************************* +** DLLoader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + + + +#ifndef DLLOADER_H +#define DLLOADER_H + +#ifdef __WIN32__ + #include <windows.h> +#else + #include <dlfcn.h> +#endif + +class DLLoader +{ + public: + DLLoader (const char *dllname); + virtual ~DLLoader (); + bool loaded () const {return _handle != 0;} + + protected: + DLLoader () : _handle(0) {} + DLLoader (const DLLoader &l) {} + void* loadFunction (const char *name); + + private: +#ifdef __WIN32__ + HINSTANCE _handle; +#else + void *_handle; +#endif +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.cpp new file mode 100644 index 00000000000..36345d7a4eb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.cpp @@ -0,0 +1,26 @@ +/************************************************************************* +** DVIActions.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "DVIActions.h" + +const double DVIActions::BP = 72.0/72.27; +const double DVIActions::IN = 1.0/72.27; +const double DVIActions::CM = 2.54*IN; +const double DVIActions::MM = 25.4*IN; diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.h new file mode 100644 index 00000000000..15f0871a2ea --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIActions.h @@ -0,0 +1,56 @@ +/************************************************************************* +** DVIActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DVIACTIONS_H +#define DVIACTIONS_H + +#include <string> +#include "Message.h" +#include "types.h" + + +class BoundingBox; +class Font; +class SpecialManager; + + +struct DVIActions +{ + static const double BP; + static const double IN; + static const double CM; + static const double MM; + virtual ~DVIActions () {} + virtual void setChar (double x, double y, unsigned c, const Font *f) {} + virtual void setRule (double x, double y, double height, double width) {} + virtual void moveToX (double x) {} + virtual void moveToY (double y) {} + virtual void defineFont (int num, const Font *font) {} + virtual void setFont (int num, const Font *font) {} + virtual void special (const std::string &s) {} + virtual void preamble (const std::string &cmt) {} + virtual void postamble () {} + virtual void beginPage (Int32 *c) {} + virtual void endPage () {} + virtual BoundingBox& bbox () =0; + virtual const SpecialManager* setProcessSpecials (const char *ignorelist) {return 0;} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.cpp new file mode 100644 index 00000000000..3aff687cf1b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.cpp @@ -0,0 +1,586 @@ +/************************************************************************* +** DVIReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdarg> +#include <fstream> +#include <iostream> +#include <sstream> +#include "types.h" +#include "DVIActions.h" +#include "DVIReader.h" +#include "Font.h" +#include "Message.h" +#include "VectorStream.h" +#include "macros.h" + +using namespace std; + + +DVIReader::DVIReader (istream &is, DVIActions *a) + : StreamReader(is), _actions(a) +{ + _inPage = false; + _pageHeight = _pageWidth = 0; + _scaleFactor = 0.0; + _inPostamble = false; +} + + +DVIActions* DVIReader::replaceActions (DVIActions *a) { + DVIActions *prev_actions = _actions; + _actions = a; + return prev_actions; +} + + +/** Reads a single DVI command from the current position of the input stream and calls the + * corresponding cmdFOO method. + * @return opcode of the executed command */ +int DVIReader::executeCommand () { + struct DVICommand { + void (DVIReader::*method)(int); + int numBytes; + }; + + /* Each cmdFOO command reads the necessary number of bytes from the stream, so executeCommand + doesn't need to know the exact DVI command format. Some cmdFOO methods are used for multiple + DVI commands because they only differ in length of their parameters. */ + static const DVICommand commands[] = { + {&DVIReader::cmdSetChar, 1}, {&DVIReader::cmdSetChar, 2}, {&DVIReader::cmdSetChar, 3}, {&DVIReader::cmdSetChar, 4}, // 128-131 + {&DVIReader::cmdSetRule, 0}, // 132 + {&DVIReader::cmdPutChar, 1}, {&DVIReader::cmdPutChar, 2}, {&DVIReader::cmdPutChar, 3}, {&DVIReader::cmdPutChar, 4}, // 133-136 + {&DVIReader::cmdPutRule, 0}, // 137 + {&DVIReader::cmdNop, 0}, // 138 + {&DVIReader::cmdBop, 0}, {&DVIReader::cmdEop, 0}, // 139-140 + {&DVIReader::cmdPush, 0}, {&DVIReader::cmdPop, 0}, // 141-142 + {&DVIReader::cmdRight, 1}, {&DVIReader::cmdRight, 2}, {&DVIReader::cmdRight, 3}, {&DVIReader::cmdRight, 4}, // 143-146 + {&DVIReader::cmdW0, 0}, // 147 + {&DVIReader::cmdW, 1}, {&DVIReader::cmdW, 2}, {&DVIReader::cmdW, 3}, {&DVIReader::cmdW, 4}, // 148-151 + {&DVIReader::cmdX0, 0}, // 152 + {&DVIReader::cmdX, 1}, {&DVIReader::cmdX, 2}, {&DVIReader::cmdX, 3}, {&DVIReader::cmdX, 4}, // 153-156 + {&DVIReader::cmdDown, 1}, {&DVIReader::cmdDown, 2}, {&DVIReader::cmdDown, 3}, {&DVIReader::cmdDown, 4}, // 157-160 + {&DVIReader::cmdY0, 0}, // 161 + {&DVIReader::cmdY, 1}, {&DVIReader::cmdY, 2}, {&DVIReader::cmdY, 3}, {&DVIReader::cmdY, 4}, // 162-165 + {&DVIReader::cmdZ0, 0}, // 166 + {&DVIReader::cmdZ, 1}, {&DVIReader::cmdZ, 2}, {&DVIReader::cmdZ, 3}, {&DVIReader::cmdZ, 4}, // 167-170 + {&DVIReader::cmdFontNum, 1}, {&DVIReader::cmdFontNum, 2}, {&DVIReader::cmdFontNum, 3}, {&DVIReader::cmdFontNum, 4}, // 235-238 + {&DVIReader::cmdXXX, 1}, {&DVIReader::cmdXXX, 2}, {&DVIReader::cmdXXX, 3}, {&DVIReader::cmdXXX, 4}, // 239-242 + {&DVIReader::cmdFontDef, 1}, {&DVIReader::cmdFontDef, 2}, {&DVIReader::cmdFontDef, 3}, {&DVIReader::cmdFontDef, 4}, // 243-246 + {&DVIReader::cmdPre, 0}, {&DVIReader::cmdPost, 0}, {&DVIReader::cmdPostPost, 0} // 247-249 + }; + + int opcode = in().get(); + if (!in() || opcode < 0) // at end of file + throw InvalidDVIFileException("invalid file"); + if (opcode >= 0 && opcode <= 127) + cmdSetChar0(opcode); + else if (opcode >= 171 && opcode <= 234) + cmdFontNum0(opcode-171); + else if (opcode >= 250) { + ostringstream oss; + oss << "undefined DVI command (opcode " << opcode << ')'; + throw DVIException(oss.str()); + } + else { + int offset = opcode <= 170 ? 128 : 235-(170-128+1); + const DVICommand &cmd = commands[opcode-offset]; + (this->*cmd.method)(cmd.numBytes); + } + return opcode; +} + + +/** Executes all DVI commands read from the input stream. */ +void DVIReader::executeAll () { + int opcode = 0; + while (!in().eof() && opcode >= 0) { + try { + opcode = executeCommand(); + } + catch (const InvalidDVIFileException &e) { + // end of stream reached + opcode = -1; + } + } +} + + +#if 0 +/** Executes all DVI commands from the preamble to postpost. */ +bool DVIReader::executeDocument () { + in().clear(); // reset all status bits + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand() != 249); // stop reading after postpost (249) + return true; +} + +bool DVIReader::executeAllPages () { + in().clear(); // reset all status bits + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand() != 248); // stop reading when postamble (248) is reached + return true; +} +#endif + + +/** Reads and executes the commands of a single page. + * This methods stops reading after the page's eop command has been executed. + * @param[in] n number of page to be executed + * @returns true if page was read successfully */ +bool DVIReader::executePage (unsigned n) { + in().clear(); // reset all status bits + if (!in()) + throw DVIException("invalid DVI file"); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + if (executeCommand() != 248) // execute postamble command but not the fontdefs + return false; + if (n < 1 || n > _totalPages) + return false; + in().seekg(_prevBop, ios_base::beg); // now on last bop + _inPostamble = false; // we jumped out of the postamble + unsigned pageCount = _totalPages; + for (; pageCount > n && _prevBop > 0; pageCount--) { + in().seekg(41, ios_base::cur); // skip bop and 10*4 \count bytes => now on pointer to prev bop + _prevBop = readSigned(4); + in().seekg(_prevBop, ios_base::beg); + } + _currPageNum = n; + while (pageCount == n && executeCommand() != 140); // 140 == eop + return true; +} + + +bool DVIReader::executePages (unsigned first, unsigned last) { + in().clear(); + if (!in()) + throw DVIException("invalid DVI file"); + if (first > last) + swap(first, last); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + if (executeCommand() != 248) // execute postamble command but not the fontdefs + return false; + first = max(1u, min(first, (unsigned)_totalPages)); + last = max(1u, min(last, (unsigned)_totalPages)); + in().seekg(_prevBop, ios_base::beg); // now on last bop + _inPostamble = false; // we jumped out of the postamble + unsigned count = _totalPages; + for (; count > first && _prevBop > 0; count--) { + in().seekg(41, ios_base::cur); // skip bop and 10*4 \count bytes => now on pointer to prev bop + _prevBop = readSigned(4); + in().seekg(_prevBop, ios_base::beg); + } + while (first <= last) { + _currPageNum = first++; + while (executeCommand () != 140); // 140 == eop + } + return true; +} + + +/** Reads and executes the commands of the postamble. */ +void DVIReader::executePostamble () { + in().clear(); // reset all status bits + if (!in()) + throw DVIException("invalid DVI file"); + in().seekg(-1, ios_base::end); // stream pointer to last byte + while (in().peek() == 223) + in().seekg(-1, ios_base::cur); // skip fill bytes + + in().seekg(-4, ios_base::cur); // now on first byte of q (pointer to begin of postamble) + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in().seekg(q, ios_base::beg); // now on begin of postamble + while (executeCommand() != 249); // read all commands until postpost (= 249) is reached +} + + +/** Returns the current x coordinate in TeX point units. + * This is the horizontal position where the next output would be placed. */ +double DVIReader::getXPos () const { + return _currPos.h; +} + + +/** Returns the current y coordinate in TeX point units. + * This is the vertical position where the next output would be placed. */ +double DVIReader::getYPos () const { + return _currPos.v; +} + + +/** Sets the horizontal position in TeX point units. */ +void DVIReader::setXPos (double x) { + _currPos.h = x; +} + + +/** Sets the vertical position in TeX point units. */ +void DVIReader::setYPos (double y) { + _currPos.v = y; +} + + +double DVIReader::getPageHeight () const { + return _pageHeight; +} + + +double DVIReader::getPageWidth () const { + return _pageWidth; +} + +///////////////////////////////////// + +/** Reads and executes DVI preamble command. */ +void DVIReader::cmdPre (int) { + UInt32 i = readUnsigned(1); // identification number (should be 2) + UInt32 num = readUnsigned(4); // numerator units of measurement + UInt32 den = readUnsigned(4); // denominator units of measurement + _mag = readUnsigned(4); // magnification + UInt32 k = readUnsigned(1); // length of following comment + string cmt = readString(k); // comment + if (i != 2) + throw DVIException("invalid identification value in DVI preamble"); + // 1 dviunit * num/den == multiples of 0.0000001m + // 1 dviunit * _scaleFactor: length of 1 dviunit in TeX points * _mag/1000 + _scaleFactor = num/25400000.0*7227.0/den*_mag/1000.0; + if (_actions) + _actions->preamble(cmt); +} + + +/** Reads and executes DVI postamble command. */ +void DVIReader::cmdPost (int) { + _prevBop = readUnsigned(4); // pointer to previous bop + UInt32 num = readUnsigned(4); + UInt32 den = readUnsigned(4); + _mag = readUnsigned(4); + _pageHeight = readUnsigned(4); // height of tallest page in dvi units + _pageWidth = readUnsigned(4); // width of widest page in dvi units + readUnsigned(2); // max. stack depth + _totalPages = readUnsigned(2); // total number of pages + // 1 dviunit * num/den == multiples of 0.0000001m + // 1 dviunit * _scaleFactor: length of 1 dviunit in TeX points * _mag/1000 + _scaleFactor = num/25400000.0*7227.0/den*_mag/1000.0; + _pageHeight *= _scaleFactor; // to pt units + _pageWidth *= _scaleFactor; + _inPostamble = true; + if (_actions) + _actions->postamble(); +} + + +/** Reads and executes DVI postpost command. */ +void DVIReader::cmdPostPost (int) { + _inPostamble = false; + readUnsigned(4); // pointer to begin of postamble + UInt32 i = readUnsigned(1); // identification byte (should be 2) + if (i == 2) + while (readUnsigned(1) == 223); // skip fill bytes (223), eof bit should be set now + else + throw DVIException("invalid identification value in postpost"); +} + + +/** Reads and executes Begin-Of-Page command. */ +void DVIReader::cmdBop (int) { + Int32 c[10]; + for (int i=0; i < 10; i++) + c[i] = readSigned(4); + readSigned(4); // pointer to peceeding bop (-1 in case of first page) + _currPos.reset(); // set all DVI registers to 0 + while (!_posStack.empty()) + _posStack.pop(); + _currFontNum = 0; + _inPage = true; + beginPage(c); + if (_actions) + _actions->beginPage(c); +} + + +/** Reads and executes End-Of-Page command. */ +void DVIReader::cmdEop (int) { + if (!_posStack.empty()) + throw DVIException("stack not empty at end of page"); + _inPage = false; + endPage(); + if (_actions) + _actions->endPage(); +} + + +/** Reads and executes push command. */ +void DVIReader::cmdPush (int) { + _posStack.push(_currPos); +} + + +/** Reads and executes pop command (restores pushed position information). */ +void DVIReader::cmdPop (int) { + if (_posStack.empty()) + throw DVIException("stack empty at pop command"); + else { + DVIPosition prevPos = _currPos; + _currPos = _posStack.top(); + _posStack.pop(); + if (_actions) { + if (prevPos.h != _currPos.h) + _actions->moveToX(_currPos.h); + if (prevPos.v != _currPos.v) + _actions->moveToY(_currPos.v); + } + } +} + + +/** Helper function that actually sets/puts a charater. It is called by the + * cmdSetChar and cmdPutChar methods. + * @param[in] c character to typeset + * @param[in] moveCursor if true, register h is increased by the character width + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::putChar (UInt32 c, bool moveCursor) { + if (_inPage) { + Font *font = _fontManager.getFont(_currFontNum); + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { // is current font a virtual font? + vector<UInt8> *dvi = const_cast<vector<UInt8>*>(vf->getDVI(c)); // get DVI snippet that describes character c + if (dvi) { + DVIPosition pos = _currPos; // save current cursor position + _currPos.x = _currPos.y = _currPos.w = _currPos.z = 0; + int save_fontnum = _currFontNum; // save current font number + _fontManager.enterVF(vf); // new font number context + cmdFontNum0(_fontManager.vfFirstFontNum(vf)); + double save_scale = _scaleFactor; + _scaleFactor = vf->scaledSize()/(1 << 20); + + VectorInputStream<UInt8> vis(*dvi); + istream &is = replaceStream(vis); + try { + executeAll(); // execute DVI fragment + } + catch (const DVIException &e) { +// Message::estream(true) << "invalid dvi in vf: " << e.getMessage() << endl; // @@ + } + replaceStream(is); // restore previous input stream + _scaleFactor = save_scale; // restore previous scale factor + _fontManager.leaveVF(); // restore previous font number context + cmdFontNum0(save_fontnum); // restore previous font number + _currPos = pos; // restore previous cursor position + } + } + else if (_actions) { + _actions->setChar(_currPos.h, _currPos.v, c, font); + } + if (moveCursor) + _currPos.h += font->charWidth(c) * font->scaleFactor() * _mag/1000.0; + } + else + throw DVIException("set_char or put_char outside page"); +} + + +/** Reads and executes set_char_x command. Puts a character at the current + * position and advances the cursor. + * @param[in] c character to set + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetChar0 (int c) { + putChar(c, true); +} + + +/** Reads and executes setx command. Puts a character at the current + * position and advances the cursor. + * @param[in] len number of parameter bytes (possible values: 1-4) + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetChar (int len) { + // According to the dvi specification all character codes are unsigned + // except len == 4. At the moment all char codes are treated as unsigned... + UInt32 c = readUnsigned(len); // if len == 4 c may be signed + putChar(c, true); +} + + +/** Reads and executes putx command. Puts a character at the current + * position but doesn't change the cursor position. + * @param[in] len number of parameter bytes (possible values: 1-4) + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdPutChar (int len) { + // According to the dvi specification all character codes are unsigned + // except len == 4. At the moment all char codes are treated as unsigned... + Int32 c = readUnsigned(len); + putChar(c, false); +} + + +/** Reads and executes set_rule command. Puts a solid rectangle at the current + * position and updates the cursor position. + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdSetRule (int) { + if (_inPage) { + double height = _scaleFactor*readSigned(4); + double width = _scaleFactor*readSigned(4); + if (_actions && height > 0 && width > 0) + _actions->setRule(_currPos.h, _currPos.v, height, width); + _currPos.h += width; + if (_actions && (height <= 0 || width <= 0)) + _actions->moveToX(_currPos.h); + } + else + throw DVIException("set_rule outside of page"); +} + + +/** Reads and executes set_rule command. Puts a solid rectangle at the current + * position but leaves the cursor position unchanged. + * @throw DVIException if method is called ouside a bop/eop pair */ +void DVIReader::cmdPutRule (int) { + if (_inPage) { + double height = _scaleFactor*readSigned(4); + double width = _scaleFactor*readSigned(4); + if (_actions && height > 0 && width > 0) + _actions->setRule(_currPos.h, _currPos.v, height, width); + } + else + throw DVIException("put_rule outside of page"); +} + + +void DVIReader::cmdNop (int) {} + +void DVIReader::cmdRight (int len) {_currPos.h += _scaleFactor*readSigned(len); if (_actions) _actions->moveToX(_currPos.h);} +void DVIReader::cmdDown (int len) {_currPos.v += _scaleFactor*readSigned(len); if (_actions) _actions->moveToY(_currPos.v);} +void DVIReader::cmdX0 (int) {_currPos.h += _currPos.x; if (_actions) _actions->moveToX(_currPos.h);} +void DVIReader::cmdY0 (int) {_currPos.v += _currPos.y; if (_actions) _actions->moveToY(_currPos.v);} +void DVIReader::cmdW0 (int) {_currPos.h += _currPos.w; if (_actions) _actions->moveToX(_currPos.h);} +void DVIReader::cmdZ0 (int) {_currPos.v += _currPos.z; if (_actions) _actions->moveToY(_currPos.v);} +void DVIReader::cmdX (int len) {_currPos.x = _scaleFactor*readSigned(len); cmdX0(0);} +void DVIReader::cmdY (int len) {_currPos.y = _scaleFactor*readSigned(len); cmdY0(0);} +void DVIReader::cmdW (int len) {_currPos.w = _scaleFactor*readSigned(len); cmdW0(0);} +void DVIReader::cmdZ (int len) {_currPos.z = _scaleFactor*readSigned(len); cmdZ0(0);} + + +void DVIReader::cmdXXX (int len) { + if (_inPage) { + UInt32 numBytes = readUnsigned(len); + string s = readString(numBytes); + if (_actions) + _actions->special(s); + } + else + throw DVIException("special outside of page"); +} + + +/** Selects a previously defined font by its number. + * @param[in] num font number + * @throw DVIException if font number is undefined */ +void DVIReader::cmdFontNum0 (int num) { + if (Font *font = _fontManager.getFont(num)) { + _currFontNum = num; + if (_actions && !dynamic_cast<VirtualFont*>(font)) + _actions->setFont(_fontManager.fontID(num), font); // all fonts get a recomputed ID + } + else { + ostringstream oss; + oss << "undefined font number " << num; + throw DVIException(oss.str()); + } +} + + +/** Selects a previously defined font. + * @param[in] len size of font number variable (in bytes) + * @throw DVIException if font number is undefined */ +void DVIReader::cmdFontNum (int len) { + UInt32 num = readUnsigned(len); + cmdFontNum0(num); +} + + +/** Helper function to handle a font definition. + * @param[in] fontnum local font number + * @param[in] name font name + * @param[in] checksum checksum to be compared with TFM checksum + * @param[in] ds design size in TeX point units + * @param[in] ss scaled size in TeX point units */ +void DVIReader::defineFont (UInt32 fontnum, const string &name, UInt32 cs, double ds, double ss) { + int id = _fontManager.registerFont(fontnum, name, cs, ds, ss); + Font *font = _fontManager.getFontById(id); + if (VirtualFont *vf = dynamic_cast<VirtualFont*>(font)) { + // read vf file, register its font and character definitions + _fontManager.enterVF(vf); + ifstream ifs(vf->path(), ios::binary); + VFReader vfReader(ifs); + vfReader.replaceActions(this); + vfReader.executeAll(); + _fontManager.leaveVF(); + } + if (_actions) + _actions->defineFont(id, font); +} + + +/** Defines a new font. + * @param[in] len size of font number variable (in bytes) */ +void DVIReader::cmdFontDef (int len) { + UInt32 fontnum = readUnsigned(len); // font number + UInt32 checksum = readUnsigned(4); // font checksum (to be compared with corresponding TFM checksum) + UInt32 ssize = readUnsigned(4); // scaled size of font in DVI units + UInt32 dsize = readUnsigned(4); // design size of font in DVI units + UInt32 pathlen = readUnsigned(1); // length of font path + UInt32 namelen = readUnsigned(1); // length of font name + string fontpath = readString(pathlen); + string fontname = readString(namelen); + + defineFont(fontnum, fontname, checksum, dsize*_scaleFactor, ssize*_scaleFactor); +} + + +/** This template method is called by the VFReader after reading a font definition from a VF file. + * @param[in] fontnum local font number + * @param[in] name font name + * @param[in] checksum checksum to be compared with TFM checksum + * @param[in] dsize design size in TeX point units + * @param[in] ssize scaled size in TeX point units */ +void DVIReader::defineVFFont (UInt32 fontnum, string path, string name, UInt32 checksum, double dsize, double ssize) { + VirtualFont *vf = _fontManager.getVF(); + defineFont(fontnum, name, checksum, dsize, ssize * vf->scaleFactor()); +} + + +/** This template method is called by the VFReader after reading a character definition from a VF file. + * @param[in] c character number + * @param[in] dvi DVI fragment describing the character */ +void DVIReader::defineVFChar (UInt32 c, vector<UInt8> *dvi) { + _fontManager.assignVfChar(c, dvi); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.h new file mode 100644 index 00000000000..3fb5f2aff61 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIReader.h @@ -0,0 +1,137 @@ +/************************************************************************* +** DVIReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DVIREADER_H +#define DVIREADER_H + +#include <map> +#include <stack> +#include <string> +#include "FontManager.h" +#include "MessageException.h" +#include "StreamReader.h" +#include "VFActions.h" +#include "types.h" + + +struct DVIException : public MessageException +{ + DVIException (const std::string &msg) : MessageException(msg) {} +}; + +struct InvalidDVIFileException : public DVIException +{ + InvalidDVIFileException(const std::string &msg) : DVIException(msg) {} +}; + +class DVIActions; +class FileFinder; + +class DVIReader : public StreamReader, protected VFActions +{ + struct DVIPosition + { + double h, v; + double x, w, y, z; + DVIPosition () {reset();} + void reset () {h = v = x = w = y = z = 0.0;} + }; + + public: + DVIReader (istream &is, DVIActions *a=0); + + bool executeDocument (); + void executeAll (); + bool executeAllPages (); + void executePostamble (); + bool executePage (unsigned n); + bool executePages (unsigned first, unsigned last); + bool isInPostamble () const {return _inPostamble;} + double getXPos () const; + double getYPos () const; + void setXPos (double x); + void setYPos (double y); + double getPageWidth () const; + double getPageHeight () const; + int getCurrentFontNumber () const {return _currFontNum;} + unsigned getCurrentPageNumber () const {return _currPageNum;} + unsigned getTotalPages () const {return _totalPages;} + DVIActions* getActions () const {return _actions;} + DVIActions* replaceActions (DVIActions *a); + const FontManager& getFontManager () const {return _fontManager;} + + protected: + int executeCommand (); + void putChar (UInt32 c, bool moveCursor); + void defineFont (UInt32 fontnum, const std::string &name, UInt32 cs, double ds, double ss); + virtual void beginPage (Int32 *c) {} + virtual void endPage () {} + + // VFAction methods + void defineVFFont (UInt32 fontnum, std::string path, std::string name, UInt32 checksum, double dsize, double ssize); + void defineVFChar (UInt32 c, vector<UInt8> *dvi); + + // the following methods represent the DVI commands + // they are called by executeCommand and should not be used directly + void cmdSetChar0 (int c); + void cmdSetChar (int len); + void cmdPutChar (int len); + void cmdSetRule (int len); + void cmdPutRule (int len); + void cmdNop (int len); + void cmdBop (int len); + void cmdEop (int len); + void cmdPush (int len); + void cmdPop (int len); + void cmdRight (int len); + void cmdDown (int len); + void cmdX0 (int len); + void cmdY0 (int len); + void cmdW0 (int len); + void cmdZ0 (int len); + void cmdX (int len); + void cmdY (int len); + void cmdW (int len); + void cmdZ (int len); + void cmdFontDef (int len); + void cmdFontNum0 (int n); + void cmdFontNum (int len); + void cmdXXX (int len); + void cmdPre (int len); + void cmdPost (int len); + void cmdPostPost (int len); + + private: + DVIActions *_actions; + bool _inPage; // true if between bop and eop + unsigned _totalPages; // total number of pages in dvi file + unsigned _currPageNum; // current page number + int _currFontNum; // current font number + double _scaleFactor; // 1 dvi unit = scaleFactor * TeX points + UInt32 _mag; // magnification factor * 1000 + bool _inPostamble; // true if stream pointer is inside the postamble + Int32 _prevBop; // pointer to previous bop + double _pageHeight, _pageWidth; // page height and width in TeX points + DVIPosition _currPos; + std::stack<DVIPosition> _posStack; + FontManager _fontManager; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.cpp new file mode 100644 index 00000000000..102a5b30366 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.cpp @@ -0,0 +1,344 @@ +/************************************************************************* +** DVIToSVG.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <ctime> +#include <fstream> +#include <sstream> +#include "Calculator.h" +#include "CharmapTranslator.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "Font.h" +#include "FontManager.h" +#include "FileFinder.h" +#include "InputReader.h" +#include "Matrix.h" +#include "Message.h" +#include "PageSize.h" +#include "SVGFontEmitter.h" +#include "SVGFontTraceEmitter.h" +#include "SVGTree.h" +#include "TFM.h" +#include "XMLDocument.h" +#include "XMLDocTypeNode.h" +#include "XMLNode.h" +#include "XMLString.h" +// +/////////////////////////////////// +// special handlers + +#include "BgColorSpecialHandler.h" +#include "ColorSpecialHandler.h" +#include "DvisvgmSpecialHandler.h" +#include "EmSpecialHandler.h" +//#include "HtmlSpecialHandler.h" +#if !DISABLE_GS + #include "PsSpecialHandler.h" +#endif +#include "TpicSpecialHandler.h" +/////////////////////////////////// + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#define VERSION_STR VERSION " (" TARGET_SYSTEM ")" +#else +#define VERSION_STR "" +#endif + +using namespace std; + +// static class variables +bool DVIToSVG::CREATE_STYLE=true; +bool DVIToSVG::USE_FONTS=true; + + +/** Returns time stamp of current date/time. */ +static string datetime () { + time_t t; + time(&t); + struct tm *tm = localtime(&t); + char *timestr = asctime(tm); + timestr[24] = 0; // remove newline + return timestr; +} + + +class PSHeaderActions : public DVIActions +{ + public : + PSHeaderActions (DVIToSVG &dvisvg) : _dvisvg(dvisvg) {} + + void special (const std::string &s) { + if (s.substr(0, 7) == "header=") + _dvisvg.specialManager().process(s, 0); + } + + BoundingBox& bbox () {return _bbox;} + + private: + DVIToSVG &_dvisvg; + BoundingBox _bbox; +}; + + +DVIToSVG::DVIToSVG (istream &is, ostream &os) + : DVIReader(is), _out(os) +{ + replaceActions(new DVIToSVGActions(*this, _svg)); +} + + +DVIToSVG::~DVIToSVG () { + delete replaceActions(0); +} + + +/** Starts the conversion process. + * @return total number of pages in DVI file */ +int DVIToSVG::convert (unsigned firstPage, unsigned lastPage) { + executePostamble(); // collect scaling and font information + if (firstPage > getTotalPages()) { + ostringstream oss; + oss << "file contains only " << getTotalPages() << " page(s)"; + throw DVIException(oss.str()); + } + if (firstPage < 0) + firstPage = 1; + + if (firstPage > 1) { + // ensure loading of PostScript prologues given at the beginning of the first page + // (prologue files are always referenced in first page) + PSHeaderActions headerActions(*this); + DVIActions *save = replaceActions(&headerActions); + executePage(1); + replaceActions(save); + } + + if (CREATE_STYLE && USE_FONTS) { + const vector<Font*> &fonts = getFontManager().getFonts(); + if (!fonts.empty()) { + XMLElementNode *styleNode = new XMLElementNode("style"); + styleNode->addAttribute("type", "text/css"); + _svg.appendToRoot(styleNode); + ostringstream style; + FORALL(fonts, vector<Font*>::const_iterator, i) { + if (!dynamic_cast<VirtualFont*>(*i)) { // skip virtual fonts + style << "text.f" << getFontManager().fontID(*i) << ' ' + << "{font-family:" << (*i)->name() + << ";font-size:" << (*i)->scaledSize() << "}\n"; + } + } + XMLCDataNode *cdata = new XMLCDataNode(style.str()); + styleNode->append(cdata); + } + } + + if (executePage(firstPage)) { // @@ + Message::mstream() << endl; + embedFonts(_svg.rootNode()); + _svg.write(_out); + _svg.reset(); + + } + return getTotalPages(); +} + + +/** This template method is called by parent class DVIReader before + * executing the BOP actions. + * @param[in] c contains information about the page (page number etc.) */ +void DVIToSVG::beginPage (Int32 *c) { + if (dynamic_cast<DVIToSVGActions*>(getActions())) { + Message::mstream() << '[' << c[0]; + _svg.appendToDoc(new XMLCommentNode(" This file was generated by dvisvgm "VERSION_STR" ")); + _svg.appendToDoc(new XMLCommentNode(" " + datetime() + " ")); + } +} + + +/** This template method is called by parent class DVIReader before + * executing the EOP actions. */ +void DVIToSVG::endPage () { + if (!dynamic_cast<DVIToSVGActions*>(getActions())) + return; + + _specialManager.notifyEndPage(); + Message::mstream() << ']'; + // set bounding box and apply page transformations + BoundingBox &bbox = getActions()->bbox(); + if (!_transCmds.empty()) { + Calculator calc; + calc.setVariable("ux", bbox.minX()); + calc.setVariable("uy", bbox.minY()); + calc.setVariable("w", bbox.width()); + calc.setVariable("h", bbox.height()); + calc.setVariable("pt", 1); + calc.setVariable("in", 72.27); + calc.setVariable("cm", 72.27/2.54); + calc.setVariable("mm", 72.27/25.4); + Matrix matrix(_transCmds, calc); + static_cast<DVIToSVGActions*>(getActions())->setPageMatrix(matrix); + if (_bboxString == "min") + bbox.transform(matrix); + } + if (string("dvi none min").find(_bboxString) == string::npos) { + istringstream iss(_bboxString); + StreamInputReader ir(iss); + ir.skipSpace(); + if (isalpha(ir.peek())) { + // set explicitly given page format + PageSize size(_bboxString); + if (size.valid()) { + // convention: DVI position (0,0) equals (1in, 1in) relative + // to the upper left vertex of the page (see DVI specification) + const double border = -72.27; + bbox = BoundingBox(border, border, size.widthInPT()+border, size.heightInPT()+border); + } + } + else { + try { + bbox = BoundingBox(_bboxString); + } + catch (const MessageException &e) { + } + } + } + else if (_bboxString == "dvi") { + // center page content + double dx = (getPageWidth()-bbox.width())/2; + double dy = (getPageHeight()-bbox.height())/2; + bbox += BoundingBox(-dx, -dy, dx, dy); + } + if (_bboxString != "none" && bbox.width() > 0) { + _svg.setBBox(bbox); + + Message::mstream() << "\npage size: " << bbox.width() << "pt" + " x " << bbox.height() << "pt" + " (" << bbox.width()/72.27*25.4 << "mm" + " x " << bbox.height()/72.27*25.4 << "mm)\n"; + } +} + + +static void collect_chars (map<const Font*, set<int> > &fm) { + typedef const map<const Font*, set<int> > UsedCharsMap; + FORALL(fm, UsedCharsMap::const_iterator, it) { + if (it->first->uniqueFont() != it->first) { + FORALL(it->second, set<int>::const_iterator, cit) + fm[it->first->uniqueFont()].insert(*cit); + } + } +} + + +/** Adds the font information to the SVG tree. + * @param[in] svgElement the font nodes are added to this node */ +void DVIToSVG::embedFonts (XMLElementNode *svgElement) { + if (!svgElement) + return; + if (!getActions()) // no dvi actions => no chars written => no fonts to embed + return; + + typedef map<const Font*, set<int> > UsedCharsMap; + const DVIToSVGActions *svgActions = static_cast<DVIToSVGActions*>(getActions()); + UsedCharsMap &usedChars = svgActions->getUsedChars(); + + collect_chars(usedChars); + + FORALL(usedChars, UsedCharsMap::const_iterator, it) { + const Font *font = it->first; + if (const PhysicalFont *ph_font = dynamic_cast<const PhysicalFont*>(font)) { + CharmapTranslator *cmt = svgActions->getCharmapTranslator(font); + // If the same character is used in various sizes we don't want to embed the complete (lengthy) path + // description multiple times because they would only differ by a scale factor. Thus it's better to + // reference the already embedded path together with a transformation attribute and let the SVG renderer + // scale the glyph properly. This is only necessary if we don't want to use font but path elements. + if (font != font->uniqueFont()) { + FORALL(it->second, set<int>::const_iterator, cit) { + ostringstream oss; + XMLElementNode *use = new XMLElementNode("use"); + oss << 'g' << getFontManager().fontID(font) << *cit; + use->addAttribute("id", oss.str()); + oss.str(""); + oss << "#g" << getFontManager().fontID(font->uniqueFont()) << *cit; + use->addAttribute("xlink:href", oss.str()); + oss.str(""); + oss << "scale(" << (font->scaledSize()/font->uniqueFont()->scaledSize()) << ')'; + use->addAttribute("transform", oss.str()); + _svg.appendToDefs(use); + } + } + else { + if (ph_font->type() == PhysicalFont::MF) { + SVGFontTraceEmitter emitter(font, getFontManager(), *cmt, _svg, USE_FONTS); + emitter.emitFont(it->second, font->name().c_str()); + } + else if (font->path()) { // path to pfb/ttf file + SVGFontEmitter emitter(font, getFontManager(), *cmt, _svg, USE_FONTS); + emitter.emitFont(it->second, font->name().c_str()); + } + else + Message::wstream(true) << "can't embed font '" << font->name() << "'\n"; + } + } + else + Message::wstream(true) << "can't embed font '" << font->name() << "'\n"; + } +} + + +/** Enables or disables processing of specials. If ignorelist == 0, all + * supported special handlers are loaded. To disable selected sets of specials, + * the corresponding prefixes can be given separated by non alpha-numeric characters, + * e.g. "color, ps, em" or "color: ps em" etc. + * A single "*" in the ignore list disables all specials. + * @param[in] ignorelist list of special prefixes to ignore + * @return the SpecialManager that handles special statements */ +const SpecialManager* DVIToSVG::setProcessSpecials (const char *ignorelist) { + if (ignorelist && strcmp(ignorelist, "*") == 0) { // ignore all specials? + _specialManager.unregisterHandlers(); + } + else { + // add special handlers + SpecialHandler *handlers[] = { + 0, // placeholder for PsSpecialHandler + new BgColorSpecialHandler, // handles background color special + new ColorSpecialHandler, // handles color specials + new DvisvgmSpecialHandler, // handles raw SVG embeddings + new EmSpecialHandler, // handles emTeX specials +// new HtmlSpecialHandler, // handles hyperref specials + new TpicSpecialHandler, // handles tpic specials + 0 + }; + SpecialHandler **p = handlers; +#if !DISABLE_GS + if (Ghostscript().available()) + *p = new PsSpecialHandler; + else +#endif + p++; + _specialManager.unregisterHandlers(); + _specialManager.registerHandlers(p, ignorelist); + } + return &_specialManager; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.h new file mode 100644 index 00000000000..f516b7ed00b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVG.h @@ -0,0 +1,60 @@ +/************************************************************************* +** DVIToSVG.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DVITOSVG_H +#define DVITOSVG_H + +#include <iostream> +#include "DVIReader.h" +#include "SpecialManager.h" +#include "SVGTree.h" + + +class DVIToSVG : public DVIReader +{ + public: + DVIToSVG (std::istream &is, std::ostream &os); + ~DVIToSVG (); + int convert (unsigned firstPage, unsigned lastPage); + const SpecialManager* setProcessSpecials (const char *ignorelist=0); + const SpecialManager& specialManager () const {return _specialManager;} + void setPageSize (const string &name) {_bboxString = name;} + void setTransformation (const std::string &cmds) {_transCmds = cmds;} + + protected: + DVIToSVG (const DVIToSVG &); + DVIToSVG operator = (const DVIToSVG &); + void beginPage (Int32 *c); + void endPage (); + void embedFonts (XMLElementNode *svgElement); + + private: + SVGTree _svg; + std::ostream &_out; ///< DVI output is written to this stream + std::string _bboxString; + std::string _transCmds; + SpecialManager _specialManager; + + public: + static bool CREATE_STYLE; ///< should <style>...</style> and class attributes be used to reference fonts? + static bool USE_FONTS; ///< if true, create font references and don't draw paths directly +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.cpp new file mode 100644 index 00000000000..b3f26173d94 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.cpp @@ -0,0 +1,225 @@ +/************************************************************************* +** DVIToSVGActions.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <cstring> +#include "BoundingBox.h" +#include "CharmapTranslator.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "Font.h" +#include "FontManager.h" +#include "Ghostscript.h" +#include "SpecialManager.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +unsigned DVIToSVGActions::PROGRESSBAR = 0; + + +DVIToSVGActions::DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg) + : _svg(svg), _dvisvg(dvisvg), _pageMatrix(0), _bgcolor(Color::WHITE) +{ + _currentFontNum = -1; + _pageCount = 0; +} + + +DVIToSVGActions::~DVIToSVGActions () { + delete _pageMatrix; + FORALL (_charmapTranslatorMap, CharmapTranslatorMap::iterator, i) + delete i->second; +} + + +void DVIToSVGActions::setPageMatrix (const Matrix &matrix) { + delete _pageMatrix; + _pageMatrix = new Matrix(matrix); +} + + +/** This method is called when a "set char" command was found in the DVI file. + * It draws a character of the current font. + * @param[in] x horizontal position of left bounding box edge + * @param[in] y vertical position of the character's baseline + * @param[in] c character code relative to the current font + * @param[in] font font to be used */ +void DVIToSVGActions::setChar (double x, double y, unsigned c, const Font *font) { +/* x *= BP; + y *= BP; */ + if (DVIToSVG::USE_FONTS) { + // If we use SVG fonts there is no need to record all font name/char/size combinations + // because the SVG font mechanism handles this automatically. It's sufficient to + // record font names and chars. The various font sizes can be ignored here. + // For a given font object, Font::uniqueFont() returns the same unique font object for + // all fonts with the same name. + font = font->uniqueFont(); + } + _usedCharsMap[font].insert(c); + + const CharmapTranslator *cmt = _charmapTranslatorMap[font->uniqueFont()]; + _svg.appendChar(c, x, y, _dvisvg.getFontManager(), *cmt); + + // update bounding box + if (font) { + /* x *= BP; + y *= BP;*/ + double s = font->scaleFactor(); // * BP; + double w = s*(font->charWidth(c) + font->italicCorr(c)); + double h = s*font->charHeight(c); + double d = s*font->charDepth(c); + BoundingBox charbox(x, y-h, x+w, y+d); + if (!getMatrix().isIdentity()) + charbox.transform(getMatrix()); + _bbox.embed(charbox); + } +} + + +/** This method is called when a "set rule" or "put rule" command was found in the + * DVI file. It draws a solid unrotated rectangle. + * @param[in] x horizontal position of left edge + * @param[in] y vertical position of bottom(!) edge + * @param[in] height length of the vertical edges + * @param[in] width length of the horizontal edges */ +void DVIToSVGActions::setRule (double x, double y, double height, double width) { +/* x *= BP; + y *= BP; + height *= BP; + width *= BP; */ + // (x,y) is the lower left corner of the rectangle + XMLElementNode *rect = new XMLElementNode("rect"); + rect->addAttribute("x", x); + rect->addAttribute("y", y-height); + rect->addAttribute("height", height); + rect->addAttribute("width", width); + if (!getMatrix().isIdentity()) + rect->addAttribute("transform", getMatrix().getSVG()); + if (getColor() != Color::BLACK) + rect->addAttribute("fill", _svg.getColor().rgbString()); + _svg.appendToPage(rect); + + // update bounding box + BoundingBox bb(x, y+height, x+width, y); + if (!getMatrix().isIdentity()) + bb.transform(getMatrix()); + _bbox.embed(bb); +} + + +void DVIToSVGActions::defineFont (int num, const Font *font) { + font = font->uniqueFont(); + if (_charmapTranslatorMap.find(font) == _charmapTranslatorMap.end()) + _charmapTranslatorMap[font] = new CharmapTranslator(font); +} + + +/** This method is called when a "set font" command was found in the DVI file. The + * font must be previously defined. + * @param[in] num unique number of the font in the DVI file (not necessarily equal to the DVI font number) + * @param[in] font pointer to the font object (always represents a physical font and never a virtual font) */ +void DVIToSVGActions::setFont (int num, const Font *font) { + _currentFontNum = num; + _svg.setFont(num, font); +} + + +/** This method is called when a "special" command was found in the DVI file. + * @param[in] s the special expression */ +void DVIToSVGActions::special (const string &s) { + try { + _dvisvg.specialManager().process(s, this, this); + // @@ output message in case of unsupported specials? + } + catch (const SpecialException &e) { + Message::estream(true) << "error in special '" << s << "': " << e.getMessage() << endl; + } +} + + +void DVIToSVGActions::beginSpecial (const char *prefix) { + static unsigned count = 0; + if (PROGRESSBAR > 0 && ++count % PROGRESSBAR == 0) { + if (count == PROGRESSBAR) + Message::mstream(false) << ':'; + Message::mstream(false) << '='; + } +} + + +void DVIToSVGActions::endSpecial (const char *) { +} + + +/** This method is called when the DVI preamble was read + * @param[in] cmt preamble comment text. */ +void DVIToSVGActions::preamble (const string &cmt) { +} + + +void DVIToSVGActions::postamble () { +} + + +/** This method is called when a "begin of page (bop)" command was found in the DVI file. + * @param[in] c array with 10 components representing \count0 ... \count9. c[0] contains the + * current (printed) page number (may differ from page count) */ +void DVIToSVGActions::beginPage (Int32 *c) { + _svg.newPage(++_pageCount); + _bbox = BoundingBox(); // clear bounding box +} + + +CharmapTranslator* DVIToSVGActions::getCharmapTranslator (const Font *font) const { + if (font) { + CharmapTranslatorMap::const_iterator it = _charmapTranslatorMap.find(font->uniqueFont()); + if (it != _charmapTranslatorMap.end()) + return it->second; + } + return 0; +} + + +/** This method is called when an "end of page (eop)" command was found in the DVI file. */ +void DVIToSVGActions::endPage () { + if (_pageMatrix) + _svg.transformPage(*_pageMatrix); + if (_bgcolor != Color::WHITE) { + XMLElementNode *r = new XMLElementNode("rect"); + r->addAttribute("x", _bbox.minX()); + r->addAttribute("y", _bbox.minY()); + r->addAttribute("width", _bbox.width()); + r->addAttribute("height", _bbox.height()); + r->addAttribute("fill", _bgcolor.rgbString()); + _svg.prependToPage(r); + } +} + + +void DVIToSVGActions::setBgColor (const Color &color) { + _bgcolor = color; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.h new file mode 100644 index 00000000000..39aace386a1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DVIToSVGActions.h @@ -0,0 +1,93 @@ +/************************************************************************* +** DVIToSVGActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DVITOSVGACTIONS_H +#define DVITOSVGACTIONS_H + +#include <map> +#include <set> +#include "BoundingBox.h" +#include "DVIActions.h" +#include "Matrix.h" +#include "SpecialActions.h" +#include "SpecialManager.h" +#include "SVGTree.h" + + +class CharmapTranslator; +class DVIToSVG; +class FileFinder; +class Font; +class XMLNode; + +class DVIToSVGActions : public DVIActions, public SpecialActions, public SpecialManager::Listener +{ + typedef std::map<const Font*, CharmapTranslator*> CharmapTranslatorMap; + typedef std::map<const Font*, std::set<int> > UsedCharsMap; + + public: + DVIToSVGActions (DVIToSVG &dvisvg, SVGTree &svg); + ~DVIToSVGActions (); + void setChar (double x, double y, unsigned c, const Font *f); + void setRule (double x, double y, double height, double width); + void setBgColor (const Color &color); + void setColor (const Color &color) {_svg.setColor(color);} + void setMatrix (const Matrix &m) {_svg.setMatrix(m);} + const Matrix& getMatrix () const {return _svg.getMatrix();} + Color getColor () const {return _svg.getColor();} + void appendToPage (XMLNode *node) {_svg.appendToPage(node);} + void appendToDefs (XMLNode *node) {_svg.appendToDefs(node);} + void moveToX (double x) {_svg.setX(x);} + void moveToY (double y) {_svg.setY(y);} + void defineFont (int num, const Font *font); + void setFont (int num, const Font *font); + void special (const string &s); + void preamble (const string &cmt); + void postamble (); + void beginPage (Int32 *c); + void endPage (); + void beginSpecial (const char *prefix); + void endSpecial (const char *prefix); + UsedCharsMap& getUsedChars () const {return _usedCharsMap;} + void setPageMatrix (const Matrix &tm); + CharmapTranslator* getCharmapTranslator (const Font *font) const; + double getX() const {return _dvisvg.getXPos();} + double getY() const {return _dvisvg.getYPos();} + void setX (double x) {_dvisvg.setXPos(x);} + void setY (double y) {_dvisvg.setYPos(y);} + BoundingBox& bbox () {return _bbox;} + + public: + static unsigned PROGRESSBAR; ///< disabled if 0, indicates skip value otherwise + + private: + SVGTree &_svg; + DVIToSVG &_dvisvg; + BoundingBox _bbox; + int _pageCount; + int _currentFontNum; + CharmapTranslatorMap _charmapTranslatorMap; + mutable UsedCharsMap _usedCharsMap; + Matrix *_pageMatrix; // transformation of whole page + Color _bgcolor; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.cpp new file mode 100644 index 00000000000..e8d80731f51 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.cpp @@ -0,0 +1,115 @@ +/************************************************************************* +** Directory.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "Directory.h" + +using namespace std; + +#ifdef __WIN32__ + #include <windows.h> +#else + #include <errno.h> + #include <sys/stat.h> +#endif + + +Directory::Directory () { +#if __WIN32__ + handle = INVALID_HANDLE_VALUE; +#else + dir = 0; +#endif +} + + +Directory::Directory (string dirname) { + open(dirname); +} + +Directory::~Directory () { + close(); +} + + +bool Directory::open (string dname) { + dirname = dname; +#ifdef __WIN32__ + firstread = true; + if (dname[dname.length()-1] == '/' || dname[dname.length()-1] == '\\') + dname = dname.substr(0, dname.length()-1); + dname += "\\*"; + handle = FindFirstFile(dname.c_str(), &fileData); + return handle != INVALID_HANDLE_VALUE; +#else + dir = opendir(dirname.c_str()); + return dir; +#endif +} + + +void Directory::close () { +#ifdef __WIN32__ + FindClose(handle); +#else + closedir(dir); +#endif +} + + +/** Reads first/next directory entry. + * @param[in] type type of entry to return (a: file or dir, f: file, d: dir) + * @return name of entry */ +const char* Directory::read (char type) { +#ifdef __WIN32__ + if (handle == INVALID_HANDLE_VALUE) + return 0; + while (firstread || FindNextFile(handle, &fileData)) { + firstread = false; + if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (type == 'a' || type == 'd') + return fileData.cFileName; + } + else if (type == 'a' || type == 'f') + return fileData.cFileName; + } + FindClose(handle); + handle = INVALID_HANDLE_VALUE; + return 0; +#else + if (!dir) + return 0; + while ((dirent = readdir(dir))) { + string path = string(dirname) + "/" + dirent->d_name; + struct stat stats; + stat(path.c_str(), &stats); + if (S_ISDIR(stats.st_mode)) { + if (type == 'a' || type == 'd') + return dirent->d_name; + } + else if (type == 'a' || type == 'f') + return dirent->d_name; + } + closedir(dir); + dir = 0; + return 0; +#endif +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.h new file mode 100644 index 00000000000..024b5b31c78 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Directory.h @@ -0,0 +1,54 @@ +/************************************************************************* +** Directory.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DIRECTORY_H +#define DIRECTORY_H + +#include <string> +#ifdef __WIN32__ + #include <windows.h> +#else + #include <dirent.h> +#endif + +class Directory +{ + public: + Directory (); + Directory (std::string path); + ~Directory (); + bool open (std::string path); + void close (); + const char* read (char type='a'); + std::string getEntry () const; + + private: + std::string dirname; +#ifdef __WIN32__ + bool firstread; + HANDLE handle; + WIN32_FIND_DATA fileData; +#else + DIR *dir; + struct dirent *dirent; +#endif +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.cpp new file mode 100644 index 00000000000..dae575ce107 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.cpp @@ -0,0 +1,175 @@ +/************************************************************************* +** DvisvgmSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include "DvisvgmSpecialHandler.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +/** Replaces constants of the form {?name} by their corresponding value. + * @param[in,out] str text to expand + * @param[in] actions interfcae to the world outside the special handler */ +static void expand_constants (string &str, SpecialActions *actions) { + struct Constant { + const char *name; + string val; + } + constants[] = { + {"x", XMLString(actions->getX())}, + {"y", XMLString(actions->getY())}, + {"color", actions->getColor().rgbString()}, + {"nl", "\n"}, + {0, ""} + }; + for (const Constant *p=constants; p->name; p++) { + const string pattern = string("{?")+p->name+"}"; + size_t pos = str.find(pattern); + while (pos != string::npos) { + str.replace(pos, strlen(p->name)+3, p->val); + pos = str.find(pattern, pos+p->val.length()); // look for further matches + } + } +} + + +/** Embeds the virtual rectangle (x, y ,w , h) into the current bounding box, + * where (x,y) is the lower left vertex composed of the current DVI position. + * @param[in] w width of the rectangle in TeX point units + * @param[in] h height of the rectangle in TeX point units + * @param[in] d depth of the rectangle in TeX point units */ +static void update_bbox (double w, double h, double d, SpecialActions *actions) { + double x = actions->getX(); + double y = actions->getY(); + actions->bbox().embed(BoundingBox(x, y, x+w, y-h)); + actions->bbox().embed(BoundingBox(x, y, x+w, y+d)); +} + + +/** Inserts raw text into the SVG tree. + * @param[in,out] in the raw text is read from this input buffer + * @param[in] actions interfcae to the world outside the special handler + * @param[in] group true if the text should be wrapped by a group element */ +static void raw (InputReader &in, SpecialActions *actions, bool group=false) { + string str; + while (!in.eof()) { + char c = in.get(); + if (isprint(c)) + str += c; + } + expand_constants(str, actions); + if (!str.empty()) { + XMLNode *node = new XMLTextNode(str); + if (group) { + XMLElementNode *g = new XMLElementNode("g"); + g->addAttribute("x", actions->getX()); + g->addAttribute("y", actions->getY()); + if (actions->getColor() != Color::BLACK) + g->addAttribute("fill", actions->getColor().rgbString()); + g->append(node); + node = g; + } + actions->appendToPage(node); + } +} + + +/** Evaluates the special dvisvgm:bbox. + * variant 1: dvisvgm:bbox [r[el]] <width> <height> [<depth>] + * variant 2: dvisvgm:bbox a[bs] <x1> <y1> <x2> <y2> + * variant 3: dvisvgm:bbox f[ix] <x1> <y1> <x2> <y2> */ +static void bbox (InputReader &in, SpecialActions *actions) { + in.skipSpace(); + char c = in.peek(); + if (isalpha(c)) { + while (!isspace(in.peek())) // skip trailing characters + in.get(); + if (c == 'a' || c == 'f') { + double p[4]; + for (int i=0; i < 4; i++) + p[i] = in.getDouble(); + BoundingBox b(p[0], p[1], p[2], p[3]); + if (c == 'a') + actions->bbox().embed(b); + else { + actions->bbox() = b; + actions->bbox().lock(); + } + } + } + else + c = 'r'; // no mode specifier => relative box parameters + + if (c == 'r') { + double w = in.getDouble(); + double h = in.getDouble(); + double d = in.getDouble(); + update_bbox(w, h, d, actions); + } +} + + +static void img (InputReader &in, SpecialActions *actions) { + double w = in.getDouble(); + double h = in.getDouble(); + string f = in.getString(); + update_bbox(w, h, 0, actions); + XMLElementNode *img = new XMLElementNode("image"); + img->addAttribute("x", actions->getX()); + img->addAttribute("y", actions->getY()); + img->addAttribute("width", w); + img->addAttribute("height", h); + img->addAttribute("xlink:href", f); + if (actions && !actions->getMatrix().isIdentity()) + img->addAttribute("transform", actions->getMatrix().getSVG()); + actions->appendToPage(img); +} + + +/** Evaluates and executes a dvisvgm special statement. + * @param[in] prefix special prefix read by the SpecialManager + * @param[in] is the special statement is read from this stream + * @param[in,out] in the raw text is read from this input buffer */ +bool DvisvgmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (actions) { + StreamInputBuffer ib(is); + BufferInputReader in(ib); + string cmd = in.getWord(); + if (cmd == "raw") // raw <text> + raw(in, actions); + else if (cmd == "bbox") // bbox [r] <width> <height> <depth> or bbox a <x1> <y1> <x2> <y2> + bbox(in, actions); + else if (cmd == "img") { // img <width> <height> <file> + img(in, actions); + } + } + return true; +} + + +const char** DvisvgmSpecialHandler::prefixes () const { + static const char *pfx[] = {"dvisvgm:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.h new file mode 100644 index 00000000000..8ecf780cf8f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/DvisvgmSpecialHandler.h @@ -0,0 +1,35 @@ +/************************************************************************* +** DvisvgmSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef DVISVGMSPECIALHANDLER_H +#define DVISVGMSPECIALHANDLER_H + +#include "SpecialHandler.h" + +class DvisvgmSpecialHandler : public SpecialHandler +{ + public: + const char* name () const {return "dvisvgm";} + const char* info () const {return "special set for embedding raw SVG snippets";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &in, SpecialActions *actions); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.cpp new file mode 100644 index 00000000000..386a28eed3d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.cpp @@ -0,0 +1,230 @@ +/************************************************************************* +** EmSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "XMLNode.h" + +using namespace std; + + +EmSpecialHandler::EmSpecialHandler () : _linewidth(0.4), _actions(0) { +} + + +/** 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] c cut direction ('h', 'v' or 'p') + * @param[in] v 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 c, const DPair &v, double lw) { + if (c == 'p') + return v.ortho()/v.length() * (lw/2); + DPair cut; + if (c == 'v' && v.x() != 0) { + double slope = v.y()/v.x(); + double h = sqrt(lw*lw*(1+slope*slope)); + cut.y(0.5*h); + } + else if (v.y() != 0) { // c == 'h' + double slope = v.x()/v.y(); + double h = sqrt(lw*lw*(1+slope*slope)); + double sgn = slope < 0 ? 1.0 : -1.0; + cut.x(0.5*h*sgn); + } + return cut; +} + + +/** Creates the SVG element that will a the line. + * @param[in] p1 first endpoint in TeX point units + * @param[in] p2 second endpoint in TeX 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 TeX point units */ +static void create_line (const DPair &p1, const DPair &p2, char c1, char c2, double lw, SpecialActions *actions) { + XMLElementNode *node=0; + DPair dir = p2-p1; + if (dir.x() == 0 || dir.y() == 0 || (c1 == 'p' && c2 == 'p')) { + // draw regular line + node = new XMLElementNode("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().rgbString()); + // update bounding box + actions->bbox().embed(p1); + actions->bbox().embed(p2); + } + 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; + node = new XMLElementNode("polygon"); + ostringstream oss; + oss << q11.x() << ',' << q11.y() << ' ' + << q12.x() << ',' << q12.y() << ' ' + << q22.x() << ',' << q22.y() << ' ' + << q21.x() << ',' << q21.y(); + node->addAttribute("points", oss.str()); + if (actions->getColor() != Color::BLACK) + node->addAttribute("fill", actions->getColor().rgbString()); + // update bounding box + actions->bbox().embed(q11); + actions->bbox().embed(q12); + actions->bbox().embed(q21); + actions->bbox().embed(q22); + } + actions->appendToPage(node); +} + + +static double read_length (InputReader &in) { + struct Unit { + const char *name; + double factor; + } + units[] = { + {"pt", 1.0}, + {"pc", 12.0}, + {"in", 72.27}, + {"bp", 72.27/72}, + {"cm", 72.27/2.54}, + {"mm", 72.27/25.4}, + {"dd", 1238.0/1157}, + {"cc", 1238.0/1157*12}, + {"sp", 1.0/65536}, + {0, 0} + }; + double len = in.getDouble(); + in.skipSpace(); + for (Unit *p=units; p->name; p++) + if (in.check(p->name)) { + len *= p->factor; + break; + } + return len; +} + + +bool EmSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + // em:moveto => move graphic cursor to dvi cursor + // em:lineto => draw line from graphic cursor to dvi cursor, move graphic cursor to dvi cursor + // 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 + + if (actions) { + _actions = actions; // save pointer to SpecialActions for later use in endPage + StreamInputBuffer ib(is, 128); + BufferInputReader in(ib); + string cmd = in.getWord(); + if (cmd == "moveto") + _pos = DPair(actions->getX(), actions->getY()); + else if (cmd == "lineto") { + DPair p(actions->getX(), actions->getY()); + create_line(_pos, p, 'p', 'p', _linewidth, actions); + _pos = p; + } + else if (cmd == "linewidth") + _linewidth = read_length(in); + else if (cmd == "point") { + DPair p(actions->getX(), actions->getY()); + int n = in.getInt(); + if (in.getPunct() == ',') { + p.x(in.getDouble()); + if (in.getPunct() == ',') + p.y(in.getDouble()); + } + _points[n] = p; + } + else if (cmd == "line") { + int n1 = in.getInt(); + int c1 = 'p'; + if (isalpha(in.peek())) + c1 = in.get(); + in.getPunct(); + int n2 = in.getInt(); + int c2 = 'p'; + if (isalpha(in.peek())) + c2 = in.get(); + double lw = _linewidth; + if (in.getPunct() == ',') + lw = read_length(in); + map<int,DPair>::iterator it1=_points.find(n1); + map<int,DPair>::iterator it2=_points.find(n2); + if (it1 != _points.end() && it2 != _points.end()) + create_line(it1->second, it2->second, c1, c2, lw, actions); + else { + // Line endpoints havn't necessarily to be defined before + // a line definition. If a point wasn't defined yet we push the line + // in a wait list and process the lines at the end of the page. + _lines.push_back(Line(n1, n2, c1, c2, lw)); + } + } + } + return true; +} + + +/** 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::endPage () { + if (_actions) { + FORALL(_lines, list<Line>::iterator, it) { + map<int,DPair>::iterator pit1=_points.find(it->p1); + map<int,DPair>::iterator pit2=_points.find(it->p2); + if (pit1 != _points.end() && pit2 != _points.end()) + create_line(pit1->second, pit2->second, it->c1, it->c2, it->width, _actions); + // all lines with still undefined points are ignored + } + } + // line and point definitions are local to a page + _lines.clear(); + _points.clear(); +} + + +const char** EmSpecialHandler::prefixes () const { + static const char *pfx[] = {"em:", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.h new file mode 100644 index 00000000000..aaee7908b73 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/EmSpecialHandler.h @@ -0,0 +1,55 @@ +/************************************************************************* +** EmSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef EMSPECIALHANDLER_H +#define EMSPECIALHANDLER_H + +#include <list> +#include <map> +#include "Pair.h" +#include "SpecialHandler.h" + + +class EmSpecialHandler : public SpecialHandler +{ + struct Line { + Line (int pp1, int pp2, char cc1, char cc2, double w) : p1(pp1), p2(pp2), c1(cc1), c2(cc2), width(w) {} + int p1, p2; ///< point numbers of line ends + char c1, c2; ///< cut type of line ends (h, v or p) + double width; ///< line width + }; + + public: + EmSpecialHandler (); + const char* name () const {return "em";} + const char* info () const {return "line drawing statements of the emTeX special set";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &in, SpecialActions *actions); + void endPage (); + + private: + std::map<int, DPair> _points; ///< points defined by special em:point + std::list<Line> _lines; ///< list of lines with undefined end points + double _linewidth; ///< global line width + DPair _pos; ///< current position of "graphic cursor" + SpecialActions *_actions; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.cpp new file mode 100644 index 00000000000..5ae027e164f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.cpp @@ -0,0 +1,264 @@ +/************************************************************************* +** FileFinder.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <fstream> +#include <map> +#include <string> +#include "FileFinder.h" +#include "Message.h" +#include "macros.h" + + +#ifdef MIKTEX + #include "MessageException.h" + #import <MiKTeX207-session.tlb> + using namespace MiKTeXSession2_7; + + static ISession2Ptr miktex_session; +#else + // unfortunately, the kpathsea headers are not C++-ready, + // so we have to wrap it with some ugly code + namespace KPS { + extern "C" { + #include <kpathsea/kpathsea.h> + } + } + using namespace KPS; +#endif + +// --------------------------------------------------- +// static member variables of FileFinder::Impl + +FileFinder::Impl* FileFinder::Impl::_instance = 0; +const char *FileFinder::Impl::_progname = 0; +bool FileFinder::Impl::_mktex_enabled = false; +FontMap FileFinder::Impl::_fontmap; +const char *FileFinder::Impl::_usermapname = 0; + +// --------------------------------------------------- + + +FileFinder::Impl::Impl () +{ +#ifdef MIKTEX + if (FAILED(CoInitialize(0))) + throw MessageException("COM library could not be initialized\n"); + + HRESULT hres = miktex_session.CreateInstance(L"MiKTeX.Session"); + if (FAILED(hres)) + throw MessageException("MiKTeX.Session could not be initialized"); +#else + kpse_set_program_name(_progname, NULL); + // enable tfm and mf generation (actually invoked by calls of kpse_make_tex) + kpse_set_program_enabled(kpse_tfm_format, 1, kpse_src_env); + kpse_set_program_enabled(kpse_mf_format, 1, kpse_src_env); + kpse_make_tex_discard_errors = false; // don't suppress messages of mktexFOO tools +#endif +} + + +FileFinder::Impl::~Impl () { + delete _instance; +#ifdef MIKTEX + miktex_session = 0; // avoid automatic calling of Release() after CoUninitialize() + CoUninitialize(); +#endif +} + + +FileFinder::Impl& FileFinder::Impl::instance () { + if (!_instance) { + _instance = new FileFinder::Impl; + _instance->initFontMap(); + } + return *_instance; +} + + +/** Determines filetype by the filename extension and calls kpse_find_file + * to actually look up the file. + * @param[in] fname name of file to look up + * @return file path on success, 0 otherwise */ +const char* FileFinder::Impl::findFile (const std::string &fname) { + size_t pos = fname.rfind('.'); + if (pos == std::string::npos) + return 0; // no extension => no search + const std::string ext = fname.substr(pos+1); // file extension +#ifdef MIKTEX + _bstr_t path; + static string ret; + try { + if (miktex_session->FindFile(fname.c_str(), path.GetAddress())) { + ret = path; + return ret.c_str(); + } + } + catch (_com_error e) { + throw MessageException((const char*)e.Description()); + } + return 0; + +#else + + static std::map<std::string, kpse_file_format_type> types; + if (types.empty()) { + types["tfm"] = kpse_tfm_format; + types["pfb"] = kpse_type1_format; + types["vf"] = kpse_vf_format; + types["mf"] = kpse_mf_format; + types["ttf"] = kpse_truetype_format; + types["map"] = kpse_fontmap_format; + types["sty"] = kpse_tex_format; + types["enc"] = kpse_enc_format; + types["pro"] = kpse_tex_ps_header_format; + } + std::map<std::string, kpse_file_format_type>::iterator it = types.find(ext.c_str()); + if (it == types.end()) + return 0; + if (char *path = kpse_find_file(fname.c_str(), it->second, 0)) { + // In the current version of libkpathsea, each call of kpse_find_file produces + // a memory leak since the path buffer is not freed. I don't think we can do + // anything against it here... + static std::string buf; + buf = path; + std::free(path); + return buf.c_str(); + } + return 0; +#endif +} + + +/** Checks whether the given file is mapped to a different name and if the + * file can be found under this name. + * @param[in] fname name of file to look up + * @param[in] fontmap font mappings + * @return file path on success, 0 otherwise */ +const char* FileFinder::Impl::findMappedFile (std::string fname) { + size_t pos = fname.rfind('.'); + if (pos == std::string::npos) + return 0; + const std::string ext = fname.substr(pos+1); // file extension + const std::string base = fname.substr(0, pos); + const char *mapped_name = _fontmap.lookup(base); + if (mapped_name) { + fname = std::string(mapped_name) + "." + ext; + const char *path; + if ((path = findFile(fname)) || (path = mktex(fname))) + return path; + } + return 0; +} + + +/** Runs external mktexFOO tool to create missing tfm or mf file. + * @param[in] fname name of file to build + * @return file path on success, 0 otherwise */ +const char* FileFinder::Impl::mktex (const std::string &fname) { + size_t pos = fname.rfind('.'); + if (!_mktex_enabled || pos == std::string::npos) + return 0; + + std::string ext = fname.substr(pos+1); // file extension + if (ext != "tfm" && ext != "mf") + return 0; + + std::string base = fname.substr(0, pos); + const char *path = 0; +#ifdef MIKTEX + // maketfm and makemf are located in miktex/bin which is in the search PATH + string toolname = (ext == "tfm" ? "maketfm" : "makemf"); + system((toolname+".exe "+fname).c_str()); + path = findFile(fname); +#else + kpse_file_format_type type = (ext == "tfm" ? kpse_tfm_format : kpse_mf_format); + path = kpse_make_tex(type, fname.c_str()); +#endif + return path; +} + + +/** Initializes a font map by reading the map file(s). + * @param[in,out] fontmap font map to be initialized */ +void FileFinder::Impl::initFontMap () { + const char *usermapname = _usermapname; + if (usermapname && *usermapname == '+') // read additional map entries? + usermapname++; + if (usermapname) { + // try to read user font map file + const char *mappath = 0; + if (!_fontmap.read(usermapname)) { + if ((mappath = findFile(usermapname))) + _fontmap.read(mappath); + else + Message::wstream(true) << "map file '" << usermapname << "' not found\n"; + } + } + if (!usermapname || *_usermapname == '+') { + const char *mapfiles[] = {"ps2pk.map", "dvipdfm.map", "psfonts.map", 0}; + const char *mf=0; + for (const char **p=mapfiles; *p && !mf; p++) + if ((mf = findFile(*p))!=0) + _fontmap.read(mf); + if (!mf) + Message::wstream(true) << "none of the default map files could be found"; + } +} + + +/** Searches a file in the TeX directory tree. + * If the file doesn't exist, maximal two further steps are applied + * (if "extended" is true): + * - checks whether the filename is mapped to a different name and returns + * the path to that name + * - in case of tfm or mf files: invokes the external mktextfm/mktexmf tool + * to create the missing file + * @param[in] fname name of file to look up + * @param[in] extended if true, use fontmap lookup and mktexFOO calls + * @return path to file on success, 0 otherwise */ +const char* FileFinder::Impl::lookup (const std::string &fname, bool extended) { + const char *path; + if ((path = findFile(fname)) || (extended && ((path = findMappedFile(fname)) || (path = mktex(fname))))) + return path; + return 0; +} + + +/** Returns the path to the corresponding encoding file for a given font file. + * @param[in] fname name of the font file + * @return path to encoding file on success, 0 otherwise */ +const char* FileFinder::Impl::lookupEncFile (std::string fname) { + if (const char *encname = lookupEncName(fname)) { + fname = std::string(encname) + ".enc"; + const char *path = findFile(fname); + if (path) + return path; + } + return 0; +} + + +const char* FileFinder::Impl::lookupEncName (std::string fname) { + size_t pos = fname.rfind('.'); + if (pos != std::string::npos) + fname = fname.substr(0, pos); // strip extension + return _fontmap.encoding(fname); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.h new file mode 100644 index 00000000000..775dfe3a516 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileFinder.h @@ -0,0 +1,79 @@ +/************************************************************************* +** FileFinder.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef KPSFILEFINDER_H +#define KPSFILEFINDER_H + +#include <string> +#include "FontMap.h" + +class FileFinder +{ + class Impl + { + public: + const char* lookup (const std::string &fname, bool extended); + const char* lookupEncFile (std::string fontname); + const char* lookupEncName (std::string fname); + static Impl& instance (); + static void setProgname (const char *progname) {_progname = progname;} + static void enableMktex (bool enable) {_mktex_enabled = enable;} + static void setUserFontMap (const char *fname) {_usermapname = fname;} + + protected: + Impl (); + ~Impl (); + const char* findFile (const std::string &fname); + const char* findMappedFile (std::string fname); + const char* mktex (const std::string &fname); + void initFontMap (); + + private: + static Impl *_instance; + static const char *_progname; + static bool _mktex_enabled; + static FontMap _fontmap; + static const char *_usermapname; + }; + + public: + static const char* lookup (const std::string &fname, bool extended=true) { + return Impl::instance().lookup(fname, extended); + } + + static const char* lookupEncFile (std::string fontname) { + return Impl::instance().lookupEncFile(fontname); + } + + static const char* lookupEncName (std::string fname) { + return Impl::instance().lookupEncName(fname); + } + + static const void init (const char *progname, bool enable_mktexmf) { + Impl::setProgname(progname); + Impl::enableMktex(enable_mktexmf); + } + + static void setUserFontMap (const char *fname) { + Impl::setUserFontMap(fname); + } +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.cpp new file mode 100644 index 00000000000..b2da18fbf69 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.cpp @@ -0,0 +1,306 @@ +/************************************************************************* +** FileSystem.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <cstring> +#include <fstream> +#include "FileSystem.h" + +#ifdef __GNUC__ +#include <unistd.h> +#endif + + +using namespace std; + +#ifdef __WIN32__ + #include <direct.h> + #include <windows.h> + const char *FileSystem::DEVNULL = "nul"; + const char FileSystem::PATHSEP = '\\'; + #define unlink _unlink +#else + #include <dirent.h> + #include <pwd.h> + #include <sys/stat.h> + #include <sys/types.h> + const char *FileSystem::DEVNULL = "/dev/null"; + const char FileSystem::PATHSEP = '/'; +#endif + + +bool FileSystem::remove (const string &fname) { + return unlink(fname.c_str()) == 0; +} + + +bool FileSystem::rename (const string &oldname, const string &newname) { + return ::rename(oldname.c_str(), newname.c_str()) == 0; +} + + +UInt64 FileSystem::filesize (const string &fname) { +#ifdef __WIN32__ + // unfortunately, stat doesn't work properly under Windows + // so we have to use this freaky code + WIN32_FILE_ATTRIBUTE_DATA attr; + GetFileAttributesExA(fname.c_str(), GetFileExInfoStandard, &attr); + return (static_cast<UInt64>(attr.nFileSizeHigh) << (8*sizeof(attr.nFileSizeLow))) | attr.nFileSizeLow; +#else + struct stat attr; + return (stat(fname.c_str(), &attr) == 0) ? attr.st_size : 0; +#endif +} + + +string FileSystem::adaptPathSeperators (string path) { + for (size_t i=0; i < path.length(); i++) + if (path[i] == PATHSEP) + path[i] = '/'; + return path; +} + + +string FileSystem::getcwd () { + char buf[1024]; +#ifdef __WIN32__ + return adaptPathSeperators(_getcwd(buf, 1024)); +#else + return ::getcwd(buf, 1024); +#endif +} + + +/** Changes the work directory. + * @param[in] path to new work directory + * @return true on success */ +bool FileSystem::chdir (const char *dir) { + bool success = false; + if (dir) { +#ifdef __WIN32__ + success = (_chdir(dir) == 0); +#else + success = (chdir(dir) == 0); +#endif + } + return success; +} + + +/** Returns the user's home directory. */ +const char* FileSystem::userdir () { +#ifdef __WIN32__ + const char *drive=getenv("HOMEDRIVE"); + const char *path=getenv("HOMEPATH"); + if (drive && path) { + static string ret = string(drive)+path; + if (!ret.empty()) + return ret.c_str(); + } + return 0; +#else + const char *dir=getenv("HOME"); + if (!dir) { + if (const char *user=getenv("USER")) { + if (struct passwd *pw=getpwnam(user)) + dir = pw->pw_dir; + } + } + return dir; +#endif +} + + +/** Private wrapper function for mkdir: creates a single folder. + * @param[in] dir folder name + * @return true on success */ +static bool s_mkdir (const char *dir) { + bool success = true; + if (!FileSystem::exists(dir)) { +#ifdef __WIN32__ + success = (_mkdir(dir) == 0); +#else + success = (mkdir(dir, 0776) == 0); +#endif + } + return success; +} + + +static bool inline s_rmdir (const char *dir) { +#ifdef __WIN32__ + return (_rmdir(dir) == 0); +#else + return (rmdir(dir) == 0); +#endif +} + + +/** Removes leading and trailing whitespace from a string. */ +static string trim (const string &str) { + int first=0, last=str.length()-1; + while (isspace(str[first])) + first++; + while (isspace(str[last])) + last--; + return str.substr(first, last-first+1); +} + + +/** Creates a new folder relative to the current work directory. If necessary, + * the parent folders are also created. + * @param[in] dir single folder name or path to folder + * @return true if folder(s) could be created */ +bool FileSystem::mkdir (const char *dir) { + bool success = false; + if (dir) { + success = true; + const string dirstr = adaptPathSeperators(trim(dir)); + for (size_t pos=1; success && (pos = dirstr.find('/', pos)) != string::npos; pos++) + success &= s_mkdir(dirstr.substr(0, pos).c_str()); + success &= s_mkdir(dirstr.c_str()); + } + return success; +} + + +/** Removes a directory and its contents. + * @param[in] dirname path to directory + * @return true on success */ +bool FileSystem::rmdir (const char *dirname) { + bool ok = false; + if (dirname && isDirectory(dirname)) { + ok = true; +#ifdef __WIN32__ + string pattern = string(dirname) + "/*"; + WIN32_FIND_DATA data; + HANDLE h = FindFirstFile(pattern.c_str(), &data); + bool ready = (h == INVALID_HANDLE_VALUE); + while (!ready && ok) { + const char *fname = data.cFileName; + string path = string(dirname) + "/" + fname; + if (isDirectory(path.c_str())) { + if (strcmp(fname, ".") != 0 && strcmp(fname, "..") != 0) + ok = rmdir(path.c_str()) && s_rmdir(path.c_str()); + } + else if (isFile(path.c_str())) + ok = remove(path); + else + ok = false; + ready = !FindNextFile(h, &data); + } + FindClose(h); +#else + if (DIR *dir = opendir(dirname)) { + struct dirent *ent; + while ((ent = readdir(dir)) && ok) { + const char *fname = ent->d_name; + string path = string(fname) + "/" + fname; + if (isDirectory(path.c_str())) { + if (strcmp(fname, ".") != 0 && strcmp(fname, "..") != 0) + ok = rmdir(path.c_str()) && s_rmdir(path.c_str()); + } + else if (isFile(path.c_str())) + ok = remove(path); + else + ok = false; + } + closedir(dir); + } +#endif + ok = s_rmdir(dirname); + } + return ok; +} + + +/** Checks if a file or directory exits. */ +bool FileSystem::exists (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + return GetFileAttributes(fname) != INVALID_FILE_ATTRIBUTES; +#else + struct stat attr; + return stat(fname, &attr) == 0; +#endif +} + + +/** Returns true if 'fname' references a directory. */ +bool FileSystem::isDirectory (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + return GetFileAttributes(fname) & FILE_ATTRIBUTE_DIRECTORY; +#else + struct stat attr; + return stat(fname, &attr) == 0 && S_ISDIR(attr.st_mode); +#endif +} + + +/** Returns true if 'fname' references a file. */ +bool FileSystem::isFile (const char *fname) { + if (!fname) + return false; +#ifdef __WIN32__ + ifstream ifs(fname); + return ifs; +#else + struct stat attr; + return stat(fname, &attr) == 0 && S_ISREG(attr.st_mode); +#endif +} + + +int FileSystem::collect (const char *dirname, vector<string> &entries) { + entries.clear(); +#ifdef __WIN32__ + string pattern = string(dirname) + "/*"; + WIN32_FIND_DATA data; + HANDLE h = FindFirstFile(pattern.c_str(), &data); + bool ready = (h == INVALID_HANDLE_VALUE); + while (!ready) { + string fname = data.cFileName; + string path = string(dirname)+"/"+fname; + string typechar = isFile(path.c_str()) ? "f" : isDirectory(path.c_str()) ? "d" : "?"; + if (fname != "." && fname != "..") + entries.push_back(typechar+fname); + ready = !FindNextFile(h, &data); + } + FindClose(h); +#else + if (DIR *dir = opendir(dirname)) { + struct dirent *ent; + while ((ent = readdir(dir))) { + string fname = ent->d_name; + string path = string(dirname)+"/"+fname; + string typechar = isFile(path.c_str()) ? "f" : isDirectory(path.c_str()) ? "d" : "?"; + if (fname != "." && fname != "..") + entries.push_back(typechar+fname); + } + closedir(dir); + } +#endif + return entries.size(); +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.h new file mode 100644 index 00000000000..5efe814b392 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FileSystem.h @@ -0,0 +1,47 @@ +/************************************************************************* +** FileSystem.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include <string> +#include <vector> +#include "types.h" + +struct FileSystem +{ + static bool remove (const std::string &fname); + static bool rename (const std::string &oldname, const std::string &newname); + static UInt64 filesize (const std::string &fname); + static std::string adaptPathSeperators (std::string path); + static std::string getcwd (); + static bool chdir (const char *dir); + static bool exists (const char *file); + static bool mkdir (const char *dir); + static bool rmdir (const char *fname); + static int collect (const char *dirname, std::vector<std::string> &entries); + static bool isDirectory (const char *fname); + static bool isFile (const char *fname); + static const char* userdir (); + static const char* DEVNULL; + static const char PATHSEP; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.cpp new file mode 100644 index 00000000000..a36725aa4be --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.cpp @@ -0,0 +1,125 @@ +/************************************************************************* +** Font.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <iostream> +#include <fstream> +#include <sstream> +#include "Font.h" +#include "FileFinder.h" +#include "Message.h" +#include "TFM.h" +#include "VFReader.h" +#include "macros.h" + +using namespace std; + + +TFMFont::TFMFont (string name, UInt32 cs, double ds, double ss) + : tfm(0), fontname(name), checksum(cs), dsize(ds), ssize(ss) +{ +} + + +TFMFont::~TFMFont () { + delete tfm; +} + + +const TFM* TFMFont::getTFM () const { + if (!tfm) { + tfm = TFM::createFromFile(fontname.c_str()); + if (!tfm) + throw FontException("can't find "+fontname+".tfm"); + } + return tfm; +} + + +double TFMFont::charWidth (int c) const {return getTFM()->getCharWidth(c);} +double TFMFont::charDepth (int c) const {return getTFM()->getCharDepth(c);} +double TFMFont::charHeight (int c) const {return getTFM()->getCharHeight(c);} +double TFMFont::italicCorr (int c) const {return getTFM()->getItalicCorr(c);} + +////////////////////////////////////////////////////////////////////////////// + +Font* PhysicalFont::create (string name, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type) { + return new PhysicalFontImpl(name, checksum, dsize, ssize, type); +} + + +Font* VirtualFont::create (string name, UInt32 checksum, double dsize, double ssize) { + return new VirtualFontImpl(name, checksum, dsize, ssize); +} + +////////////////////////////////////////////////////////////////////////////// + +PhysicalFontImpl::PhysicalFontImpl (string name, UInt32 cs, double ds, double ss, PhysicalFont::Type type) + : TFMFont(name, cs, ds, ss), filetype(type) +{ +} + + +const char* PhysicalFontImpl::path () const { + string ext; + switch (filetype) { + case PFB: ext = "pfb"; break; + case TTF: ext = "ttf"; break; + case MF : ext = "mf"; break; + } + return FileFinder::lookup(name()+"."+ext); +} + + +////////////////////////////////////////////////////////////////////////////// + +VirtualFontImpl::VirtualFontImpl (string name, UInt32 cs, double ds, double ss) + : TFMFont(name, cs, ds, ss) +{ +} + + +VirtualFontImpl::~VirtualFontImpl () { + // delete dvi vectors received by VFReaderAction + for (map<UInt32, DVIVector*>::iterator i=charDefs.begin(); i != charDefs.end(); ++i) + delete i->second; +} + + +const char* VirtualFontImpl::path () const { + return FileFinder::lookup(name()+".vf"); +} + + +void VirtualFontImpl::assignChar (UInt32 c, DVIVector *dvi) { + if (dvi) { + if (charDefs.find(c) == charDefs.end()) + charDefs[c] = dvi; + else + delete dvi; + } +} + + +const vector<UInt8>* VirtualFontImpl::getDVI (int c) const { + map<UInt32,DVIVector*>::const_iterator it = charDefs.find(c); + return (it == charDefs.end() ? 0 : it->second); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.h new file mode 100644 index 00000000000..bbd91780a55 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Font.h @@ -0,0 +1,230 @@ +/************************************************************************* +** Font.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONT_H +#define FONT_H + +#include <map> +#include <string> +#include <vector> +#include "MessageException.h" +#include "VFActions.h" +#include "VFReader.h" +#include "types.h" + +using std::map; +using std::string; +using std::vector; + + +class FontEncoding; +class TFM; + + +/** Abstract base for all font classes. */ +struct Font +{ + virtual ~Font () {} + virtual Font* clone (double ds, double sc) const =0; + virtual const Font* uniqueFont () const =0; + virtual string name () const =0; + virtual double designSize () const =0; + virtual double scaledSize () const =0; + virtual double scaleFactor () const {return scaledSize()/designSize();} + virtual double charWidth (int c) const =0; + virtual double charDepth (int c) const =0; + virtual double charHeight (int c) const =0; + virtual double italicCorr (int c) const =0; + virtual const TFM* getTFM () const =0; + virtual const char* path () const =0; +}; + + +/** Empty font without any glyphs. Instances of this class are used + * if no physical or virtual font file can be found. + * The metric values returned by the member functions are based on cmr10. */ +struct EmptyFont : public Font +{ + public: + EmptyFont (string name) : fontname(name) {} + Font* clone (double ds, double sc) const {return new EmptyFont(*this);} + const Font* uniqueFont () const {return this;} + string name () const {return fontname;} + double designSize () const {return 10;} // cmr10 design size in pt + double scaledSize () const {return 10;} // cmr10 scaled size in pt + double charWidth (int c) const {return 9.164;} // width of cmr10's 'M' in pt + double charHeight (int c) const {return 6.833;} // height of cmr10's 'M' in pt + double charDepth (int c) const {return 0;} + double italicCorr (int c) const {return 0;} + const TFM* getTFM () const {return 0;} + const char* path () const {return 0;} + + private: + string fontname; +}; + + +/** Interface for all physical fonts. */ +struct PhysicalFont : public virtual Font +{ + enum Type {MF, PFB, TTF}; + static Font* create (string name, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type); + virtual Type type () const =0; +}; + + +/** Interface for all virtual fonts. */ +class VirtualFont : public virtual Font +{ + friend class FontManager; + public: + typedef vector<UInt8> DVIVector; + + public: + static Font* create (string name, UInt32 checksum, double dsize, double ssize); + virtual const DVIVector* getDVI (int c) const =0; + + protected: + virtual void assignChar (UInt32 c, DVIVector *dvi) =0; +}; + + +class TFMFont : public virtual Font +{ + public: + TFMFont (string name, UInt32 checksum, double dsize, double ssize); + ~TFMFont (); + const TFM* getTFM () const; + string name () const {return fontname;} + double designSize () const {return dsize;} + double scaledSize () const {return ssize;} + double charWidth (int c) const; + double charDepth (int c) const; + double charHeight (int c) const; + double italicCorr (int c) const; + + private: + mutable TFM *tfm; + string fontname; + UInt32 checksum; ///< cheksum to be compared with TFM checksum + double dsize; ///< design size in TeX point units + double ssize; ///< scaled size +}; + + +class PhysicalFontProxy : public PhysicalFont +{ + friend class PhysicalFontImpl; + public: + Font* clone (double ds, double sc) const {return new PhysicalFontProxy(*this, ds, sc);} + const Font* uniqueFont () const {return pf;} + string name () const {return pf->name();} + double designSize () const {return dsize;} + double scaledSize () const {return ssize;} + double charWidth (int c) const {return pf->charWidth(c);} + double charDepth (int c) const {return pf->charDepth(c);} + double charHeight (int c) const {return pf->charHeight(c);} + double italicCorr (int c) const {return pf->italicCorr(c);} + const TFM* getTFM () const {return pf->getTFM();} + const char* path () const {return pf->path();} + Type type () const {return pf->type();} + + protected: + PhysicalFontProxy (const PhysicalFont *font, double ds, double ss) : pf(font), dsize(ds), ssize(ss) {} + PhysicalFontProxy (const PhysicalFontProxy &proxy, double ds, double ss) : pf(proxy.pf), dsize(ds), ssize(ss) {} + + private: + const PhysicalFont *pf; + double dsize; ///< design size in TeX point units + double ssize; ///< scaled size +}; + + +class PhysicalFontImpl : public PhysicalFont, public TFMFont +{ + friend class PhysicalFont; + public: + Font* clone (double ds, double ss) const {return new PhysicalFontProxy(this, ds, ss);} + const Font* uniqueFont () const {return this;} + const char* path () const; + Type type () const {return filetype;} + + protected: + PhysicalFontImpl (string name, UInt32 checksum, double dsize, double ssize, PhysicalFont::Type type); + + private: + Type filetype; +}; + + +class VirtualFontProxy : public VirtualFont +{ + friend class VirtualFontImpl; + public: + Font* clone (double ds, double ss) const {return new VirtualFontProxy(*this, ds, ss);} + const Font* uniqueFont () const {return vf;} + string name () const {return vf->name();} + const DVIVector* getDVI (int c) const {return vf->getDVI(c);} + double designSize () const {return dsize;} + double scaledSize () const {return ssize;} + double charWidth (int c) const {return vf->charWidth(c);} + double charDepth (int c) const {return vf->charDepth(c);} + double charHeight (int c) const {return vf->charHeight(c);} + double italicCorr (int c) const {return vf->italicCorr(c);} + const TFM* getTFM () const {return vf->getTFM();} + const char* path () const {return vf->path();} + + protected: + VirtualFontProxy (const VirtualFont *font, double ds, double ss) : vf(font), dsize(ds), ssize(ss) {} + VirtualFontProxy (const VirtualFontProxy &proxy, double ds, double ss) : vf(proxy.vf), dsize(ds), ssize(ss) {} + void assignChar (UInt32 c, DVIVector *dvi) {delete dvi;} + + private: + const VirtualFont *vf; + double dsize; ///< design size in TeX point units + double ssize; ///< scaled size in TeX point units +}; + + +class VirtualFontImpl : public VirtualFont, public TFMFont +{ + friend class VirtualFont; + public: + ~VirtualFontImpl (); + Font* clone (double ds, double ss) const {return new VirtualFontProxy(this, ds, ss);} + const Font* uniqueFont () const {return this;} + const DVIVector* getDVI (int c) const; + const char* path () const; + + protected: + VirtualFontImpl (string name, UInt32 checksum, double dsize, double ssize); + void assignChar (UInt32 c, DVIVector *dvi); + + private: + map<UInt32, DVIVector*> charDefs; ///< dvi subroutines defining the characters +}; + + +struct FontException : public MessageException +{ + FontException (string msg) : MessageException(msg) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.cpp new file mode 100644 index 00000000000..3973d5db659 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.cpp @@ -0,0 +1,386 @@ +/************************************************************************* +** FontCache.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <algorithm> +#include <cstring> +#include <fstream> +#include <iomanip> +#include <sstream> +#include "FileSystem.h" +#include "FontCache.h" +#include "FontGlyph.h" +//#include "gzstream.h" +#include "types.h" + +using namespace std; + + +static UInt32 read_unsigned (int bytes, istream &is) { + UInt32 ret = 0; + for (bytes--; bytes >= 0 && !is.eof(); bytes--) { + UInt32 b = is.get(); + ret |= b << (8*bytes); + } + return ret; +} + + +static Int32 read_signed (int bytes, istream &is) { + Int32 ret = is.get(); + if (ret & 128) // negative value? + ret |= 0xffffff00; + for (bytes-=2; bytes >= 0 && !is.eof(); bytes--) + ret = (ret << 8) | is.get(); + return ret; +} + + +static void write_unsigned (UInt32 value, int bytes, ostream &os) { + for (bytes--; bytes >= 0; bytes--) + os.put((value >> (8*bytes)) & 0xff); +} + + +static inline void write_signed (Int32 value, int bytes, ostream &os) { + write_unsigned((UInt32)value, bytes, os); +} + + +static LPair read_pair (int bytes, istream &is) { + long x = read_signed(bytes, is); + long y = read_signed(bytes, is); + return LPair(x, y); +} + + +FontCache::FontCache () : _changed(false) +{ +} + + +FontCache::~FontCache () { + clear(); +} + + +/** Removes all data from the cache. This does not affect the cache files. */ +void FontCache::clear () { + FORALL(_glyphs, GlyphMap::iterator, it) { + delete it->second; + } + _glyphs.clear(); +} + + +/** Assigns glyph data to a character and adds it to the cache. + * @param[in] c character code + * @param[in] glyph font glyph data */ +void FontCache::setGlyph (int c, const Glyph *glyph) { + if (!glyph || glyph->empty()) + delete glyph; + else { + GlyphMap::iterator it = _glyphs.find(c); + if (it != _glyphs.end()) { + delete it->second; + it->second = glyph; + } + else + _glyphs[c] = glyph; + _changed = true; + } +} + + +/** Returns the corresponding glyph data of a given character of the current font. + * @param[in] c character code + * @return font glyph data (0 if no matching data was found) */ +const Glyph* FontCache::getGlyph (int c) const { + GlyphMap::const_iterator it = _glyphs.find(c); + return (it != _glyphs.end()) ? it->second : 0; +} + + +/** Writes the current cache data to a file (only if anything changed after + * the last call of read()). + * @param[in] fontname name of current font + * @param[in] dir directory where the cache file should go + * @return true if writing was successful */ +bool FontCache::write (const char *fontname, const char *dir) const { + if (!_changed) + return true; + + if (fontname && strlen(fontname) > 0) { + if (dir == 0 || strlen(dir) == 0) + dir = FileSystem::getcwd().c_str(); + ostringstream oss; + oss << dir << '/' << fontname << ".fgd"; +// ogzstream ofs(oss.str().c_str(), 9, ios::binary|ios::out); + ofstream ofs(oss.str().c_str(), ios::binary); + return write(fontname, ofs); + } + return false; +} + + +/** Returns the minimal number of bytes needed to store the given value. */ +static int max_int_size (Int32 value) { + Int32 limit = 0x7f; + for (int i=1; i <= 4; i++) { + if ((value < 0 && -value <= limit+1) || (value >= 0 && value <= limit)) + return i; + limit = (limit << 8) | 0xff; + } + return 4; +} + + +/** Returns the minimal number of bytes needed to store the biggest + * pair component of the given vector. */ +static int max_int_size (const vector<LPair> &pairs) { + int ret=0; + FORALL(pairs, vector<LPair>::const_iterator, it) { + ret = max(ret, max_int_size(it->x())); + ret = max(ret, max_int_size(it->y())); + } + return ret; +} + + +/** Writes the current cache data to a stream (only if anything changed after + * the last call of read()). + * @param[in] fontname name of current font + * @param[in] os output stream + * @return true if writing was successful */ +bool FontCache::write (const char *fontname, ostream &os) const { + if (!_changed) + return true; + + if (os) { + write_unsigned(VERSION, 1, os); + for (const char *p=fontname; *p; p++) + os.put(*p); + os.put(0); + write_unsigned(_glyphs.size(), 4, os); + FORALL(_glyphs, GlyphMap::const_iterator, it) { + write_unsigned(it->first, 4, os); + write_unsigned(it->second->commands().size(), 2, os); + FORALL(it->second->commands(), list<GlyphCommand*>::const_iterator, cit) { + const vector<LPair> ¶ms = (*cit)->params(); + int bytes = max_int_size(params); + UInt8 cmdchar = (bytes << 5) | ((*cit)->getSVGPathCommand() - 'A'); + write_unsigned(cmdchar, 1, os); + for (size_t i=0; i < params.size(); i++) { + write_signed(params[i].x(), bytes, os); + write_signed(params[i].y(), bytes, os); + } + } + } + return true; + } + return false; +} + + +/** Reads font glyph information from a file. + * @param[in] fontname name of font data to read + * @param[in] dir directory where the cache files are located + * @return true if reading was successful */ +bool FontCache::read (const char *fontname, const char *dir) { + clear(); + if (fontname && strlen(fontname) > 0) { + if (dir == 0 || strlen(dir) == 0) + dir = FileSystem::getcwd().c_str(); + ostringstream oss; + oss << dir << '/' << fontname << ".fgd"; + ifstream ifs(oss.str().c_str(), ios::binary); +// igzstream ifs(oss.str().c_str(), 9, ios::binary|ios::in); + return read(fontname, ifs); + } + return false; +} + + +/** Reads font glyph information from a stream. + * @param[in] fontname name of font data to read + * @param[in] dir input stream + * @return true if reading was successful */ +bool FontCache::read (const char *fontname, istream &is) { + clear(); + if (is) { + if (read_unsigned(1, is) != VERSION) + return false; + string fname; + while (!is.eof() && is.peek() != 0) + fname += is.get(); + is.get(); // skip 0-byte + if (fname != fontname) + return false; + UInt32 num_glyphs = read_unsigned(4, is); + while (num_glyphs-- > 0) { + UInt32 c = read_unsigned(4, is); // character code + UInt16 s = read_unsigned(2, is); // number of path commands + Glyph *glyph = new Glyph; + while (s-- > 0) { + UInt8 cmdval = read_unsigned(1, is); + UInt8 cmdchar = (cmdval & 0x1f) + 'A'; + int bytes = cmdval >> 5; + GlyphCommand *cmd=0; + switch (cmdchar) { + case 'C': { + LPair p1 = read_pair(bytes, is); + LPair p2 = read_pair(bytes, is); + LPair p3 = read_pair(bytes, is); + cmd = new GlyphCubicTo(p1, p2, p3); + break; + } + case 'H': + cmd = new GlyphHorizontalLineTo(read_pair(bytes, is)); + break; + case 'L': + cmd = new GlyphLineTo(read_pair(bytes, is)); + break; + case 'M': + cmd = new GlyphMoveTo(read_pair(bytes, is)); + break; + case 'Q': { + LPair p1 = read_pair(bytes, is); + LPair p2 = read_pair(bytes, is); + cmd = new GlyphConicTo(p1, p2); + break; + } + case 'S': { + LPair p1 = read_pair(bytes, is); + LPair p2 = read_pair(bytes, is); + cmd = new GlyphShortCubicTo(p1, p2); + break; + } + case 'T': + cmd = new GlyphShortConicTo(read_pair(bytes, is)); + break; + case 'V': + cmd = new GlyphVerticalLineTo(read_pair(bytes, is)); + break; + case 'Z': + cmd = new GlyphClosePath(); + } + if (cmd) + glyph->addCommand(cmd); + } + setGlyph(c, glyph); + } + _changed = false; + return true; + } + return false; +} + + +/** Collects font cache information. + * @param[in] dirname path to font cache directory + * @param[out] infos the collected data + * @return true on success */ +bool FontCache::fontinfo (const char *dirname, std::vector<FontInfo> &infos) { + infos.clear(); + if (dirname) { + vector<string> fnames; + FileSystem::collect(dirname, fnames); + FORALL(fnames, vector<string>::iterator, it) { + if ((*it)[0] == 'f' && it->length() > 5 && it->substr(it->length()-4) == ".fgd") { + FontInfo info; + string path = string(dirname)+"/"+(it->substr(1)); + ifstream ifs(path.c_str(), ios::binary); + if (fontinfo(ifs, info)) + infos.push_back(info); + } + } + } + return infos.size() > 0; +} + + +/** Collects font cache information of a single font. + * @param[in] is input stream of the cache file + * @param[out] info the collected data + * @return true on success */ +bool FontCache::fontinfo (std::istream &is, FontInfo &info) { + info.name.clear(); + info.numchars = info.numbytes = info.numcmds = 0; + if (is) { + if ((info.version = read_unsigned(1, is)) != VERSION) + return false; + while (!is.eof() && is.peek() != 0) + info.name += is.get(); + is.get(); // skip 0-byte + info.numchars = read_unsigned(4, is); + for (UInt32 i=0; i < info.numchars; i++) { + read_unsigned(4, is); // character code + UInt16 s = read_unsigned(2, is); // number of path commands + while (s-- > 0) { + UInt8 cmdval = read_unsigned(1, is); + UInt8 cmdchar = (cmdval & 0x1f) + 'A'; + int bytes = cmdval >> 5; + int bc = 0; + switch (cmdchar) { + case 'C': bc = 6*bytes; break; + case 'H': + case 'L': + case 'M': + case 'T': + case 'V': bc = 2*bytes; break; + case 'Q': + case 'S': bc = 4*bytes; break; + case 'Z': break; + default : return false; + } + info.numbytes += bc+1; // command length + command + info.numcmds++; + is.seekg(bc, ios_base::cur); + } + info.numbytes += 6; // number of path commands + char code + } + info.numbytes += 6+info.name.length(); // version + 0-byte + fontname + number of chars + } + return true; +} + + +/** Collects font cache information and write it to a stream. + * @param[in] dirname path to font cache directory + * @param[in] os output is written to this stream */ +void FontCache::fontinfo (const char *dirname, ostream &os) { + vector<FontInfo> infos; + if (fontinfo(dirname, infos)) { + os << "cache format version " << infos[0].version << endl; + typedef map<string,FontInfo*> SortMap; + SortMap sortmap; + FORALL(infos, vector<FontInfo>::iterator, it) + sortmap[it->name] = &(*it); + + FORALL(sortmap, SortMap::iterator, it) { + os << setw(10) << left << it->second->name + << setw(5) << right << it->second->numchars << " chars" + << setw(10) << right << it->second->numcmds << " cmds" + << setw(10) << right << it->second->numbytes << " bytes" + << endl; + } + } + else + os << "cache is empty\n"; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.h new file mode 100644 index 00000000000..6ce8528b533 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontCache.h @@ -0,0 +1,64 @@ +/************************************************************************* +** FontCache.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTCACHE_H +#define FONTCACHE_H + +#include <iostream> +#include <string> +#include <map> +#include "FontGlyph.h" + +class FontCache +{ + typedef std::map<int, const Glyph*> GlyphMap; + + public: + struct FontInfo + { + std::string name; // fontname + UInt16 version; + UInt32 numchars; // number of characters + UInt32 numbytes; // number of bytes + UInt32 numcmds; // number of path commands + }; + + public: + FontCache (); + ~FontCache (); + bool read (const char *fontname, const char *dir); + bool read (const char *fontname, std::istream &is); + bool write (const char *fontname, const char *dir) const; + bool write (const char *fontname, std::ostream &os) const; + const Glyph* getGlyph (int c) const; + void setGlyph (int c, const Glyph *glyph); + void clear (); + + static bool fontinfo (const char *dirname, std::vector<FontInfo> &infos); + static bool fontinfo (std::istream &is, FontInfo &info); + static void fontinfo (const char *dirname, ostream &os); + + private: + const static UInt8 VERSION = 3; + GlyphMap _glyphs; + bool _changed; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEmitter.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEmitter.h new file mode 100644 index 00000000000..e39cf6c56ca --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEmitter.h @@ -0,0 +1,41 @@ +/************************************************************************* +** FontEmitter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTEMITTER_H +#define FONTEMITTER_H + +#include <set> + + +struct FontEmitter +{ + virtual ~FontEmitter () {} + + /** Emits all glyphs of the font. */ + virtual int emitFont (const char *id) =0; + + /** Emits selected glyphs of the font. */ + virtual int emitFont (const std::set<int> &usedChars, const char *id) =0; + + /** Emits a single glyph. */ + virtual bool emitGlyph (int c) =0; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.cpp new file mode 100644 index 00000000000..6ed681e84ea --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.cpp @@ -0,0 +1,133 @@ +/************************************************************************* +** FontEncoding.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <fstream> +#include "FontEncoding.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "FileFinder.h" +#include "Message.h" + +using namespace std; + +static string read_entry (InputReader &in); +static bool valid_name_char (char c); + + +FontEncoding::FontEncoding (const string &encname) : _encname(encname) +{ + read(); +} + + +const char* FontEncoding::path () const { + return FileFinder::lookup(_encname+".enc"); +} + + + +/** Search for suitable enc-file and read its encoding information. + * The file contents must be a valid PostScript vector with 256 entries. */ +void FontEncoding::read () { + if (const char *p = path()) { + ifstream ifs(p); + read(ifs); + } + else + Message::mstream(true) << "encoding file '" << _encname << ".enc' not found\n"; +} + + +/** Read encoding information from stream. */ +void FontEncoding::read (istream &is) { + StreamInputBuffer ib(is, 256); + BufferInputReader in(ib); + _table.resize(256); + + // find beginning of vector + while (!in.eof()) { + in.skipSpace(); + if (in.peek() == '%') + in.skipUntil("\n"); + else + if (in.get() == '[') + break; + } + + // read vector entries + int n=0; + while (!in.eof()) { + in.skipSpace(); + if (in.peek() == '%') + in.skipUntil("\n"); + else if (in.peek() == ']') { + in.get(); + break; + } + else { + string entry = read_entry(in); + if (entry == ".notdef") + entry.clear(); + if (n < 256) + _table[n++] = entry; + } + } + // remove trailing .notdef names + for (n--; n > 0 && _table[n].empty(); n--); + _table.resize(n+1); +} + + +static string read_entry (InputReader &in) { + string entry; + bool accept_slashes=true; + while (!in.eof() && ((in.peek() == '/' && accept_slashes) || valid_name_char(in.peek()))) { + if (in.peek() != '/') + accept_slashes = false; + entry += in.get(); + } + if (entry.length() > 1) { + // strip leading slashes + // According to the PostScript specification, a single slash without further + // following characters is a valid name. + size_t n=0; + while (n < entry.length() && entry[n] == '/') + n++; + entry = entry.substr(n); + } + return entry; +} + + +static bool valid_name_char (char c) { + const char *delimiters = "<>(){}[]/~%"; + return isprint(c) && !isspace(c) && !strchr(delimiters, c); +} + + +/** Returns an entry of the encoding table. + * @param[in] c character code + * @return character name assigned to charcter code c*/ +const char* FontEncoding::getEntry (int c) const { + if (c >= 0 && (size_t)c < _table.size()) + return !_table[c].empty() ? _table[c].c_str() : 0; + return 0; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.h new file mode 100644 index 00000000000..89eb760c3ce --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEncoding.h @@ -0,0 +1,45 @@ +/************************************************************************* +** FontEncoding.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTENCODING_H +#define FONTENCODING_H + +#include <istream> +#include <string> +#include <vector> +#include "types.h" + +class FontEncoding +{ + public: + FontEncoding (const std::string &name); + void read (); + void read (std::istream &is); + int size () const {return _table.size();} + std::string name () const {return _encname;} + const char* getEntry (int c) const; + const char* path () const; + + private: + std::string _encname; + std::vector<std::string> _table; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.cpp new file mode 100644 index 00000000000..38acd1e73bb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.cpp @@ -0,0 +1,336 @@ +/************************************************************************* +** FontEngine.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iostream> +#include <ft2build.h> +#include FT_GLYPH_H +#include FT_OUTLINE_H +#include FT_TRUETYPE_TABLES_H +#include "FontEngine.h" +#include "Message.h" +#include "macros.h" + +using namespace std; + + +FontEngine::FontEngine () { + _currentFace = 0; + _currentChar = _currentGlyphIndex = 0; + _horDeviceRes = _vertDeviceRes = 300; + _ptSize = 0; + if (FT_Init_FreeType(&_library)) + Message::estream(true) << "FontEngine: error initializing FreeType library\n"; +} + + +FontEngine::~FontEngine () { + if (_currentFace && FT_Done_Face(_currentFace)) + Message::estream(true) << "FontEngine: error removing glyph\n"; + if (FT_Done_FreeType(_library)) + Message::estream(true) << "FontEngine: error removing FreeType library\n"; +} + + +void FontEngine::setDeviceResolution (int x, int y) { + _horDeviceRes = x; + _vertDeviceRes = y; +} + + +/** Builds a table that maps glyph indexes to char codes. + * @param[in] face font face to be used + * @param[out] reverseMap the resulting map */ +static void build_reverse_map (FT_Face face, map<UInt32, UInt32> &reverseMap) { + UInt32 glyphIndex; + UInt32 charcode = FT_Get_First_Char(face, &glyphIndex); + while (glyphIndex) { +// if (reverseMap.find(glyphIndex) == reverseMap.end()) + reverseMap[glyphIndex] = charcode; + charcode = FT_Get_Next_Char(face, charcode, &glyphIndex); + } +} + + +/** Sets the font to be used. + * @param[in] fname path to font file + * @param[in] ptSize font size in point units + * @return true on success */ +bool FontEngine::setFont (const string &fname, int ptSize) { + if (FT_New_Face(_library, fname.c_str(), 0, &_currentFace)) { + Message::estream(true) << "FontEngine: error reading file " << fname << endl; + return false; + } + if (ptSize && FT_Set_Char_Size(_currentFace, 0, ptSize*64, _horDeviceRes, _vertDeviceRes)) { + Message::estream(true) << "FontEngine: error setting character size\n"; + return false; + } + // look for a custom character map + for (int i=0; i < _currentFace->num_charmaps; i++) { + FT_CharMap charmap = _currentFace->charmaps[i]; + if (charmap->encoding == FT_ENCODING_ADOBE_CUSTOM) { + FT_Set_Charmap(_currentFace, charmap); + break; + } + } + _ptSize = ptSize; + return true; +} + + + +void FontEngine::buildTranslationMap (map<UInt32, UInt32> &translationMap) const { + FT_CharMap unicodeMap=0, customMap=0; + for (int i=0; i < _currentFace->num_charmaps; i++) { + FT_CharMap charmap = _currentFace->charmaps[i]; + if (charmap->encoding == FT_ENCODING_ADOBE_CUSTOM) + customMap = charmap; + else if (charmap->encoding == FT_ENCODING_UNICODE) + unicodeMap = charmap; + } + if (unicodeMap == 0 || customMap == 0) + return; + + map<UInt32,UInt32> reverseMap; + build_reverse_map(_currentFace, reverseMap); + + FT_Set_Charmap(_currentFace, unicodeMap); + UInt32 glyphIndex; + UInt32 charcode = FT_Get_First_Char(_currentFace, &glyphIndex); + while (glyphIndex) { + translationMap[reverseMap[glyphIndex]] = charcode; + charcode = FT_Get_Next_Char(_currentFace, charcode, &glyphIndex); + } + FT_Set_Charmap(_currentFace, customMap); +} + + +const char* FontEngine::getFamilyName () const { + return _currentFace ? _currentFace->family_name : 0; +} + +const char* FontEngine::getStyleName () const { + return _currentFace ? _currentFace->style_name : 0; +} + +int FontEngine::getUnitsPerEM () const { + return _currentFace ? _currentFace->units_per_EM : 0; +} + +int FontEngine::getAscender () const { + return _currentFace ? _currentFace->ascender : 0; +} + +int FontEngine::getDescender () const { + return _currentFace ? _currentFace->descender : 0; +} + +int FontEngine::getHAdvance () const { + if (_currentFace) { + TT_OS2 *table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2)); + return table ? table->xAvgCharWidth : 0; + } + return 0; +} + +int FontEngine::getHAdvance (unsigned c) const { + if (_currentFace) { + int index = FT_Get_Char_Index(_currentFace, (FT_ULong)c); + FT_Load_Glyph(_currentFace, index, FT_LOAD_NO_SCALE); + return _currentFace->glyph->metrics.horiAdvance; + } + return 0; +} + + +int FontEngine::getHAdvance (const char *name) const { + if (_currentFace && name) { + int index = FT_Get_Name_Index(_currentFace, (FT_String*)name); + FT_Load_Glyph(_currentFace, index, FT_LOAD_NO_SCALE); + return _currentFace->glyph->metrics.horiAdvance; + } + return 0; +} + + +/** Get first available character of the current font face. */ +int FontEngine::getFirstChar () const { + if (_currentFace) + return _currentChar = FT_Get_First_Char(_currentFace, &_currentGlyphIndex); + return 0; +} + + +/** Get the next available character of the current font face. */ +int FontEngine::getNextChar () const { + if (_currentFace && _currentGlyphIndex) + return _currentChar = FT_Get_Next_Char(_currentFace, _currentChar, &_currentGlyphIndex); + return getFirstChar(); +} + + +/** Returns the glyph name for a given charater code. + * @param[in] c char code + * @return glyph name */ +string FontEngine::getGlyphName (unsigned c) const { + if (_currentFace && FT_HAS_GLYPH_NAMES(_currentFace)) { + char buf[256]; + int index = FT_Get_Char_Index(_currentFace, c); + FT_Get_Glyph_Name(_currentFace, index, buf, 256); + return string(buf); + } + return ""; +} + + +/* Returns the character code for a given glyph name. + * @param name glyph name + * @return char code or 0 if name couldn't be found +int FontEngine::getCharByGlyphName (const char *name) const { + if (_currentFace && FT_HAS_GLYPH_NAMES(_currentFace)) { + int index = FT_Get_Name_Index(_currentFace, (FT_String*)name); + map<UInt32, UInt32>::const_iterator it = _reverseMap.find(index); + if (it != _reverseMap.end()) + return it->second; + } + return 0; +}*/ + + +vector<int> FontEngine::getPanose () const { + vector<int> panose(10); + if (_currentFace) { + TT_OS2 *table = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(_currentFace, ft_sfnt_os2)); + if (table) + for (int i=0; i < 10; i++) + panose[i] = table->panose[i]; + } + return panose; +} + + +bool FontEngine::setCharSize (int ptSize) { + if (_currentFace) { + if (FT_Set_Char_Size(_currentFace, 0, ptSize*64, _horDeviceRes, _vertDeviceRes)) { + Message::estream(true) << "FontEngine: error setting character size\n"; + return false; + } + _ptSize = ptSize; + return true; + } + Message::wstream(true) << "FontEngine: can't set char size, no font face selected\n"; + return false; +} + + +// handle API change in freetype version 2.2.1 +#if FREETYPE_MAJOR >= 2 && FREETYPE_MINOR >= 2 && FREETYPE_PATCH >= 1 + typedef const FT_Vector *FTVectorPtr; +#else + typedef FT_Vector *FTVectorPtr; +#endif + +// Callback functions used by traceOutline +static int moveto (FTVectorPtr to, void *user) { + FEGlyphCommands *commands = static_cast<FEGlyphCommands*>(user); + commands->moveTo(to->x, to->y); + return 0; +} + + +static int lineto (FTVectorPtr to, void *user) { + FEGlyphCommands *commands = static_cast<FEGlyphCommands*>(user); + commands->lineTo(to->x, to->y); + return 0; +} + + +static int conicto (FTVectorPtr control, FTVectorPtr to, void *user) { + FEGlyphCommands *commands = static_cast<FEGlyphCommands*>(user); + commands->conicTo(control->x, control->y, to->x, to->y); + return 0; +} + + +static int cubicto (FTVectorPtr control1, FTVectorPtr control2, FTVectorPtr to, void *user) { + FEGlyphCommands *commands = static_cast<FEGlyphCommands*>(user); + commands->cubicTo(control1->x, control1->y, control2->x, control2->y, to->x, to->y); + return 0; +} + + +/** Traces the outline of a glyph by calling the corresponding "drawing" functions. + * Each glyph is composed of straight lines, quadratic (conic) or cubic B�zier curves. + * This function takes all these outline segments and processes them by calling + * the corresponding functions. The functions must be provided in form of a + * FEGlyphCommands object. + * @param[in] index index of the glyph that will be traced + * @param[in] commands the drawing commands to be executed + * @param[in] scale if true the current pt size will be considered otherwise the plain TrueType units are used. + * @return false on errors */ +static bool trace_outline (FT_Face face, int index, FEGlyphCommands &commands, bool scale) { + if (face) { + if (FT_Load_Glyph(face, index, scale ? FT_LOAD_DEFAULT : FT_LOAD_NO_SCALE)) { + Message::estream(true) << "can't load glyph " << int(index) << endl; + return false; + } + + if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) { + Message::estream(true) << "no outlines found in glyph " << int(index) << endl; + return false; + } + FT_Outline outline = face->glyph->outline; + const FT_Outline_Funcs funcs = {moveto, lineto, conicto, cubicto, 0, 0}; + FT_Outline_Decompose(&outline, &funcs, &commands); + return true; + } + Message::wstream(true) << "FontEngine: can't trace outline, no font face selected\n"; + return false; +} + + + +/** Traces the outline of a glyph by calling the corresponding "drawing" functions. + * Each glyph is composed of straight lines, quadratic (conic) or cubic B�zier curves. + * This function takes all these outline segments and processes them by calling + * the corresponding functions. The functions must be provided in form of a + * FEGlyphCommands object. + * @param[in] chr the glyph of this character will be traced + * @param[in] commands the drawing commands to be executed + * @param[in] scale if true the current pt size will be considered otherwise + * the plain TrueType units are used. + * @return false on errors */ +bool FontEngine::traceOutline (unsigned char chr, FEGlyphCommands &commands, bool scale) const { + if (_currentFace) { + int index = FT_Get_Char_Index(_currentFace, chr); + return trace_outline(_currentFace, index, commands, scale); + } + Message::wstream(true) << "FontEngine: can't trace outline, no font face selected\n"; + return false; +} + + +bool FontEngine::traceOutline (const char *name, FEGlyphCommands &commands, bool scale) const { + if (_currentFace) { + int index = FT_Get_Name_Index(_currentFace, (FT_String*)name); + return trace_outline(_currentFace, index, commands, scale); + } + Message::wstream(true) << "FontEngine: can't trace outline, no font face selected\n"; + return false; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.h new file mode 100644 index 00000000000..7e2593dc1e5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontEngine.h @@ -0,0 +1,84 @@ +/************************************************************************* +** FontEngine.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTENGINE_H +#define FONTENGINE_H + +#include <ft2build.h> +#include FT_FREETYPE_H +#include <map> +#include <string> +#include <vector> +#include "types.h" + +using std::map; +using std::string; +using std::vector; + + +struct FEGlyphCommands +{ + virtual ~FEGlyphCommands () {} + virtual void moveTo(long x, long y) {} + virtual void lineTo(long x, long y) {} + virtual void conicTo(long x1, long y1, long x2, long y2) {} + virtual void cubicTo(long x1, long y1, long x2, long y2, long x3, long y3) {} +}; + + +/** This class provides methods to handle font files and font data. + * It's a wrapper for the Freetype font library. */ +class FontEngine +{ + public: + FontEngine (); + ~FontEngine (); + void setDeviceResolution (int x, int y); + bool setFont (const string &fname, int ptSize=0); + bool setCharSize (int ptSize); + bool getGlyphMetrics (unsigned char chr, int &width, int &height, int &depth) const; + bool traceOutline (unsigned char chr, FEGlyphCommands &commands, bool scale=true) const; + bool traceOutline (const char *name, FEGlyphCommands &commands, bool scale) const; + const char* getFamilyName () const; + const char* getStyleName () const; + int getUnitsPerEM () const; + int getAscender () const; + int getDescender () const; + int getHAdvance () const; + int getHAdvance (unsigned int c) const; + int getHAdvance (const char *name) const; +// int getVAdvance () const; + int getFirstChar () const; + int getNextChar () const; + int getCharSize () const {return _ptSize;} + vector<int> getPanose () const; + string getGlyphName (unsigned int c) const; + int getCharByGlyphName (const char *name) const; + void buildTranslationMap (map<UInt32,UInt32> &translationMap) const; + + private: + int _horDeviceRes, _vertDeviceRes; + mutable unsigned int _currentChar, _currentGlyphIndex; + FT_Face _currentFace; + FT_Library _library; + int _ptSize; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.cpp new file mode 100644 index 00000000000..882fb5a0292 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.cpp @@ -0,0 +1,277 @@ +/************************************************************************* +** FontGlyph.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "FontEncoding.h" +#include "FontEngine.h" +#include "FontGlyph.h" +#include "Message.h" +#include "Pair.h" +#include "macros.h" + +using namespace std; + +GlyphCommand::GlyphCommand (const LPair &p) : _params(1) { + _params[0] = p; +} + + +GlyphCommand::GlyphCommand (const LPair &p1, const LPair &p2) : _params(2) { + _params[0] = p1; + _params[1] = p2; +} + + +GlyphCommand::GlyphCommand (const LPair &p1, const LPair &p2, const LPair &p3) : _params(3) { + _params[0] = p1; + _params[1] = p2; + _params[2] = p3; +} + + +LPair GlyphCommand::param (int n) const { + if (n < 0) + n = _params.size() + n; + if (n >= 0 && size_t(n) < _params.size()) + return _params[n]; + return LPair(); +} + + +void GlyphCommand::writeSVGCommand (ostream &os, double sx, double sy) const { + os << getSVGPathCommand(); + FORALL(_params, ConstIterator, i) { + if (i != _params.begin()) + os << ' '; + os << (i->x()*sx) << ' ' << (i->y()*sy); + } +} + + +GlyphCommand* GlyphMoveTo::combine (GlyphCommand &cmd) { + if (cmd.getSVGPathCommand() == 'M' && _params.size() == 1) + return &cmd; + if (cmd.getSVGPathCommand() == 'L') { + _params.insert(_params.end(), cmd.params().begin(), cmd.params().end()); + return this; + } + return 0; +} + + +GlyphCommand* GlyphLineTo::combine (GlyphCommand &cmd) { + if (cmd.getSVGPathCommand() == getSVGPathCommand()) { + _params.insert(_params.end(), cmd.params().begin(), cmd.params().end()); + return this; + } + return 0; +} + + +void GlyphHorizontalLineTo::writeSVGCommand (ostream &os, double sx, double sy) const { + os << getSVGPathCommand() << _params[0].x()*sx; +} + + +void GlyphVerticalLineTo::writeSVGCommand (ostream &os, double sx, double sy) const { + os << getSVGPathCommand() << _params[0].y()*sy; +} + + +GlyphCommand* GlyphCubicTo::combine (GlyphCommand &cmd) { +/* if (cmd.getSVGPathCommand() == 'C' && cmd.getParams().size() == 3) { + LPair c1 = getParam(-2); + LPair e1 = getParam(-1); + LPair b2 = cmd.getParam(0); + LPair c2 = cmd.getParam(1); + if (e1 == b2 && c2 == e1*2-c1) + return new GlyphShortCubicTo(cmd.getParam(-2), cmd.getParam(-1)); + else { + _params.insert(_params.end(), cmd.getParams().begin(), cmd.getParams().end()); + return this; + } + }*/ + return 0; +} + + +/////////////////////////// + + +class Commands : public FEGlyphCommands { + public: + Commands (Glyph &g) : glyph(g) {} + + void moveTo(long x, long y) { + glyph.addCommand(new GlyphMoveTo(LPair(x, y))); + } + + void lineTo(long x, long y) { + glyph.addCommand(new GlyphLineTo(LPair(x, y))); + } + + void conicTo(long x1, long y1, long x2, long y2) { + glyph.addCommand(new GlyphConicTo(LPair(x1, y1), LPair(x2, y2))); + } + + void cubicTo(long x1, long y1, long x2, long y2, long x3, long y3) { + glyph.addCommand(new GlyphCubicTo(LPair(x1, y1), LPair(x2, y2), LPair(x3, y3))); + } + + private: + Glyph &glyph; +}; + + +Glyph::~Glyph () { + clear(); +} + + +/** Removes all path commands from the glyph and frees the allocated objects. */ +void Glyph::clear () { + FORALL(_commands, Iterator, i) + delete *i; + _commands.clear(); +} + + +/** Appends a new path command to the current glyph. + * @param[in] cmd command to append */ +void Glyph::addCommand (GlyphCommand *cmd) { + if (cmd) + _commands.push_back(cmd); +} + + +void Glyph::read (unsigned char c, const FontEncoding *encoding, const FontEngine &fontEngine) { + Commands _commands(*this); + if (encoding) { + if (const char *name = encoding->getEntry(c)) + fontEngine.traceOutline(name, _commands, false); + else + Message::wstream(true) << "no encoding for char #" << int(c) << " in '" << encoding->name() << "'\n"; + } + else + fontEngine.traceOutline(c, _commands, false); +} + + +/** Writes an SVG representation of the path commands to a stream. The parameters + * can be scaled by the given factors. + * @param[in] os output stream + * @param[in] sx horizontal scale factor + * @param[in] sy vertical scale factor */ +void Glyph::writeSVGCommands (ostream &os, double sx, double sy) const { + FORALL (_commands, ConstIterator, i) + (*i)->writeSVGCommand(os, sx, sy); +} + + +/** Calls a function for all path sections/commands. + * @param[in] f function to be called + * @param[in] userParam parameter passed to function f */ +void Glyph::forAllCommands (void (*f)(GlyphCommand*, void*), void *userParam) { + FORALL(_commands, Iterator, i) + f(*i, userParam); +} + + +/** Detects all open paths of the glyph's outline and closes them by adding a closePath command. + * Most font formats only support closed outline paths so there are no explicit closePath statements + * in the glyph's outline description. All open paths are automatically closed by the renderer. + * This method detects all open paths and adds the missing closePath statement. */ +void Glyph::closeOpenPaths () { + GlyphCommand *prevCommand = 0; + FORALL(_commands, Iterator, i) { + if ((*i)->getSVGPathCommand() == 'M' && prevCommand && prevCommand->getSVGPathCommand() != 'Z') { + prevCommand = *i; + _commands.insert(i, new GlyphClosePath); + ++i; // skip inserted closePath command in next iteration step + } + else + prevCommand = *i; + } + if (!_commands.empty()) + _commands.push_back(new GlyphClosePath); +} + + +/** Optimizes the glyph's outline description by using command sequences with less parameters. + * TrueType and Type1 fonts only support 3 drawing commands (moveto, lineto, conicto/cubicto). + * In the case of successive bezier curve sequences, control points or tangent slopes are often + * identical so that the path description contains redundant information. SVG provides shorthand + * curve commands that need less parameters because they reuse previously given arguments. + * This method detects such command sequences and replaces them by their short form. It does not + * recompute the whole paths to reduce the number of necessary line/curve segments. */ +void Glyph::optimizeCommands () { + LPair fp; // first point of current path + LPair cp; // current point (where path drawing continues) + ConstIterator prev; // preceding command + LPair pstore[2]; + FORALL(_commands, Iterator, it) { + char cmd = (*it)->getSVGPathCommand(); + const vector<LPair> ¶ms = (*it)->params(); + GlyphCommand *new_command = 0; + switch (cmd) { + case 'M': + fp = params[0]; // record first point of path + break; + case 'Z': + cp = fp; + break; + case 'L': + if (params[0].x() == cp.x()) + new_command = new GlyphVerticalLineTo(params[0]); + else if (params[0].y() == cp.y()) + new_command = new GlyphHorizontalLineTo(params[0]); + break; + case 'C': + if ((*prev)->getSVGPathCommand() == 'C' || (*prev)->getSVGPathCommand() == 'S') { + if (params[0] == pstore[1]*2-pstore[0]) // is first control point reflection of preceding second control point? + new_command = new GlyphShortCubicTo(params[1], params[2]); + } + pstore[0] = params[1]; // store second control point and + pstore[1] = params[2]; // curve endpoint + break; + case 'Q': + if ((*prev)->getSVGPathCommand() == 'Q' || (*prev)->getSVGPathCommand() == 'T') { + if (params[0] == pstore[1]*2-pstore[0]) + new_command = new GlyphShortConicTo(params[1]); + } + // [pass through] + case 'S': + case 'T': + pstore[0] = params[0]; // store (second) control point and + pstore[1] = params[1]; // curve endpoint + break; + } + // update current point + if (!(*it)->params().empty()) + cp = (*it)->param(-1); + + // replace current command by shorthand form + if (new_command) { + delete *it; + *it = new_command; + new_command = 0; + } + prev = it; + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.h new file mode 100644 index 00000000000..44a6b65553b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontGlyph.h @@ -0,0 +1,145 @@ +/************************************************************************* +** FontGlyph.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTGLYPH_H +#define FONTGLYPH_H + +#include <ostream> +#include <list> +#include <vector> +#include "Pair.h" + +using std::ostream; +using std::list; +using std::vector; + +class GlyphCommand +{ + public: + GlyphCommand () {} + GlyphCommand (const LPair &p); + GlyphCommand (const LPair &p1, const LPair &p2); + GlyphCommand (const LPair &p1, const LPair &p2, const LPair &p3); + virtual ~GlyphCommand () {} + virtual char getSVGPathCommand () const =0; + virtual GlyphCommand* combine (GlyphCommand &cmd) {return 0;} + virtual const vector<LPair>& params () const {return _params;} + virtual LPair param (int n) const; + virtual void writeSVGCommand (ostream &os, double sx=1, double sy=1) const; + + protected: + typedef vector<LPair>::iterator Iterator; + typedef vector<LPair>::const_iterator ConstIterator; + vector<LPair> _params; +}; + + +struct GlyphMoveTo : public GlyphCommand +{ + GlyphMoveTo (const LPair &p) : GlyphCommand(p) {} + char getSVGPathCommand () const {return 'M';} + GlyphCommand* combine (GlyphCommand &cmd); +}; + + +struct GlyphLineTo : public GlyphCommand +{ + GlyphLineTo (const LPair &p) : GlyphCommand(p) {} + char getSVGPathCommand () const {return 'L';} + GlyphCommand* combine (GlyphCommand &cmd); +}; + + +struct GlyphHorizontalLineTo : public GlyphLineTo +{ + GlyphHorizontalLineTo (const LPair &p) : GlyphLineTo(LPair(p.x(), 0)) {} + char getSVGPathCommand () const {return 'H';} + void writeSVGCommand (ostream &os, double sx=1, double sy=1) const; +}; + + +struct GlyphVerticalLineTo : public GlyphLineTo +{ + GlyphVerticalLineTo (const LPair &p) : GlyphLineTo(LPair(0, p.y())) {} + char getSVGPathCommand () const {return 'V';} + void writeSVGCommand (ostream &os, double sx=1, double sy=1) const; +}; + + +struct GlyphConicTo : public GlyphCommand +{ + GlyphConicTo (const LPair &p1, const LPair &p2) : GlyphCommand(p1, p2) {} + char getSVGPathCommand () const {return 'Q';} +}; + + +struct GlyphShortConicTo : public GlyphCommand +{ + GlyphShortConicTo (const LPair &p) : GlyphCommand(p) {} + char getSVGPathCommand () const {return 'T';} +}; + + +struct GlyphCubicTo : public GlyphCommand +{ + GlyphCubicTo (const LPair &p1, const LPair &p2, const LPair &p3) : GlyphCommand(p1, p2, p3) {} + char getSVGPathCommand () const {return 'C';} + GlyphCommand* combine (GlyphCommand &cmd); +}; + + +struct GlyphShortCubicTo : public GlyphCommand +{ + GlyphShortCubicTo (const LPair &p1, const LPair &p2) : GlyphCommand(p1, p2) {} + char getSVGPathCommand () const {return 'S';} +}; + + +struct GlyphClosePath : public GlyphCommand +{ + char getSVGPathCommand () const {return 'Z';} +}; + + +class FontEncoding; +class FontEngine; + +class Glyph +{ + typedef list<GlyphCommand*> CommandList; + typedef CommandList::iterator Iterator; + typedef CommandList::const_iterator ConstIterator; + public: + ~Glyph (); + void addCommand(GlyphCommand *cmd); + void clear (); + void closeOpenPaths (); + void optimizeCommands (); + void read (unsigned char c, const FontEncoding *encoding, const FontEngine &fontEngine); + void writeSVGCommands (ostream &os, double sx, double sy) const; + void forAllCommands (void (*f)(GlyphCommand*, void*), void *userParam=0); + bool empty () const {return _commands.empty();} + const CommandList& commands () const {return _commands;} + + private: + CommandList _commands; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.cpp new file mode 100644 index 00000000000..6d8fb154a3d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.cpp @@ -0,0 +1,264 @@ +/************************************************************************* +** FontManager.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <fstream> +#include "Font.h" +#include "FontEncoding.h" +#include "FontManager.h" +#include "FileFinder.h" +#include "Message.h" +#include "macros.h" + +using namespace std; + + +FontManager::FontManager () +{ +} + + +FontManager::~FontManager () { + FORALL(_fonts, vector<Font*>::iterator, i) + delete *i; + typedef map<string,FontEncoding*>::iterator Iterator; + FORALL(_encMap, Iterator, i) + delete i->second; +} + + +/** Returns a unique ID that identifies the font. + * @param[in] n local font number, as used in DVI and VF files + * @return non-negative font ID if font was found, -1 otherwise */ +int FontManager::fontID (int n) const { + if (_vfStack.empty()) { + Num2IdMap::const_iterator it = _num2id.find(n); + return (it == _num2id.end()) ? -1 : it->second; + } + VfNum2IdMap::const_iterator vit = _vfnum2id.find(_vfStack.top()); + if (vit == _vfnum2id.end()) + return -1; + const Num2IdMap &num2id = vit->second; + Num2IdMap::const_iterator it = num2id.find(n); + return (it == num2id.end()) ? -1 : it->second; +} + + +int FontManager::fontID (const Font *font) const { + for (size_t i=0; i < _fonts.size(); i++) + if (_fonts[i] == font) + return i; + return -1; +} + + +int FontManager::fontID (const string &name) const { + map<string,int>::const_iterator it = _name2id.find(name); + if (it == _name2id.end()) + return -1; + return it->second; +} + + +int FontManager::fontnum (int id) const { + if (id < 0 || size_t(id) > _fonts.size()) + return -1; + if (_vfStack.empty()) { + FORALL(_num2id, Num2IdMap::const_iterator, i) + if (i->second == id) + return i->first; + } + else { + VfNum2IdMap::const_iterator it = _vfnum2id.find(_vfStack.top()); + if (it == _vfnum2id.end()) + return -1; + const Num2IdMap &num2id = it->second; + FORALL(num2id, Num2IdMap::const_iterator, i) + if (i->second == id) + return i->first; + } + return -1; +} + + +int FontManager::vfFirstFontNum (VirtualFont *vf) const { + VfFirstFontMap::const_iterator it = _vfFirstFontMap.find(vf); + return (it == _vfFirstFontMap.end()) ? -1 : it->second; +} + + +/** Returns a previously registered font. + * @param[in] n local font number, as used in DVI and VF files + * @return pointer to font if font was found, 0 otherwise */ +Font* FontManager::getFont (int n) const { + int id = fontID(n); + return (id < 0) ? 0 : _fonts[id]; +} + + +Font* FontManager::getFont (const string &name) const { + int id = fontID(name); + if (id < 0) + return 0; + return _fonts[id]; +} + + +Font* FontManager::getFontById (int id) const { + if (id < 0 || size_t(id) >= _fonts.size()) + return 0; + return _fonts[id]; +} + + +/** Returns the current active virtual font. */ +VirtualFont* FontManager::getVF () const { + return _vfStack.empty() ? 0 : _vfStack.top(); +} + + +/** Registers a new font to be managed by the FontManager. If there is + * already a registered font assigned to number n, nothing happens. + * @param[in] fontnum local font number, as used in DVI and VF files + * @param[in] name fontname, e.g. cmr10 + * @param[in] checksum checksum to be compared with TFM checksum + * @param[in] dsize design size in TeX point units + * @param[in] ssize scaled size in TeX point units + * @return id of registered font */ +int FontManager::registerFont (UInt32 fontnum, string name, UInt32 checksum, double dsize, double ssize) { + int id = fontID(fontnum); + if (id >= 0) + return id; + + Font *newfont = 0; + int newid = _fonts.size(); // the new font gets this ID + Name2IdMap::iterator it = _name2id.find(name); + if (it != _name2id.end()) { // font with same name already registered? + Font *font = _fonts[it->second]; + newfont = font->clone(dsize, ssize); + } + else { + if (FileFinder::lookup(name+".pfb")) + newfont = PhysicalFont::create(name, checksum, dsize, ssize, PhysicalFont::PFB); + else if (FileFinder::lookup(name+".ttf")) + newfont = PhysicalFont::create(name, checksum, dsize, ssize, PhysicalFont::TTF); + else if (FileFinder::lookup(name+".vf")) + newfont = VirtualFont::create(name, checksum, dsize, ssize); + else if (FileFinder::lookup(name+".mf")) + newfont = PhysicalFont::create(name, checksum, dsize, ssize, PhysicalFont::MF); + else { + newfont = new EmptyFont(name); + Message::wstream(true) << "font '" << name << "' not found\n"; + } + _name2id[name] = newid; + + const char *encname = FileFinder::lookupEncName(name); + if (encname && _encMap.find(encname) == _encMap.end()) + _encMap[encname] = new FontEncoding(encname); + } + _fonts.push_back(newfont); + if (_vfStack.empty()) // register font referenced in dvi file? + _num2id[fontnum] = newid; + else { // register font referenced in vf file + VirtualFont *vf = const_cast<VirtualFont*>(_vfStack.top()); + _vfnum2id[vf][fontnum] = newid; + if (_vfFirstFontMap.find(vf) == _vfFirstFontMap.end()) // first fontdef of VF? + _vfFirstFontMap[vf] = fontnum; + } + return newid; +} + + +/** Enters a new virtual font frame. + * This method must be called before processing a VF character. + * @param[in] vf virtual font */ +void FontManager::enterVF (VirtualFont *vf) { + if (vf) + _vfStack.push(vf); +} + + +/** Leaves a previously entered virtual font frame. */ +void FontManager::leaveVF () { + if (!_vfStack.empty()) + _vfStack.pop(); +} + + +/** Assigns a sequence of DVI commands to a char code. + * @param[in] c character code + * @param[in] dvi points to vector with DVI commands */ +void FontManager::assignVfChar (int c, vector<UInt8> *dvi) { + if (!_vfStack.empty() && dvi) + _vfStack.top()->assignChar(c, dvi); +} + + +/** Returns the encoding of a given font. + * @param[in] font font whose encoding will be returned + * @return pointer to encoding object, or 0 if there is no encoding defined */ +FontEncoding* FontManager::encoding (const Font *font) const { + if (font) { + if (const char *encname = FileFinder::lookupEncName(font->name())) { + map<string,FontEncoding*>::const_iterator it = _encMap.find(encname); + if (it != _encMap.end()) + return it->second; + } + } + return 0; +} + + +ostream& FontManager::write (ostream &os, Font *font, int level) { +#if 0 + if (font) { + int id = -1; + for (int i=0; i < fonts.size() && id < 0; i++) + if (fonts[i] == font) + id = i; + + VirtualFont *vf = dynamic_cast<VirtualFont*>(font); + for (int j=0; j < level+1; j++) + os << " "; + os << "id " << id + << " fontnum " << fontnum(id) << " " + << (vf ? "VF" : "PF") << " " + << font->name() + << endl; + + if (vf) { + enterVF(vf); + const Num2IdMap &num2id = vfnum2id.find(vf)->second; + FORALL(num2id, Num2IdMap::const_iterator, i) { + Font *font = fonts[i->second]; + write(os, font, level+1); + } + leaveVF(); + } + } + else { + for (int i=0; i < fonts.size(); i++) + write(os, fonts[i], level); + os << endl; + } +#endif + return os; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.h new file mode 100644 index 00000000000..b1ee735a097 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontManager.h @@ -0,0 +1,89 @@ +/************************************************************************* +** FontManager.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTMANAGER_H +#define FONTMANAGER_H + +#include <map> +#include <ostream> +#include <set> +#include <string> +#include <stack> +#include <vector> +#include "types.h" + +using std::map; +using std::ostream; +using std::set; +using std::string; +using std::stack; +using std::vector; + +class FileFinder; +class Font; +class FontEncoding; +class TFM; +class VirtualFont; + +/** This class provides methods for an easy DVI font handling. + * DVI and VF files use local font numbers to reference fonts. For SVG output + * we need a single list with unique IDs of all physical fonts. Characters of + * virtual fonts are completely replaced by their DVI description so they don't + * appear anywhere in the output. */ +class FontManager +{ + typedef map<UInt32,int> Num2IdMap; + typedef map<string,int> Name2IdMap; + typedef map<VirtualFont*,Num2IdMap> VfNum2IdMap; + typedef map<VirtualFont*, UInt32> VfFirstFontMap; + typedef map<string,FontEncoding*> EncodingMap; + typedef stack<VirtualFont*> VfStack; + public: + FontManager (); + ~FontManager (); + int registerFont (UInt32 fontnum, string fontname, UInt32 checksum, double dsize, double scale); + Font* getFont (int n) const; + Font* getFont (const string &name) const; + Font* getFontById (int id) const; + VirtualFont* getVF () const; + int fontID (int n) const; + int fontID (const Font *font) const; + int fontID (const string &name) const; + int fontnum (int id) const; + int vfFirstFontNum (VirtualFont *vf) const; + int decodeChar (int c) const; + void enterVF (VirtualFont *vf); + void leaveVF (); + void assignVfChar (int c, vector<UInt8> *dvi); + const vector<Font*>& getFonts () const {return _fonts;} + FontEncoding* encoding (const Font *font) const; + ostream& write (ostream &os, Font *font=0, int level=0); + + private: + vector<Font*> _fonts; ///< all registered Fonts (indexed by fontID) + Num2IdMap _num2id; ///< DVI font number -> fontID + Name2IdMap _name2id; ///< fontname -> fontID + VfNum2IdMap _vfnum2id; + VfStack _vfStack; ///< stack of currently processed virtual fonts + VfFirstFontMap _vfFirstFontMap; ///< VF -> local font number of first font defined in VF + EncodingMap _encMap; ///< encname -> encoding table +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.cpp new file mode 100644 index 00000000000..9d5ac6ee96f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.cpp @@ -0,0 +1,237 @@ +/************************************************************************* +** FontMap.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <fstream> +#include <iostream> +#include <vector> +#include "Directory.h" +#include "FontMap.h" + +using namespace std; + +enum FontMapFieldType {FM_ERROR=0, FM_NONE, FM_NAME, FM_PS_CODE, FM_HEADER, FM_ENC, FM_FONT}; + + +static char* str_tolower (char *str); +static inline char* get_extension (char *fname); +static FontMapFieldType read_entry (char* &first, char* &last, bool name_only=false); + + + +FontMap::FontMap (const string &fname) { + read(fname); +} + + +bool FontMap::read (const string &fname) { + ifstream ifs(fname.c_str()); + if (ifs) { + if (fname.find("dvipdfm") != string::npos) + readPdfMap(ifs); + else + readPsMap(ifs); + return true; + } + return false; +} + + +/** Read map file in dvips format. + * @param[in] is data is read from this stream */ +void FontMap::readPsMap (istream &is) { + char buf[512]; + while (is && !is.eof()) { + is.getline(buf, 512); + if (!buf[0] || strchr(" %#;*", buf[0])) // comment? + continue; + char *first=buf, *last=buf, *end=buf+is.gcount()-1; + MapEntry entry; + string name; + while (last < end && *first) { + last = first; + switch (read_entry(first, last)) { + case FM_NAME: + if (name.empty()) + name = first; + break; + case FM_ENC: + entry.encname = first; break; + case FM_FONT: + entry.fontname = first; break; + case FM_ERROR: + continue; + default: + break; + } + first = last+1; + } + // strip filename suffix + size_t len; + if ((len = entry.encname.length()) > 4 && entry.encname.substr(len-4) == ".enc") + entry.encname = entry.encname.substr(0, len-4); + if ((len = entry.fontname.length()) > 4 && entry.fontname[len-4] == '.') + entry.fontname = entry.fontname.substr(0, len-4); + + if (!name.empty() && ((name != entry.fontname && !entry.fontname.empty()) || !entry.encname.empty())) + _fontMap[name] = entry; + } +} + + +/** Read map file in dvipdfm format. + * <font name> [<encoding>|default|none] [<map target>] [options] + * The optional trailing dvipdfm-parameters -r, -e and -s are ignored. + * @param[in] is data is read from this stream */ +void FontMap::readPdfMap (istream &is) { + char buf[512]; + while (is && !is.eof()) { + is.getline(buf, 512); + if (!buf[0] || strchr(" %#;*", buf[0])) // comment? + continue; + char *first=buf, *last=buf, *end=buf+is.gcount()-1; + vector<string> fields; + for (int i=0; i < 3 && last < end && *first; i++) { + FontMapFieldType type = read_entry(first, last, true); + if (*first == '-') + break; + if (type == FM_NAME) + fields.push_back(first); + first = last+1; + } + if (fields.size() > 1 && (fields[1] == "default" || fields[1] == "none")) + fields[1].clear(); + + if (fields.size() < 2) + continue; + if ((fields.size() == 2 && fields[1].empty()) || (fields.size() == 3 && fields[1].empty() && fields[0] == fields[2])) + continue; + + _fontMap[fields[0]].fontname = fields[fields.size() == 2 ? 0 : 2]; + _fontMap[fields[0]].encname = fields[1]; + } +} + + + +static char* str_tolower (char *str) { + for (char *p=str; *p; p++) + *p = tolower(*p); + return str; +} + + +static inline char* get_extension (char *fname) { + if (char* p=strrchr(fname, '.')) + return p+1; + return 0; +} + + + + +/** Reads a single line entry. + * @param[in,out] first pointer to first char of entry + * @param[in,out] last pointer to last char of entry + * @param[in] name_only true, if special meanings of \" and < should be ignored + * @return entry type */ +static FontMapFieldType read_entry (char* &first, char* &last, bool name_only) { + while (*first && isspace(*first)) + first++; + if (!name_only) { + if (*first == '"') { + last = first+1; + while (*last && *last != '"') + last++; + if (*last == 0) // quote not closed => skip invalid line + return FM_ERROR; + return FM_PS_CODE; + } + else if (*first == '<') { + bool eval_prefix = true; + FontMapFieldType type=FM_HEADER; + first++; + if (isspace(*first)) { + first++; + eval_prefix = false; + } + else if (*first == '<' || *first == '[') { + type = (*first == '<') ? FM_FONT : FM_ENC; + first++; + } + if (read_entry(first, last, true) != FM_NAME) + return FM_ERROR; + if (type == FM_HEADER) { + if (char *ext = get_extension(first)) { + ext = str_tolower(ext); + if (strcmp(ext, "enc")==0) + return FM_ENC; + if (strcmp(ext, "pfb")==0 || strcmp(ext, "pfa")==0) + return FM_FONT; + } + } + return type; + } + } + last = first; + while (*last && !isspace(*last)) + last++; + *last = 0; + return (first < last) ? FM_NAME : FM_NONE; +} + + +ostream& FontMap::write (ostream &os) const { + for (map<string,MapEntry>::const_iterator i=_fontMap.begin(); i != _fontMap.end(); ++i) + os << i->first << " -> " << i->second.fontname << " [" << i->second.encname << "]\n"; + return os; +} + + +void FontMap::readdir (const string &dirname) { + Directory dir(dirname); + while (const char *fname = dir.read('f')) { + if (strlen(fname) >= 4 && strcmp(fname+strlen(fname)-4, ".map") == 0) { + string path = dirname + "/" + fname; + read(path.c_str()); + } + } +} + + +/** Returns name of font that is mapped to a given font. + * @param[in] fontname name of font whose mapped name is retrieved + * @returns name of mapped font */ +const char* FontMap::lookup (const string &fontname) const { + ConstIterator it = _fontMap.find(fontname); + if (it == _fontMap.end()) + return 0; + return it->second.fontname.c_str(); +} + + +/** Returns the name of the assigned encoding for a given font. + * @param[in] fontname name of font whose encoding is returned + * @return name of encoding, 0 if there is no encoding assigned */ +const char* FontMap::encoding (const string &fontname) const { + ConstIterator it = _fontMap.find(fontname); + if (it == _fontMap.end() || it->second.encname.empty()) + return 0; + return it->second.encname.c_str(); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.h new file mode 100644 index 00000000000..8ca075fb36b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/FontMap.h @@ -0,0 +1,63 @@ +/************************************************************************* +** FontMap.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef FONTMAP_H +#define FONTMAP_H + +#include <cstring> +#include <istream> +#include <map> +#include <ostream> +#include <string> + +using std::istream; +using std::map; +using std::ostream; + +class FontMap +{ + struct MapEntry + { + std::string fontname; ///< target font name + std::string encname; ///< name of font encoding + }; + + typedef map<std::string,MapEntry>::const_iterator ConstIterator; + + public: + FontMap () {} + FontMap (const std::string &fname); + FontMap (istream &is); + bool read (const std::string &fname); + void readdir (const std::string &dirname); + void clear () {_fontMap.clear();} + ostream& write (ostream &os) const; + const char* lookup(const std::string &fontname) const; + const char* encoding (const std::string &fontname) const; + + protected: + void readPsMap (istream &is); + void readPdfMap (istream &is); + + private: + map<std::string,MapEntry> _fontMap; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.cpp new file mode 100644 index 00000000000..4707520ba38 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.cpp @@ -0,0 +1,86 @@ +/************************************************************************* +** GFGlyphTracer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "GFGlyphTracer.h" +#include "Pair.h" + +using namespace std; + + + +GFGlyphTracer::GFGlyphTracer (istream &is, double upp) : GFTracer(is, upp) +{ + _glyph = new Glyph; + _transfered = false; +} + + +GFGlyphTracer::~GFGlyphTracer () { + if (!_transfered) + delete _glyph; +} + + +void GFGlyphTracer::moveTo (double x, double y) { + LPair p(x, y); + _glyph->addCommand(new GlyphMoveTo(p)); +} + + +void GFGlyphTracer::lineTo (double x, double y) { + LPair p(x, y); + _glyph->addCommand(new GlyphLineTo(p)); +} + + +void GFGlyphTracer::curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y) { + LPair p1(c1x, c1y); + LPair p2(c2x, c2y); + LPair p3(x, y); + _glyph->addCommand(new GlyphCubicTo(p1, p2, p3)); +} + + +void GFGlyphTracer::closePath () { + _glyph->addCommand(new GlyphClosePath()); +} + + +void GFGlyphTracer::endChar (UInt32 c) { + if (_transfered) { + _glyph = new Glyph; + _transfered = false; + } + else + _glyph->clear(); + GFTracer::endChar(c); + _glyph->optimizeCommands(); +} + + +/** Returns a pointer to the current glyph object and transfers its ownership. That means + * the caller is responsible for deleting the object after its usage. GFGlyphTracer doesn't + * care for it any longer. To just retrieve the glyph without transferring ownership, use + * getGlyph(). */ +Glyph* GFGlyphTracer::transferGlyph () { + _transfered = true; + return _glyph; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.h new file mode 100644 index 00000000000..7c63ac5b932 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFGlyphTracer.h @@ -0,0 +1,45 @@ +/************************************************************************* +** GFGlyphTracer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef GFGLYPHTRACER_H +#define GFGLYPHTRACER_H + +#include "FontGlyph.h" +#include "GFTracer.h" + +class GFGlyphTracer : public GFTracer +{ + public: + GFGlyphTracer (istream &is, double upp); + ~GFGlyphTracer (); + void moveTo (double x, double y); + void lineTo (double x, double y); + void curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y); + void closePath (); + void endChar (UInt32 c); + const Glyph& getGlyph () const {return *_glyph;} + Glyph* transferGlyph (); + + private: + Glyph *_glyph; + bool _transfered; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.cpp new file mode 100644 index 00000000000..121b9e44b59 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.cpp @@ -0,0 +1,372 @@ +/************************************************************************* +** GFReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iostream> +#include "GFReader.h" +#include "Message.h" +#include "macros.h" + +using namespace std; + +struct GFCommand +{ + void (GFReader::*method)(int); + int numBytes; +}; + +struct CharInfo +{ + CharInfo (Int32 dxx, Int32 dyy, Int32 w, UInt32 p) + : dx(dxx), dy(dyy), width(w), location(p) {} + + Int32 dx, dy; + Int32 width; // 2^24 * (true width)/(design size) + UInt32 location; +}; + + +static inline double fix2double (Int32 fix) { + return double(fix)/(1 << 20); +} + + +static inline double scaled2double (Int32 scaled) { + return double(scaled)/(1 << 16); +} + + +GFReader::GFReader (istream &is) : in(is), valid(true) +{ + minX = maxX = minY = maxY = x = y = 0; +} + + +GFReader::~GFReader () { + FORALL(charInfoMap, Iterator, i) + delete i->second; +} + + +UInt32 GFReader::readUnsigned (int bytes) { + UInt32 ret = 0; + for (int i=bytes-1; i >= 0 && !in.eof(); i--) { + UInt32 b = in.get(); + ret |= b << (8*i); + } + return ret; +} + + +Int32 GFReader::readSigned (int bytes) { + Int32 ret = in.get(); + if (ret & 128) // negative value? + ret |= 0xffffff00; + for (int i=bytes-2; i >= 0 && !in.eof(); i--) + ret = (ret << 8) | in.get(); + return ret; +} + + +string GFReader::readString (int bytes) { + char *buf = new char[bytes+1]; + if (bytes > 0) + in.get(buf, bytes+1); // reads 'bytes' bytes (pos. bytes+1 is set to 0) + else + *buf = 0; + string ret = buf; + delete [] buf; + return ret; +} + + +/** Reads a single GF command from the current position of the input stream and calls the + * corresponding cmdFOO method. + * @return opcode of the executed command */ +int GFReader::executeCommand () { + /* Each cmdFOO command reads the necessary number of bytes from the stream so executeCommand + doesn't need to know the exact GF command format. Some cmdFOO methods are used for multiple + GF commands because they only differ in the size of their parameters. */ + static const GFCommand commands[] = { + {&GFReader::cmdPaint, 1}, {&GFReader::cmdPaint, 2}, {&GFReader::cmdPaint, 3}, // 64-66 + {&GFReader::cmdBoc, 0}, {&GFReader::cmdBoc1, 0}, // 67-68 + {&GFReader::cmdEoc, 0}, // 69 + {&GFReader::cmdSkip, 0}, {&GFReader::cmdSkip, 1}, {&GFReader::cmdSkip, 2},{&GFReader::cmdSkip, 3}, // 70-73 + {&GFReader::cmdXXX, 1}, {&GFReader::cmdXXX, 2}, {&GFReader::cmdXXX, 3}, {&GFReader::cmdXXX, 4}, // 239-242 + {&GFReader::cmdYYY, 0}, // 243 + {&GFReader::cmdNop, 0}, // 244 + {&GFReader::cmdCharLoc, 0}, {&GFReader::cmdCharLoc0, 0}, // 245-246 + {&GFReader::cmdPre, 0}, {&GFReader::cmdPost, 0}, {&GFReader::cmdPostPost, 0} // 247-249 + }; + + int opcode = in.get(); + if (opcode < 0) { // at end of file + Message::estream(true) << "unexpected end of file\n"; + return 249; // postpost opcode => stop further reading + } + if (opcode >= 0 && opcode <= 63) + cmdPaint0(opcode); + else if (opcode >= 74 && opcode <= 238) + cmdNewRow(opcode-74); + else if (opcode >= 250) { + Message::estream(true) << "undefined GF command (opcode " << opcode << ")\n"; + valid = false; + } + else { + int offset = opcode <= 73 ? 64 : 239-(73-64+1); + const GFCommand &cmd = commands[opcode-offset]; + if (cmd.method) + (this->*cmd.method)(cmd.numBytes); + } + return opcode; +} + + +bool GFReader::executeChar (UInt8 c) { + in.clear(); + if (charInfoMap.empty()) + executePostamble(); // read character infos + in.clear(); + Iterator it = charInfoMap.find(c); + if (in && valid && it != charInfoMap.end()) { + in.seekg(it->second->location, ios_base::beg); + while (valid && executeCommand() != 69); // execute all commands until eoc is reached + return valid; + } + return false; +} + + +bool GFReader::executeAllChars () { + in.clear(); + if (charInfoMap.empty()) + executePostamble(); // read character infos + in.clear(); + if (in && valid) { + in.seekg(0); + while (valid && executeCommand() != 248); // execute all commands until postamble is reached + return valid; + } + return false; +} + + +bool GFReader::executePostamble () { + in.clear(); + if (!in) + return false; + in.seekg(-1, ios_base::end); + while (in.peek() == 223) // skip fill bytes + in.seekg(-1, ios_base::cur); + in.seekg(-4, ios_base::cur); + UInt32 q = readUnsigned(4); // pointer to begin of postamble + in.seekg(q, ios_base::beg); // now on begin of postamble + while (valid && executeCommand() != 249); // execute all commands until postpost is reached + return valid; +} + + +/** Returns the design size of this font int TeX point units. */ +double GFReader::getDesignSize () const { + return fix2double(designSize); +} + +/** Returns the number of horizontal pixels per point. */ +double GFReader::getHPixelsPerPoint () const { + return scaled2double(hppp); +} + +/** Returns the number of vertical pixels per point. */ +double GFReader::getVPixelsPerPoint () const { + return scaled2double(vppp); +} + +/** Returns the width of character c in TeX point units */ +double GFReader::getCharWidth (UInt32 c) const { + ConstIterator it = charInfoMap.find(c%256); + return it == charInfoMap.end() ? 0 : it->second->width*getDesignSize()/(1<<24); +} + +/////////////////////// + + +/** Reads the preamble. */ +void GFReader::cmdPre (int) { + UInt32 i = readUnsigned(1); + if (i == 131) { + UInt32 k = readUnsigned(1); + string s = readString(k); + preamble(s); + } + else { + Message::estream(true) << "invalid identification number in GF preamble\n"; + valid = false; + } +} + + +/** Reads the postamble. */ +void GFReader::cmdPost (int) { + readUnsigned(4); // pointer to byte after final eoc + designSize = readUnsigned(4); // design size of font in points + checksum = readUnsigned(4); // checksum + hppp = readUnsigned(4); // horizontal pixels per point (scaled int) + vppp = readUnsigned(4); // vertical pixels per point (scaled int) + in.seekg(16, ios_base::cur); // skip x and y bounds + postamble(); +} + + +/** Reads trailing bytes at end of stream. */ +void GFReader::cmdPostPost (int) { + readUnsigned(4); // pointer to begin of postamble + UInt32 i = readUnsigned(1); + if (i == 131) + while (readUnsigned(1) == 223); // skip fill bytes + else { + Message::estream(true) << "invalid identification number in GF preamble\n"; + valid = false; + } +} + + +/** Inverts "paint color" (black to white or vice versa) of n pixels + * and advances the cursor by n. + * @param[in] n number of pixels to be inverted */ +void GFReader::cmdPaint0 (int n) { + if (penDown) // set pixels? + bitmap.setBits(y, x, n); + x += n; + penDown = !penDown; // inverse pen state +} + + +/** Inverts "paint color" (black to white or vice versa) of n pixels + * and advances the cursor by n. The number n of pixels is read from + * the input stream. + * @param[in] len size of n in bytes */ +void GFReader::cmdPaint (int len) { + UInt32 pixels = readUnsigned(len); + cmdPaint0(pixels); +} + + +/** Beginning of character (generic format). */ +void GFReader::cmdBoc (int) { + currentChar = readSigned(4); + readSigned(4); // pointer to previous boc with same c mod 256 + minX = readSigned(4); + maxX = readSigned(4); + minY = readSigned(4); + maxY = readSigned(4); + x = minX; + y = maxY; + penDown = false; + bitmap.resize(minX, maxX, minY, maxY); + beginChar(currentChar); +} + + +/** Beginning of character (compact format). */ +void GFReader::cmdBoc1 (int) { + currentChar = readUnsigned(1); + UInt32 dx = readUnsigned(1); + maxX = readUnsigned(1); + minX = maxX - dx; + UInt32 dy = readUnsigned(1); + maxY = readUnsigned(1); + minY = maxY - dy; + x = minX; + y = maxY; + penDown = false; + bitmap.resize(minX, maxX, minY, maxY); + beginChar(currentChar); +} + + +/** End of character. */ +void GFReader::cmdEoc (int) { + endChar(currentChar); +} + + +/** Moves cursor to the beginning of a following row and sets + * paint color to white. + * @param[in] len if 0: move to next row, otherwise: number of bytes to read. + * The read value denotes the number of rows to be skipped. */ +void GFReader::cmdSkip (int len) { + if (len == 0) + y--; + else + y -= readUnsigned(len)+1; + x = minX; + penDown = false; +} + + +/** Moves cursor to pixel number 'col' in the next row and sets + * the paint color to black. + * @param[in] col pixel/column number */ +void GFReader::cmdNewRow (int col) { + x = minX + col ; + y--; + penDown = true; +} + + +void GFReader::cmdXXX (int len) { + UInt32 n = readUnsigned(len); + string str = readString(n); + special(str); +} + + +void GFReader::cmdYYY (int) { + Int32 y = readSigned(4); + numspecial(y); +} + + +/** Does nothing. */ +void GFReader::cmdNop (int) { +} + + +/** Reads character locator (part of postamble) */ +void GFReader::cmdCharLoc0 (int) { + UInt8 c = readUnsigned(1); // character code mod 256 + UInt8 dm = readUnsigned(1); // + Int32 w = readSigned(4); // (1<<24)*characterWidth/designSize + Int32 p = readSigned(4); // pointer to begin of (last) character data + Int32 dx = 65536*dm; + Int32 dy = 0; + charInfoMap[c] = new CharInfo(dx, dy, w, p); +} + + +/** Reads character locator (part of postamble) */ +void GFReader::cmdCharLoc (int) { + UInt32 c = readUnsigned(1); // character code mod 256 + Int32 dx = readSigned(4); // horizontal escapement (scaled pixel units) + Int32 dy = readSigned(4); // vertical escapement (scaled pixel units) + Int32 w = readSigned(4); // (1<<24)*characterWidth/designSize + Int32 p = readSigned(4); // pointer to begin of (last) character data + charInfoMap[c] = new CharInfo(dx, dy, w, p); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.h new file mode 100644 index 00000000000..d647393359f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFReader.h @@ -0,0 +1,98 @@ +/************************************************************************* +** GFReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef GFREADER_H +#define GFREADER_H + +#include <istream> +#include <map> +#include <string> +#include <vector> +#include "Bitmap.h" +#include "types.h" + +using std::istream; +using std::map; +using std::string; +using std::vector; + +class CharInfo; + +class GFReader +{ + typedef map<UInt8,CharInfo*>::iterator Iterator; + typedef map<UInt8,CharInfo*>::const_iterator ConstIterator; + public: + GFReader (istream &is); + virtual ~GFReader (); + bool executeChar (UInt8 c); + bool executeAllChars (); + bool executePostamble (); + virtual void preamble (const string &str) {} + virtual void postamble () {} + virtual void beginChar (UInt32 c) {} + virtual void endChar (UInt32 c) {} + virtual void special (string str) {} + virtual void numspecial (Int32 y) {} + const Bitmap& getBitmap () const {return bitmap;} + double getDesignSize () const; + double getHPixelsPerPoint () const; + double getVPixelsPerPoint () const; + double getCharWidth (UInt32 c) const; + UInt32 getChecksum () const {return checksum;} + + protected: + Int32 readSigned (int bytes); + UInt32 readUnsigned (int bytes); + string readString (int len); + int executeCommand (); + istream& getInputStream () const {return in;} + + void cmdPre (int); + void cmdPost (int); + void cmdPostPost (int); + void cmdPaint0 (int pixels); + void cmdPaint (int len); + void cmdBoc (int); + void cmdBoc1 (int); + void cmdEoc (int); + void cmdSkip (int len); + void cmdNewRow (int col); + void cmdXXX (int len); + void cmdYYY (int); + void cmdNop (int); + void cmdCharLoc0 (int); + void cmdCharLoc (int); + + private: + istream ∈ + Int32 minX, maxX, minY, maxY; + Int32 x, y; // current pen location (pixel units) + Int32 currentChar; + Bitmap bitmap; // bitmap of current char + FixWord designSize; // designSize + ScaledInt hppp, vppp; // horizontal and vertical pixel per point + UInt32 checksum; + map<UInt8,CharInfo*> charInfoMap; + bool penDown; + bool valid; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.cpp new file mode 100644 index 00000000000..4d494934c0d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.cpp @@ -0,0 +1,103 @@ +/************************************************************************* +** GFTracer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iostream> +#include <fstream> +#include <sstream> +#include "FontGlyph.h" +#include "GFTracer.h" +#include "Message.h" + +#ifdef __MSVC__ +#include <potracelib.h> +#else +extern "C" { +#include <potracelib.h> +} +#endif + +using namespace std; + + +GFTracer::GFTracer (istream &is) + : GFReader(is), _unitsPerPoint(0.0) +{ +} + + +/** Constructs a new GFTracer. + * @param[in] is GF file is read from this stream + * @param[in] upp target units per TeX point */ +GFTracer::GFTracer (istream &is, double upp) + : GFReader(is), _unitsPerPoint(upp) +{ +} + + +void GFTracer::beginChar (UInt32 c) { +} + + +void GFTracer::endChar (UInt32 c) { + const Bitmap &bitmap = getBitmap(); + if (bitmap.empty()) + return; + + // prepare potrace's bitmap structure + vector<potrace_word> buffer; + potrace_bitmap_t pobitmap; + pobitmap.w = bitmap.width(); + pobitmap.h = bitmap.height(); + pobitmap.dy = bitmap.copy(buffer); + pobitmap.map = &buffer[0]; + potrace_param_t *param = potrace_param_default(); + potrace_state_t *state = potrace_trace(param, &pobitmap); + potrace_param_free(param); + + if (!state || state->status == POTRACE_STATUS_INCOMPLETE) + Message::wstream(true) << "error while tracing character\n"; + else { + double hsf=1.0, vsf=1.0; // horizontal a d vertical scale factor + if (_unitsPerPoint != 0.0) { + hsf = _unitsPerPoint/getHPixelsPerPoint(); // horizontal scale factor + vsf = _unitsPerPoint/getVPixelsPerPoint(); // vertical scale factor + } + for (potrace_path_t *path = state->plist; path; path = path->next) { + potrace_dpoint_t &p = path->curve.c[path->curve.n-1][2]; // start/end point + moveTo(hsf*(p.x+bitmap.xshift()), vsf*(p.y+bitmap.yshift())); + for (int i=0; i < path->curve.n; i++) { + if (path->curve.tag[i] == POTRACE_CURVETO) { + curveTo(hsf*(path->curve.c[i][0].x+bitmap.xshift()), vsf*(path->curve.c[i][0].y+bitmap.yshift()), + hsf*(path->curve.c[i][1].x+bitmap.xshift()), vsf*(path->curve.c[i][1].y+bitmap.yshift()), + hsf*(path->curve.c[i][2].x+bitmap.xshift()), vsf*(path->curve.c[i][2].y+bitmap.yshift())); + } + else { + lineTo(hsf*(path->curve.c[i][1].x+bitmap.xshift()), vsf*(path->curve.c[i][1].y+bitmap.yshift())); + if (i == path->curve.n-1) + closePath(); + else + lineTo(hsf*(path->curve.c[i][2].x+bitmap.xshift()), vsf*(path->curve.c[i][2].y+bitmap.yshift())); + } + } + } + } + potrace_state_free(state); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.h new file mode 100644 index 00000000000..bfa21accad6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GFTracer.h @@ -0,0 +1,44 @@ +/************************************************************************* +** GFTracer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef GFTRACER_H +#define GFTRACER_H + +#include <istream> +#include "GFReader.h" + +class GFTracer : public GFReader +{ + public: + GFTracer (std::istream &is); + GFTracer (std::istream &is, double upp); + virtual ~GFTracer () {} + virtual void moveTo (double x, double y) {} + virtual void lineTo (double x, double y) {} + virtual void curveTo (double c1x, double c1y, double c2x, double c2y, double x, double y) {} + virtual void closePath () {} + void beginChar (UInt32 c); + void endChar (UInt32 c); + + private: + double _unitsPerPoint; ///< target units per TeX point +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.cpp new file mode 100644 index 00000000000..2af61f51e27 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.cpp @@ -0,0 +1,223 @@ +/************************************************************************* +** Ghostscript.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "Ghostscript.h" +#if !DISABLE_GS + +#include <cstring> +#include <sstream> + +using namespace std; + +#ifdef __WIN32__ + #define GS_DL_NAME "gsdll32.dll" +#else + #define GS_DL_NAME "libgs.so" +#endif + + +/** Loads the Ghostscript library but does not create an instance. This + * constructor should only be used to call available() and revision(). */ +Ghostscript::Ghostscript () +#if !HAVE_LIBGS +: DLLoader(GS_DL_NAME) +#endif +{ + _inst = 0; +} + + +/** Tries to load the shared library and to initialize Ghostscript. + * @param[in] argc number of parameters in array argv + * @param[in] argv parameters passed to Ghostscript + * @param[in] caller this parameter is passed to all callback functions */ +Ghostscript::Ghostscript (int argc, const char **argv, void *caller) +#if !HAVE_LIBGS + : DLLoader(GS_DL_NAME) +#endif +{ + int status = new_instance(&_inst, caller); + if (status < 0) + _inst = 0; + else { + init_with_args(argc, (char**)argv); + } +} + + +/** Exits Ghostscript and unloads the dynamic library. */ +Ghostscript::~Ghostscript () { + if (_inst) { + exit(); + delete_instance(); + } +} + + +/** Returns true if Ghostscript library was found and can be loaded. */ +bool Ghostscript::available () { +#if HAVE_LIBGS + return true; +#else + return loaded(); +#endif +} + + +/** Retrieves version information about Ghostscript. + * @param[out] r takes the revision information (see GS API documentation for further details) + * @return true on success */ +bool Ghostscript::revision (gsapi_revision_t *r) { +#if HAVE_LIBGS + return (gsapi_revision(r, sizeof(gsapi_revision_t)) == 0); +#else + if (PFN_gsapi_revision fn = (PFN_gsapi_revision)loadFunction("gsapi_revision")) + return (fn(r, sizeof(gsapi_revision_t)) == 0); + return false; +#endif +} + + +string Ghostscript::revision () { + gsapi_revision_t r; + if (revision(&r)) { + ostringstream oss; + oss << r.product << ' ' << (r.revision/100) << '.' << (r.revision%100); + return oss.str(); + } + return ""; +} + + +/** Creates a new instance of Ghostscript. This method is called by the constructor and + * should not be used elsewhere. + * @param[out] psinst handle of newly created instance (or 0 on error) + * @param[in] caller pointer forwarded to callback functions */ +int Ghostscript::new_instance (void **psinst, void *caller) { +#if HAVE_LIBGS + return gsapi_new_instance(psinst, caller); +#else + if (PFN_gsapi_new_instance fn = (PFN_gsapi_new_instance)loadFunction("gsapi_new_instance")) + return fn(psinst, caller); + *psinst = 0; + return 0; +#endif +} + + +/** Destroys the current instance of Ghostscript. This method is called by the destructor + * and should not be used elsewhere. */ +void Ghostscript::delete_instance () { +#if HAVE_LIBGS + gsapi_delete_instance(_inst); +#else + if (PFN_gsapi_delete_instance fn = (PFN_gsapi_delete_instance)loadFunction("gsapi_delete_instance")) + fn(_inst); +#endif +} + + +/** Exits the interpreter. Must be called before destroying the GS instance. */ +int Ghostscript::exit () { +#if HAVE_LIBGS + return gsapi_exit(_inst); +#else + if (PFN_gsapi_exit fn = (PFN_gsapi_exit)loadFunction("gsapi_exit")) + return fn(_inst); + return 0; +#endif +} + + +/** Sets the I/O callback functions. + * @param[in] in pointer to stdin handler + * @param[in] out pointer to stdout handler + * @param[in] err pointer to stderr handler */ +int Ghostscript::set_stdio (Stdin in, Stdout out, Stderr err) { +#if HAVE_LIBGS + return gsapi_set_stdio(_inst, in, out, err); +#else + if (PFN_gsapi_set_stdio fn = (PFN_gsapi_set_stdio)loadFunction("gsapi_set_stdio")) + return fn(_inst, in, out, err); + return 0; +#endif +} + + +/** Initializes Ghostscript with a set of optional parameters. This + * method is called by the constructor and should not be used elsewhere. + * @param[in] argc number of paramters + * @param[in] argv parameters passed to Ghostscript */ +int Ghostscript::init_with_args (int argc, char **argv) { +#if HAVE_LIBGS + return gsapi_init_with_args(_inst, argc, argv); +#else + if (PFN_gsapi_init_with_args fn = (PFN_gsapi_init_with_args)loadFunction("gsapi_init_with_args")) + return fn(_inst, argc, argv); + return 0; +#endif +} + + +/** Tells Ghostscript that several calls of run_string_continue will follow. */ +int Ghostscript::run_string_begin (int user_errors, int *pexit_code) { +#if HAVE_LIBGS + return gsapi_run_string_begin(_inst, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_begin fn = (PFN_gsapi_run_string_begin)loadFunction("gsapi_run_string_begin")) + return fn(_inst, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + + +/** Executes a chunk of PostScript commands given by a buffer of characters. The size of + * this buffer must not exceed 64KB. Longer programs can be split into arbitrary smaller chunks + * and passed to Ghostscript by successive calls of run_string_continue. + * @param[in] str buffer containing the PostScript code + * @param[in] length number of characters in buffer + * @param[in] user_errors if non-negative, the default PS error values will be generated, otherwise this value is returned + * @param[out] pexit_code takes the PS error code */ +int Ghostscript::run_string_continue (const char *str, unsigned length, int user_errors, int *pexit_code) { +#if HAVE_LIBGS + return gsapi_run_string_continue(_inst, str, length, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_continue fn = (PFN_gsapi_run_string_continue)loadFunction("gsapi_run_string_continue")) + return fn(_inst, str, length, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + + +/** Terminates the successive code feeding. Must be called after the last call of run_string_continue. */ +int Ghostscript::run_string_end (int user_errors, int *pexit_code) { +#if HAVE_LIBGS + return gsapi_run_string_end(_inst, user_errors, pexit_code); +#else + if (PFN_gsapi_run_string_end fn = (PFN_gsapi_run_string_end)loadFunction("gsapi_run_string_end")) + return fn(_inst, user_errors, pexit_code); + *pexit_code = 0; + return 0; +#endif +} + +#endif // !DISABLE_GS diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.h new file mode 100644 index 00000000000..776f29bf008 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Ghostscript.h @@ -0,0 +1,97 @@ +/************************************************************************* +** Ghostscript.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef GHOSTSCRIPT_H +#define GHOSTSCRIPT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string> +#if HAVE_LIBGS + #include <ghostscript/iapi.h> +#else + #include "DLLoader.h" + #include "iapi.h" +#endif + +#if defined(__WIN32__) && !defined(_Windows) + #define _Windows +#endif + +#if DISABLE_GS +struct Ghostscript +{ + typedef int (GSDLLCALLPTR Stdin) (void *caller, char *buf, int len); + typedef int (GSDLLCALLPTR Stdout) (void *caller, const char *str, int len); + typedef int (GSDLLCALLPTR Stderr) (void *caller, const char *str, int len); + + Ghostscript () {} + Ghostscript (int argc, const char **argv, void *caller=0) {} + bool available () {return false;} + bool revision (gsapi_revision_t *r) {return false;} + std::string revision () {return "";} + int set_stdio (Stdin in, Stdout out, Stderr err) {return 0;} + int run_string_begin (int user_errors, int *pexit_code) {return 0;} + int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code) {return 0;} + int run_string_end (int user_errors, int *pexit_code) {return 0;} + int exit () {return 0;} +}; + +#else + +/** Wrapper class of (a subset of) the Ghostscript API. */ +class Ghostscript +#if !HAVE_LIBGS +: public DLLoader +#endif +{ + public: + typedef int (GSDLLCALLPTR Stdin) (void *caller, char *buf, int len); + typedef int (GSDLLCALLPTR Stdout) (void *caller, const char *str, int len); + typedef int (GSDLLCALLPTR Stderr) (void *caller, const char *str, int len); + + public: + Ghostscript (); + Ghostscript (int argc, const char **argv, void *caller=0); + ~Ghostscript (); + bool available (); + bool revision (gsapi_revision_t *r); + std::string revision (); + int set_stdio (Stdin in, Stdout out, Stderr err); + int run_string_begin (int user_errors, int *pexit_code); + int run_string_continue (const char *str, unsigned int length, int user_errors, int *pexit_code); + int run_string_end (int user_errors, int *pexit_code); + int exit (); + + protected: + Ghostscript (const Ghostscript &gs) {} + int init_with_args (int argc, char **argv); + int new_instance (void **psinst, void *caller); + void delete_instance (); + + private: + void *_inst; ///< Ghostscript handle needed to call the gsapi_foo functions +}; + +#endif // DISABLE_GS + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GraphicPath.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GraphicPath.h new file mode 100644 index 00000000000..e577821c0a7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/GraphicPath.h @@ -0,0 +1,257 @@ +/************************************************************************* +** GraphicPath.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef GRAPHICPATH_H +#define GRAPHICPATH_H + +#include <list> +#include <ostream> +#include <vector> +#include "BoundingBox.h" +#include "Matrix.h" +#include "Pair.h" + + +template <typename T> +class GraphicPath +{ + typedef Pair<T> Point; + + struct Command { + enum Type {MOVETO, LINETO, CONICTO, CUBICTO, CLOSEPATH}; + + Command (Type t) : type(t) {} + + Command (Type t, const Point &p) : type(t) { + params[0] = p; + } + + Command (Type t, const Point &p1, const Point &p2) : type(t) { + params[0] = p1; + params[1] = p2; + } + + Command (Type t, const Point &p1, const Point &p2, const Point &p3) : type(t) { + params[0] = p1; + params[1] = p2; + params[2] = p3; + } + + int numParams () const { + switch (type) { + case CLOSEPATH : return 0; + case MOVETO : + case LINETO : return 1; + case CONICTO : return 2; + case CUBICTO : return 3; + } + return 0; + } + + void transform (const Matrix &matrix) { + for (int i=0; i < numParams(); i++) + params[i] = matrix * params[i]; + } + + Type type; + Point params[3]; + }; + + struct Actions + { + virtual void moveto (const Point &p) {} + virtual void lineto (const Point &p) {} + virtual void hlineto (const T &y) {} + virtual void vlineto (const T &x) {} + virtual void sconicto (const Point &p) {} + virtual void conicto (const Point &p1, const Point &p2) {} + virtual void scubicto (const Point &p1, const Point &p2) {} + virtual void cubicto (const Point &p1, const Point &p2, const Point &p3) {} + virtual void closepath () {} + virtual bool quit () {return false;} + }; + + typedef typename std::vector<Command>::iterator Iterator; + typedef typename std::vector<Command>::const_iterator ConstIterator; + typedef typename std::vector<Command>::const_reverse_iterator ConstRevIterator; + + public: + void newpath () { + _commands.clear(); + } + + /// Returns true if path is empty (there is nothing to draw) + bool empty () const { + return _commands.empty(); + } + + void moveto (const T &x, const T &y) { + moveto(Point(x, y)); + } + + void moveto (const Point &p) { + // avoid sequences of several MOVETOs; always use latest + if (_commands.empty() || _commands.back().type != Command::MOVETO) + _commands.push_back(Command(Command::MOVETO, p)); + else + _commands.back().params[0] = p; + } + + void lineto (const T &x, const T &y) { + lineto(Point(x, y)); + } + + void lineto (const Point &p) { + _commands.push_back(Command(Command::LINETO, p)); + } + + void conicto (const T &x1, const T &y1, const T &x2, const T &y2) { + conicto(Point(x1, y1), Point(x2, y2)); + } + + void conicto (const Point &p1, const Point &p2) { + _commands.push_back(Command(Command::CONICTO, p1, p2)); + } + + void cubicto (const T &x1, const T &y1, const T &x2, const T &y2, const T &x3, const T &y3) { + cubicto(Point(x1, y1), Point(x2, y2), Point(x3, y3)); + } + + void cubicto (const Point &p1, const Point &p2, const Point &p3) { + _commands.push_back(Command(Command::CUBICTO, p1, p2, p3)); + } + + void closepath () { + _commands.push_back(Command(Command::CLOSEPATH)); + } + + void writeSVG (std::ostream &os, double sx=1.0, double sy=1.0) const { + struct WriteActions : Actions { + WriteActions (std::ostream &os) : _os(os) {} + void moveto (const Point &p) {write('M', p);} + void lineto (const Point &p) {write('L', p);} + void hlineto (const T &y) {_os << 'H' << y;} + void vlineto (const T &x) {_os << 'V' << x;} + void sconicto (const Point &p) {write('T', p); } + void conicto (const Point &p1, const Point &p2) {write('Q', p1); write(' ', p2);} + void scubicto (const Point &p1, const Point &p2) {write('S', p1); write(' ', p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {write('C', p1); write(' ', p2); write(' ', p3);} + void closepath () {_os << 'Z';} + void write (char prefix, const Point &p) {_os << prefix << p.x() << ' ' << p.y();} + std::ostream &_os; + } actions(os); + iterate(actions, true); + } + + void computeBBox (BoundingBox &bbox) const { + struct BBoxActions : Actions { + BBoxActions (BoundingBox &bb) : bbox(bb) {} + void moveto (const Point &p) {bbox.embed(p);} + void lineto (const Point &p) {bbox.embed(p);} + void conicto (const Point &p1, const Point &p2) {bbox.embed(p1); bbox.embed(p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {bbox.embed(p1); bbox.embed(p2); bbox.embed(p3);} + BoundingBox &bbox; + } actions(bbox); + iterate(actions, false); + } + + bool isDot (Point &p) const { + struct DotActions : Actions { + DotActions () : differs(false) {} + void moveto (const Point &p) {point = p;} + void lineto (const Point &p) {differs = (p != point);} + void conicto (const Point &p1, const Point &p2) {differs = (point != p1 || point != p2);} + void cubicto (const Point &p1, const Point &p2, const Point &p3) {differs = (point != p1 || point != p2 || point != p3);} + bool quit () {return differs;} + Point point; + bool differs; + } actions; + iterate(actions, false); + p = actions.point; + return !actions.differs; + } + + void transform (const Matrix &matrix) { + FORALL(_commands, Iterator, it) + it->transform(matrix); + } + + void iterate (Actions &actions, bool optimize) const; + + private: + std::vector<Command> _commands; +}; + + +template <typename T> +void GraphicPath<T>::iterate (Actions &actions, bool optimize) const { + ConstIterator prev; // pointer to preceding command + Point fp; // first point of current path + Point cp; // current point + Point pstore[2]; + for (ConstIterator it=_commands.begin(); it != _commands.end() && !actions.quit(); ++it) { + const Point *params = it->params; + switch (it->type) { + case Command::MOVETO: + actions.moveto(params[0]); + fp = params[0]; + break; + case Command::LINETO: + if (optimize) { + if (cp.x() == params[0].x()) + actions.vlineto(params[0].y()); + else if (cp.y() == params[0].y()) + actions.hlineto(params[0].x()); + else + actions.lineto(params[0]); + } + else + actions.lineto(params[0]); + break; + case Command::CONICTO: + if (optimize && prev->type == Command::CONICTO && params[0] == pstore[1]*T(2)-pstore[0]) + actions.sconicto(params[1]); + else + actions.conicto(params[0], params[1]); + pstore[0] = params[0]; // store control point and + pstore[1] = params[1]; // curve endpoint + break; + case Command::CUBICTO: + // is first control point reflection of preceding second control point? + if (optimize && prev->type == Command::CUBICTO && params[0] == pstore[1]*T(2)-pstore[0]) + actions.scubicto(params[1], params[2]); + else + actions.cubicto(params[0], params[1], params[2]); + pstore[0] = params[1]; // store second control point and + pstore[1] = params[2]; // curve endpoint + break; + case Command::CLOSEPATH: + actions.closepath(); + cp = fp; + } + // update current point + const int np = it->numParams(); + if (np > 0) + cp = it->params[np-1]; + prev = it; + } +} + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.cpp new file mode 100644 index 00000000000..17b95960e3f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.cpp @@ -0,0 +1,137 @@ +/************************************************************************* +** InputBuffer.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include "InputBuffer.h" + +using namespace std; + + +StreamInputBuffer::StreamInputBuffer (istream &is, unsigned bufsize) + : _is(is), _bufsize(bufsize), _buf1(new UInt8[_bufsize]), _buf2(new UInt8[_bufsize]), _bufptr(_buf1) +{ + _size1 = fillBuffer(_buf1); + _size2 = fillBuffer(_buf2); +} + + +StreamInputBuffer::~StreamInputBuffer () { + delete [] _buf1; + delete [] _buf2; +} + + +int StreamInputBuffer::get () { + if (pos() == _size1) { + if (_size2 == 0) + return -1; + swap(_buf1, _buf2); + _size1 = _size2; + _bufptr = _buf1; + _size2 = fillBuffer(_buf2); + } + UInt8 c = *_bufptr++; + return c; +} + + +/** Returns the next character to be read without skipping it. + * Same as peek(0). */ +int StreamInputBuffer::peek () const { + if (pos() < _size1) + return *_bufptr; + return _size2 > 0 ? *_buf2 : -1; +} + + +/** Returns the n-th next character without skipping it. */ +int StreamInputBuffer::peek (unsigned n) const { + if (pos()+n < _size1) + return *(_bufptr+n); + if (pos()+n < _size1+_size2) + return *(_buf2 + pos()+n-_size1); + return -1; +} + + +/** Fills the buffer by reading a sequence of characters from the assigned + * input stream. + * @param[in] buf pointer to character buffer to be filled + * @return number of characters read */ +int StreamInputBuffer::fillBuffer (UInt8 *buf) { + if (_is && !_is.eof()) { + _is.read((char*)buf, _bufsize); + return _is.gcount(); + } + return 0; +} + +/////////////////////////////////////////////// + +SplittedCharInputBuffer::SplittedCharInputBuffer (const char *buf1, unsigned s1, const char *buf2, unsigned s2) { + _buf[0] = buf1; + _buf[1] = buf2; + _size[0] = buf1 ? s1 : 0; + _size[1] = buf2 ? s2 : 0; + _index = _size[0] ? 0 : 1; +} + + +int SplittedCharInputBuffer::get () { + if (_size[_index] == 0) + return -1; + int ret = *_buf[_index]++; + _size[_index]--; + if (_index == 0 && _size[0] == 0) + _index++; + return ret; +} + + +int SplittedCharInputBuffer::peek () const { + return _size[_index] ? *_buf[_index] : -1; +} + + +int SplittedCharInputBuffer::peek (unsigned n) const { + if (n < _size[_index]) + return _buf[_index][n]; + n -= _size[_index]; + if (_index == 0 && n < _size[1]) + return _buf[1][n]; + return -1; +} + +/////////////////////////////////////////////// + + +int TextStreamInputBuffer::get () { + int c = StreamInputBuffer::get(); + if (c == '\n') { + _line++; + _col = 1; + } + else + _col++; + return c; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.h new file mode 100644 index 00000000000..936370a3fa7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputBuffer.h @@ -0,0 +1,141 @@ +/************************************************************************* +** InputBuffer.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef INPUTBUFFER_H +#define INPUTBUFFER_H + +#include <algorithm> +#include <cstring> +#include <istream> +#include <string> +#include <ostream> +#include "types.h" + +struct InputBuffer +{ + virtual ~InputBuffer () {} + virtual int get () =0; + virtual int peek () const =0; + virtual int peek (unsigned n) const =0; + virtual bool eof () const =0; +}; + + +class StreamInputBuffer : public InputBuffer +{ + public: + StreamInputBuffer (std::istream &is, unsigned bufsize=1024); + ~StreamInputBuffer (); + int get (); + int peek () const; + int peek (unsigned n) const; + bool eof () const {return pos() == _size1 && _size2 == 0;} + + protected: + int fillBuffer (UInt8 *buf); + unsigned pos () const {return _bufptr-_buf1;} + + private: + std::istream &_is; + const unsigned _bufsize; ///< maximal number of bytes each buffer can hold + UInt8 *_buf1; ///< pointer to first buffer + UInt8 *_buf2; ///< pointer to second buffer + unsigned _size1; ///< number of bytes in buffer 1 + unsigned _size2; ///< number of bytes in buffer 2 + UInt8 *_bufptr; ///< pointer to next byte to read +}; + + +class StringInputBuffer : public InputBuffer +{ + public: + StringInputBuffer (std::string &str) : _str(str), _pos(0) {} + int get () {return _pos < _str.length() ? _str[_pos++] : -1;} + int peek () const {return _pos < _str.length() ? _str[_pos] : -1;} + int peek (unsigned n) const {return _pos+n < _str.length() ? _str[_pos+n] : -1;} + bool eof () const {return _pos >= _str.length();} + + private: + std::string &_str; + unsigned _pos; +}; + + +class CharInputBuffer : public InputBuffer +{ + public: + CharInputBuffer (const char *buf, unsigned size) : _pos(buf), _size(buf ? size : 0) {} + + int get () { + if (_size <= 0) + return -1; + else { + _size--; + return *_pos++; + } + } + + + void assign (const char *buf, unsigned size) { + _pos = buf; + _size = size; + } + + void assign (const char *buf) {assign(buf, strlen(buf));} + int peek () const {return _size > 0 ? *_pos : -1;} + int peek (unsigned n) const {return _size >= n ? _pos[n] : -1;} + bool eof () const {return _size <= 0;} + + private: + const char *_pos; + unsigned _size; +}; + + +class SplittedCharInputBuffer : public InputBuffer +{ + public: + SplittedCharInputBuffer (const char *buf1, unsigned s1, const char *buf2, unsigned s2); + int get (); + int peek () const; + int peek (unsigned n) const; + bool eof () const {return _size[_index] == 0;} +// bool check (const char *s, bool consume=true); + + private: + const char *_buf[2]; + unsigned _size[2]; + int _index; +}; + + +class TextStreamInputBuffer : public StreamInputBuffer +{ + public: + TextStreamInputBuffer (std::istream &is) : StreamInputBuffer(is), _line(1), _col(1) {} + int get (); + int line () const {return _line;} + int col () const {return _col;} + + private: + int _line, _col; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.cpp new file mode 100644 index 00000000000..4ab8d4a12bb --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.cpp @@ -0,0 +1,279 @@ +/************************************************************************* +** InputReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <vector> +#include "InputReader.h" + +using namespace std; + + +/** Skips n characters. */ +void InputReader::skip (unsigned n) { + while (n-- > 0) + get(); +} + + +/** Moves the buffer pointer to the next non-space character. A following call + * of get() returns this character. */ +void InputReader::skipSpace () { + while (isspace(peek())) + get(); +} + + +/** Tries to find a given string and skips all characters preceding that string. + * @param[in] s string to look for (must not be longer than the maximal buffer size) + * @param[in] consume if true, the buffer pointer is moved to the first charater following string s + * @return true if s was found */ +bool InputReader::skipUntil (const char *s, bool consume) { + bool found; + while (!eof() && !(found = check(s, consume))) + get(); + return found; +} + + +/** Checks if the next characters to be read match a given string. + * @param[in] s string to be matched + * @param[in] consume if true, the characters of the matched string are skipped + * @return true if s matches */ +bool InputReader::check (const char *s, bool consume) { + unsigned count = 0; + for (const char *p=s; *p; p++) { + if (peek(count++) != *p) + return false; + } + if (consume) + skip(count); + return true; +} + + +int InputReader::compare (const char *s, bool consume) { + unsigned count = 0; + for (const char *p=s; *p; p++) { + int c = peek(count++); + if (c != *p) + return *p < c ? -1 : 1; + } + if (consume) + skip(count); + return 0; +} + + +/** Reads an integer from the buffer. All characters that are part of + * the read integer constant are skipped. If this function returns false, + * the buffer pointer points to the same position as before the function call. + * @param[out] val contains the read integer value on success + * @param[in] accept_sign if false, only positive integers (without sign) are accepted + * @return true if integer could be read */ +bool InputReader::parseInt (int &val, bool accept_sign) { + val = 0; + int fac=1; + char sign; // explicitly given sign + if (accept_sign && ((sign = peek()) == '+' || sign == '-')) { + if (isdigit(peek(1))) { + get(); // skip sign + if (sign == '-') + fac = -1; + } + else + return false; + } + else if (!isdigit(peek())) + return false; + + while (isdigit(peek())) + val = val*10 + (get()-'0'); + val *= fac; + return true; +} + + +bool InputReader::parseUInt (unsigned &val) { + val = 0; + if (!isdigit(peek())) + return false; + while (isdigit(peek())) + val += val*10 + (get()-'0'); + return true; +} + + +bool InputReader::parseInt (int base, int &val) { + if (base < 2 || base > 32) + return false; + + const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + const char maxdigit = digits[base-1]; + char c; + if (!isalnum(c = tolower(peek())) || c > maxdigit) + return false; + + val = 0; + while (isalnum(c = tolower(peek())) && c <= maxdigit) { + get(); + int digit = c - (c <= '9' ? '0' : 'a'-10); + val = val*base + digit; + } + return true; +} + + +/** Reads a double from the buffer. All characters that are part of + * the read double constant are skipped. If this function returns false, + * the buffer pointer points to the same position as before the function call. + * @param[out] val contains the read double value on success + * @return number details: 0=no number, 'i'=integer, 'f'=floating point number */ +char InputReader::parseDouble (double &val) { + int fac=1; + int int_part=0; + bool is_float = false; + if (parseInt(int_part)) { // match [+-]?[0-9]+\.? + if (peek() == '.') { + get(); + is_float = true; + } + if (int_part < 0) { + fac = -1; + int_part = -int_part; + } + } + else { // match [+-]?\. + char sign; // explicitly given sign + if ((sign = peek()) == '+' || sign == '-') { // match [+-]?\.[0-9] + if (peek(1) != '.' || !isdigit(peek(2))) + return 0; + if (sign == '-') + fac = -1; + skip(2); // skip sign and dot + } + else if (peek() == '.' && isdigit(peek(1))) + get(); + else + return 0; + is_float = true; + } + // parse fractional part + double frac_part=0.0; + for (double u=10; isdigit(peek()); u*=10) + frac_part += (get()-'0')/u; + val = (int_part + frac_part) * fac; + // parse exponent + char c; + if (tolower(peek()) == 'e' && (isdigit(c=peek(1)) || ((c == '+' || c == '-') && isdigit(peek(2))))) { + get(); // skip 'e' + int exp; + parseInt(exp); + val *= pow(10.0, exp); + is_float = true; + } + return is_float ? 'f' : 'i'; +} + + +/** Reads an integer value from the buffer. If no valid integer constant + * could be found at the current position 0 is returned. */ +int InputReader::getInt () { + skipSpace(); + int val; + return parseInt(val) ? val : 0; +} + + +/** Reads an double value from the buffer. If no valid double constant + * could be found at the current position 0 is returned. */ +double InputReader::getDouble () { + skipSpace(); + double val; + return parseDouble(val) ? val : 0.0; +} + + +string InputReader::getWord () { + string ret; + skipSpace(); + while (isalpha(peek())) + ret += get(); + return ret; +} + + +char InputReader::getPunct () { + skipSpace(); + if (ispunct(peek())) + return get(); + return 0; +} + + +string InputReader::getString (char quotechar) { + string ret; + skipSpace(); + if (quotechar == 0) { + while (!eof() && !isspace(peek()) && isprint(peek())) + ret += get(); + } + else if (peek() == quotechar) { + get(); + while (!eof() && peek() != quotechar) + ret += get(); + get(); + } + return ret; +} + + +int InputReader::parseAttributes (map<string,string> &attr) { + bool ready=false; + while (!eof() && !ready) { + string key; + skipSpace(); + while (isalnum(peek())) + key += get(); + skipSpace(); + if (peek() == '=') { + get(); + skipSpace(); + string val = getString(); + attr[key] = val; + } + else + ready = true; + } + return attr.size(); +} + +////////////////////////////////////////// + + +int StreamInputReader::peek (unsigned n) const { + if (n == 0) + return peek(); + vector<char> chars(n); + _is.read(&chars[0], n); + int ret = peek(); + for (int i=n-1; i >= 0; i--) + _is.putback(chars[i]); + return ret; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.h new file mode 100644 index 00000000000..0a9b8778738 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/InputReader.h @@ -0,0 +1,84 @@ +/************************************************************************* +** InputReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef INPUTREADER_H +#define INPUTREADER_H + +#include <istream> +#include <map> +#include <string> +#include "InputBuffer.h" + + +struct InputReader +{ + virtual int get () =0; + virtual int peek () const =0; + virtual int peek (unsigned n) const =0; + virtual bool eof () const =0; + virtual bool check (char c) const {return peek() == c;} + virtual bool check (const char *s, bool consume=true); + virtual int compare (const char *s, bool consume=true); + virtual void skip (unsigned n); + virtual bool skipUntil (const char *s, bool consume=true); + virtual void skipSpace (); + virtual int getInt (); + virtual bool parseInt (int &val, bool accept_sign=true); + virtual bool parseInt (int base, int &val); + virtual bool parseUInt (unsigned &val); + virtual char parseDouble (double &val); + virtual double getDouble (); + virtual std::string getWord (); + virtual char getPunct (); + virtual std::string getString (char quotechar=0); + virtual int parseAttributes (std::map<std::string,std::string> &attr); + virtual operator bool () const {return !eof();} +}; + + +class StreamInputReader : public InputReader +{ + public: + StreamInputReader (std::istream &is) : _is(is) {} + int get () {return _is.get();} + int peek () const {return _is.peek();} + int peek (unsigned n) const; + bool eof () const {return !_is || _is.eof();} + + private: + std::istream &_is; +}; + + +class BufferInputReader : public InputReader +{ + public: + BufferInputReader (InputBuffer &ib) : _ib(&ib) {} + void assign (InputBuffer &ib) {_ib = &ib;} + int get () {return _ib->get();} + int peek () const {return _ib->peek();} + int peek (unsigned n) const {return _ib->peek(n);} + bool eof () const {return _ib->eof();} + + private: + InputBuffer *_ib; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.cpp new file mode 100644 index 00000000000..da2fc767245 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.cpp @@ -0,0 +1,84 @@ +/************************************************************************* +** Length.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "InputReader.h" +#include "Length.h" + +#define UNIT(c1,c2) ((c1 << 8)|c2) + +using namespace std; + + +void Length::set (const string &len) { + switch (len.length()) { + case 0: + _pt = 0; + break; + case 1: + if (isdigit(len[0])) + _pt = len[0] - '0'; + else + throw UnitException("invalid length: "+len); + break; + default: + istringstream iss(len); + StreamInputReader ir(iss); + double val; + if (!ir.parseDouble(val)) + throw UnitException("invalid length: "+len); + string unit = ir.getWord(); + set(val, unit); + } +} + + +void Length::set (double val, Unit unit) { + switch (unit) { + case PT: _pt = val; break; + case BP: _pt = val*72.27/72; break; + case IN: _pt = val*72.27; break; + case CM: _pt = val/2.54*72.27; break; + case MM: _pt = val/25.4*72.27; break; + case PC: _pt = val/12*72.27; break; + } +} + + +void Length::set (double val, string unitstr) { + if (unitstr.empty()) + unitstr = "pt"; + else if (unitstr.length() != 2) + throw UnitException("invalid length unit: "+unitstr); + + Unit unit; + switch (UNIT(unitstr[0], unitstr[1])) { + case UNIT('p','t'): unit = PT; break; + case UNIT('b','p'): unit = BP; break; + case UNIT('i','n'): unit = IN; break; + case UNIT('c','m'): unit = CM; break; + case UNIT('m','m'): unit = MM; break; + case UNIT('p','c'): unit = PC; break; + default: + throw UnitException("invalid length unit: "+unitstr); + } + set(val, unit); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.h new file mode 100644 index 00000000000..338975bf965 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Length.h @@ -0,0 +1,58 @@ +/************************************************************************* +** Length.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef LENGTH_H +#define LENGTH_H + +#include <string> +#include "MessageException.h" + +struct UnitException : MessageException +{ + UnitException (const std::string &msg) : MessageException(msg) {} +}; + + +class Length +{ + public: + enum Unit {PT, BP, CM, MM, IN, PC}; + + public: + Length () : _pt(0) {} + Length (double val, Unit unit=PT) {set(val, unit);} + Length (double val, const std::string &unit) {set(val, unit);} + Length (const std::string &len) {set(len);} + void set (double val, Unit unit); + void set (double val, std::string unit); + void set (const std::string &len); + + double pt () const {return _pt;} + double in () const {return _pt/72.27;} + double bp () const {return in()*72;} + double cm () const {return in()*2.54;} + double mm () const {return cm()*10;} + double pc () const {return in()*12;} + + private: + double _pt; // length in TeX point units +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.am b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.am new file mode 100644 index 00000000000..a86c5611b28 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.am @@ -0,0 +1,55 @@ +## This file is part of dvisvgm +## Copyright (C) 2005-2009 Martin Gieseking <martin.gieseking@uos.de> +## +## Process this file with automake. + +bin_PROGRAMS = dvisvgm +noinst_LIBRARIES = libdvisvgm.a + +dvisvgm_SOURCES = gzstream.h StreamCounter.h \ + dvisvgm.cpp gzstream.cpp + +dvisvgm_LDADD = $(noinst_LIBRARIES) @EXTRA_LIBS@ +dvisvgm_DEPENDENCIES = $(noinst_LIBRARIES) @EXTRA_LIBS@ + +libdvisvgm_a_SOURCES = Bitmap.h BoundingBox.h BgColorSpecialHandler.h Calculator.h CharmapTranslator.h CmdLineParserBase.h Color.h \ + ColorSpecialHandler.h CommandLine.h Directory.h DLLoader.h DVIActions.h DVIReader.h DvisvgmSpecialHandler.h DVIToSVG.h \ + DVIToSVGActions.h EmSpecialHandler.h FileFinder.h FileSystem.h Font.h FontCache.h FontEmitter.h FontEncoding.h FontEngine.h \ + FontGlyph.h FontManager.h FontMap.h GFReader.h GFTracer.h GFGlyphTracer.h Ghostscript.h GraphicPath.h InputBuffer.h InputReader.h \ + Length.h macros.h Matrix.h Message.h MessageException.h MetafontWrapper.h PageSize.h Pair.h PSInterpreter.h PsSpecialHandler.h \ + SpecialActions.h SpecialHandler.h SpecialManager.h StreamReader.h SVGFontEmitter.h SVGFontTraceEmitter.h SVGTree.h \ + TpicSpecialHandler.h TFM.h types.h VectorStream.h VFActions.h VFReader.h XMLDocTypeNode.h XMLDocument.h XMLNode.h XMLString.h \ + BgColorSpecialHandler.cpp Bitmap.cpp BoundingBox.cpp Calculator.cpp CharmapTranslator.cpp CmdLineParserBase.cpp Color.cpp \ + ColorSpecialHandler.cpp CommandLine.cpp Directory.cpp DLLoader.cpp DVIActions.cpp DVIReader.cpp DvisvgmSpecialHandler.cpp \ + DVIToSVG.cpp DVIToSVGActions.cpp EmSpecialHandler.cpp FileFinder.cpp FileSystem.cpp Font.cpp FontCache.cpp FontEncoding.cpp \ + FontEngine.cpp FontGlyph.cpp FontManager.cpp FontMap.cpp GFReader.cpp GFGlyphTracer.cpp GFTracer.cpp Ghostscript.cpp \ + InputBuffer.cpp InputReader.cpp Length.cpp Matrix.cpp Message.cpp MetafontWrapper.cpp PageSize.cpp PSInterpreter.cpp \ + PsSpecialHandler.cpp SpecialManager.cpp StreamReader.cpp SVGFontEmitter.cpp SVGFontTraceEmitter.cpp SVGTree.cpp TFM.cpp \ + TpicSpecialHandler.cpp VFReader.cpp XMLDocument.cpp XMLNode.cpp XMLString.cpp + +EXTRA_DIST = options.xml psdefs.psc iapi.h ierrors.h + +AM_CXXFLAGS = -Wall + +# the commandline parser is generated from options.xml by opt2cpp +CommandLine.cpp: options.xml + if test -f opt2cpp.xsl; then \ + rm -f $@ $*.h; \ + xsltproc opt2cpp.xsl $<; \ + fi + +# The required MikTeX functions are declared in .def files that reference a DLL. +# It's necessary to create import libraries from these .def files. dlltool helps us +# to do that. +.def.a: + dlltool -d $< -l $@ -U + + +# Create a C string definition containing the PostScript routines psdefs.ps needed by class PSInterpreter +psdefs.psc: psdefs.ps + if test -f $<; then \ + ps2c PSInterpreter::PSDEFS $< >$@; \ + fi + +psdefs.ps: ; + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.in b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.in new file mode 100644 index 00000000000..0d4789c72d5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Makefile.in @@ -0,0 +1,607 @@ +# Makefile.in generated by automake 1.11 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = dvisvgm$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libdvisvgm_a_AR = $(AR) $(ARFLAGS) +libdvisvgm_a_LIBADD = +am_libdvisvgm_a_OBJECTS = BgColorSpecialHandler.$(OBJEXT) \ + Bitmap.$(OBJEXT) BoundingBox.$(OBJEXT) Calculator.$(OBJEXT) \ + CharmapTranslator.$(OBJEXT) CmdLineParserBase.$(OBJEXT) \ + Color.$(OBJEXT) ColorSpecialHandler.$(OBJEXT) \ + CommandLine.$(OBJEXT) Directory.$(OBJEXT) DLLoader.$(OBJEXT) \ + DVIActions.$(OBJEXT) DVIReader.$(OBJEXT) \ + DvisvgmSpecialHandler.$(OBJEXT) DVIToSVG.$(OBJEXT) \ + DVIToSVGActions.$(OBJEXT) EmSpecialHandler.$(OBJEXT) \ + FileFinder.$(OBJEXT) FileSystem.$(OBJEXT) Font.$(OBJEXT) \ + FontCache.$(OBJEXT) FontEncoding.$(OBJEXT) \ + FontEngine.$(OBJEXT) FontGlyph.$(OBJEXT) FontManager.$(OBJEXT) \ + FontMap.$(OBJEXT) GFReader.$(OBJEXT) GFGlyphTracer.$(OBJEXT) \ + GFTracer.$(OBJEXT) Ghostscript.$(OBJEXT) InputBuffer.$(OBJEXT) \ + InputReader.$(OBJEXT) Length.$(OBJEXT) Matrix.$(OBJEXT) \ + Message.$(OBJEXT) MetafontWrapper.$(OBJEXT) PageSize.$(OBJEXT) \ + PSInterpreter.$(OBJEXT) PsSpecialHandler.$(OBJEXT) \ + SpecialManager.$(OBJEXT) StreamReader.$(OBJEXT) \ + SVGFontEmitter.$(OBJEXT) SVGFontTraceEmitter.$(OBJEXT) \ + SVGTree.$(OBJEXT) TFM.$(OBJEXT) TpicSpecialHandler.$(OBJEXT) \ + VFReader.$(OBJEXT) XMLDocument.$(OBJEXT) XMLNode.$(OBJEXT) \ + XMLString.$(OBJEXT) +libdvisvgm_a_OBJECTS = $(am_libdvisvgm_a_OBJECTS) +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_dvisvgm_OBJECTS = dvisvgm.$(OBJEXT) gzstream.$(OBJEXT) +dvisvgm_OBJECTS = $(am_dvisvgm_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(libdvisvgm_a_SOURCES) $(dvisvgm_SOURCES) +DIST_SOURCES = $(libdvisvgm_a_SOURCES) $(dvisvgm_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_CPPFLAGS = @AM_CPPFLAGS@ +AM_LDFLAGS = @AM_LDFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXTRA_LIBS = @EXTRA_LIBS@ +FREETYPE_CONFIG = @FREETYPE_CONFIG@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +noinst_LIBRARIES = libdvisvgm.a +dvisvgm_SOURCES = gzstream.h StreamCounter.h \ + dvisvgm.cpp gzstream.cpp + +dvisvgm_LDADD = $(noinst_LIBRARIES) @EXTRA_LIBS@ +dvisvgm_DEPENDENCIES = $(noinst_LIBRARIES) @EXTRA_LIBS@ +libdvisvgm_a_SOURCES = Bitmap.h BoundingBox.h BgColorSpecialHandler.h Calculator.h CharmapTranslator.h CmdLineParserBase.h Color.h \ + ColorSpecialHandler.h CommandLine.h Directory.h DLLoader.h DVIActions.h DVIReader.h DvisvgmSpecialHandler.h DVIToSVG.h \ + DVIToSVGActions.h EmSpecialHandler.h FileFinder.h FileSystem.h Font.h FontCache.h FontEmitter.h FontEncoding.h FontEngine.h \ + FontGlyph.h FontManager.h FontMap.h GFReader.h GFTracer.h GFGlyphTracer.h Ghostscript.h GraphicPath.h InputBuffer.h InputReader.h \ + Length.h macros.h Matrix.h Message.h MessageException.h MetafontWrapper.h PageSize.h Pair.h PSInterpreter.h PsSpecialHandler.h \ + SpecialActions.h SpecialHandler.h SpecialManager.h StreamReader.h SVGFontEmitter.h SVGFontTraceEmitter.h SVGTree.h \ + TpicSpecialHandler.h TFM.h types.h VectorStream.h VFActions.h VFReader.h XMLDocTypeNode.h XMLDocument.h XMLNode.h XMLString.h \ + BgColorSpecialHandler.cpp Bitmap.cpp BoundingBox.cpp Calculator.cpp CharmapTranslator.cpp CmdLineParserBase.cpp Color.cpp \ + ColorSpecialHandler.cpp CommandLine.cpp Directory.cpp DLLoader.cpp DVIActions.cpp DVIReader.cpp DvisvgmSpecialHandler.cpp \ + DVIToSVG.cpp DVIToSVGActions.cpp EmSpecialHandler.cpp FileFinder.cpp FileSystem.cpp Font.cpp FontCache.cpp FontEncoding.cpp \ + FontEngine.cpp FontGlyph.cpp FontManager.cpp FontMap.cpp GFReader.cpp GFGlyphTracer.cpp GFTracer.cpp Ghostscript.cpp \ + InputBuffer.cpp InputReader.cpp Length.cpp Matrix.cpp Message.cpp MetafontWrapper.cpp PageSize.cpp PSInterpreter.cpp \ + PsSpecialHandler.cpp SpecialManager.cpp StreamReader.cpp SVGFontEmitter.cpp SVGFontTraceEmitter.cpp SVGTree.cpp TFM.cpp \ + TpicSpecialHandler.cpp VFReader.cpp XMLDocument.cpp XMLNode.cpp XMLString.cpp + +EXTRA_DIST = options.xml psdefs.psc iapi.h ierrors.h +AM_CXXFLAGS = -Wall +all: all-am + +.SUFFIXES: +.SUFFIXES: .a .cpp .def .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libdvisvgm.a: $(libdvisvgm_a_OBJECTS) $(libdvisvgm_a_DEPENDENCIES) + -rm -f libdvisvgm.a + $(libdvisvgm_a_AR) libdvisvgm.a $(libdvisvgm_a_OBJECTS) $(libdvisvgm_a_LIBADD) + $(RANLIB) libdvisvgm.a +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +dvisvgm$(EXEEXT): $(dvisvgm_OBJECTS) $(dvisvgm_DEPENDENCIES) + @rm -f dvisvgm$(EXEEXT) + $(CXXLINK) $(dvisvgm_OBJECTS) $(dvisvgm_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BgColorSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Bitmap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BoundingBox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Calculator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CharmapTranslator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CmdLineParserBase.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ColorSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CommandLine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DLLoader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DVIActions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DVIReader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DVIToSVG.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DVIToSVGActions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Directory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DvisvgmSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EmSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileFinder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileSystem.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Font.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontCache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontEncoding.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontEngine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontGlyph.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontManager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FontMap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFGlyphTracer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFReader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GFTracer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Ghostscript.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InputBuffer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InputReader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Length.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Matrix.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Message.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetafontWrapper.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PSInterpreter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PageSize.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PsSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SVGFontEmitter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SVGFontTraceEmitter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SVGTree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpecialManager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StreamReader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TFM.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TpicSpecialHandler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/VFReader.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLDocument.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLNode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLString.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dvisvgm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzstream.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-noinstLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +# the commandline parser is generated from options.xml by opt2cpp +CommandLine.cpp: options.xml + if test -f opt2cpp.xsl; then \ + rm -f $@ $*.h; \ + xsltproc opt2cpp.xsl $<; \ + fi + +# The required MikTeX functions are declared in .def files that reference a DLL. +# It's necessary to create import libraries from these .def files. dlltool helps us +# to do that. +.def.a: + dlltool -d $< -l $@ -U + +# Create a C string definition containing the PostScript routines psdefs.ps needed by class PSInterpreter +psdefs.psc: psdefs.ps + if test -f $<; then \ + ps2c PSInterpreter::PSDEFS $< >$@; \ + fi + +psdefs.ps: ; + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.cpp new file mode 100644 index 00000000000..f971bf24cb5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.cpp @@ -0,0 +1,409 @@ +/************************************************************************* +** Matrix.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <limits> +#include <sstream> +#include "Calculator.h" +#include "Matrix.h" + +using namespace std; + +static double deg2rad (double deg) { + const double PI = acos(-1.0); + return PI*deg/180.0; +} + + +static double round (double x, int n) { + double pow10 = pow(10.0, n); + return floor(x*pow10+0.5)/pow10; +} + + +/** Creates a diagonal matrix ((d,0,0),(0,d,0),(0,0,d)). + * @param[in] d value of diagonal elements */ +Matrix::Matrix (double d) { + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + values[i][j] = (i==j ? d : 0); +} + + +/** Creates the matrix ((v0,v1,v2),(v3,v4,v5),(v6,v7,v8)). + * Expects that array v consists of 'size' elements. If size is less than 9, the + * remaining matrix components will be set to those of the identity matrix. + * @param v array containing the matrix components */ +Matrix::Matrix (double v[], unsigned size) { + set(v, size); +} + + +/** Creates the matrix ((v0,v1,v2),(v3,v4,v5),(v6,v7,v8)). + * If vector v has less than 9 elements, the remaining matrix components will be set to + * those of the identity matrix. + * @param v array containing the matrix components */ +Matrix::Matrix (const std::vector<double> &v) { + set(v); +} + + +Matrix::Matrix (const string &cmds, Calculator &calc) { + parse(cmds, calc); +} + + +Matrix& Matrix::set (double v[], unsigned size) { + size = min(size, 9u); + for (unsigned i=0; i < size; i++) + values[i/3][i%3] = v[i]; + for (unsigned i=size; i < 9; i++) + values[i/3][i%3] = (i%4 ? 0 : 1); + return *this; +} + + +Matrix& Matrix::set (const vector<double> &v) { + unsigned size = min((unsigned)v.size(), 9u); + for (unsigned i=0; i < size; i++) + values[i/3][i%3] = v[i]; + for (unsigned i=size; i < 9; i++) + values[i/3][i%3] = (i%4 ? 0 : 1); + return *this; +} + + +Matrix& Matrix::translate (double tx, double ty) { + if (tx != 0 || ty != 0) { + TranslationMatrix t(tx, ty); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::scale (double sx, double sy) { + if (sx != 1 || sy != 1) { + ScalingMatrix s(sx, sy); + rmultiply(s); + } + return *this; +} + + +/** Multiplies this matrix by ((cos d, -sin d, 0), (sin d, cos d, 0), (0,0,1)) that + * describes an anti-clockwise rotation by d degrees. + * @param[in] deg rotation angle in degrees */ +Matrix& Matrix::rotate (double deg) { + RotationMatrix r(deg); + rmultiply(r); + return *this; +} + + +Matrix& Matrix::xskew (double deg) { + double t = tan(deg2rad(deg)); + if (t != 0) { + double v[] = {1, t}; + Matrix t(v, 2); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::yskew (double deg) { + double t = tan(deg2rad(deg)); + if (t != 0) { + double v[] = {1, 0, 0, t}; + Matrix t(v, 4); + rmultiply(t); + } + return *this; +} + + +Matrix& Matrix::flip (bool haxis, double a) { + double s = 1; + if (haxis) // mirror at horizontal axis? + s = -1; + double v[] = {-s, 0, (haxis ? 0 : 2*a), 0, s, (haxis ? 2*a : 0), 0, 0, 1}; + Matrix t(v); + rmultiply(t); + return *this; +} + + +/** Swaps rows and columns of the matrix. */ +Matrix& Matrix::transpose () { + for (int i=0; i < 3; i++) + for (int j=i+1; j < 3; j++) + swap(values[i][j], values[j][i]); + return *this; +} + + +/** Multiplies this matrix M with matrix tm (tm is the factor on the left side): M := tm * M */ +Matrix& Matrix::lmultiply (const Matrix &tm) { + Matrix ret; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + for (int k=0; k < 3; k++) + ret.values[i][j] += values[i][k] * tm.values[k][j]; + return *this = ret; +} + + +/** Multiplies this matrix M with matrix tm (tm is the factor on the right side): M := M * tm */ +Matrix& Matrix::rmultiply (const Matrix &tm) { + Matrix ret; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + for (int k=0; k < 3; k++) + ret.values[i][j] += tm.values[i][k] * values[k][j]; + return *this = ret; +} + + +DPair Matrix::operator * (const DPair &p) const { + double pp[] = {p.x(), p.y(), 1}; + double ret[]= {0, 0}; + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + ret[i] += values[i][j] * pp[j]; + return DPair(ret[0], ret[1]); +} + + +/** Returns true if this matrix equals. Checks equality by comparing the matrix components. */ +bool Matrix::operator == (const Matrix &m) const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + if (values[i][j] != m.values[i][j]) + return false; + return true; +} + + +/** Returns true if this matrix doesn't equal m. Checks inequality by comparing the matrix components. */ +bool Matrix::operator != (const Matrix &m) const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) + if (values[i][j] != m.values[i][j]) + return true; + return false; +} + + +/** Returns true if this matrix is the identity matrix ((1,0,0),(0,1,0),(0,0,1)). */ +bool Matrix::isIdentity() const { + for (int i=0; i < 2; i++) + for (int j=0; j < 3; j++) { + const double &v = values[i][j]; + if ((i == j && v != 1) || (i != j && v != 0)) + return false; + } + return true; +} + + +/** Checks whether this matrix describes a plain translation (without any other transformations). + * If so, the parameters tx and ty are filled with the translation components. + * @param[out] tx horizontal translation + * @param[out] ty vertical translation + * @return true if matrix describes a pure translation */ +bool Matrix::isTranslation (double &tx, double &ty) const { + tx = values[0][2]; + ty = values[1][2]; + for (int i=0; i < 3; i++) + for (int j=0; j < 2; j++) { + const double &v = values[i][j]; + if ((i == j && v != 1) || (i != j && v != 0)) + return false; + } + return values[2][2] == 1; +} + + +/** Gets a parameter for the transformation command. + * @param[in] is parameter chars are read from this stream + * @param[in] calc parameters can be arithmetic expressions, so we need a calculator to evaluate them + * @param[in] def default value if parameter is optional + * @param[in] optional true if parameter is optional + * @param[in] leadingComma true if first non-blank must be a comma + * @return value of argument */ +static double getArgument (istream &is, Calculator &calc, double def, bool optional, bool leadingComma) { + while (isspace(is.peek())) + is.get(); + if (!optional && leadingComma && is.peek() != ',') + throw ParserException("',' expected"); + if (is.peek() == ',') { + is.get(); // skip comma + optional = false; // now we expect a parameter + } + string expr; + while (is && !isupper(is.peek()) && is.peek() != ',') + expr += is.get(); + if (expr.length() == 0) { + if (optional) + return def; + else + throw ParserException("parameter expected"); + } + return calc.eval(expr); +} + + +Matrix& Matrix::parse (istream &is, Calculator &calc) { + *this = Matrix(1); + while (is) { + while (isspace(is.peek())) + is.get(); + char cmd = is.get(); + switch (cmd) { + case 'T': { + double tx = getArgument(is, calc, 0, false, false); + double ty = getArgument(is, calc, 0, true, true); + translate(tx, ty); + break; + } + case 'S': { + double sx = getArgument(is, calc, 1, false, false); + double sy = getArgument(is, calc, sx, true, true ); + scale(sx, sy); + break; + } + case 'R': { + double a = getArgument(is, calc, 0, false, false); + double x = getArgument(is, calc, calc.getVariable("ux")+calc.getVariable("w")/2, true, true); + double y = getArgument(is, calc, calc.getVariable("uy")+calc.getVariable("h")/2, true, true); + translate(-x, -y); + rotate(a); + translate(x, y); + break; + } + case 'F': { + char c = is.get(); + if (c != 'H' && c != 'V') + throw ParserException("'H' or 'V' expected"); + double a = getArgument(is, calc, 0, false, false); + flip(c == 'H', a); + break; + } + case 'K': { + char c = is.get(); + if (c != 'X' && c != 'Y') + throw ParserException("transformation command 'K' must be followed by 'X' or 'Y'"); + double a = getArgument(is, calc, 0, false, false); + if (fabs(cos(deg2rad(a))) <= numeric_limits<double>::epsilon()) { + ostringstream oss; + oss << "illegal skewing angle: " << a << " degrees"; + throw ParserException(oss.str()); + } + if (c == 'X') + xskew(a); + else + yskew(a); + break; + } + case 'M': { + double v[9]; + for (int i=0; i < 6; i++) + v[i] = getArgument(is, calc, i%4 ? 0 : 1, i!=0, i!=0); + // third row (0, 0, 1) + v[6] = v[7] = 0; + v[8] = 1; + Matrix tm(v); + rmultiply(tm); + break; + } + default: + ostringstream oss; + oss << "transformation command expected (found '" << cmd << "' instead)"; + throw ParserException(oss.str()); + } + } + return *this; +} + + +Matrix& Matrix::parse (const string &cmds, Calculator &calc) { + istringstream iss; + iss.str(cmds); + return parse(iss, calc); +} + + +/** Returns an SVG matrix expression that can be used in transform attributes. + * ((a,b,c),(d,e,f),(0,0,1)) => matrix(a d b e c f) */ +string Matrix::getSVG () const { + ostringstream oss; + oss << "matrix("; + for (int i=0; i < 3; i++) { + for (int j=0; j < 2; j++) { + if (i > 0 || j > 0) + oss << ' '; + oss << round(values[j][i], 3); + } + } + oss << ')'; + return oss.str(); +} + + +ostream& Matrix::write (ostream &os) const { + os << '('; + for (int i=0; i < 3; i++) { + os << '(' << values[i][0]; + for (int j=1; j < 3; j++) + os << ',' << values[i][j]; + os << ')'; + if (i < 2) + os << ','; + } + os << ')'; + return os; +} + + +////////////////////////////////////////////////////////////////// + + +TranslationMatrix::TranslationMatrix (double tx, double ty) { + double v[] = {1, 0, tx, 0, 1, ty}; + set(v, 6); +} + + +ScalingMatrix::ScalingMatrix (double sx, double sy) { + double v[] = {sx, 0, 0, 0, sy}; + set(v, 5); +} + + +RotationMatrix::RotationMatrix (double deg) { + double rad = deg2rad(deg); + double c = cos(rad); + double s = sin(rad); + double v[] = {c, -s, 0, s, c}; + set(v, 5); +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.h new file mode 100644 index 00000000000..b9fb08ff39c --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Matrix.h @@ -0,0 +1,88 @@ +/************************************************************************* +** Matrix.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef MATRIX_H +#define MATRIX_H + +#include <istream> +#include <string> +#include <vector> +#include "MessageException.h" +#include "Pair.h" + + +struct ParserException : public MessageException +{ + ParserException (const std::string &msg) : MessageException(msg) {} +}; + +class Calculator; + +class Matrix +{ + public: + Matrix (const std::string &cmds, Calculator &calc); + Matrix (double d=0); + Matrix (double v[], unsigned size=9); + Matrix (const std::vector<double> &v); + Matrix& set (double v[], unsigned size); + Matrix& set (const std::vector<double> &v); + Matrix& transpose (); + Matrix& parse (std::istream &is, Calculator &c); + Matrix& parse (const std::string &cmds, Calculator &c); + Matrix& lmultiply (const Matrix &tm); + Matrix& rmultiply (const Matrix &tm); + Matrix& translate (double tx, double ty); + Matrix& scale (double sx, double sy); + Matrix& rotate (double deg); + Matrix& xskew (double deg); + Matrix& yskew (double deg); + Matrix& flip (bool h, double a); + DPair operator * (const DPair &p) const; + bool operator == (const Matrix &m) const; + bool operator != (const Matrix &m) const; + bool isIdentity() const; + bool isTranslation (double &tx, double &ty) const; + std::string getSVG () const; + std::ostream& write (std::ostream &os) const; + + private: + double values[3][3]; // row x col +}; + + +struct TranslationMatrix : public Matrix +{ + TranslationMatrix (double tx, double ty); +}; + + +struct ScalingMatrix : public Matrix +{ + ScalingMatrix (double sx, double sy); +}; + + +struct RotationMatrix : public Matrix +{ + RotationMatrix (double deg); +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.cpp new file mode 100644 index 00000000000..5a4e0b05526 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.cpp @@ -0,0 +1,74 @@ +/************************************************************************* +** Message.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdarg> +#include <iostream> +#include "Message.h" + +using namespace std; + + +struct NullStreamBuf : public streambuf +{ + streambuf::int_type overflow (int c) {return 0;} + streambuf::int_type underflow () {return traits_type::eof();} + int sync () {return traits_type::eof();} +}; + + +struct NullStream : public ostream +{ + NullStream () : ostream(new NullStreamBuf) {} + ~NullStream () {delete rdbuf();} +}; + + +static NullStream nullStream; + +// maximal verbosity +int Message::level = Message::MESSAGES | Message::WARNINGS | Message::ERRORS; + + +/** Returns the stream for usual messages. */ +ostream& Message::mstream (bool prefix) { + ostream *os = (level & MESSAGES) ? &cerr : &nullStream; + if (prefix) + *os << "MESSAGE: "; + return *os; +} + + +/** Returns the stream for warning messages. */ +ostream& Message::wstream (bool prefix) { + ostream *os = (level & WARNINGS) ? &cerr : &nullStream; + if (prefix) + *os << "WARNING: "; + return *os; +} + + +/** Returns the stream for error messages. */ +ostream& Message::estream (bool prefix) { + ostream *os = (level & ERRORS) ? &cerr : &nullStream; + if (prefix) + *os << "ERROR: "; + return *os; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.h new file mode 100644 index 00000000000..80a67412556 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Message.h @@ -0,0 +1,37 @@ +/************************************************************************* +** Message.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef MESSAGE_H +#define MESSAGE_H + +#include <string> +#include <ostream> + +struct Message +{ + static std::ostream& mstream (bool prefix=false); + static std::ostream& estream (bool prefix=false); + static std::ostream& wstream (bool prefix=false); + + enum {ERRORS=1, WARNINGS=2, MESSAGES=4}; + static int level; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MessageException.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MessageException.h new file mode 100644 index 00000000000..2a0dbe591e7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MessageException.h @@ -0,0 +1,38 @@ +/************************************************************************* +** MessageException.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef MESSAGEEXCEPTION_H +#define MESSAGEEXCEPTION_H + +#include <string> + +using std::string; + +class MessageException +{ + public: + MessageException (const string &msg) : message(msg) {} + const string& getMessage () const {return message;} + + private: + string message; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.cpp new file mode 100644 index 00000000000..f551b640ef1 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.cpp @@ -0,0 +1,152 @@ +/************************************************************************* +** MetafontWrapper.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstdlib> +#include <cctype> +#include <fstream> +#include <sstream> +#include "FileSystem.h" +#include "FileFinder.h" +#include "Message.h" +#include "MetafontWrapper.h" + +#ifdef __WIN32__ +#include <windows.h> +#endif + +using namespace std; + + +static int execute (const char *cmd, const char *params) { +#ifdef __WIN32__ + SECURITY_ATTRIBUTES sa; + ZeroMemory(&sa, sizeof(sa)); + sa.nLength = sizeof(sa); + sa.bInheritHandle = true; + + STARTUPINFO si; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + HANDLE devnull = CreateFile("nul", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.hStdError = GetStdHandle(STD_ERROR_HANDLE); + si.hStdOutput = devnull; + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(pi)); + + string cmdline = string("\"")+cmd+"\" "+params; + CreateProcess(NULL, (LPSTR)cmdline.c_str(), NULL, NULL, true, 0, NULL, NULL, &si, &pi); + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD exitcode = -1; + GetExitCodeProcess(pi.hProcess, &exitcode); + CloseHandle(devnull); + return exitcode; +#else + ostringstream oss; + oss << cmd << ' ' << params << " >" << FileSystem::DEVNULL; + return system(oss.str().c_str()); +#endif +} + + +MetafontWrapper::MetafontWrapper (const string &fname) + : _fontname(fname) +{ +} + + +/** Calls Metafont and evaluates the logfile. If a gf file was successfully + * generated the dpi value is stripped from the filename + * (e.g. cmr10.600gf => cmr10.gf). This makes life easier... + * @param[in] mode Metafont mode, e.g. "ljfour" + * @param[in] mag magnification factor + * @return return value of Metafont system call */ +int MetafontWrapper::call (const string &mode, double mag) { + if (!FileFinder::lookup(_fontname+".mf")) + return 1; // mf file not available => no need to call the "slow" Metafont + FileSystem::remove(_fontname+".gf"); + +#ifdef __WIN32__ + const char *cmd = FileFinder::lookup("mf.exe", false); +#else + const char *cmd = "mf"; +#endif + ostringstream oss; + oss << "\"\\mode=" << mode << ";" + "mag:=" << mag << ";" + "batchmode;" + "input " << _fontname << "\""; + Message::mstream() << "running Metafont for " << _fontname << endl; + int ret = execute(cmd, oss.str().c_str()); + + // try to read Metafont's logfile and get name of created GF file + ifstream ifs((_fontname+".log").c_str()); + if (ifs) { + char buf[128]; + while (ifs) { + ifs.getline(buf, 128); + string line = buf; + if (line.substr(0, 17) == "Output written on") { + size_t pos = line.find("gf ", 18+_fontname.length()); + if (pos != string::npos) { + string gfname = line.substr(18, pos-16); // GF filename found + FileSystem::rename(gfname, _fontname+".gf"); + } + break; + } + } + } + return ret; +} + + +/** Calls Metafont if output files (tfm and gf) don't already exist. */ +int MetafontWrapper::make (const string &mode, double mag) { + ifstream tfm((_fontname+".tfm").c_str()); + ifstream gf((_fontname+".gf").c_str()); + if (gf && tfm) // @@ distinguish between gf and tfm + return 0; + return call(mode, mag); +} + + +bool MetafontWrapper::success () const { + ifstream tfm((_fontname+".tfm").c_str()); + ifstream gf((_fontname+".gf").c_str()); + return tfm && gf; +} + + +/** Remove all files created by a Metafont call (tfm, gf, log). + * @param[in] keepGF if true, GF files won't be removed */ +void MetafontWrapper::removeOutputFiles (bool keepGF) { + removeOutputFiles(_fontname, keepGF); +} + + +/** Remove all files created by a Metafont call for a given font (tfm, gf, log). + * @param[in] fontname name of font whose temporary files should be removed + * @param[in] keepGF if true, GF files will be kept */ +void MetafontWrapper::removeOutputFiles (const string &fontname, bool keepGF) { + const char *ext[] = {"gf", "tfm", "log", 0}; + for (const char **p = keepGF ? ext+2 : ext; *p; ++p) + FileSystem::remove(fontname + "." + *p); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.h new file mode 100644 index 00000000000..bae3af16587 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/MetafontWrapper.h @@ -0,0 +1,44 @@ +/************************************************************************* +** MetafontWrapper.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef METAFONTWRAPPER_H +#define METAFONTWRAPPER_H + +#include <string> + +using std::string; + +class FileFinder; + +class MetafontWrapper +{ + public: + MetafontWrapper (const string &fontname); + int call (const string &mode, double mag); + int make (const string &mode, double mag); + bool success () const; + void removeOutputFiles (bool keepGF=false); + static void removeOutputFiles (const string &fontname, bool keepGF=false); + + private: + string _fontname; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.cpp new file mode 100644 index 00000000000..831bf5fd206 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.cpp @@ -0,0 +1,280 @@ +/************************************************************************* +** PSInterpreter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include <fstream> +#include <iostream> +#include <sstream> +#include "FileFinder.h" +#include "InputReader.h" +#include "Message.h" +#include "PSInterpreter.h" +#include "psdefs.psc" + +using namespace std; + + +const char *PSInterpreter::GSARGS[] = { + "gs", // dummy name + "-q", // be quiet, suppress gs banner + "-dSAFER", // disallow writing of files + "-dNODISPLAY", // we don't need a display device + "-dNOPAUSE", // keep going + "-dNOPROMPT", + "-dNOBIND", +}; + + +PSInterpreter::PSInterpreter (PSActions *actions) + : _gs(sizeof(GSARGS)/sizeof(char*), GSARGS, this), _mode(PS_NONE), _actions(actions), _inError(false) +{ + _gs.set_stdio(input, output, error); + _initialized = false; +} + + +/** Executes a chunk of PostScript code. + * @param[in] str buffer containing the code + * @param[in] len number of characters in buffer + * @param[in] flush If true, a final 'flush' is sent which forces the + * output buffer to be written immediately.*/ +void PSInterpreter::execute (const char *str, size_t len, bool flush) { + if (!_initialized) { + // Before executing any random PS code redefine some operators and run + // initializing PS code. This cannot be done in the constructor because we + // need the completely initialized PSInterpreter object here. + _initialized = true; + execute(PSDEFS); + } + if (_mode != PS_QUIT) { + int status; + if (_mode == PS_NONE) { + _gs.run_string_begin(0, &status); + _mode = PS_RUNNING; + } + const char *p=str; + // feed Ghostscript with code chunks that are not larger than 64KB + // => see documentation of gsapi_run_string_foo() + while (PS_RUNNING && len > 0) { + size_t chunksize = min(len, (size_t)0xffff); + _gs.run_string_continue(p, chunksize, 0, &status); + p += chunksize; + len -= chunksize; + if (status == -101) { // e_Quit + _gs.exit(); + _mode = PS_QUIT; + } + else if (status <= -100) { + _gs.exit(); + _mode = PS_QUIT; + throw PSException("fatal PostScript error"); + } + } + if (flush) { + // force writing contents of output buffer + _gs.run_string_continue(" flush ", 7, 0, &status); + } + } +} + + +void PSInterpreter::execute (istream &is) { + char buf[4096]; + while (is && !is.eof()) { + is.read(buf, 4096); + execute(buf, is.gcount(), false); + } + execute(" ", 1); +} + + +/** This callback function handles input from stdin to Ghostscript. Currently not needed. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf takes the read characters + * @param[in] len size of buffer buf + * @return number of read characters */ +int GSDLLCALL PSInterpreter::input (void *inst, char *buf, int len) { + return 0; +} + + +/** This callback function handles output from Ghostscript to stdout. It looks for + * emitted commands staring with "dvi." and executes them by calling method callActions. + * Ghostscript sends the text in chunks by several calls of this function. + * Unfortunately, the PostScript specification wants error messages also to be sent to stdout + * instead of stderr. Thus, we must collect and concatenate the chunks until an evaluable text + * snippet is completely received. Furthermore, error messages have to be recognized and to be + * filtered out. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf contains the characters to be output + * @param[in] len number of characters in buf + * @return number of processed characters (equals 'len') */ +int GSDLLCALL PSInterpreter::output (void *inst, const char *buf, int len) { + PSInterpreter *self = static_cast<PSInterpreter*>(inst); + if (self && self->_actions) { + const size_t MAXLEN = 512; // maximal line length (longer lines are of no interest) + const char *end = buf+len-1; // last position of buf + for (const char *first=buf, *last=buf; first <= end; last++, first=last) { + // move first and last to begin and end of the next line, respectively + while (last <= end && *last != '\n') + last++; + size_t linelength = last-first+1; + if (linelength > MAXLEN) // skip long lines since they don't contain any relevant information + continue; + + vector<char> &linebuf = self->_linebuf; // just a shorter name... + if ((*last == '\n' || !self->active())) { + if (linelength + linebuf.size() > 5) { // prefix "dvi." plus final newline + SplittedCharInputBuffer ib(linebuf.empty() ? 0 : &linebuf[0], linebuf.size(), first, linelength); + BufferInputReader in(ib); + in.skipSpace(); + if (self->_inError) { + if (in.check("dvi.enderror")) { + // @@ + self->_errorMessage.clear(); + self->_inError = false; + } + else + self->_errorMessage += string(first, linelength); + } + if (in.check("dvi.")) { + if (in.check("beginerror")) // all following output belongs to an error message + self->_inError = true; + else + self->callActions(in); + } + } + linebuf.clear(); + } + else { // no line end found => + // save remaining characters and prepend them to the next incoming chunk of characters + linelength--; // last == end+1 => linelength is 1 too large + if (linebuf.size() + linelength > MAXLEN) + linebuf.clear(); // don't care for long lines + else { + size_t currsize = linebuf.size(); + linebuf.resize(currsize+linelength); + memcpy(&linebuf[currsize], first, linelength); + } + } + } + } + return len; +} + + +/** Converts a vector of strings to a vector of doubles. + * @param[in] str the strings to be converted + * @param[out] d the resulting doubles */ +static void str2double (const vector<string> &str, vector<double> &d) { + for (size_t i=0; i < str.size(); i++) { + istringstream iss(str[i]); + iss >> d[i]; + } +} + + +/** Evaluates a command emitted by Ghostscript and invokes the corresponding + * method of interface class PSActions. + * @param[in] in reader pointing to the next command */ +void PSInterpreter::callActions (InputReader &in) { + // array of currently supported operators (must be ascendingly sorted) + static const struct Operator { + const char *name; // name of operator + int pcount; // number of parameters (< 0 : variable number of parameters) + void (PSActions::*op)(vector<double> &p); // operation handler + } operators [] = { + {"clip", 0, &PSActions::clip}, + {"closepath", 0, &PSActions::closepath}, + {"curveto", 6, &PSActions::curveto}, + {"eoclip", 0, &PSActions::eoclip}, + {"eofill", 0, &PSActions::eofill}, + {"fill", 0, &PSActions::fill}, + {"grestore", 0, &PSActions::grestore}, + {"gsave", 0, &PSActions::gsave}, + {"initclip", 0, &PSActions::initclip}, + {"lineto", 2, &PSActions::lineto}, + {"moveto", 2, &PSActions::moveto}, + {"newpath", 0, &PSActions::newpath}, + {"rotate", 1, &PSActions::rotate}, + {"scale", 2, &PSActions::scale}, + {"setcmykcolor", 4, &PSActions::setcmykcolor}, + {"setdash", -1, &PSActions::setdash}, + {"setgray", 1, &PSActions::setgray}, + {"sethsbcolor", 3, &PSActions::sethsbcolor}, + {"setlinecap", 1, &PSActions::setlinecap}, + {"setlinejoin", 1, &PSActions::setlinejoin}, + {"setlinewidth", 1, &PSActions::setlinewidth}, + {"setmatrix", 6, &PSActions::setmatrix}, + {"setmiterlimit", 1, &PSActions::setmiterlimit}, + {"setpos", 2, &PSActions::setpos}, + {"setrgbcolor", 3, &PSActions::setrgbcolor}, + {"stroke", 0, &PSActions::stroke}, + {"translate", 2, &PSActions::translate}, + }; + if (_actions) { + in.skipSpace(); + // binary search + int first=0, last=sizeof(operators)/sizeof(Operator)-1; + while (first <= last) { + int mid = first+(last-first)/2; + int cmp = in.compare(operators[mid].name); + if (cmp > 0) + last = mid-1; + else if (cmp < 0) + first = mid+1; + else { + // collect parameters and call handler + vector<string> params; + int pcount = operators[mid].pcount; + if (pcount < 0) { // variable number of parameters? + in.skipSpace(); + while (!in.eof()) { // read all available parameters + params.push_back(in.getString()); + in.skipSpace(); + } + } + else { // fixed number of parameters + for (int i=0; i < pcount; i++) { + in.skipSpace(); + params.push_back(in.getString()); + } + } + vector<double> v(params.size()); + str2double(params, v); + (_actions->*operators[mid].op)(v); + } + } + } +} + + +/** This callback function handles output from Ghostscript to stderr. + * @param[in] inst pointer to calling instance of PSInterpreter + * @param[in] buf contains the characters to be output + * @param[in] len number of chars in buf + * @return number of processed characters */ +int GSDLLCALL PSInterpreter::error (void *inst, const char *buf, int len) { + ostringstream oss; + oss << "PostScript error:\n"; + oss.write(buf, len); + return len; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.h new file mode 100644 index 00000000000..f37d16db2d6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PSInterpreter.h @@ -0,0 +1,103 @@ +/************************************************************************* +** PSInterpreter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef PSINTERPRETER_H +#define PSINTERPRETER_H + +#include <cstring> +#include <istream> +#include <string> +#include <vector> +#include "Ghostscript.h" +#include "InputReader.h" +#include "MessageException.h" + + +struct PSException : public MessageException +{ + PSException (const std::string &msg) : MessageException(msg) {} +}; + + +struct PSActions +{ + virtual void clip (std::vector<double> &p) =0; + virtual void closepath (std::vector<double> &p) =0; + virtual void curveto (std::vector<double> &p) =0; + virtual void eoclip (std::vector<double> &p) =0; + virtual void eofill (std::vector<double> &p) =0; + virtual void fill (std::vector<double> &p) =0; + virtual void gsave (std::vector<double> &p) =0; + virtual void grestore (std::vector<double> &p) =0; + virtual void initclip (std::vector<double> &p) =0; + virtual void lineto (std::vector<double> &p) =0; + virtual void moveto (std::vector<double> &p) =0; + virtual void newpath (std::vector<double> &p) =0; + virtual void rotate (std::vector<double> &p) =0; + virtual void scale (std::vector<double> &p) =0; + virtual void setcmykcolor (std::vector<double> &cmyk) =0; + virtual void setdash (std::vector<double> &p) =0; + virtual void setgray (std::vector<double> &p) =0; + virtual void sethsbcolor (std::vector<double> &hsb) =0; + virtual void setlinecap (std::vector<double> &p) =0; + virtual void setlinejoin (std::vector<double> &p) =0; + virtual void setlinewidth (std::vector<double> &p) =0; + virtual void setmatrix (std::vector<double> &p) =0; + virtual void setmiterlimit (std::vector<double> &p) =0; + virtual void setpos (std::vector<double> &p) =0; + virtual void setrgbcolor (std::vector<double> &rgb) =0; + virtual void stroke (std::vector<double> &p) =0; + virtual void translate (std::vector<double> &p) =0; +}; + + +class PSInterpreter +{ + enum Mode {PS_NONE, PS_RUNNING, PS_QUIT}; + + public: + PSInterpreter (PSActions *actions=0); + void execute (const char *str, size_t len, bool flush=true); + void execute (const char *str) {execute(str, std::strlen(str));} + void execute (const std::string &str) {execute(str.c_str());} + void execute (std::istream &is); + bool active () const {return _mode != PS_QUIT;} + + protected: + // callback functions + static int GSDLLCALL input (void *inst, char *buf, int len); + static int GSDLLCALL output (void *inst, const char *buf, int len); + static int GSDLLCALL error (void *inst, const char *buf, int len); + + void callActions (InputReader &cib); + + private: + Ghostscript _gs; + Mode _mode; ///< current execution mode + PSActions *_actions; ///< actions to be performed + std::vector<char> _linebuf; + std::string _errorMessage; ///< text of error message + bool _inError; ///< true if scanning error message + bool _initialized; ///< true if PSInterpreter has been completely initialized + static const char *GSARGS[]; ///< parameters passed to Ghostscript + static const char *PSDEFS; ///< initial PostScript definitions +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.cpp new file mode 100644 index 00000000000..c6e14e78c52 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.cpp @@ -0,0 +1,156 @@ +/************************************************************************* +** PageSize.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <algorithm> +#include <cctype> +#include <cmath> +#include <sstream> +#include "PageSize.h" + +using namespace std; + +// make sure tolower is a function (and not a macro) +// so that 'transform' can be applied +static int my_tolower (int c) { + return tolower(c); +} + + +/** Computes width and height of ISO/DIN An in millimeters. + * @param[in] n the A level (e.g. n=4 => DIN A4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeASize (int n, double &width, double &height) { + double sqrt2 = sqrt(2.0); + height = floor(1189.0/pow(sqrt2, n)+0.5); + width = floor(height/sqrt2+0.5); +} + + +/** Computes width and height of ISO/DIN Bn in millimeters. + * @param[in] n the B level (e.g. n=4 => DIN B4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeBSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeASize(n-1, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Computes width and height of ISO/DIN Cn in millimeters. + * @param[in] n the C level (e.g. n=4 => DIN C4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeCSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeBSize(n, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Computes width and height of ISO/DIN Dn in millimeters. + * @param[in] n the D level (e.g. n=4 => DIN D4) + * @param[out] width contains the page width when function returns + * @param[out] height contains the page height when function returns */ +static void computeDSize (int n, double &width, double &height) { + double w, h; + computeASize(n, width, height); + computeBSize(n+1, w, h); + width = floor(sqrt(width * w)+0.5); + height = floor(sqrt(height * h)+0.5); +} + + +/** Constructs a PageSize object of given size. + * @param[in] name specifies the page size, e.g. "A4" or "letter" */ +PageSize::PageSize (string name) : width(0), height(0) { + resize(name); +} + + +void PageSize::resize (double w, double h) { + width = w; + height = h; +} + +void PageSize::resize (string name) { + if (name.length() < 2) + throw PageSizeException("unknown page format: "+name); + + transform(name.begin(), name.end(), name.begin(), my_tolower); + // extract optional suffix + size_t pos = name.rfind("-"); + bool landscape = false; + if (pos != string::npos) { + string suffix = name.substr(pos); + name = name.substr(0, pos); + if (suffix == "-l" || suffix == "-landscape") + landscape = true; + else if (suffix != "-p" && suffix != "-portrait") + throw PageSizeException("invalid page format suffix: " + suffix); + } + + if (name == "invoice") { + width = 140; + height = 216; + } + else if (name == "executive") { + width = 184; + height = 267; + } + else if (name == "legal") { + width = 216; + height = 356; + } + else if (name == "letter") { + width = 216; + height = 279; + } + else if (name == "ledger") { + width = 279; + height = 432; + } + else if (isdigit(name[1]) && name.length() < 5) { // limit length of number to prevent arithmetic errors + istringstream iss(name.substr(1)); + int n; + iss >> n; + switch (name[0]) { + case 'a' : computeASize(n, width, height); break; + case 'b' : computeBSize(n, width, height); break; + case 'c' : computeCSize(n, width, height); break; + case 'd' : computeDSize(n, width, height); break; + default : throw PageSizeException("invalid page format: "+name); + } + } + if (width == 0 || height == 0) + throw PageSizeException("unknown page format: "+name); + if (landscape) + swap(width, height); + + const double ptpmm = 72.27/25.4; // TeX points per millimeter (72.27pt = 1in = 25.4mm) + width *= ptpmm; + height *= ptpmm; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.h new file mode 100644 index 00000000000..b19e29c43b2 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PageSize.h @@ -0,0 +1,49 @@ +/************************************************************************* +** PageSize.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef PAGESIZE_H +#define PAGESIZE_H + +#include <string> +#include "MessageException.h" + +struct PageSizeException : public MessageException +{ + PageSizeException (const string &msg) : MessageException(msg) {} +}; + +class PageSize +{ + public: + PageSize (double w=0, double h=0) : width(w), height(h) {} + PageSize (std::string name); + void resize (std:: string name); + void resize (double w, double h); + double widthInPT () const {return width;} + double heightInPT () const {return height;} + double widthInMM () const {return width*25.4/72.27;} + double heightInMM () const {return height*25.4/72.27;} + bool valid () const {return width > 0 && height > 0;} + + private: + double width, height; // in pt +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Pair.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Pair.h new file mode 100644 index 00000000000..efa489ac7ed --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/Pair.h @@ -0,0 +1,78 @@ +/************************************************************************* +** Pair.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef PAIR_H +#define PAIR_H + +#include <cmath> +#include <ostream> +#include "macros.h" + +template <typename T> +class Pair +{ + public: + Pair (T x=0, T y=0) : _x(x), _y(y) {} + Pair operator += (const Pair &p) {_x += p._x; _y += p._y; return *this;} + Pair operator -= (const Pair &p) {_x -= p._x; _y -= p._y; return *this;} + Pair operator *= (T c) {_x *= c; _y *= c; return *this;} + Pair operator /= (T c) {_x /= c; _y /= c; return *this;} + Pair ortho () const {return Pair(-_y, _x);} + double length () const {return std::sqrt(_x*_x + _y*_y);} + bool operator == (const Pair &p) const {return _x == p._x && _y == p._y;} + bool operator != (const Pair &p) const {return _x != p._x || _y != p._y;} + T x () const {return _x;} + T y () const {return _y;} + void x (const T &xx) {_x = xx;} + void y (const T &yy) {_y = yy;} + std::ostream& write (std::ostream &os) const {return os << '(' << _x << ',' << _y << ')';} + + private: + T _x, _y; +}; + + +struct LPair : public Pair<long> +{ + LPair (long x=0, long y=0) : Pair<long>(x, y) {} + explicit LPair (double x, double y) : Pair<long>(long(x+0.5), long(y+0.5)) {} + LPair (const Pair<long> &p) : Pair<long>(p) {} + operator Pair<long> () {return *this;} +}; + +typedef Pair<double> DPair; + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR(Pair<T>, +) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR(Pair<T>, -) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR2(Pair<T>, T, *) + +template <typename T> +IMPLEMENT_ARITHMETIC_OPERATOR2(Pair<T>, T, /) + +template <typename T> +IMPLEMENT_OUTPUT_OPERATOR(Pair<T>) + +IMPLEMENT_ARITHMETIC_OPERATOR2(LPair, long, *) +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.cpp new file mode 100644 index 00000000000..bf04e49bfe7 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.cpp @@ -0,0 +1,611 @@ +/************************************************************************* +** PsSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <fstream> +#include <iostream> +#include <sstream> +#include "FileFinder.h" +#include "Message.h" +#include "PsSpecialHandler.h" +#include "SpecialActions.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +static inline double str2double (const string &str) { + double ret; + istringstream iss(str); + iss >> ret; + return ret; +} + + +PsSpecialHandler::PsSpecialHandler () : _psi(this), _actions(0), _initialized(false) +{ +} + + +/** Initializes the PostScript handler. It's called by the first use of process(). The + * deferred initialization speeds up the conversion of DVI files that doesn't contain + * PS specials. */ +void PsSpecialHandler::initialize (SpecialActions *actions) { + if (!_initialized) { + // initial values of graphics state + _linewidth = 1; + _linecap = _linejoin = 0; + _miterlimit = 4; + _xmlnode = 0; + + // execute dvips prologue/header files + const char *headers[] = {"tex.pro", "texps.pro", "special.pro", /*"color.pro",*/ 0}; + for (const char **p=headers; *p; ++p) { + if (const char *path = FileFinder::lookup(*p, false)) { + ifstream ifs(path); + _psi.execute(ifs); + } + else + Message::wstream(true) << "PostScript header file " << *p << " not found\n"; + } + // push dictionary "TeXDict" with dvips definitions on dictionary stack + // and initialize basic dvips PostScript variables + ostringstream oss; + oss << " TeXDict begin 0 0 1000 72.27 72.27 () @start " + " 0 0 moveto "; + if (actions) { + float r, g, b; + actions->getColor().getRGB(r, g, b); + oss << r << ' ' << g << ' ' << b << " setrgbcolor "; + } + _psi.execute(oss.str()); + _initialized = true; + } +} + + +const char* PsSpecialHandler::info () const { + static string str = "dvips PostScript specials (using " + Ghostscript().revision() + ")"; + return str.c_str(); +} + + +void PsSpecialHandler::updatePos () { + if (_actions) { + ostringstream oss; + const double x = _actions->getX(), y = _actions->getY(); + oss << ' ' << x << ' ' << y << " moveto "; + _psi.execute(oss.str()); + _currentpoint = DPair(x, y); + } +} + + +bool PsSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (!_initialized) + initialize(actions); + _actions = actions; + + if (*prefix == '"') { + // read and execute literal PostScript code (isolated by a wrapping save/restore pair) + updatePos(); + _psi.execute(" @beginspecial @setspecial "); + _psi.execute(is); + _psi.execute(" @endspecial "); + } + else if (*prefix == '!') { + // execute literal PostScript header + _psi.execute(" @defspecial "); + _psi.execute(is); + _psi.execute(" @fedspecial "); + } + else if (strcmp(prefix, "header=") == 0) { + // read and execute PS header files + string fname; + is >> fname; + if (const char *path = FileFinder::lookup(fname, false)) { + ifstream ifs(path); + _psi.execute(ifs); + } + else + Message::estream(true) << "PS header file '" << fname << "' not found"; + } + else if (strcmp(prefix, "psfile=") == 0 || strcmp(prefix, "PSfile=") == 0) { + if (_actions) { + StreamInputReader in(is); + string fname = in.getString(in.peek() == '"' ? '"' : 0); + map<string,string> attr; + in.parseAttributes(attr); + psfile(fname, attr); + } + } + else if (strcmp(prefix, "ps::") == 0) { + if (is.peek() != '[') { + // execute literal PostScript without initial positioning and without any wrapping code + _psi.execute(is); + _psi.execute(" setpos "); // forces a call of PSActions::setpos to get the current PS position + _actions->setX(_currentpoint.x()); + _actions->setY(_currentpoint.y()); + } + else { + is.get(); + string label; + int c; + while (!is.eof() && (c = is.get()) != ']') + label += c; + if (label != "begin" && label != "end") { + Message::wstream(true) << "invalid PostScript special ps::[" << label << "]\n"; + return false; + } + _psi.execute(is); + } + } + else { // ps: ... + updatePos(); + StreamInputReader in(is); + if (in.check(" plotfile ")) { // ps: plotfile fname + string fname = in.getString(); + ifstream ifs(fname.c_str()); + if (ifs) + _psi.execute(ifs); + else + Message::wstream(true) << "file '" << fname << "' not found in ps: plotfile\n"; + } + else { + // execute literal PostScript (without any wrapping code) + _psi.execute(is); + _psi.execute(" setpos "); // forces a call of PSActions::setpos to get the current PS position + _actions->setX(_currentpoint.x()); + _actions->setY(_currentpoint.y()); + } + } + return true; +} + + +void PsSpecialHandler::psfile (const string &fname, const map<string,string> &attr) { + ifstream ifs(fname.c_str()); + if (!ifs) + Message::wstream(true) << "file '" << fname << "' not found in special 'psfile'\n"; + else { + const double BP = 72.27/72.0; // factor to convert bp -> pt + map<string,string>::const_iterator it; + // coordinates of lower left and upper right vertex (result in TeX points) + double llx = (it = attr.find("llx")) != attr.end() ? str2double(it->second)*BP : 0; + double lly = (it = attr.find("lly")) != attr.end() ? str2double(it->second)*BP : 0; + double urx = (it = attr.find("urx")) != attr.end() ? str2double(it->second)*BP : 0; + double ury = (it = attr.find("ury")) != attr.end() ? str2double(it->second)*BP : 0; + + // actual width and height (result in 10th of TeX points) + double rwi = (it = attr.find("rwi")) != attr.end() ? str2double(it->second)*BP : 0; + double rhi = (it = attr.find("rhi")) != attr.end() ? str2double(it->second)*BP : 0; + + // user transformations (default values chosen according to dvips manual) + double hoffset = (it = attr.find("hoffset")) != attr.end() ? str2double(it->second)*BP : 0; + double voffset = (it = attr.find("voffset")) != attr.end() ? str2double(it->second)*BP : 0; + double hsize = (it = attr.find("hsize")) != attr.end() ? str2double(it->second)*BP : 612*BP; + double vsize = (it = attr.find("vsize")) != attr.end() ? str2double(it->second)*BP : 792*BP; + double hscale = (it = attr.find("hscale")) != attr.end() ? str2double(it->second) : 100; + double vscale = (it = attr.find("vscale")) != attr.end() ? str2double(it->second) : 100; + double angle = (it = attr.find("angle")) != attr.end() ? str2double(it->second) : 0; + + double x=_actions->getX(), y=_actions->getY(); + double w=(urx-llx), h=(ury-lly); // width and height of (E)PS image in TeX points + if (w <= 0) + w = hsize; + if (h <= 0) + h = vsize; + h *= -1; // must be negative to get the bounding box right + + double sx=1, sy=1; + if (rwi != 0 || rhi != 0) { + sx = rwi/10/w; + sy = rhi/10/fabs(h); + if (sx == 0) + sx = sy; + else if (sy == 0) + sy = sx; + } + w *= sx; + h *= sy; + + Matrix usertrans(1); // transformations given by the user + if (hscale != 100 || vscale != 100) + usertrans.scale(hscale/100, vscale/100); + if (angle != 0) + usertrans.rotate(angle); + if (hoffset != 0 || voffset != 0) + usertrans.translate(hoffset, voffset); + + Matrix trans(1); // final transformation to position the graphic correctly + trans.translate(-llx, -lly).rmultiply(usertrans).scale(sx, -sy).translate(x, y); + + _xmlnode = new XMLElementNode("g"); + updatePos(); + _psi.execute(ifs); + if (!_xmlnode->empty()) { + _xmlnode->addAttribute("transform", trans.getSVG()); + _actions->appendToPage(_xmlnode); + } + else + delete _xmlnode; + _xmlnode = 0; + + // adapt bounding box + BoundingBox bbox(x, y, x+w, y+h); + bbox.transform(usertrans); + _actions->bbox().embed(bbox); + } +} + +/////////////////////////////////////////////////////// + +void PsSpecialHandler::gsave (vector<double> &p) { + _clipStack.dup(); +} + + +void PsSpecialHandler::grestore (vector<double> &p) { + if (!_clipStack.empty()) + _clipStack.pop(); +} + + +void PsSpecialHandler::moveto (vector<double> &p) { + _path.moveto(p[0], p[1]); +} + + +void PsSpecialHandler::lineto (vector<double> &p) { + _path.lineto(p[0], p[1]); +} + + +void PsSpecialHandler::curveto (vector<double> &p) { + _path.cubicto(p[0], p[1], p[2], p[3], p[4], p[5]); +} + + +void PsSpecialHandler::closepath (vector<double> &p) { + _path.closepath(); +} + + +/** Draws the current path recorded by previously executed path commands (moveto, lineto,...). + * @param[in] p not used */ +void PsSpecialHandler::stroke (vector<double> &p) { + if (!_path.empty() && _actions) { + BoundingBox bbox; + if (!_actions->getMatrix().isIdentity()) { + _path.transform(_actions->getMatrix()); + if (!_xmlnode) + bbox.transform(_actions->getMatrix()); + } + + const double pt = 72.27/72.0; // factor to convert bp -> pt + ScalingMatrix scale(pt, pt); + _path.transform(scale); + bbox.transform(scale); + + XMLElementNode *path=0; + Pair<double> point; + if (_path.isDot(point)) { // zero-length path? + if (_linecap == 1) { // round line ends? => draw dot + double x = point.x(); + double y = point.y(); + double r = _linewidth/2.0; + path = new XMLElementNode("circle"); + path->addAttribute("cx", XMLString(x)); + path->addAttribute("cy", XMLString(y)); + path->addAttribute("r", XMLString(r)); + path->addAttribute("fill", _actions->getColor().rgbString()); + bbox = BoundingBox(x-r, y-r, x+r, y+r); + } + } + else { + // compute bounding box + _path.computeBBox(bbox); + bbox.expand(_linewidth/2); + + ostringstream oss; + _path.writeSVG(oss); + path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + path->addAttribute("stroke", _actions->getColor().rgbString()); + path->addAttribute("fill", "none"); + if (_linewidth != 1) + path->addAttribute("stroke-width", XMLString(_linewidth)); + if (_miterlimit != 4) + path->addAttribute("stroke-miterlimit", XMLString(_miterlimit)); + if (_linecap > 0) // default value is "butt", no need to set it explicitely + path->addAttribute("stroke-linecap", XMLString(_linecap == 1 ? "round" : "square")); + if (_linejoin > 0) // default value is "miter", no need to set it explicitely + path->addAttribute("stroke-linejoin", XMLString(_linecap == 1 ? "round" : "bevel")); + if (_dashpattern.size() > 0) { + ostringstream oss; + for (size_t i=0; i < _dashpattern.size(); i++) { + if (i > 0) + oss << ','; + oss << _dashpattern[i]; + } + path->addAttribute("stroke-dasharray", oss.str()); + if (_dashoffset != 0) + path->addAttribute("stroke-dashoffset", _dashoffset); + } + } + if (_clipStack.top()) { + // assign clipping path and clip bounding box + path->addAttribute("clip-path", XMLString("url(#clip")+XMLString(_clipStack.topID())+XMLString(")")); + BoundingBox clipbox; + _clipStack.top()->computeBBox(clipbox); + bbox.intersect(clipbox); + } + + if (_xmlnode) + _xmlnode->append(path); + else { + _actions->appendToPage(path); + _actions->bbox().embed(bbox); + } + _path.newpath(); + } +} + + +/** Draws a closed path filled with the current color. + * @param[in] p not used + * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ +void PsSpecialHandler::fill (vector<double> &p, bool evenodd) { + if (!_path.empty() && _actions) { + // compute bounding box + BoundingBox bbox; + _path.computeBBox(bbox); + if (!_actions->getMatrix().isIdentity()) { + _path.transform(_actions->getMatrix()); + if (!_xmlnode) + bbox.transform(_actions->getMatrix()); + } + + const double pt = 72.27/72.0; // factor to convert bp -> pt + ScalingMatrix scale(pt, pt); + _path.transform(scale); + bbox.transform(scale); + + ostringstream oss; + _path.writeSVG(oss); + XMLElementNode *path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + if (_actions->getColor() != Color::BLACK) + path->addAttribute("fill", _actions->getColor().rgbString()); + if (_clipStack.top()) { + // assign clipping path and clip bounding box + path->addAttribute("clip-path", XMLString("url(#clip")+XMLString(_clipStack.topID())+XMLString(")")); + BoundingBox clipbox; + _clipStack.top()->computeBBox(clipbox); + bbox.intersect(clipbox); + } + if (evenodd) // SVG default fill rule is "nonzero" algorithm + path->addAttribute("fill-rule", "evenodd"); + if (_xmlnode) + _xmlnode->append(path); + else { + _actions->appendToPage(path); + _actions->bbox().embed(bbox); + } + _path.newpath(); + } +} + + +/** Clears the current clipping path. + * @param[in] p not used */ +void PsSpecialHandler::initclip (vector<double> &p) { + _clipStack.push(); // push empty path +} + + +/** Assigns a new clipping path. + * @param[in] p not used + * @param[in] evenodd true: use even-odd fill algorithm, false: use nonzero fill algorithm */ +void PsSpecialHandler::clip (vector<double> &p, bool evenodd) { + // when this method is called, _path contains the clipping path + if (!_path.empty() && _actions) { + if (!_actions->getMatrix().isIdentity()) + _path.transform(_actions->getMatrix()); + + const double pt = 72.27/72.0; // factor to convert bp -> pt + ScalingMatrix scale(pt, pt); + _path.transform(scale); + + + int oldID = _clipStack.topID(); + _clipStack.replace(_path); + int newID = _clipStack.topID(); + + ostringstream oss; + _path.writeSVG(oss); + XMLElementNode *path = new XMLElementNode("path"); + path->addAttribute("d", oss.str()); + if (evenodd) + path->addAttribute("clip-rule", "evenodd"); + + XMLElementNode *clip = new XMLElementNode("clipPath"); + clip->addAttribute("id", XMLString("clip")+XMLString(newID)); + if (oldID) + clip->addAttribute("clip-path", XMLString("url(#clip")+XMLString(oldID)+XMLString(")")); + + clip->append(path); + _actions->appendToDefs(clip); + } +} + + +/** Clears current path */ +void PsSpecialHandler::newpath (vector<double> &p) { + _path.newpath(); +} + + +void PsSpecialHandler::setmatrix (vector<double> &p) { + if (_actions) { + // Ensure vector p has 6 elements. If necessary, add missing ones + // using corresponding values of the identity matrix. + if (p.size() < 6) { + p.resize(6); + for (int i=p.size(); i < 6; i++) + p[i] = (i%3 ? 0 : 1); + } + // PS matrix [a b c d e f] equals ((a,b,0),(c,d,0),(e,f,1)). + // Since PS uses left multiplications, we must transpose and reorder + // the matrix to ((a,c,e),(b,d,f),(0,0,1)). This is done by the + // following swaps. + swap(p[1], p[2]); // => (a, c, b, d, e, f) + swap(p[2], p[4]); // => (a, c, e, d, b, f) + swap(p[3], p[4]); // => (a, c, e, b, d, f) + Matrix m(p); + _actions->setMatrix(m); + } +} + + +// In contrast to SVG, PostScript transformations are applied in +// reverse order (M' = T*M). Thus, the transformation matrices must be +// left-multiplied in the following methods scale(), translate() and rotate(). + + +void PsSpecialHandler::scale (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + ScalingMatrix s(p[0], p[1]); + m.lmultiply(s); + _actions->setMatrix(m); + } +} + + +void PsSpecialHandler::translate (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + TranslationMatrix t(p[0], p[1]); + m.lmultiply(t); + _actions->setMatrix(m); + } +} + + +void PsSpecialHandler::rotate (vector<double> &p) { + if (_actions) { + Matrix m = _actions->getMatrix(); + RotationMatrix r(p[0]); + m.lmultiply(r); + _actions->setMatrix(m); + } +} + +void PsSpecialHandler::setgray (vector<double> &p) { + if (_actions) { + Color c; + c.setGray((float)p[0]); + _actions->setColor(c); + } +} + + +void PsSpecialHandler::setrgbcolor (vector<double> &p) { + if (_actions) + _actions->setColor(Color((float)p[0], (float)p[1], (float)p[2])); +} + + +void PsSpecialHandler::setcmykcolor (vector<double> &p) { + if (_actions) { + Color c; + c.setCMYK(p[0], p[1], p[2], p[3]); + _actions->setColor(c); + } +} + + +void PsSpecialHandler::sethsbcolor (vector<double> &p) { + if (_actions) { + Color c; + c.setHSB(p[0], p[1], p[2]); + _actions->setColor(c); + } +} + + +/** Sets the dash parameters used for stroking. + * @param[in] p dash pattern array m1,...,mn plus trailing dash offset */ +void PsSpecialHandler::setdash (vector<double> &p) { + _dashpattern.clear(); + for (size_t i=0; i < p.size()-1; i++) + _dashpattern.push_back((int) (p[i]*1.00375)); + _dashoffset = (int) (p.back()*1.00375); +} + + +//////////////////////////////////////////// + +void PsSpecialHandler::ClippingStack::push () { + if (!_stack.empty()) + _stack.push(0); +} + + +void PsSpecialHandler::ClippingStack::push (const Path &path) { + if (!path.empty()) { + _paths.push_back(path); + _stack.push(_paths.size()); + } +} + + +void PsSpecialHandler::ClippingStack::clear() { + _paths.clear(); + while (!_stack.empty()) + _stack.pop(); +} + + +void PsSpecialHandler::ClippingStack::replace (const Path &path) { + if (path.empty()) + push(path); + else { + _paths.push_back(path); + if (!_stack.empty()) + _stack.pop(); + _stack.push(_paths.size()); + } +} + + +void PsSpecialHandler::ClippingStack::dup () { + if (!_stack.empty()) + _stack.push(_stack.top()); +} + + +const char** PsSpecialHandler::prefixes () const { + static const char *pfx[] = {"header=", "psfile=", "PSfile=", "ps:", "ps::", "!", "\"", 0}; + return pfx; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.h new file mode 100644 index 00000000000..50d02b78f07 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/PsSpecialHandler.h @@ -0,0 +1,111 @@ +/************************************************************************* +** PsSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef PSSPECIALHANDLER_H +#define PSSPECIALHANDLER_H + +#include <stack> +#include <vector> +#include "GraphicPath.h" +#include "PSInterpreter.h" +#include "SpecialHandler.h" + +class XMLElementNode; + +class PsSpecialHandler : public SpecialHandler, protected PSActions +{ + class ClippingStack + { + typedef GraphicPath<double> Path; + public: + void push (); + void push (const Path &path); + void replace (const Path &path); + void dup (); + void pop () {_stack.pop();} + void clear (); + bool empty () {return _stack.empty();} + Path* top () {return (!_stack.empty() && _stack.top()) ? &_paths[_stack.top()-1] : 0;} + int topID () {return _stack.empty() ? 0 : _stack.top();} + + private: + std::vector<Path> _paths; + std::stack<int> _stack; + }; + + public: + PsSpecialHandler (); + const char* name () const {return "ps";} + const char* info () const; + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + + protected: + void initialize (SpecialActions *actions); + void updatePos (); + void psfile (const std::string &fname, const std::map<std::string,std::string> &attr); + + void clip (std::vector<double> &p) {clip(p, false);} + void clip (std::vector<double> &p, bool evenodd); + void closepath (std::vector<double> &p); + void curveto (std::vector<double> &p); + void eoclip (std::vector<double> &p) {clip(p, true);} + void eofill (std::vector<double> &p) {fill(p, true);} + void fill (std::vector<double> &p) {fill(p, false);} + void fill (std::vector<double> &p, bool evenodd); + void gsave (std::vector<double> &p); + void grestore (std::vector<double> &p); + void initclip (std::vector<double> &p); + void lineto (std::vector<double> &p); + void moveto (std::vector<double> &p); + void newpath (std::vector<double> &p); + void rotate (std::vector<double> &p); + void scale (std::vector<double> &p); + void setcmykcolor (std::vector<double> &cmyk); + void setdash (std::vector<double> &p); + void setgray (std::vector<double> &p); + void sethsbcolor (std::vector<double> &hsb); + void setlinecap (std::vector<double> &p) {_linecap = (unsigned int) p[0];} + void setlinejoin (std::vector<double> &p) {_linejoin = (unsigned int) p[0];} + void setlinewidth (std::vector<double> &p) {_linewidth = p[0] ? p[0]*1.00375 : 0.5;} + void setmatrix (std::vector<double> &p); + void setmiterlimit (std::vector<double> &p) {_miterlimit = p[0]*1.00375;} + void setpos (std::vector<double> &p) {_currentpoint = DPair(p[0], p[1]);} + void setrgbcolor (std::vector<double> &rgb); + void stroke (std::vector<double> &p); + void translate (std::vector<double> &p); + + private: + PSInterpreter _psi; + SpecialActions *_actions; + bool _initialized; + XMLElementNode *_xmlnode; ///< if != 0, created SVG elements are appended to this node + GraphicPath<double> _path; + DPair _currentpoint; ///< current PS position + float _linewidth; ///< current linewidth + float _miterlimit; ///< current miter limit + unsigned _linecap : 2; ///< current line cap (0=butt, 1=round, 2=projecting square) + unsigned _linejoin : 2; ///< current line join (0=miter, 1=round, 2=bevel) + int _dashoffset; ///< current dash offset + std::vector<int> _dashpattern; + ClippingStack _clipStack; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.cpp new file mode 100644 index 00000000000..88bae2b3813 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.cpp @@ -0,0 +1,125 @@ +/************************************************************************* +** SVGFontEmitter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "macros.h" +#include "CharmapTranslator.h" +#include "Font.h" +#include "FontEncoding.h" +#include "FontEngine.h" +#include "FontManager.h" +#include "FontGlyph.h" +#include "SVGFontEmitter.h" +#include "SVGTree.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +SVGFontEmitter::SVGFontEmitter (const Font *font, const FontManager &fm, const CharmapTranslator &cmt, SVGTree &svg, bool uf) + : _fontManager(fm), _charmapTranslator(cmt), _svg(svg), _useFonts(uf) +{ + _font = font; + _fontEngine.setFont(font->path()); +} + + + +int SVGFontEmitter::emitFont (const char *id) { + return emitFont(0, id); +} + + +int SVGFontEmitter::emitFont (const set<int> &usedChars, const char *id) { + return emitFont(&usedChars, id); +} + + +int SVGFontEmitter::emitFont (const set<int> *usedChars, const char *id) { + if (!usedChars || usedChars->empty()) + return 0; + + XMLElementNode *fontNode=0; + if (_useFonts) { + fontNode = new XMLElementNode("font"); + if (id && strlen(id) > 0) + fontNode->addAttribute("id", id); + fontNode->addAttribute("horiz-adv", XMLString(_fontEngine.getHAdvance())); + _svg.appendToDefs(fontNode); + + XMLElementNode *faceNode = new XMLElementNode("font-face"); + faceNode->addAttribute("font-family", (id && strlen(id) > 0) ? id : _fontEngine.getFamilyName()); + faceNode->addAttribute("units-per-em", XMLString(_fontEngine.getUnitsPerEM())); + faceNode->addAttribute("ascent", XMLString(_fontEngine.getAscender())); + faceNode->addAttribute("descent", XMLString(_fontEngine.getDescender())); + fontNode->append(faceNode); + FORALL(*usedChars, set<int>::const_iterator, i) { + emitGlyph(*i); // create new glyphNode + fontNode->append(_glyphNode); + } + } + else { + FORALL(*usedChars, set<int>::const_iterator, i) { + emitGlyph(*i); // create new glyphNode + _svg.appendToDefs(_glyphNode); + } + } + return usedChars->size(); +} + + +bool SVGFontEmitter::emitGlyph (int c) { + double sx=1.0, sy=1.0; + FontEncoding *encoding = _fontManager.encoding(_font); + if (_useFonts) { + _glyphNode = new XMLElementNode("glyph"); + _glyphNode->addAttribute("unicode", XMLString(_charmapTranslator.unicode(c), false)); + int advance; + string name; + if (encoding && encoding->getEntry(c)) { + advance = _fontEngine.getHAdvance(encoding->getEntry(c)); + name = encoding->getEntry(c); + } + else { + advance = _fontEngine.getHAdvance(c); + name = _fontEngine.getGlyphName(c); + } + _glyphNode->addAttribute("horiz-adv-x", XMLString(advance)); + _glyphNode->addAttribute("glyph-name", name); + } + else { + ostringstream oss; + oss << 'g' << _fontManager.fontID(_font) << c; + _glyphNode = new XMLElementNode("path"); + _glyphNode->addAttribute("id" , oss.str()); + sx = double(_font->scaledSize())/_fontEngine.getUnitsPerEM(); + sy = -sx; + } + ostringstream path; + Glyph glyph; + glyph.read(c, encoding, _fontEngine); + glyph.closeOpenPaths(); + glyph.optimizeCommands(); + glyph.writeSVGCommands(path, sx, sy); + _glyphNode->addAttribute("d", path.str()); + return true; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.h new file mode 100644 index 00000000000..b3dda8b91d5 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.h @@ -0,0 +1,56 @@ +/************************************************************************* +** SVGFontEmitter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SVGFONTDEFEMITTER_H +#define SVGFONTDEFEMITTER_H + + +#include "FontEmitter.h" +#include "FontEngine.h" + + +class CharmapTranslator; +class FontManager; +class SVGTree; +class XMLElementNode; + +class SVGFontEmitter : public FontEmitter +{ + public: + SVGFontEmitter (const Font *font, const FontManager &fm, const CharmapTranslator &cmt, SVGTree &svg, bool uf); + int emitFont (const char *id); + int emitFont (const std::set<int> &usedChars, const char *id); + bool emitGlyph (int c); + const XMLElementNode* getGlyphNode () const {return _glyphNode;} + + protected: + int emitFont (const std::set<int> *usedCharsm, const char *id); + + private: + const Font *_font; + FontEngine _fontEngine; + const FontManager &_fontManager; + const CharmapTranslator &_charmapTranslator; + SVGTree &_svg; + mutable XMLElementNode *_glyphNode; // current <glyph ...>-node + bool _useFonts; ///< create font elements or draw paths? +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.cpp new file mode 100644 index 00000000000..e7da9986581 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.cpp @@ -0,0 +1,213 @@ +/************************************************************************* +** SVGFontTraceEmitter.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include <fstream> +#include <iostream> +#include <sstream> +#include <string> +#include "Font.h" +#include "FontCache.h" +#include "FontManager.h" +#include "GFGlyphTracer.h" +#include "macros.h" +#include "Message.h" +#include "MetafontWrapper.h" +#include "SVGFontTraceEmitter.h" +#include "SVGTree.h" +#include "TFM.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + +const char *SVGFontTraceEmitter::CACHE_PATH = 0; +bool SVGFontTraceEmitter::TRACE_ALL = false; +double SVGFontTraceEmitter::METAFONT_MAG = 4; + + +SVGFontTraceEmitter::SVGFontTraceEmitter (const Font *f, const FontManager &fm, const CharmapTranslator &cmt, SVGTree &svg, bool uf) + : _gfTracer(0), _in(0), _font(f), _fontManager(fm), _cache(0), + _charmapTranslator(cmt), _svg(svg), _glyphNode(0), _useFonts(uf) +{ + if (CACHE_PATH && _font) { + _cache = new FontCache; + if (TRACE_ALL && prepareTracer()) { + traceAllGlyphs(); + _cache->write(_font->name().c_str(), CACHE_PATH); + } + else + _cache->read(_font->name().c_str(), CACHE_PATH); + } +} + + +SVGFontTraceEmitter::~SVGFontTraceEmitter () { + delete _gfTracer; + delete _in; + if (_cache && _font) + _cache->write(_font->name().c_str(), CACHE_PATH); + delete _cache; + MetafontWrapper::removeOutputFiles(_font->name()); +} + + +/** Creates the tracer object and calls Metafont to generate a GF file of the current font. + * @return true if GF file tracer were successfully created */ +bool SVGFontTraceEmitter::prepareTracer () { + if (!_gfTracer) { + MetafontWrapper mf(_font->name()); + mf.make("ljfour", METAFONT_MAG); // call Metafont if necessary + if (mf.success() && _font->getTFM()) { + _in = new ifstream((_font->name()+".gf").c_str(), ios_base::binary); + _gfTracer = new GFGlyphTracer(*_in, 1000.0/_font->getTFM()->getDesignSize()); // 1000 units per em + Message::mstream() << "tracing glyphs of " << _font->name() << endl; + } + else { + Message::wstream(true) << "unable to find " << _font->name() << ".mf, can't embed font\n"; + return false; // Metafont failed + } + } + return true; +} + + +int SVGFontTraceEmitter::emitFont (const char *id) { + // @@ not needed at the moment + return 0; +} + + +/** Appends a new font element of the current font to the SVG document. + * @param[in] usedChars characters to be embedded + * @param[in] id unique font identifier (usually the font name) + * @return number of embedded glyphs */ +int SVGFontTraceEmitter::emitFont (const set<int> &usedChars, const char *id) { + return emitFont(&usedChars, id); +} + + +/** Appends a new font element of the current font to the SVG document. + * @param[in] usedChars characters to be embedded + * @param[in] id unique font identifier (usually the font name) + * @return number of embedded glyphs */ +int SVGFontTraceEmitter::emitFont (const set<int> *usedChars, const char *id) { + if (!usedChars || usedChars->empty()) + return 0; + + XMLElementNode *fontNode=0; + if (_useFonts) { + fontNode = new XMLElementNode("font"); + if (id && strlen(id) > 0) + fontNode->addAttribute("id", id); + _svg.appendToDefs(fontNode); + + XMLElementNode *faceNode = new XMLElementNode("font-face"); + faceNode->addAttribute("font-family", id); + faceNode->addAttribute("units-per-em", XMLString(1000)); + fontNode->append(faceNode); + FORALL(*usedChars, set<int>::const_iterator, i) { + emitGlyph(*i); // create new glyphNode + fontNode->append(_glyphNode); + } + } + else { + FORALL(*usedChars, set<int>::const_iterator, i) { + emitGlyph(*i); // create new glyphNode + _svg.appendToDefs(_glyphNode); + } + } + + if (_gfTracer) + Message::mstream() << endl; + return usedChars->size(); +} + + +static inline void write_char_info (int c, ostream &os) { + os << '['; + if (isprint(c)) + os << char(c); + else + os << '#' << c; +} + + +/** Creates the SVG definition of a single glyph. + * @param[in] c character code of the glyph + * @param[in] duplicate true if the glyph is already included in different size */ +bool SVGFontTraceEmitter::emitGlyph (int c) { + const TFM *tfm = _font->getTFM(); + if (!tfm) + return false; + + bool write_info=false; + const Glyph *glyph = _cache ? _cache->getGlyph(c) : 0; + if (!glyph && prepareTracer()) { + write_char_info(c, Message::wstream()); + _gfTracer->executeChar(c); + glyph = &_gfTracer->getGlyph(); + if (_cache) + _cache->setGlyph(c, _gfTracer->transferGlyph()); + write_info = true; + } + + ostringstream path; + double sx=1.0, sy=1.0; + if (_useFonts) { + _glyphNode = new XMLElementNode("glyph"); + _glyphNode->addAttribute("unicode", XMLString(_charmapTranslator.unicode(c), false)); + _glyphNode->addAttribute("horiz-adv-x", XMLString(1000.0*tfm->getCharWidth(c)/tfm->getDesignSize())); + } + else { + ostringstream oss; + oss << 'g' << _fontManager.fontID(_font) << c; + _glyphNode = new XMLElementNode("path"); + _glyphNode->addAttribute("id", oss.str()); + sx = _font->scaledSize()/1000.0; // 1000 units per em + sy = -sx; + } + glyph->writeSVGCommands(path, sx, sy); + _glyphNode->addAttribute("d", path.str()); + if (write_info) + Message::mstream() << ']'; + return true; +} + + +/** Traces all glyphs of the current font and stores them in the cache. + * If caching is disabled nothing happens. */ +void SVGFontTraceEmitter::traceAllGlyphs () { + const TFM *tfm = _font->getTFM(); + if (tfm && _cache && prepareTracer()) { + int fchar = tfm->firstChar(); + int lchar = tfm->lastChar(); + for (int i=fchar; i <= lchar; i++) { + if (!_cache->getGlyph(i)) { + write_char_info(i, Message::wstream()); + if (_gfTracer->executeChar(i)) // does char i exist in font? + _cache->setGlyph(i, _gfTracer->transferGlyph()); + else + Message::wstream() << "(empty)"; + Message::wstream() << ']'; + } + } + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.h new file mode 100644 index 00000000000..347d0d32f00 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontTraceEmitter.h @@ -0,0 +1,70 @@ +/************************************************************************* +** SVGFontTraceEmitter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SVGFONTTRACEREMITTER_H +#define SVGFONTTRACEREMITTER_H + +#include <istream> +#include <set> +#include "CharmapTranslator.h" +#include "FontEmitter.h" +#include "XMLNode.h" + + +class FileFinder; +class Font; +class FontCache; +class FontManager; +class GFGlyphTracer; +class SVGTree; +class XMLElementNode; + +class SVGFontTraceEmitter : public FontEmitter +{ + public: + SVGFontTraceEmitter (const Font *font, const FontManager &fm, const CharmapTranslator &cmt, SVGTree &svg, bool uf); + ~SVGFontTraceEmitter (); + int emitFont (const char *id); + int emitFont (const std::set<int> &usedChars, const char *id); + bool emitGlyph (int c); + + public: + static const char *CACHE_PATH; ///< path to cache directory (0 if caching is disabled) + static bool TRACE_ALL; ///< if true, not only the actually used, but all font glyphs are traced + static double METAFONT_MAG; ///< magnification factor for Metafont calls + + protected: + int emitFont (const std::set<int> *usedChars, const char *id); + bool prepareTracer (); + void traceAllGlyphs (); + + private: + GFGlyphTracer *_gfTracer; + std::istream *_in; + const Font *_font; + const FontManager &_fontManager; + FontCache *_cache; + const CharmapTranslator &_charmapTranslator; + SVGTree &_svg; + XMLElementNode *_glyphNode; + bool _useFonts; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.cpp new file mode 100644 index 00000000000..757d5c32701 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.cpp @@ -0,0 +1,191 @@ +/************************************************************************* +** SVGTree.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "BoundingBox.h" +#include "CharmapTranslator.h" +#include "DVIToSVG.h" +#include "Font.h" +#include "FontManager.h" +#include "SVGTree.h" +#include "XMLDocument.h" +#include "XMLDocTypeNode.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + + +SVGTree::SVGTree () : _font(0), _color(Color::BLACK), _matrix(1) { + _xchanged = _ychanged = false; + _fontnum = 0; + reset(); +} + + +/** Clears the SVG tree and initializes the root element. */ +void SVGTree::reset () { + _doc.clear(); + _root = new XMLElementNode("svg"); + _root->addAttribute("version", "1.1"); + _root->addAttribute("xmlns", "http://www.w3.org/2000/svg"); + _root->addAttribute("xmlns:xlink", "http://www.w3.org/1999/xlink"); + _doc.setRootNode(_root); + _doc.append(new XMLDocTypeNode("svg", "PUBLIC", + "\"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"")); + _page = _text = _span = _defs = 0; +} + + +/** Sets the bounding box of the document. */ +void SVGTree::setBBox (const BoundingBox &bbox) { + _root->addAttribute("width", XMLString(bbox.width())); + _root->addAttribute("height", XMLString(bbox.height())); + _root->addAttribute("viewBox", bbox.toSVGViewBox()); +} + + +/** Starts a new page. + * @param[in] pageno number of new page */ +void SVGTree::newPage (int pageno) { + _page = new XMLElementNode("g"); + if (pageno >= 0) + _page->addAttribute("id", string("page")+XMLString(pageno)); + _root->append(_page); + _text = _span = 0; +} + + +void SVGTree::appendToDefs (XMLNode *node) { + if (!_defs) { + _defs = new XMLElementNode("defs"); + _root->prepend(_defs); + } + _defs->append(node); +} + +/** Appends a single charater to the current text node. If necessary, and depending on output mode + * and further output states, new XML elements (text, tspan, g, ...) are created. + * @param[in] c character to be added + * @param[in] x x coordinate + * @param[in] y y coordinate + * @param[in] fontManager the FontManager provides information about the fonts used in the document + * @param[in] cmt the CharmapTranslator remaps the character codes */ +void SVGTree::appendChar (int c, double x, double y, const FontManager &fontManager, const CharmapTranslator &cmt) { + XMLElementNode *node=_span; + if (DVIToSVG::USE_FONTS) { + // changes of fonts and transformations require a new text element + if (!_text || _font.changed() || _matrix.changed()) { + newTextNode(x, y); + node = _text; + _color.changed(true); + } + if (_xchanged || _ychanged || (_color.changed() && _color.get() != Color::BLACK)) { + // if drawing position was explicitly changed, create a new tspan element + _span = new XMLElementNode("tspan"); + if (_xchanged) { + _span->addAttribute("x", x); + _xchanged = false; + } + if (_ychanged) { + _span->addAttribute("y", y); + _ychanged = false; + } + if (_color.get() != Color::BLACK) { + _span->addAttribute("fill", _color.get().rgbString()); + _color.changed(false); + } + _text->append(_span); + node = _span; + } + if (!node) { + if (!_text) + newTextNode(x, y); + node = _text; + } + node->append(XMLString(cmt.unicode(c), false)); + } + else { + if (_color.changed() || _matrix.changed()) { + bool set_color = (_color.changed() && _color.get() != Color::BLACK); + bool set_matrix = (_matrix.changed() && !_matrix.get().isIdentity()); + if (set_color || set_matrix) { + _span = new XMLElementNode("g"); + if (_color.get() != Color::BLACK) + _span->addAttribute("fill", _color.get().rgbString()); + if (!_matrix.get().isIdentity()) + _span->addAttribute("transform", _matrix.get().getSVG()); + _page->append(_span); + node = _span; + _color.changed(false); + _matrix.changed(false); + } + else if (_color.get() == Color::BLACK && _matrix.get().isIdentity()) + node = _span = 0; + } + + if (!node) + node = _page; + ostringstream oss; + oss << "#g" << fontManager.fontID(_font) << c; + XMLElementNode *use = new XMLElementNode("use"); + use->addAttribute("x", XMLString(x)); + use->addAttribute("y", XMLString(y)); + use->addAttribute("xlink:href", oss.str()); + node->append(use); + } +} + + +/** Creates a new text element. This is a helper function used by appendChar(). + * @param[in] x current x coordinate + * @param[in] y current y coordinate */ +void SVGTree::newTextNode (double x, double y) { + _text = new XMLElementNode("text"); + _span = 0; // no tspan in text element yet + if (DVIToSVG::USE_FONTS) { + const Font *font = _font.get(); + if (DVIToSVG::CREATE_STYLE || !font) + _text->addAttribute("class", string("f")+XMLString(_fontnum)); + else { + _text->addAttribute("font-family", font->name()); + _text->addAttribute("font-size", font->scaledSize()); + } + } + _text->addAttribute("x", x); + _text->addAttribute("y", y); + if (!_matrix.get().isIdentity()) + _text->addAttribute("transform", _matrix.get().getSVG()); + _page->append(_text); + _font.changed(false); + _matrix.changed(false); + _xchanged = false; + _ychanged = false; +} + + +void SVGTree::setFont (int num, const Font *font) { + _font.set(font); + _fontnum = num; +} + + +void SVGTree::transformPage (const Matrix &m) { + _page->addAttribute("transform", m.getSVG()); +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.h new file mode 100644 index 00000000000..b70327d48a4 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGTree.h @@ -0,0 +1,95 @@ +/************************************************************************* +** SVGTree.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SVGTREE_H +#define SVGTREE_H + +#include "Color.h" +#include "Matrix.h" +#include "XMLDocument.h" +#include "XMLNode.h" + +class BoundingBox; +class CharmapTranslator; +class Color; +class Font; +class FontManager; +class Matrix; + +class SVGTree +{ + template <typename T> + class Property { + public: + Property (const T &v) : _value(v), _changed(false) {} + + void set (const T &v) { + if (v != _value) { + _value = v; + _changed = true; + } + } + + const T& get () const {return _value;} + operator const T& () {return _value;} + bool changed () const {return _changed;} + void changed (bool c) {_changed = c;} + + private: + T _value; + bool _changed; + }; + + public: + SVGTree (); + void reset (); + void write (ostream &os) const {_doc.write(os);} + void newPage (int pageno); + void appendToDefs (XMLNode *node); + void appendToPage (XMLNode *node) {_page->append(node);} + void prependToPage (XMLNode *node){_page->prepend(node);} + void appendToDoc (XMLNode *node) {_doc.append(node);} + void appendToRoot (XMLNode *node) {_root->append(node);} + void appendChar (int c, double x, double y, const FontManager &fm, const CharmapTranslator &cmt); + void setBBox (const BoundingBox &bbox); + void setFont (int id, const Font *font); + void setX (double x) {_xchanged = true;} + void setY (double y) {_ychanged = true;} + void setMatrix (const Matrix &m) {_matrix.set(m);} + void setColor (const Color &c) {_color.set(c);} + void transformPage (const Matrix &m); + const Color& getColor () const {return _color.get();} + const Matrix& getMatrix () const {return _matrix.get();} + XMLElementNode* rootNode () const {return _root;} + + protected: + void newTextNode (double x, double y); + + private: + XMLDocument _doc; + XMLElementNode *_root, *_page, *_text, *_span, *_defs; + bool _xchanged, _ychanged; + Property<const Font*> _font; + Property<Color> _color; + Property<Matrix> _matrix; + int _fontnum; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialActions.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialActions.h new file mode 100644 index 00000000000..95ccd58e48b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialActions.h @@ -0,0 +1,71 @@ +/************************************************************************* +** SpecialActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SPECIALACTIONS_H +#define SPECIALACTIONS_H + +#include <string> +#include "BoundingBox.h" +#include "Color.h" +#include "Matrix.h" + +class XMLNode; + +struct SpecialActions +{ + virtual ~SpecialActions () {} + virtual double getX() const =0; + virtual double getY() const =0; + virtual void setX(double x) =0; + virtual void setY(double y) =0; + virtual void setColor (const Color &color) =0; + virtual Color getColor () const =0; + virtual void setMatrix (const Matrix &m) =0; + virtual const Matrix& getMatrix () const =0; + virtual void setBgColor (const Color &color) =0; + virtual void appendToPage (XMLNode *node) =0; + virtual void appendToDefs (XMLNode *node) =0; + virtual BoundingBox& bbox () =0; +}; + + +class SpecialEmptyActions : public SpecialActions +{ + public: + double getX() const {return 0;} + double getY() const {return 0;} + void setX(double x) {} + void setY(double y) {} + void setColor (const Color &color) {} + void setBgColor (const Color &color) {} + Color getColor () const {return 0;} + void setMatrix (const Matrix &m) {} + const Matrix& getMatrix () const {return _matrix;} + void appendToPage (XMLNode *node) {} + void appendToDefs (XMLNode *node) {} + BoundingBox& bbox () {return _bbox;} + + private: + BoundingBox _bbox; + Matrix _matrix; +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialHandler.h new file mode 100644 index 00000000000..4ad13852056 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialHandler.h @@ -0,0 +1,49 @@ +/************************************************************************* +** SpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SPECIALHANDLER_H +#define SPECIALHANDLER_H + +#include <istream> +#include <list> +#include "MessageException.h" + + +class SpecialActions; + + +struct SpecialException : public MessageException +{ + SpecialException (const std::string &msg) : MessageException(msg) {} +}; + + +struct SpecialHandler +{ + virtual ~SpecialHandler () {} + virtual const char** prefixes () const=0; + virtual const char* info () const=0; + virtual const char* name () const=0; + virtual bool process (const char *prefix, std::istream &is, SpecialActions *actions)=0; + virtual void endPage () {} +}; + + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.cpp new file mode 100644 index 00000000000..f7c1fc74ccf --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.cpp @@ -0,0 +1,134 @@ +/************************************************************************* +** SpecialManager.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iomanip> +#include <sstream> +#include "SpecialActions.h" +#include "SpecialManager.h" +#include "macros.h" + +using namespace std; + + +SpecialManager::~SpecialManager () { + unregisterHandlers(); +} + + +void SpecialManager::unregisterHandlers () { + FORALL(_pool, vector<SpecialHandler*>::iterator, it) + delete *it; +} + + +/** Registers a single special handler. This method doesn't check if a + * handler of the same class is already registered. + * @param[in] pointer to handler to be registered */ +void SpecialManager::registerHandler (SpecialHandler *handler) { + if (handler) { + // get array of prefixes this handler is responsible for + _pool.push_back(handler); + for (const char **p=handler->prefixes(); *p; ++p) + _handlers[*p] = handler; + } +} + + +/** Registers a multiple special handlers. + * If ignorelist == 0, all given handlers are registered. To exclude selected sets of + * specials, the corresponding names can be given separated by non alpha-numeric characters, + * e.g. "color, ps, em" or "color: ps em" etc. + * @param[in] handlers pointer to zero-terminated array of handlers to be registered + * @param[in] ignorelist list of special names to be ignored */ +void SpecialManager::registerHandlers (SpecialHandler **handlers, const char *ignorelist) { + if (handlers) { + string ign = ignorelist ? ignorelist : ""; + FORALL(ign, string::iterator, it) + if (!isalnum(*it)) + *it = '%'; + ign = "%"+ign+"%"; + + for (; *handlers; handlers++) { + if (ign.find("%"+string((*handlers)->name())+"%") == string::npos) + registerHandler(*handlers); + else + delete *handlers; + } + } +} + + +/** Looks for an appropriate handler for a given special prefix. + * @param[in] prefix the special prefix, e.g. "color" or "em" + * @return in case of success: pointer to handler, 0 otherwise */ +SpecialHandler* SpecialManager::findHandler (const string &prefix) const { + ConstIterator it = _handlers.find(prefix); + if (it != _handlers.end()) + return it->second; + return 0; +} + + +/** Executes a special command. + * @param[in] special the special expression + * @param[in] actions actions the special handlers can perform + * @param[in] listener object that wants to be notified about the processing state + * @return true if a special handler was found + * @throw SpecialException in case of errors during special processing */ +bool SpecialManager::process (const string &special, SpecialActions *actions, Listener *listener) const { + istringstream iss(special); + string prefix; + int c; + while (isalnum(c=iss.get())) + prefix += c; + if (ispunct(c)) // also add seperation character to identifying prefix + prefix += c; + if (SpecialHandler *handler = findHandler(prefix)) { + if (listener) + listener->beginSpecial(prefix.c_str()); + bool ret = handler->process(prefix.c_str(), iss, actions); + if (listener) + listener->endSpecial(prefix.c_str()); + return ret; + } + return false; +} + + +void SpecialManager::notifyEndPage () { + FORALL(_handlers, Iterator, it) + it->second->endPage(); +} + + +void SpecialManager::writeHandlerInfo (ostream &os) const { + typedef map<string, SpecialHandler*> SortMap; + SortMap m; + FORALL(_handlers, ConstIterator, it) + m[it->second->name()] = it->second; + + FORALL(m, SortMap::iterator, it) { + os << setw(10) << left << it->second->name() << ' '; + if (it->second->info()) + os << it->second->info(); + os << endl; + } +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.h new file mode 100644 index 00000000000..26faf620e69 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SpecialManager.h @@ -0,0 +1,67 @@ +/************************************************************************* +** SpecialManager.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef SPECIALMANAGER_H +#define SPECIALMANAGER_H + +#include <map> +#include <ostream> +#include <string> +#include <vector> +#include "SpecialHandler.h" + +class SpecialActions; + +class SpecialManager +{ + public: + struct Listener + { + virtual void beginSpecial (const char *prefix)=0; + virtual void endSpecial (const char *prefix)=0; + }; + + private: + typedef std::vector<SpecialHandler*> HandlerPool; + typedef std::map<std::string,SpecialHandler*> HandlerMap; + typedef HandlerMap::iterator Iterator; + typedef HandlerMap::const_iterator ConstIterator; + + public: + SpecialManager () {} + virtual ~SpecialManager (); + void registerHandler (SpecialHandler *handler); + void registerHandlers (SpecialHandler **handlers, const char *ignorelist); + void unregisterHandlers (); + bool process (const std::string &special, SpecialActions *actions, Listener *listener=0) const; + void notifyEndPage (); + void writeHandlerInfo (std::ostream &os) const; + + protected: + SpecialManager (const SpecialManager &) {} + void operator = (const SpecialManager &) {} + SpecialHandler* findHandler (const std::string &prefix) const; + + private: + HandlerPool _pool; ///< stores pointers to all handlers + HandlerMap _handlers; ///< pointers to handlers for corresponding prefixes +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamCounter.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamCounter.h new file mode 100644 index 00000000000..00df0703b8a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamCounter.h @@ -0,0 +1,100 @@ +/************************************************************************* +** StreamCounter.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef STREAMCOUNTER_H +#define STREAMCOUNTER_H + +#include <ostream> +#include "types.h" + + +/** This class template is used to count the number of characters + * written to a stream buffer. It simply counts the characters written + * and forwards them to the target buffer. */ +template <typename C, typename T=std::char_traits<C> > +class CountingStreamBuf : public std::basic_streambuf<C,T> +{ + public: + explicit CountingStreamBuf (std::basic_streambuf<C,T> *b) + : targetBuf(b), counter(0) {} + + UInt64 count () const {return counter;} + void reset () {counter = 0;} + + protected: + CountingStreamBuf (const CountingStreamBuf &csb); + CountingStreamBuf& operator = (const CountingStreamBuf &csb); + + typename T::int_type overflow (typename T::int_type c=T::eof()) { + typename T::int_type n = targetBuf->sputc(c); + if (!T::eq_int_type(c, T::eof()) && !T::eq_int_type(n, T::eof())) + counter++; + return n; + } + + std::streamsize xsputn (const C *buf, std::streamsize bufsize) { + std::streamsize n = targetBuf->sputn(buf, bufsize); + counter += n; + return n; + } + + private: + std::basic_streambuf<C,T> *targetBuf; + UInt64 counter; +}; + + +/** This class template assigns a counting buffer to a stream. It makes + * the use of CountingStreamBuf more comfortable. */ +template <typename C, typename T=std::char_traits<C> > +class StreamCounter +{ + public: + explicit StreamCounter (std::basic_ios<C,T> &stream) + : targetStream(stream), + targetBuf(stream.rdbuf()), + countingBuf(new CountingStreamBuf<C,T>(stream.rdbuf())) + { + stream.rdbuf(countingBuf); + valid = true; + } + + ~StreamCounter () { + if (valid) + targetStream.rdbuf(targetBuf); + delete countingBuf; + } + + UInt64 count () const {return countingBuf->count();} + void reset () {countingBuf->reset();} + void invalidate () {valid = false;} + + protected: + StreamCounter (const StreamCounter &csf); + StreamCounter operator = (const StreamCounter &csf); + + private: + bool valid; ///< true if target stream is valid + std::basic_ios<C,T> &targetStream; + std::basic_streambuf<C,T> *targetBuf; + CountingStreamBuf<C,T> *countingBuf; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.cpp new file mode 100644 index 00000000000..ad4685f23b0 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.cpp @@ -0,0 +1,85 @@ +/************************************************************************* +** StreamReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "StreamReader.h" +#include "macros.h" + +using namespace std; + +StreamReader::StreamReader (istream &s) + : is(&s) +{ +} + + +istream& StreamReader::replaceStream (istream &in) { + istream &ret = *is; + is = ∈ + return ret; +} + + +/** Reads an unsigned integer from assigned input stream. + * @param[in] bytes number of bytes to read (max. 4) + * @return read integer */ +UInt32 StreamReader::readUnsigned (int bytes) { + UInt32 ret = 0; + for (bytes--; bytes >= 0 && !is->eof(); bytes--) { + UInt32 b = is->get(); + ret |= b << (8*bytes); + } + return ret; +} + + +/** Reads an signed integer from assigned input stream. + * @param[in] bytes number of bytes to read (max. 4) + * @return read integer */ +Int32 StreamReader::readSigned (int bytes) { + Int32 ret = is->get(); + if (ret & 128) // negative value? + ret |= 0xffffff00; + for (bytes-=2; bytes >= 0 && !is->eof(); bytes--) + ret = (ret << 8) | is->get(); + return ret; +} + + +string StreamReader::readString (int length) { + if (!is) + throw StreamReaderException("no stream assigned"); + char *buf = new char[length+1]; + if (length > 0) + is->get(buf, length+1); // reads 'length' bytes (pos. length+1 is set to 0) + else + *buf = 0; + string ret = buf; + delete [] buf; + return ret; +} + + +vector<UInt8>& StreamReader::readBytes (int n, vector<UInt8> &bytes) { + if (n > 0) + in().read((char*)&bytes[0], n); + return bytes; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.h new file mode 100644 index 00000000000..65817e8d3ac --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/StreamReader.h @@ -0,0 +1,59 @@ +/************************************************************************* +** StreamReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef STREAMREADER_H +#define STREAMREADER_H + +#include <istream> +#include <string> +#include <vector> +#include "MessageException.h" +#include "types.h" + +using std::istream; +using std::string; +using std::vector; + +class StreamReader +{ + public: + StreamReader (istream &s); + virtual ~StreamReader () {} + istream& replaceStream (istream &s); + UInt32 readUnsigned (int n); + Int32 readSigned (int n); + string readString (int length); + vector<UInt8>& readBytes (int n, vector<UInt8> &bytes); + int readByte () {return is->get();} + + protected: + istream& in () {return *is;} + + private: + istream *is; +}; + + +struct StreamReaderException : public MessageException +{ + StreamReaderException (const string &msg) : MessageException(msg) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.cpp new file mode 100644 index 00000000000..3683e642d22 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.cpp @@ -0,0 +1,161 @@ +/************************************************************************* +** TFM.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <iostream> +#include <fstream> +#include <vector> +#include "FileFinder.h" +#include "Message.h" +#include "MetafontWrapper.h" +#include "TFM.h" + +using namespace std; + + +/** Reads a single unsigned integer value of given size (max. 4 bytes). + * @param[in] is characters are read from this stream + * @param[in] n number of bytes to be read */ +static UInt32 read_unsigned (istream &is, int n) { + UInt32 ret = 0; + for (int i=n-1; i >= 0 && !is.eof(); i--) { + UInt32 b = is.get(); + ret |= b << (8*i); + } + return ret; +} + + +/** Reads a sequence of n TFM words (4 Bytes each). + * @param[in] is reads from this stream + * @param[out] v the read words + * @param[in] n number of words to be read + * @return dynamically allocated array containing the read words + * (must be deleted by the caller) */ +template <typename T> +static void read_words (istream &is, vector<T> &v, unsigned n) { + v.clear(); + v.resize(n); + for (unsigned i=0; i < n; i++) + v[i] = read_unsigned(is, 4); +} + + +/** Converts a TFM fix point value to double. */ +static double fix2double (FixWord fix) { + return double(fix)/(1 << 20); +} + + +TFM::TFM () : _checksum(0), _firstChar(0), _lastChar(0), _designSize(0) +{ +} + + +TFM::TFM (istream &is) { + readFromStream(is); +} + + +TFM* TFM::createFromFile (const char *fontname) { + string filename = string(fontname) + ".tfm"; + const char *path = FileFinder::lookup(filename); + ifstream ifs(path, ios_base::binary); + if (ifs) + return new TFM(ifs); + return 0; +} + + +bool TFM::readFromStream (istream &is) { + is.seekg(2, ios_base::beg); // skip file size + UInt16 lh = read_unsigned(is, 2); // length of header in 4 byte words + _firstChar= read_unsigned(is, 2); // smalles character code in font + _lastChar = read_unsigned(is, 2); // largest character code in font + UInt16 nw = read_unsigned(is, 2); // number of words in width table + UInt16 nh = read_unsigned(is, 2); // number of words in height table + UInt16 nd = read_unsigned(is, 2); // number of words in depth table + UInt16 ni = read_unsigned(is, 2); // number of words in italic corr. table +// UInt16 nl = read_unsigned(is, 2); // number of words in lig/kern table +// UInt16 nk = read_unsigned(is, 2); // number of words in kern table +// UInt16 ne = read_unsigned(is, 2); // number of words in ext. char table +// UInt16 np = read_unsigned(is, 2); // number of font parameter words + + is.seekg(8, ios_base::cur); // move to header (skip above commented bytes) + _checksum = read_unsigned(is, 4); + _designSize = read_unsigned(is, 4); + is.seekg(24+lh*4, ios_base::beg); // move to char info table + read_words(is, _charInfoTable, _lastChar-_firstChar+1); + read_words(is, _widthTable, nw); + read_words(is, _heightTable, nh); + read_words(is, _depthTable, nd); + read_words(is, _italicTable, ni); + return true; +} + + +/** Returns the design size of this font in TeX point units. */ +double TFM::getDesignSize () const { + return fix2double(_designSize); +} + + +// the char info word for each character consists of 4 bytes holding the following information: +// width index w, height index (h), depth index (d), italic correction index (it), +// tag (tg) and a remainder: +// +// byte 1 | byte 2 | byte 3 | byte 4 +// xxxxxxxx | xxxx xxxx | xxxxxx xx | xxxxxxxx +// w | h d | it tg | remainder + +/** Returns the width of char c in TeX point units. */ +double TFM::getCharWidth (int c) const { + if (c < _firstChar || c > _lastChar || unsigned(c-_firstChar) >= _charInfoTable.size()) + return 0; + int index = (_charInfoTable[c-_firstChar] >> 24) & 0xFF; + return fix2double(_widthTable[index]) * fix2double(_designSize); +} + + +/** Returns the height of char c in TeX point units. */ +double TFM::getCharHeight (int c) const { + if (c < _firstChar || c > _lastChar || unsigned(c-_firstChar) >= _charInfoTable.size()) + return 0; + int index = (_charInfoTable[c-_firstChar] >> 20) & 0x0F; + return fix2double(_heightTable[index]) * fix2double(_designSize); +} + + +/** Returns the depth of char c in TeX point units. */ +double TFM::getCharDepth (int c) const { + if (c < _firstChar || c > _lastChar || unsigned(c-_firstChar) >= _charInfoTable.size()) + return 0; + int index = (_charInfoTable[c-_firstChar] >> 16) & 0x0F; + return fix2double(_depthTable[index]) * fix2double(_designSize); +} + + +/** Returns the italic correction of char c in TeX point units. */ +double TFM::getItalicCorr (int c) const { + if (c < _firstChar || c > _lastChar || unsigned(c-_firstChar) >= _charInfoTable.size()) + return 0; + int index = (_charInfoTable[c-_firstChar] >> 10) & 0x3F; + return fix2double(_italicTable[index]) * fix2double(_designSize); +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.h new file mode 100644 index 00000000000..b8c44af5363 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TFM.h @@ -0,0 +1,59 @@ +/************************************************************************* +** TFM.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef TFM_H +#define TFM_H + +#include <istream> +#include <vector> +#include "types.h" + +class FileFinder; + +class TFM +{ + public: + TFM (); + TFM (std::istream &is); + static TFM* createFromFile (const char *fname); + double getDesignSize () const; + double getCharWidth (int c) const; + double getCharHeight (int c) const; + double getCharDepth (int c) const; + double getItalicCorr (int c) const; + UInt16 getChecksum () const {return _checksum;} + UInt16 firstChar () const {return _firstChar;} + UInt16 lastChar () const {return _lastChar;} + + protected: + bool readFromStream (std::istream &is); + + private: + UInt16 _checksum; + UInt16 _firstChar, _lastChar; + FixWord _designSize; ///< design size of the font in TeX points (7227 pt = 254 cm) + std::vector<UInt32> _charInfoTable; + std::vector<FixWord> _widthTable; ///< character widths in design size units + std::vector<FixWord> _heightTable; ///< character height in design size units + std::vector<FixWord> _depthTable; ///< character depth in design size units + std::vector<FixWord> _italicTable; ///< italic corrections in design size units +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.cpp new file mode 100644 index 00000000000..9418215f39f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.cpp @@ -0,0 +1,312 @@ +/************************************************************************* +** TpicSpecialHandler.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <cstring> +#include <sstream> +#include "Color.h" +#include "InputBuffer.h" +#include "InputReader.h" +#include "SpecialActions.h" +#include "TpicSpecialHandler.h" +#include "XMLNode.h" +#include "XMLString.h" +#include "types.h" + +using namespace std; + + +TpicSpecialHandler::TpicSpecialHandler () { + reset(); +} + + +void TpicSpecialHandler::endPage () { + reset(); +} + + +void TpicSpecialHandler::reset () { + _points.clear(); + _penwidth = 1.0; + _fill = -1.0; // no fill +} + + +/** Creates SVG elements that draw lines through the recorded points. + * @param[in] fill true if enclosed area should be filled + * @param[in] ddist dash/dot distance of line in TeX point units + * (0:solid line, >0:dashed line, <0:dotted line) */ +void TpicSpecialHandler::drawLines (bool fill, double ddist, SpecialActions *actions) { + if (actions && _points.size() > 0) { + XMLElementNode *elem=0; + if (_points.size() == 1) { + const DPair &p = _points.back(); + elem = new XMLElementNode("circle"); + elem->addAttribute("cx", p.x()+actions->getX()); + elem->addAttribute("cy", p.y()+actions->getY()); + elem->addAttribute("r", _penwidth/2.0); + actions->bbox().embed(p, _penwidth/2.0); + } + else { + if (_points.size() == 2 || (!fill && _points.front() != _points.back())) { + elem = new XMLElementNode("polyline"); + elem->addAttribute("fill", "none"); + elem->addAttribute("stroke-linecap", "round"); + } + else { + if (_points.front() == _points.back()) + _points.pop_back(); + if (_fill < 0) + _fill = 1; + Color color = actions->getColor(); + color *= _fill; + elem = new XMLElementNode("polygon"); + elem->addAttribute("fill", fill ? color.rgbString() : "none"); + } + ostringstream oss; + FORALL(_points, vector<DPair>::iterator, it) { + if (it != _points.begin()) + oss << ' '; + double x = it->x()+actions->getX(); + double y = it->y()+actions->getY(); + oss << x << ',' << y; + actions->bbox().embed(x, y); + } + elem->addAttribute("points", oss.str()); + elem->addAttribute("stroke", "black"); + elem->addAttribute("stroke-width", XMLString(_penwidth)); + } + if (ddist > 0) + elem->addAttribute("stroke-dasharray", XMLString(ddist)); + else if (ddist < 0) { + ostringstream oss; + oss << _penwidth << ' ' << -ddist; + elem->addAttribute("stroke-dasharray", oss.str()); + } + actions->appendToPage(elem); + } + reset(); +} + + +void TpicSpecialHandler::drawSplines (double ddist, SpecialActions *actions) { + if (actions && _points.size() > 0) { + const size_t size = _points.size(); + if (size < 3) + drawLines(false, ddist, actions); + else { + double x = actions->getX(); + double y = actions->getY(); + DPair p(x,y); + ostringstream oss; + oss << 'M' << x+_points[0].x() << ',' << y+_points[0].y(); + DPair mid = p+_points[0]+(_points[1]-_points[0])/2.0; + oss << 'L' << mid.x() << ',' << mid.y(); + actions->bbox().embed(p+_points[0]); + for (size_t i=1; i < size-1; i++) { + const DPair p0 = p+_points[i-1]; + const DPair p1 = p+_points[i]; + const DPair p2 = p+_points[i+1]; + mid = p1+(p2-p1)/2.0; + oss << 'Q' << p1.x() << ',' << p1.y() + << ' ' << mid.x() << ',' << mid.y(); + actions->bbox().embed(mid); + actions->bbox().embed((p0+p1*6.0+p2)/8.0, _penwidth); + } + if (_points[0] == _points[size-1]) // closed path? + oss << 'Z'; + else { + oss << 'L' << x+_points[size-1].x() << ',' << y+_points[size-1].y(); + actions->bbox().embed(p+_points[size-1]); + } + + Color color = actions->getColor(); + color *= _fill; + XMLElementNode *path = new XMLElementNode("path"); + if (_fill >= 0) { + if (_points[0] != _points[size-1]) + oss << 'Z'; + path->addAttribute("fill", color.rgbString()); + } + else + path->addAttribute("fill", "none"); + + path->addAttribute("d", oss.str()); + path->addAttribute("stroke", actions->getColor().rgbString()); + path->addAttribute("stroke-width", XMLString(_penwidth)); + if (ddist > 0) + path->addAttribute("stroke-dasharray", XMLString(ddist)); + else if (ddist < 0) { + ostringstream oss; + oss << _penwidth << ' ' << -ddist; + path->addAttribute("stroke-dasharray", oss.str()); + } + actions->appendToPage(path); + } + } + reset(); +} + + +void TpicSpecialHandler::drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions) { + if (actions) { + const double PI2 = 4*asin(1.0); + angle1 *= -1; + angle2 *= -1; + if (fabs(angle1) > PI2) { + int n = angle1/PI2; + angle1 = angle1 - n*PI2; + angle2 = angle2 - n*PI2; + } + + double x = cx + actions->getX(); + double y = cy + actions->getY(); + XMLElementNode *elem=0; + if (fabs(angle1-angle2) >= PI2) { // closed ellipse? + elem = new XMLElementNode("ellipse"); + elem->addAttribute("cx", XMLString(x)); + elem->addAttribute("cy", XMLString(y)); + elem->addAttribute("rx", XMLString(rx)); + elem->addAttribute("ry", XMLString(ry)); + } + else { + if (angle1 < 0) + angle1 = PI2+angle1; + if (angle2 < 0) + angle2 = PI2+angle2; + elem = new XMLElementNode("path"); + int large_arg = fabs(angle1-angle2) > PI2/2 ? 0 : 1; + int sweep = angle1 > angle2 ? 0 : 1; + if (angle1 > angle2) { + large_arg = 1-large_arg; + sweep = 1-sweep; + } + ostringstream oss; + oss << 'M' << x+rx*cos(angle1) << ',' << y+ry*sin(-angle1) + << 'A' << rx << ',' << ry + << " 0 " + << large_arg << ' ' << sweep << ' ' + << x+rx*cos(angle2) << ',' << y-ry*sin(angle2); + if (_fill >= 0) + oss << 'Z'; + elem->addAttribute("d", oss.str()); + } + elem->addAttribute("stroke-width", _penwidth); + elem->addAttribute("stroke", actions->getColor().rgbString()); + elem->addAttribute("stroke-linecap", "round"); + elem->addAttribute("fill", "none"); + if (_fill >= 0) { + Color color=actions->getColor(); + color *= _fill; + elem->addAttribute("fill", color.rgbString()); + } + else + elem->addAttribute("fill", "none"); + actions->appendToPage(elem); + actions->bbox().embed(BoundingBox(cx-rx, cy-ry, cx+rx, cy+ry)); + } + reset(); +} + + +#define cmd_id(c1,c2) ((c1 << 8) | c2) + +bool TpicSpecialHandler::process (const char *prefix, istream &is, SpecialActions *actions) { + if (!prefix || strlen(prefix) != 2) + return false; + + const double PT=0.07227; // factor for milli-inch to TeX points + StreamInputBuffer ib(is); + BufferInputReader in(ib); + switch (cmd_id(prefix[0], prefix[1])) { + case cmd_id('p','n'): // set pen width in milli-inches + _penwidth = in.getDouble()*PT; + break; + case cmd_id('b','k'): // set fill color to black + _fill = 0; + break; + case cmd_id('w','h'): // set fill color to white + _fill = 1; + break; + case cmd_id('s','h'): // set fill color to given gray level + in.skipSpace(); + _fill = in.eof() ? 0.5 : max(0.0, min(1.0, in.getDouble())); + break; + case cmd_id('t','x'): // set fill pattern + break; + case cmd_id('p','a'): { // add point to path + double x=in.getDouble()*PT; + double y=in.getDouble()*PT; + _points.push_back(DPair(x,y)); + break; + } + case cmd_id('f','p'): // draw solid lines through recorded points; close and fill path if fill color was defined + drawLines(_fill >= 0, 0, actions); + break; + case cmd_id('i','p'): // as above but always fill polygon + drawLines(true, 0, actions); + break; + case cmd_id('d','a'): // as fp but draw dashed lines + drawLines(_fill >= 0, in.getDouble()*72.27, actions); + break; + case cmd_id('d','t'): // as fp but draw dotted lines + drawLines(_fill >= 0, -in.getDouble()*72.27, actions); + break; + case cmd_id('s','p'): { // draw quadratic splines through recorded points + double ddist = in.getDouble(); + drawSplines(ddist, actions); + break; + } + case cmd_id('a','r'): { // draw elliptical arc + double cx = in.getDouble()*PT; + double cy = in.getDouble()*PT; + double rx = in.getDouble()*PT; + double ry = in.getDouble()*PT; + double a1 = in.getDouble(); + double a2 = in.getDouble(); + drawArc(cx, cy, rx, ry, a1, a2, actions); + break; + } + case cmd_id('i','a'): { // fill elliptical arc + double cx = in.getDouble()*PT; + double cy = in.getDouble()*PT; + double rx = in.getDouble()*PT; + double ry = in.getDouble()*PT; + double a1 = in.getDouble(); + double a2 = in.getDouble(); + if (_fill < 0) + _fill = 1; + drawArc(cx, cy, rx, ry, a1, a2, actions); + if (_fill < 0) + _fill = -1; + break; + } + default: + return false; + } + return true; +} + + +const char** TpicSpecialHandler::prefixes () const { + static const char *pfx[] = {"ar", "bk", "da", "dt", "fp", "ia", "ip", "pa", "pn", "sh", "sp", "tx", "wh", 0}; + return pfx; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.h new file mode 100644 index 00000000000..6856e5e9413 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/TpicSpecialHandler.h @@ -0,0 +1,50 @@ +/************************************************************************* +** TpicSpecialHandler.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef TPICSPECIALHANDLER_H +#define TPICSPECIALHANDLER_H + +#include <list> +#include "Pair.h" +#include "SpecialHandler.h" + +class TpicSpecialHandler : public SpecialHandler +{ + public: + TpicSpecialHandler (); + const char* info () const {return "TPIC specials";} + const char* name () const {return "tpic";} + const char** prefixes () const; + bool process (const char *prefix, std::istream &is, SpecialActions *actions); + void endPage (); + + protected: + void reset (); + void drawLines (bool fill, double ddist, SpecialActions *actions); + void drawSplines (double ddist, SpecialActions *actions); + void drawArc (double cx, double cy, double rx, double ry, double angle1, double angle2, SpecialActions *actions); + + private: + double _penwidth; ///< pen width in TeX point units + double _fill; ///< fill intensity [0,1]; if < 0, we don't fill anything + std::vector<DPair> _points; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFActions.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFActions.h new file mode 100644 index 00000000000..6b08064510d --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFActions.h @@ -0,0 +1,41 @@ +/************************************************************************* +** VFActions.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef VFACTIONS_H +#define VFACTIONS_H + +#include <string> +#include <vector> +#include "types.h" + +using std::string; +using std::vector; + + +struct VFActions +{ + virtual ~VFActions () {} + virtual void preamble (string comment, UInt32 checksum, double dsize) {} + virtual void postamble () {} + virtual void defineVFFont (UInt32 fontnum, string path, string name, UInt32 checksum, double dsize, double ssize) {} + virtual void defineVFChar (UInt32 c, vector<UInt8> *dvi) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.cpp new file mode 100644 index 00000000000..691e3f52598 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.cpp @@ -0,0 +1,190 @@ +/************************************************************************* +** VFReader.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "Font.h" +#include "VFActions.h" +#include "VFReader.h" +#include "macros.h" + +using namespace std; + + +/** Converts a TFM fix point value to double. */ +inline static double fix2double (FixWord fix) { + return double(fix)/(1 << 20); +} + + +VFReader::VFReader (istream &is) + : StreamReader(is), actions(0) { +} + + +VFReader::~VFReader () { +} + + +VFActions* VFReader::replaceActions (VFActions *a) { + VFActions *ret = actions; + actions = a; + return ret; +} + + +/** Reads a single VF command from the current position of the input stream and calls the + * corresponding cmdFOO method. The execution can be influenced by a function of type ApproveOpcode. + * It takes an opcode and returns true if the command is supposed to be executed. + * @param[in] approve function to approve invocation of the action assigned to command + * @return opcode of the executed command */ +int VFReader::executeCommand (ApproveAction approve) { + int opcode = in().get(); + if (!in() || opcode < 0) // at end of file + throw VFException("invalid file"); + + bool approved = !approve || approve(opcode); + VFActions *act = actions; + if (!approved) + replaceActions(0); // disable actions + + if (opcode <= 241) // short character definition? + cmdShortChar(opcode); + else if (opcode >= 243 && opcode <= 246) // font definition? + cmdFontDef(opcode-243+1); + else { + switch (opcode) { + case 242: cmdLongChar(); break; // long character definition + case 247: cmdPre(); break; // preamble + case 248: cmdPost(); break; // postamble + default : { // invalid opcode + replaceActions(act); // reenable actions + ostringstream oss; + oss << "undefined VF command (opcode " << opcode << ')'; + throw VFException(oss.str()); + } + } + } + replaceActions(act); // reenable actions + return opcode; +} + + +bool VFReader::executeAll () { + in().clear(); // reset all status bits + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand() != 248); // stop reading after post (248) + return true; +} + + +/// Returns true if op indicates the preamble or a font definition +static bool is_pre_or_fontdef (int op) {return op > 242;} +static bool is_chardef (int op) {return op < 243;} + + +bool VFReader::executePreambleAndFontDefs () { + in().clear(); + if (!in()) + return false; + in().seekg(0); // move file pointer to first byte of the input stream + while (!in().eof() && executeCommand(is_pre_or_fontdef) > 242); // stop reading after last font definition + return true; +} + + +bool VFReader::executeCharDefs () { + in().clear(); + if (!in()) + return false; + in().seekg(0); + while (!in().eof() && executeCommand(is_chardef) < 243); // stop reading after last char definition + return true; +} + +////////////////////////////////////////////////////////////////////////////// + +/** Reads and executes DVI preamble command. */ +void VFReader::cmdPre () { + UInt32 i = readUnsigned(1); // identification number (should be 2) + UInt32 k = readUnsigned(1); // length of following comment + string cmt = readString(k); // comment + UInt32 cs = readUnsigned(4); // check sum to be compared with TFM cecksum + UInt32 ds = readUnsigned(4); // design size (same as TFM design size) (fix_word) + designSize = fix2double(ds); + if (i != 202) + throw VFException("invalid identification value in preamble"); + if (actions) + actions->preamble(cmt, cs, ds); +} + + +void VFReader::cmdPost () { + while ((readUnsigned(1)) == 248); // skip fill bytes + if (actions) + actions->postamble(); +} + + +void VFReader::cmdLongChar () { + UInt32 pl = readUnsigned(4); // packet length (length of DVI subroutine) + if (actions) { + UInt32 cc = readUnsigned(4); // character code + readUnsigned(4); // character width from corresponding TFM file + vector<UInt8> *dvi = new vector<UInt8>(pl); // DVI subroutine + readBytes(pl, *dvi); + actions->defineVFChar(cc, dvi); // call template method for user actions + } + else + in().seekg(8+pl, ios::cur); // skip remaining char definition bytes +} + + +/** Reads and executes short_char_x command. + * @param[in] pl packet length (length of DVI subroutine) */ +void VFReader::cmdShortChar (int pl) { + if (actions) { + UInt32 cc = readUnsigned(1); // character code + readUnsigned(3); // character width from corresponding TFM file + vector<UInt8> *dvi = new vector<UInt8>(pl); // DVI subroutine + readBytes(pl, *dvi); + actions->defineVFChar(cc, dvi); // call template method for user actions + } + else + in().seekg(4+pl, ios::cur); // skip char definition bytes +} + + +void VFReader::cmdFontDef (int len) { + UInt32 fontnum = readUnsigned(len); // font number + UInt32 checksum = readUnsigned(4); // font checksum (to be compared with corresponding TFM checksum) + UInt32 ssize = readUnsigned(4); // scaled size of font relative to design size (fix_word) + UInt32 dsize = readUnsigned(4); // design size of font (same as TFM design size) (fix_word) + UInt32 pathlen = readUnsigned(1); // length of font path + UInt32 namelen = readUnsigned(1); // length of font name + string fontpath = readString(pathlen); + string fontname = readString(namelen); + if (actions) { + double ss = fix2double(ssize); + double ds = fix2double(dsize); + actions->defineVFFont(fontnum, fontpath, fontname, checksum, ds, ss*designSize); + } +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.h new file mode 100644 index 00000000000..c9b1df5518a --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VFReader.h @@ -0,0 +1,74 @@ +/************************************************************************* +** VFReader.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef VFREADER_H +#define VFREADER_H + +#include <istream> +#include <map> +#include <stack> +#include <string> +#include "MessageException.h" +#include "StreamReader.h" +#include "types.h" + +using std::istream; +using std::map; +using std::stack; +using std::string; + +struct VFException : public MessageException +{ + VFException (const string &msg) : MessageException(msg) {} +}; + + +class FontManager; +class VFActions; + + +class VFReader : public StreamReader +{ + typedef bool (*ApproveAction)(int); + public: + VFReader (istream &is); + virtual ~VFReader (); + VFActions* replaceActions (VFActions *a); + bool executeAll (); + bool executePreambleAndFontDefs (); + bool executeCharDefs (); + + protected: + int executeCommand (ApproveAction approve=0); + + // the following methods represent the VF commands + // they are called by executeCommand and should not be used directly + void cmdPre (); + void cmdPost (); + void cmdShortChar (int pl); + void cmdLongChar (); + void cmdFontDef (int len); + + private: + VFActions *actions; ///< actions to execute when reading a VF command + double designSize; ///< design size of currently read VF +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VectorStream.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VectorStream.h new file mode 100644 index 00000000000..ea2bf42d968 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/VectorStream.h @@ -0,0 +1,46 @@ +/************************************************************************* +** VectorStream.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef VECTORSTREAM_H +#define VECTORSTREAM_H + +#include <istream> +#include <vector> + + +template <typename T> +struct VectorStreamBuffer : public std::streambuf +{ + VectorStreamBuffer (std::vector<T> &source) { + setg((char*)&source[0], (char*)&source[0], (char*)&source[0]+source.size()); + } +}; + + +template <typename T> +class VectorInputStream : public std::istream +{ + public: + VectorInputStream (std::vector<T> &source) : std::istream(&buf), buf(source) {} + private: + VectorStreamBuffer<T> buf; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocTypeNode.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocTypeNode.h new file mode 100644 index 00000000000..368e33fd170 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocTypeNode.h @@ -0,0 +1,41 @@ +/************************************************************************* +** XMLDocTypeNode.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef XMLDOCTYPENODE_H +#define XMLDOCTYPENODE_H + +#include "XMLNode.h" + +class XMLDocTypeNode : public XMLDeclarationNode +{ + public: + XMLDocTypeNode (const string &rootName, const string &type, const string ¶m) + : XMLDeclarationNode("DOCTYPE", rootName + " " + type + " " + param) {} +}; + + +class XMLEntityNode : public XMLDeclarationNode +{ + public: + XMLEntityNode (const string &n, const string &v) + : XMLDeclarationNode("ENTITY", n + " " + v) {} +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.cpp new file mode 100644 index 00000000000..03ef5b28c98 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.cpp @@ -0,0 +1,100 @@ +/************************************************************************* +** XMLDocument.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "macros.h" +#include "XMLDocument.h" + +using namespace std; + +XMLDocument::XMLDocument (XMLElementNode *root) + : rootElement(root), emitted(false) +{ +} + + +XMLDocument::~XMLDocument () { + clear(); +} + + +void XMLDocument::clear () { + delete rootElement; + rootElement = 0; + FORALL(nodes, list<XMLNode*>::iterator, i) + delete *i; + nodes.clear(); +} + + +void XMLDocument::append (XMLNode *node) { + if (!node) + return; + XMLElementNode *newRoot = dynamic_cast<XMLElementNode*>(node); + if (newRoot) { // there can only be one root element node in the document + delete rootElement; // so if there is already one... + rootElement = newRoot; // ...we replace it + } + else + nodes.push_back(node); +} + + +void XMLDocument::setRootNode (XMLElementNode *root) { + delete rootElement; + rootElement = root; +} + + +ostream& XMLDocument::write (ostream &os) const { + if (rootElement) { // no root element => no output + os << "<?xml version='1.0' encoding='ISO-8859-1'?>\n"; + FORALL(nodes, list<XMLNode*>::const_iterator, i) + (*i)->write(os); + rootElement->write(os); + } + return os; +} + +/** Writes a part of the XML document to the given output stream and removes + * the completely written nodes. The output stops when a stop node is reached + * (this node won't be printed at all). If a node was only partly emitted, i.e. + * its child was the stop node, a further call of emit will continue the output. + * @param[in] os stream to which the output is written + * @param[in] stopElement node where emitting stops (if 0 the whole tree will be emitted) + * @return true if node was completely emitted */ +bool XMLDocument::emit (ostream& os, XMLNode *stopNode) { + if (rootElement) { // no root element => no output + if (!emitted) { + os << "<?xml version='1.0' encoding='ISO-8859-1'?>\n"; + emitted = true; + } + FORALL(nodes, list<XMLNode*>::iterator, i) { + if ((*i)->emit(os, stopNode)) { + list<XMLNode*>::iterator it = i++; // prevent i from being invalidated... + nodes.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + return rootElement->emit(os, stopNode); + } + return true; +} diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.h new file mode 100644 index 00000000000..ce4cbef570f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLDocument.h @@ -0,0 +1,44 @@ +/************************************************************************* +** XMLDocument.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef XMLDOCUMENT_H +#define XMLDOCUMENT_H + +#include "XMLNode.h" + +class XMLDocument +{ + public: + XMLDocument (XMLElementNode *root=0); + ~XMLDocument (); + void clear (); + void append (XMLNode *node); + void setRootNode (XMLElementNode *root); + const XMLElementNode* getRootElement () const {return rootElement;} + ostream& write (ostream &os) const; + bool emit (ostream& os, XMLNode *stopNode); + + private: + list<XMLNode*> nodes; + XMLElementNode *rootElement; + bool emitted; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.cpp new file mode 100644 index 00000000000..f3e79dc2f20 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.cpp @@ -0,0 +1,257 @@ +/************************************************************************* +** XMLNode.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "macros.h" +#include "XMLNode.h" +#include "XMLString.h" + +using namespace std; + +bool XMLNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + write(os); + return true; +} + + +XMLElementNode::XMLElementNode (const string &n) : name(n), emitted(false) { +} + + +XMLElementNode::~XMLElementNode () { + FORALL(children, ElementList::iterator, i) + delete *i; +} + + +void XMLElementNode::addAttribute (const string &name, const string &value) { + attributes[name] = value; +} + + +void XMLElementNode::addAttribute (const string &name, double value) { + attributes[name] = XMLString(value); +} + + +void XMLElementNode::append (XMLNode *child) { + if (!child) + return; + XMLTextNode *textNode1 = dynamic_cast<XMLTextNode*>(child); + if (!textNode1 || children.empty()) + children.push_back(child); + else { + if (XMLTextNode *textNode2 = dynamic_cast<XMLTextNode*>(children.back())) + textNode2->append(textNode1); // merge two consecutive text nodes + else + children.push_back(child); + } +} + + +void XMLElementNode::append (const string &str) { + if (children.empty() || !dynamic_cast<XMLTextNode*>(children.back())) + children.push_back(new XMLTextNode(str)); + else + static_cast<XMLTextNode*>(children.back())->append(str); +} + + +void XMLElementNode::prepend (XMLNode *child) { + if (!child) + return; + XMLTextNode *textNode1 = dynamic_cast<XMLTextNode*>(child); + if (!textNode1 || children.empty()) + children.push_front(child); + else { + if (XMLTextNode *textNode2 = dynamic_cast<XMLTextNode*>(children.back())) + textNode2->prepend(textNode1); // merge two consecutive text nodes + else + children.push_front(child); + } +} + + +ostream& XMLElementNode::write (ostream &os) const { + os << '<' << name; + FORALL(attributes, AttribMap::const_iterator, i) + os << ' ' << i->first << "='" << i->second << '\''; + if (children.empty()) + os << "/>\n"; + else { + os << '>'; + if (dynamic_cast<XMLElementNode*>(children.front())) + os << '\n'; + FORALL(children, ElementList::const_iterator, i) + (*i)->write(os); + os << "</" << name << ">\n"; + } + return os; +} + + +/** Writes a part of the XML tree to the given output stream and removes + * the completely written nodes. The output stops when a stop node is reached + * (this node won't be printed at all). If a node was only partly emitted, i.e. + * its child was the stop node, a further call of emit will continue the output. + * @param[in] os stream to which the output is sent to + * @param[in] stopElement node where emitting stops (if 0 the whole tree will be emitted) + * @return true if node was completely emitted + * */ +bool XMLElementNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + + if (!emitted) { + os << '<' << name; + FORALL(attributes, AttribMap::iterator, i) + os << ' ' << i->first << "='" << i->second << '\''; + if (children.empty()) + os << "/>\n"; + else { + os << '>'; + if (dynamic_cast<XMLElementNode*>(children.front())) + os << '\n'; + } + + emitted = true; + } + if (!children.empty()) { + FORALL(children, ElementList::iterator, i) { + if ((*i)->emit(os, stopNode)) { + ElementList::iterator it = i++; // prevent i from being invalidated... + children.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + os << "</" << name << ">\n"; + } + return true; +} + + +bool XMLElementNode::hasAttribute (const string &name) const { + return attributes.find(name) != attributes.end(); +} + + +////////////////////// + +void XMLTextNode::append (XMLNode *node) { + if (XMLTextNode *tn = dynamic_cast<XMLTextNode*>(node)) + append(tn); + else + delete node; +} + + +void XMLTextNode::append (XMLTextNode *node) { + if (node) + text += node->text; + delete node; +} + + +void XMLTextNode::append (const string &str) { + text += str; +} + + +void XMLTextNode::prepend (XMLNode *node) { + if (XMLTextNode *tn = dynamic_cast<XMLTextNode*>(node)) + prepend(tn); + else + delete node; +} + + +////////////////////// + +XMLDeclarationNode::XMLDeclarationNode (const string &n, const string &p) + : name(n), params(p), emitted(false) +{ +} + + +XMLDeclarationNode::~XMLDeclarationNode () { + FORALL(children, list<XMLDeclarationNode*>::iterator, i) + delete *i; +} + +void XMLDeclarationNode::append (XMLDeclarationNode *child) { + if (child) + children.push_back(child); +} + +ostream& XMLDeclarationNode::write (ostream &os) const { + os << "<!" << name << ' ' << params; + if (children.empty()) + os << ">\n"; + else { + os << "[\n"; + FORALL(children, list<XMLDeclarationNode*>::const_iterator, i) + (*i)->write(os); + os << "]>\n"; + } + return os; +} + + +bool XMLDeclarationNode::emit (ostream &os, XMLNode *stopNode) { + if (this == stopNode) + return false; + + if (!emitted) { + os << "<!" << name << ' ' << params; + if (children.empty()) + os << ">\n"; + else + os << "[\n"; + emitted = true; + } + if (!children.empty()) { + FORALL(children, list<XMLDeclarationNode*>::iterator, i) { + if ((*i)->emit(os, stopNode)) { + list<XMLDeclarationNode*>::iterator it = i++; // prevent i from being invalidated... + children.erase(it); // ... by erase + --i; // @@ what happens if i points to first child? + } + else + return false; + } + os << "]>\n"; + } + return true; + +} + +////////////////////// + +ostream& XMLCDataNode::write (ostream &os) const { + os << "<![CDATA[\n" + << data + << "]]>\n"; + return os; +} + + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.h new file mode 100644 index 00000000000..b44726b65be --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLNode.h @@ -0,0 +1,122 @@ +/************************************************************************* +** XMLNode.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef XMLNODE_H +#define XMLNODE_H + +#include <list> +#include <map> +#include <ostream> +#include <string> + +using std::list; +using std::map; +using std::ostream; +using std::string; + +struct XMLNode +{ + virtual ~XMLNode () {} + virtual ostream& write (ostream &os) const =0; + virtual bool emit (ostream &os, XMLNode *stopElement); + virtual void append (XMLNode *child) {} + virtual void prepend (XMLNode *child) {} +}; + + +class XMLElementNode : public XMLNode +{ + typedef map<string,string> AttribMap; + typedef list<XMLNode*> ElementList; + public: + XMLElementNode (const string &name); + ~XMLElementNode (); + void addAttribute (const string &name, const string &value); + void addAttribute (const string &name, double value); + void append (XMLNode *child); + void append (const string &str); + void prepend (XMLNode *child); + bool hasAttribute (const string &name) const; + ostream& write (ostream &os) const; + bool emit (ostream &os, XMLNode *stopElement); + bool empty () const {return children.empty();} + + private: + string name; // element name (<name a1="v1" .. an="vn">...</name>) + AttribMap attributes; + ElementList children; // child nodes + bool emitted; // true if node has been (partly) emitted +}; + + +class XMLTextNode : public XMLNode +{ + public: + XMLTextNode (const string &str) : text(str) {} + void append (XMLNode *node); + void append (XMLTextNode *node); + void append (const string &str); + void prepend (XMLNode *child); + ostream& write (ostream &os) const {return os << text;} + + private: + string text; +}; + + +class XMLCommentNode : public XMLNode +{ + public: + XMLCommentNode (const string &str) : text(str) {} + ostream& write (ostream &os) const {return os << "<!--" << text << "-->\n";} + + private: + string text; +}; + + +class XMLDeclarationNode : public XMLNode +{ + public: + XMLDeclarationNode (const string &n, const string &p); + ~XMLDeclarationNode (); + void append (XMLDeclarationNode *child); + ostream& write (ostream &os) const; + bool emit (ostream &os, XMLNode *stopElement); + + private: + string name; + string params; + list<XMLDeclarationNode*> children; + bool emitted; +}; + + +class XMLCDataNode : public XMLNode +{ + public: + XMLCDataNode (const string &d) : data(d) {} + ostream& write (ostream &os) const; + + private: + string data; +}; + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.cpp new file mode 100644 index 00000000000..4c1cae32a38 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.cpp @@ -0,0 +1,102 @@ +/************************************************************************* +** XMLString.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 "macros.h" +#include "XMLString.h" + +using namespace std; + +static string translate (unsigned c) { + switch (c) { + case '<' : return "<"; + case '&' : return "&"; + case '"' : return """; + case '\'': return "'"; + } + ostringstream oss; + if (c >= 32 && c <= 126) + oss << char(c); + else + oss <<"&#" << unsigned(c) << ';'; + return oss.str(); +} + + +XMLString::XMLString (const string &str, bool plain) { + if (plain) + *this = str; + else { + FORALL(str, string::const_iterator, i) + *this += translate(*i); + } +} + + +XMLString::XMLString (const char *str, bool plain) { + if (str) { + if (plain) + *this = str; + else { + while (*str) + *this += translate(*str++); + } + } +} + + +XMLString::XMLString (int n, bool cast) { + if (cast) { + stringstream ss; + ss << n; + ss >> *this; + } + else + *this += translate(n); +} + + +XMLString::XMLString (double x) { + stringstream ss; + ss << x; + ss >> *this; +} + + +/* +ostream& XMLString::write (ostream &os) const { + const string *self = static_cast<const string*>(this); + FORALL(*self, string::const_iterator, i) { + unsigned char c = *i; + switch (c) { + case '<' : os << "<"; break; + case '&' : os << "&"; break; + case '"' : os << """; break; + case '\'': os << "'"; break; + default : + if (c >= 32 && c <= 126) + os << c; + else + os << "&#" << int(c) << ';'; + } + } + return os; +} +*/ diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.h new file mode 100644 index 00000000000..f634a473d96 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/XMLString.h @@ -0,0 +1,47 @@ +/************************************************************************* +** XMLString.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef XMLSTRING_H +#define XMLSTRING_H + +#include <ostream> +#include <string> +#include <sstream> +#include "macros.h" + +using std::string; +using std::ostream; +using std::stringstream; + +class XMLString : public string +{ + public: + XMLString () : string() {} + XMLString (const char *str, bool plain=false); + XMLString (const string &str, bool plain=false); + XMLString (int n, bool cast=true); + XMLString (double x); +// ostream& write (ostream &os) const; +}; + + +//IMPLEMENT_OUTPUT_OPERATOR(XMLString) + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/dvisvgm.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/dvisvgm.cpp new file mode 100644 index 00000000000..b51c16d736b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/dvisvgm.cpp @@ -0,0 +1,293 @@ +/************************************************************************* +** dvisvgm.cpp ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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 <fstream> +#include <iostream> +#include <sstream> +#include <string> +#include <sys/timeb.h> +#include <time.h> +#include "gzstream.h" +#include "CommandLine.h" +#include "DVIToSVG.h" +#include "DVIToSVGActions.h" +#include "FileSystem.h" +#include "FontCache.h" +#include "InputReader.h" +#include "Message.h" +#include "FileFinder.h" +#include "PageSize.h" +#include "SpecialManager.h" +#include "StreamCounter.h" +#include "SVGFontTraceEmitter.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#define EMAIL " <" PACKAGE_BUGREPORT ">" +#else +#define EMAIL "Martin Gieseking <martin.gieseking@uos.de>" +#endif + +using namespace std; + + +/** Simple private auto pointer class to simplify pointer handling in main function. */ +template <typename T> +class Pointer +{ + public: + Pointer (T *p=0, bool free=true) : _p(p), _free(free) {} + Pointer (const Pointer &p) : _p(p._p), _free(p._free) {p._p = 0;} + ~Pointer () {if (_free) delete _p;} + T& operator * () {return *_p;} + void operator = (const Pointer &p) {_p=p._p; _free=p._free; p._p=0;} + void release () { + if (_free) delete _p; + _p=0; + } + + private: + mutable T *_p; + bool _free; ///< delete pointer in destructor? +}; + + +static void show_help (const CommandLine &cmd) { + cout << PACKAGE_STRING "\n\n"; + cmd.help(); + cout << "\nCopyright (C) 2005-2009 Martin Gieseking <martin.gieseking@uos.de> \n\n"; +} + + +static string remove_path (string fname) { + fname = FileSystem::adaptPathSeperators(fname); + size_t slashpos = fname.rfind('/'); + if (slashpos == string::npos) + return fname; + return fname.substr(slashpos+1); +} + + +static string ensure_suffix (string fname, const string &suffix) { + size_t dotpos = remove_path(fname).rfind('.'); + if (dotpos == string::npos) { + dotpos = fname.length(); + fname += "."+suffix; + } + return fname; +} + + +static string remove_suffix (string fname) { + size_t dotpos = fname.rfind('.'); + if (dotpos == string::npos) + return fname; + return fname.substr(0, dotpos); +} + + +/** Returns timestamp (wall time) in seconds. */ +static double get_time () { + struct timeb tb; + ftime(&tb); + return tb.time + tb.millitm/1000.0; +} + + +static void set_trans (DVIToSVG &dvisvg, const CommandLine &args) { + ostringstream oss; + if (args.rotate_given()) + oss << 'R' << args.rotate_arg() << ",w/2,h/2"; + if (args.translate_given()) + oss << 'T' << args.translate_arg(); + if (args.scale_given()) + oss << 'S' << args.scale_arg(); + if (args.transform_given()) + oss << args.transform_arg(); + dvisvg.setTransformation(oss.str()); +} + + +static bool set_cache_dir (const CommandLine &args) { + if (args.cache_given() && !args.cache_arg().empty()) { + if (args.cache_arg() == "none") + SVGFontTraceEmitter::CACHE_PATH = 0; + else if (FileSystem::exists(args.cache_arg().c_str())) + SVGFontTraceEmitter::CACHE_PATH = args.cache_arg().c_str(); + else + Message::wstream(true) << "cache directory '" << args.cache_arg() << "' does not exist (caching disabled)" << endl; + } + else { + const char *userdir = FileSystem::userdir(); + if (userdir) { + static string path = userdir; + path += "/.dvisvgm"; + path = FileSystem::adaptPathSeperators(path); + if (!FileSystem::exists(path.c_str())) + FileSystem::mkdir(path.c_str()); + SVGFontTraceEmitter::CACHE_PATH = path.c_str(); + } + if (args.cache_given() && args.cache_arg().empty()) { + cout << "cache directory: " << (SVGFontTraceEmitter::CACHE_PATH ? SVGFontTraceEmitter::CACHE_PATH : "(none)") << endl; + FontCache::fontinfo(SVGFontTraceEmitter::CACHE_PATH, cout); + return false; + } + } + return true; +} + + +static bool check_bbox (const string &bboxstr) { + const char *formats[] = {"none", "min", "dvi", 0}; + for (const char **p=formats; *p; ++p) + if (bboxstr == *p) + return true; + if (isalpha(bboxstr[0])) { + try { + PageSize size(bboxstr); + return true; + } + catch (const PageSizeException &e) { + Message::estream(true) << "invalid bounding box format '" << bboxstr << "'\n"; + return false; + } + } + try { + BoundingBox bbox; + bbox.set(bboxstr); + return true; + } + catch (const MessageException &e) { + Message::estream(true) << e.getMessage() << endl; + return false; + } +} + + +int main (int argc, char *argv[]) { + CommandLine args; + args.parse(argc, argv); + if (args.error()) + return 1; + + if (args.version_given()) { + cout << PACKAGE_STRING "\n"; + return 0; + } + if (args.list_specials_given()) { + DVIToSVG dvisvg(cin, cout); + if (const SpecialManager *sm = dvisvg.setProcessSpecials()) + sm->writeHandlerInfo(cout); + return 0; + } + + if (!set_cache_dir(args)) + return 0; + + if (argc == 1 || args.help_given()) { + show_help(args); + return 0; + } + + if (argc > 1 && args.numFiles() < 1) { + Message::estream(true) << "no input file given" << endl; + return 1; + } + + if (args.progress_given()) + DVIToSVGActions::PROGRESSBAR = args.progress_arg()+1; + + if (args.stdout_given() && args.zip_given()) { + Message::estream(true) << "writing SVGZ files to stdout is not supported\n"; + return 1; + } + if (args.map_file_given()) + FileFinder::setUserFontMap(args.map_file_arg().c_str()); + + if (!check_bbox(args.bbox_arg())) + return 1; + + DVIToSVG::CREATE_STYLE = !args.no_styles_given(); + DVIToSVG::USE_FONTS = !args.no_fonts_given(); + SVGFontTraceEmitter::TRACE_ALL = args.trace_all_given(); + SVGFontTraceEmitter::METAFONT_MAG = args.mag_arg(); + + double start_time = get_time(); + + string dvifile = ensure_suffix(args.file(0), "dvi"); + string svgfile = args.output_given() ? args.output_arg() : remove_suffix(remove_path(dvifile)); + svgfile = ensure_suffix(svgfile, args.zip_given() ? "svgz" : "svg"); + + ifstream ifs(dvifile.c_str(), ios_base::binary|ios_base::in); + if (!ifs) + Message::estream(true) << "can't open file '" << dvifile << "' for reading\n"; + else { + Pointer<ostream> out; + if (args.stdout_given()) + out = Pointer<ostream>(&cout, false); + else if (args.zip_given()) + out = Pointer<ostream>(new ogzstream(svgfile.c_str(), args.zip_arg())); + else + out = Pointer<ostream>(new ofstream(svgfile.c_str(), ios_base::binary)); + + if (!*out) + Message::estream(true) << "can't open file '" << svgfile << "' for writing\n"; + else { + StreamCounter<char> sc(*out); + Message::level = args.verbosity_arg(); + DVIToSVG dvisvg(ifs, *out); + const char *ignore_specials = args.no_specials_given() ? (args.no_specials_arg().empty() ? "*" : args.no_specials_arg().c_str()) : 0; + dvisvg.setProcessSpecials(ignore_specials); + set_trans(dvisvg, args); + dvisvg.setPageSize(args.bbox_arg()); + + try { + FileFinder::init(argv[0], !args.no_mktexmf_given()); + if (int pages = dvisvg.convert(args.page_arg(), args.page_arg())) { + if (!args.stdout_given()) + sc.invalidate(); // output buffer is no longer valid + // valgrind issues an invalid conditional jump/move in the deflate function of libz here. + // According to libz FAQ #36 this is not a bug but intended behavior. + out.release(); // force writing + const char *pstr = pages == 1 ? "" : "s"; + UInt64 nbytes = args.stdout_given() ? sc.count() : FileSystem::filesize(svgfile); + Message::mstream() << "1 "; + if (pages > 1) + Message::mstream() << "of " << pages << " "; + Message::mstream() << "page" << pstr << " written to " + << (args.stdout_given() ? "<stdout>" : svgfile) + << " (" << nbytes << " bytes"; + if (args.zip_given()) + Message::mstream() << " = " << floor(double(nbytes)/sc.count()*100.0+0.5) << "%"; + Message::mstream() << ") in " << (get_time()-start_time) << " seconds\n"; + } + } + catch (DVIException &e) { + Message::estream() << "DVI error: " << e.getMessage() << endl; + } + catch (MessageException &e) { + Message::estream(true) << e.getMessage() << endl; + } + } + } + return 0; +} + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.cpp b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.cpp new file mode 100644 index 00000000000..1712c1e113b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.cpp @@ -0,0 +1,170 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.C +// Revision : $Revision: 1.3 $ +// Revision_date : $Date: 2006/01/05 16:22:35 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#include "gzstream.h" +#include <iostream> +#include <string.h> // for memcpy + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See header file for user classes. +// ---------------------------------------------------------------------------- + +// -------------------------------------- +// class gzstreambuf: +// -------------------------------------- + +gzstreambuf* gzstreambuf::open(const char* name, int compression_level, int open_mode) { + if ( is_open()) + return (gzstreambuf*)0; + mode = open_mode; + // no append nor read/write mode + if ((mode & std::ios::ate) || (mode & std::ios::app) + || ((mode & std::ios::in) && (mode & std::ios::out))) + return (gzstreambuf*)0; + if (compression_level < 1) + compression_level = 1; + else if (compression_level > 9) + compression_level = 9; + char fmode[10]; + char* fmodeptr = fmode; + if ( mode & std::ios::in) + *fmodeptr++ = 'r'; + else if ( mode & std::ios::out) + *fmodeptr++ = 'w'; + *fmodeptr++ = 'b'; + *fmodeptr++ = '0'+compression_level; + *fmodeptr = '\0'; + file = gzopen( name, fmode); + if (file == 0) + return (gzstreambuf*)0; + opened = 1; + return this; +} + +gzstreambuf * gzstreambuf::close() { + if ( is_open()) { + sync(); + opened = 0; + if ( gzclose( file) == Z_OK) + return this; + } + return (gzstreambuf*)0; +} + +int gzstreambuf::underflow() { // used for input buffer only + if ( gptr() && ( gptr() < egptr())) + return * reinterpret_cast<unsigned char *>( gptr()); + + if ( ! (mode & std::ios::in) || ! opened) + return EOF; + // Josuttis' implementation of inbuf + int n_putback = gptr() - eback(); + if ( n_putback > 4) + n_putback = 4; + memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback); + + int num = gzread( file, buffer+4, bufferSize-4); + if (num <= 0) // ERROR or EOF + return EOF; + + // reset buffer pointers + setg( buffer + (4 - n_putback), // beginning of putback area + buffer + 4, // read position + buffer + 4 + num); // end of buffer + + // return next character + return * reinterpret_cast<unsigned char *>( gptr()); +} + +int gzstreambuf::flush_buffer() { + // Separate the writing of the buffer from overflow() and + // sync() operation. + int w = pptr() - pbase(); + if ( gzwrite( file, pbase(), w) != w) + return EOF; + pbump( -w); + return w; +} + +int gzstreambuf::overflow( int c) { // used for output buffer only + if ( ! ( mode & std::ios::out) || ! opened) + return EOF; + if (c != EOF) { + *pptr() = c; + pbump(1); + } + if ( flush_buffer() == EOF) + return EOF; + return c; +} + +int gzstreambuf::sync() { + // Changed to use flush_buffer() instead of overflow( EOF) + // which caused improper behavior with std::endl and flush(), + // bug reported by Vincent Ricard. + if ( pptr() && pptr() > pbase()) { + if ( flush_buffer() == EOF) + return -1; + } + return 0; +} + +// -------------------------------------- +// class gzstreambase: +// -------------------------------------- + +gzstreambase::gzstreambase( const char* name, int compression_level, int mode) { + init( &buf); + open( name, compression_level, mode); +} + +gzstreambase::~gzstreambase() { + buf.close(); +} + +void gzstreambase::open( const char* name, int compression_level, int open_mode) { + if ( ! buf.open( name, compression_level, open_mode)) + clear( rdstate() | std::ios::badbit); +} + +void gzstreambase::close() { + if ( buf.is_open()) + if ( ! buf.close()) + clear( rdstate() | std::ios::badbit); +} + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +// ============================================================================ +// EOF // diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.h new file mode 100644 index 00000000000..bca84f1b4e8 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/gzstream.h @@ -0,0 +1,121 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.h +// Revision : $Revision: 1.3 $ +// Revision_date : $Date: 2006/01/05 16:22:35 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#ifndef GZSTREAM_H +#define GZSTREAM_H 1 + +// standard C++ with new header file names and std:: namespace +#include <iostream> +#include <fstream> +#include <zlib.h> + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See below for user classes. +// ---------------------------------------------------------------------------- + +class gzstreambuf : public std::streambuf { +private: + static const int bufferSize = 47+256; // size of data buff + // totals 512 bytes under g++ for igzstream at the end. + + gzFile file; // file handle for compressed file + char buffer[bufferSize]; // data buffer + char opened; // open/close state of stream + int mode; // I/O mode + + int flush_buffer(); +public: + gzstreambuf() : opened(0) { + setp( buffer, buffer + (bufferSize-1)); + setg( buffer + 4, // beginning of putback area + buffer + 4, // read position + buffer + 4); // end position + // ASSERT: both input & output capabilities will not be used together + } + int is_open() { return opened; } + gzstreambuf* open(const char* name, int compression_level, int open_mode); + gzstreambuf* close(); + ~gzstreambuf() { close(); } + + virtual int overflow( int c = EOF); + virtual int underflow(); + virtual int sync(); +}; + +class gzstreambase : virtual public std::ios { +protected: + gzstreambuf buf; +public: + gzstreambase() { init(&buf); } + gzstreambase( const char* name, int compression_level, int open_mode); + ~gzstreambase(); + void open( const char* name, int compression_level, int open_mode); + void close(); + gzstreambuf* rdbuf() { return &buf; } +}; + +// ---------------------------------------------------------------------------- +// User classes. Use igzstream and ogzstream analogously to ifstream and +// ofstream respectively. They read and write files based on the gz* +// function interface of the zlib. Files are compatible with gzip compression. +// ---------------------------------------------------------------------------- + +class igzstream : public gzstreambase, public std::istream { +public: + igzstream() : std::istream( &buf) {} + igzstream( const char* name, int compression_level, int open_mode = std::ios::in) + : gzstreambase(name, compression_level, open_mode), std::istream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int compression_level, int open_mode = std::ios::in) { + gzstreambase::open( name, compression_level, open_mode); + } +}; + +class ogzstream : public gzstreambase, public std::ostream { +public: + ogzstream() : std::ostream( &buf) {} + ogzstream( const char* name, int compression_level, int mode = std::ios::out) + : gzstreambase(name, compression_level, mode), std::ostream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int compression_level, int open_mode = std::ios::out) { + gzstreambase::open(name, compression_level, open_mode); + } +}; + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +#endif // GZSTREAM_H +// ============================================================================ +// EOF // + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/iapi.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/iapi.h new file mode 100644 index 00000000000..8e29d938d03 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/iapi.h @@ -0,0 +1,300 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id: iapi.h 9043 2008-08-28 22:48:19Z giles $ */ + +/* + * Public API for Ghostscript interpreter + * for use both as DLL and for static linking. + * + * Should work for Windows, OS/2, Linux, Mac. + * + * DLL exported functions should be as similar as possible to imain.c + * You will need to include "ierrors.h". + * + * Current problems: + * 1. Ghostscript does not support multiple instances. + * 2. Global variables in gs_main_instance_default() + * and gsapi_instance_counter + */ + +/* Exported functions may need different prefix + * GSDLLEXPORT marks functions as exported + * GSDLLAPI is the calling convention used on functions exported + * by Ghostscript + * GSDLLCALL is used on callback functions called by Ghostscript + * When you include this header file in the caller, you may + * need to change the definitions by defining these + * before including this header file. + * Make sure you get the calling convention correct, otherwise your + * program will crash either during callbacks or soon after returning + * due to stack corruption. + */ + +#ifndef iapi_INCLUDED +# define iapi_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WINDOWS_) || defined(__WINDOWS__) +# ifndef _Windows +# define _Windows +# endif +#endif + +#ifdef _Windows +# ifndef GSDLLEXPORT +# define GSDLLEXPORT __declspec(dllexport) +# endif +# ifndef GSDLLAPI +# define GSDLLAPI __stdcall +# endif +# ifndef GSDLLCALL +# define GSDLLCALL __stdcall +# endif +#endif /* _Windows */ + +#if defined(OS2) && defined(__IBMC__) +# ifndef GSDLLAPI +# define GSDLLAPI _System +# endif +# ifndef GSDLLCALL +# define GSDLLCALL _System +# endif +#endif /* OS2 && __IBMC */ + +#ifdef __MACOS__ +# pragma export on +#endif + +#ifndef GSDLLEXPORT +# define GSDLLEXPORT +#endif +#ifndef GSDLLAPI +# define GSDLLAPI +#endif +#ifndef GSDLLCALL +# define GSDLLCALL +#endif + +#if defined(__IBMC__) +# define GSDLLAPIPTR * GSDLLAPI +# define GSDLLCALLPTR * GSDLLCALL +#else +# define GSDLLAPIPTR GSDLLAPI * +# define GSDLLCALLPTR GSDLLCALL * +#endif + +#ifndef display_callback_DEFINED +# define display_callback_DEFINED +typedef struct display_callback_s display_callback; +#endif + +typedef struct gsapi_revision_s { + const char *product; + const char *copyright; + long revision; + long revisiondate; +} gsapi_revision_t; + + +/* Get version numbers and strings. + * This is safe to call at any time. + * You should call this first to make sure that the correct version + * of the Ghostscript is being used. + * pr is a pointer to a revision structure. + * len is the size of this structure in bytes. + * Returns 0 if OK, or if len too small (additional parameters + * have been added to the structure) it will return the required + * size of the structure. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_revision(gsapi_revision_t *pr, int len); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * If you try to create two instances, the second attempt + * will return < 0 and set pinstance to NULL. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Create a new instance of Ghostscript. + * This instance is passed to most other API functions. + * The caller_handle will be provided to callback functions. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_new_instance(void **pinstance, void *caller_handle); + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * Ghostscript supports only one instance. + * The current implementation uses a global static instance + * counter to make sure that only a single instance is used. + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ +/* Destroy an instance of Ghostscript + * Before you call this, Ghostscript must have finished. + * If Ghostscript has been initialised, you must call gsapi_exit() + * before gsapi_delete_instance. + */ +GSDLLEXPORT void GSDLLAPI +gsapi_delete_instance(void *instance); + +/* Set the callback functions for stdio + * The stdin callback function should return the number of + * characters read, 0 for EOF, or -1 for error. + * The stdout and stderr callback functions should return + * the number of characters written. + * If a callback address is NULL, the real stdio will be used. + */ +GSDLLEXPORT int GSDLLAPI +gsapi_set_stdio(void *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); + +/* Set the callback function for polling. + * This is used for handling window events or cooperative + * multitasking. This function will only be called if + * Ghostscript was compiled with CHECK_INTERRUPTS + * as described in gpcheck.h. + * The polling function should return 0 if all is well, + * and negative if it wants ghostscript to abort. + * The polling function must be fast. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_poll(void *instance, + int (GSDLLCALLPTR poll_fn)(void *caller_handle)); + +/* Set the display device callback structure. + * If the display device is used, this must be called + * after gsapi_new_instance() and before gsapi_init_with_args(). + * See gdevdisp.h for more details. + */ +GSDLLEXPORT int GSDLLAPI gsapi_set_display_callback( + void *instance, display_callback *callback); + + +/* Initialise the interpreter. + * This calls gs_main_init_with_args() in imainarg.c + * 1. If quit or EOF occur during gsapi_init_with_args(), + * the return value will be e_Quit. This is not an error. + * You must call gsapi_exit() and must not call any other + * gsapi_XXX functions. + * 2. If usage info should be displayed, the return value will be e_Info + * which is not an error. Do not call gsapi_exit(). + * 3. Under normal conditions this returns 0. You would then + * call one or more gsapi_run_*() functions and then finish + * with gsapi_exit(). + */ +GSDLLEXPORT int GSDLLAPI gsapi_init_with_args(void *instance, + int argc, char **argv); + +/* + * The gsapi_run_* functions are like gs_main_run_* except + * that the error_object is omitted. + * If these functions return <= -100, either quit or a fatal + * error has occured. You then call gsapi_exit() next. + * The only exception is gsapi_run_string_continue() + * which will return e_NeedInput if all is well. + */ + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_begin(void *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_continue(void *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_end(void *instance, + int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string_with_length(void *instance, + const char *str, unsigned int length, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_string(void *instance, + const char *str, int user_errors, int *pexit_code); + +GSDLLEXPORT int GSDLLAPI +gsapi_run_file(void *instance, + const char *file_name, int user_errors, int *pexit_code); + + +/* Exit the interpreter. + * This must be called on shutdown if gsapi_init_with_args() + * has been called, and just before gsapi_delete_instance(). + */ +GSDLLEXPORT int GSDLLAPI +gsapi_exit(void *instance); + +/* Visual Tracer */ +/* This function is only for debug purpose clients */ +struct vd_trace_interface_s; +GSDLLEXPORT void GSDLLAPI +gsapi_set_visual_tracer(struct vd_trace_interface_s *I); + + +/* function prototypes */ +typedef int (GSDLLAPIPTR PFN_gsapi_revision)( + gsapi_revision_t *pr, int len); +typedef int (GSDLLAPIPTR PFN_gsapi_new_instance)( + void **pinstance, void *caller_handle); +typedef void (GSDLLAPIPTR PFN_gsapi_delete_instance)( + void *instance); +typedef int (GSDLLAPIPTR PFN_gsapi_set_stdio)(void *instance, + int (GSDLLCALLPTR stdin_fn)(void *caller_handle, char *buf, int len), + int (GSDLLCALLPTR stdout_fn)(void *caller_handle, const char *str, int len), + int (GSDLLCALLPTR stderr_fn)(void *caller_handle, const char *str, int len)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_poll)(void *instance, + int(GSDLLCALLPTR poll_fn)(void *caller_handle)); +typedef int (GSDLLAPIPTR PFN_gsapi_set_display_callback)( + void *instance, display_callback *callback); +typedef int (GSDLLAPIPTR PFN_gsapi_init_with_args)( + void *instance, int argc, char **argv); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_begin)( + void *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_continue)( + void *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_end)( + void *instance, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string_with_length)( + void *instance, const char *str, unsigned int length, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_string)( + void *instance, const char *str, + int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_run_file)(void *instance, + const char *file_name, int user_errors, int *pexit_code); +typedef int (GSDLLAPIPTR PFN_gsapi_exit)(void *instance); +typedef void (GSDLLAPIPTR PFN_gsapi_set_visual_tracer) + (struct vd_trace_interface_s *I); + + +#ifdef __MACOS__ +#pragma export off +#endif + +#ifdef __cplusplus +} /* extern 'C' protection */ +#endif + +#endif /* iapi_INCLUDED */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ierrors.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ierrors.h new file mode 100644 index 00000000000..3184341177e --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/ierrors.h @@ -0,0 +1,153 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ + +/* $Id: ierrors.h 8022 2007-06-05 22:23:38Z giles $ */ +/* Definition of error codes */ + +#ifndef ierrors_INCLUDED +# define ierrors_INCLUDED + +/* + * DO NOT USE THIS FILE IN THE GRAPHICS LIBRARY. + * THIS FILE IS PART OF THE POSTSCRIPT INTERPRETER. + * USE gserrors.h IN THE LIBRARY. + */ + +/* + * A procedure that may return an error always returns + * a non-negative value (zero, unless otherwise noted) for success, + * or negative for failure. + * We use ints rather than an enum to avoid a lot of casting. + */ + +/* Define the error name table */ +extern const char *const gs_error_names[]; + + /* ------ PostScript Level 1 errors ------ */ + +#define e_unknownerror (-1) /* unknown error */ +#define e_dictfull (-2) +#define e_dictstackoverflow (-3) +#define e_dictstackunderflow (-4) +#define e_execstackoverflow (-5) +#define e_interrupt (-6) +#define e_invalidaccess (-7) +#define e_invalidexit (-8) +#define e_invalidfileaccess (-9) +#define e_invalidfont (-10) +#define e_invalidrestore (-11) +#define e_ioerror (-12) +#define e_limitcheck (-13) +#define e_nocurrentpoint (-14) +#define e_rangecheck (-15) +#define e_stackoverflow (-16) +#define e_stackunderflow (-17) +#define e_syntaxerror (-18) +#define e_timeout (-19) +#define e_typecheck (-20) +#define e_undefined (-21) +#define e_undefinedfilename (-22) +#define e_undefinedresult (-23) +#define e_unmatchedmark (-24) +#define e_VMerror (-25) /* must be the last Level 1 error */ + +#define LEVEL1_ERROR_NAMES\ + "unknownerror", "dictfull", "dictstackoverflow", "dictstackunderflow",\ + "execstackoverflow", "interrupt", "invalidaccess", "invalidexit",\ + "invalidfileaccess", "invalidfont", "invalidrestore", "ioerror",\ + "limitcheck", "nocurrentpoint", "rangecheck", "stackoverflow",\ + "stackunderflow", "syntaxerror", "timeout", "typecheck", "undefined",\ + "undefinedfilename", "undefinedresult", "unmatchedmark", "VMerror" + + /* ------ Additional Level 2 errors (also in DPS) ------ */ + +#define e_configurationerror (-26) +#define e_undefinedresource (-27) +#define e_unregistered (-28) + +#define LEVEL2_ERROR_NAMES\ + "configurationerror", "undefinedresource", "unregistered" + + /* ------ Additional DPS errors ------ */ + +#define e_invalidcontext (-29) +/* invalidid is for the NeXT DPS extension. */ +#define e_invalidid (-30) + +#define DPS_ERROR_NAMES\ + "invalidcontext", "invalidid" + +#define ERROR_NAMES\ + LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES, DPS_ERROR_NAMES + + /* ------ Pseudo-errors used internally ------ */ + +/* + * Internal code for a fatal error. + * gs_interpret also returns this for a .quit with a positive exit code. + */ +#define e_Fatal (-100) + +/* + * Internal code for the .quit operator. + * The real quit code is an integer on the operand stack. + * gs_interpret returns this only for a .quit with a zero exit code. + */ +#define e_Quit (-101) + +/* + * Internal code for a normal exit from the interpreter. + * Do not use outside of interp.c. + */ +#define e_InterpreterExit (-102) + +/* + * Internal code that indicates that a procedure has been stored in the + * remap_proc of the graphics state, and should be called before retrying + * the current token. This is used for color remapping involving a call + * back into the interpreter -- inelegant, but effective. + */ +#define e_RemapColor (-103) + +/* + * Internal code to indicate we have underflowed the top block + * of the e-stack. + */ +#define e_ExecStackUnderflow (-104) + +/* + * Internal code for the vmreclaim operator with a positive operand. + * We need to handle this as an error because otherwise the interpreter + * won't reload enough of its state when the operator returns. + */ +#define e_VMreclaim (-105) + +/* + * Internal code for requesting more input from run_string. + */ +#define e_NeedInput (-106) + +/* + * Internal code for a normal exit when usage info is displayed. + * This allows Window versions of Ghostscript to pause until + * the message can be read. + */ +#define e_Info (-110) + +/* + * Define which error codes require re-executing the current object. + */ +#define ERROR_IS_INTERRUPT(ecode)\ + ((ecode) == e_interrupt || (ecode) == e_timeout) + +#endif /* ierrors_INCLUDED */ diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/macros.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/macros.h new file mode 100644 index 00000000000..9a276dd33d6 --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/macros.h @@ -0,0 +1,45 @@ +/************************************************************************* +** macros.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef MACROS_H +#define MACROS_H + +#define FORALL(container, itertype, itervar) \ + for (itertype itervar=(container).begin(); itervar != (container).end(); ++itervar) + +#define IMPLEMENT_ARITHMETIC_OPERATOR(class, op) \ + inline class operator op (class a, const class &b) { \ + return a op##= b; \ + } + +#define IMPLEMENT_ARITHMETIC_OPERATOR2(class, scalar, op) \ + inline class operator op (class a, scalar b) { \ + return a op##= b; \ + } + +#define IMPLEMENT_OUTPUT_OPERATOR(class) \ + inline std::ostream& operator << (std::ostream &os, class obj) { \ + return obj.write(os); \ + } + +#include <iostream> +#define SHOW(x) std::cerr << __FILE__ ", " << __LINE__ << ": " << #x << "=" << (x) << std::endl + +#endif diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/options.xml b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/options.xml new file mode 100644 index 00000000000..2445c49150b --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/options.xml @@ -0,0 +1,121 @@ +<?xml version="1.0"?> +<!-- ********************************************************************* +** options.xml ** +** ** +** This file is part of dvisvgm - the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +***********************************************************************--> + +<cmdline class="CommandLine"> + <program> + <name>dvisvgm</name> + <usage>[options] dvifile</usage> + <description>This program converts DVI files, as created by TeX/LaTeX to\nthe XML-based scalable vector graphics format SVG.</description> + </program> + <options> + <section title="Input options"> + <option long="page" short="p"> + <arg type="unsigned" name="number" default="1"/> + <description>choose page to convert</description> + </option> + <option long="map-file" short="m"> + <arg type="string" name="[+]filename"/> + <description>set [additional] font map file name</description> + </option> + </section> + <section title="SVG output options"> + <option long="bbox" short="b"> + <arg type="string" name="fmt" default="min"/> + <description>set format or size of bounding box</description> + </option> + <option long="output" short="o"> + <arg type="string" name="filename"/> + <description>set name of output file</description> + </option> + <option long="stdout" short="s"> + <description>write SVG output to stdout</description> + </option> + <option long="no-fonts" short="n"> + <description>draw glyphs by using path elements</description> + </option> + <option long="no-styles"> + <description>don't use styles to reference fonts</description> + </option> + <option long="zip" short="z"> + <arg type="int" name="level" default="9" optional="yes"/> + <description>create compressed .svgz file</description> + </option> + </section> + <section title="SVG transformations"> + <option long="rotate" short="r"> + <arg type="double" name="angle"/> + <description>rotate page content clockwise</description> + </option> + <option long="scale" short="c"> + <arg type="string" name="sx[,sy]"/> + <description>scale page content</description> + </option> + <option long="translate" short="t"> + <arg type="string" name="tx[,ty]"/> + <description>shift page content</description> + </option> + <option long="transform" short="T"> + <arg type="string" name="commands"/> + <description>transform page content</description> + </option> + </section> + <section title="Processing options"> + <option long="cache" short="C"> + <arg type="string" name="dir" optional="yes"/> + <description>set/print path of cache directory</description> + </option> + <option long="mag" short="M"> + <arg type="double" name="factor" default="4"/> + <description>magnification of Metafont output</description> + </option> + <option long="no-mktexmf"> + <description>don't try to create missing fonts</description> + </option> + <option long="no-specials" short="S"> + <arg type="string" name="prefixes" optional="yes"/> + <description>don't process [selected] specials</description> + </option> + <option long="trace-all" short="a"> + <description>trace all glyphs of used bitmap fonts</description> + </option> + </section> + <section title="Message options"> + <option long="help" short="h"> + <description>print this help and exit</description> + </option> + <option long="list-specials" short="l"> + <description>print supported special sets and exit</description> + </option> + <option long="progress" short="P"> + <arg type="unsigned" name="skip" default="100" optional="yes"/> + <description>enable progess indicator</description> + </option> + <option long="verbosity" short="v"> + <arg type="unsigned" name="level" default="7"/> + <description>set verbosity level (0-7)</description> + </option> + <option long="version" short="V"> + <description>print version and exit</description> + </option> + </section> + </options> +</cmdline> + diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/psdefs.psc b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/psdefs.psc new file mode 100644 index 00000000000..25a7d59c3fa --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/psdefs.psc @@ -0,0 +1,56 @@ +/************************************************************************* +** psdefs.psc ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +const char *PSInterpreter::PSDEFS = +"3 dict dup begin/Install{matrix setmatrix}def/HWResolution[72.27 72.27]def/PageS" +"ize[10000 10000]def end setpagedevice/:gsave systemdict/gsave get def/:grestore " +"systemdict/grestore get def/@dodraw true store/prval{dup type/stringtype eq{prin" +"t}{30 string cvs print}ifelse}def/prseq{-1 1{-1 roll prval( )print}for(\\n)print" +"}def/prcmd{( )exch(\\ndvi.)3{print}repeat prseq}def/cvxall{{cvx}forall}def/sysex" +"ec{systemdict exch get exec}def/defpr{[exch[/copy systemdict]cvxall 5 -1 roll du" +"p 6 1 roll[/get/exec]cvxall 6 -1 roll dup 7 1 roll 4 -1 roll dup 5 1 roll dup le" +"ngth string cvs/prcmd cvx]cvx def}def errordict begin/nocurrentpoint{pop false}d" +"ef end/setpos{currentpoint dup type cvlit/booleantype eq{pop}{2(setpos)prcmd}ife" +"lse}def/prpath{{2(moveto)prcmd}{2(lineto)prcmd}{6(curveto)prcmd}{0(closepath)prc" +"md}pathforall}def/charpath{/@dodraw false store/charpath sysexec/@dodraw true st" +"ore}def/show{@dodraw{true charpath eofill 0(show)prcmd}if}def/stroke{@dodraw{0(n" +"ewpath)prcmd prpath 0(stroke)prcmd newpath}{/stroke sysexec}ifelse}def/fill{@dod" +"raw{0(newpath)prcmd prpath 0(fill)prcmd newpath}{/fill sysexec}ifelse}def/eofill" +"{@dodraw{0(newpath)prcmd prpath 0(eofill)prcmd newpath}{/eofill sysexec}ifelse}d" +"ef/clip{/clip sysexec 0(newpath)prcmd prpath 0(clip)prcmd}def/eoclip{/eoclip sys" +"exec 0(newpath)prcmd prpath 0(eoclip)prcmd}def/initclip 0 defpr/adddot{dup lengt" +"h 1 add string dup 0 46 put dup 3 -1 roll 1 exch putinterval}def/setlinewidth 1 " +"defpr/setlinecap 1 defpr/setlinejoin 1 defpr/setmiterlimit 1 defpr/setdash{mark " +"3 1 roll 2 copy/setdash sysexec exch aload length 1 add -1 roll counttomark(setd" +"ash)prcmd pop}def/gsave 0 defpr/grestore{:grestore currentlinewidth 1(setlinewid" +"th)prcmd currentlinecap 1(setlinecap)prcmd currentlinejoin 1(setlinejoin)prcmd c" +"urrentmiterlimit 1(setmiterlimit)prcmd currentrgbcolor 3(setrgbcolor)prcmd 6 arr" +"ay currentmatrix aload pop 6(setmatrix)prcmd currentdash mark 3 1 roll exch aloa" +"d length 1 add -1 roll counttomark(setdash)prcmd pop 0(grestore)prcmd}def/rotate" +"{dup type/arraytype ne{dup 1(rotate)prcmd}if/rotate sysexec}def/scale{dup type/a" +"rraytype ne{2 copy 2(scale)prcmd}if/scale sysexec}def/translate{dup type/arrayty" +"pe ne{2 copy 2(translate)prcmd}if/translate sysexec}def/setmatrix{dup/setmatrix " +"sysexec aload pop 6(setmatrix)prcmd}def/initmatrix{matrix setmatrix}def/concat{m" +"atrix currentmatrix matrix concatmatrix setmatrix}def/setgray 1 defpr/setcmykcol" +"or 4 defpr/sethsbcolor 3 defpr/setrgbcolor 3 defpr/.handleerror errordict/handle" +"error get def errordict begin/handleerror{0(beginerror)prcmd .handleerror 0(ende" +"rror)prcmd}.bind def end "; + +// vim: set syntax=cpp: diff --git a/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/types.h b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/types.h new file mode 100644 index 00000000000..1fc3e24359f --- /dev/null +++ b/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/types.h @@ -0,0 +1,84 @@ +/************************************************************************* +** types.h ** +** ** +** This file is part of dvisvgm -- the DVI to SVG converter ** +** Copyright (C) 2005-2009 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/>. ** +*************************************************************************/ + +#ifndef TYPES_H +#define TYPES_H + +namespace internal { + template<unsigned BYTES> + class ERROR_inttype_not_available + { + ERROR_inttype_not_available(); + }; + + template<bool FIRST, typename A, typename B> + struct select + { + typedef A T; + }; + + template<typename A, typename B> + struct select<false, A, B> + { + typedef B T; + }; +} + + +// Retrieves a signed integer type with sizeof(T) == BYTES +template<unsigned BYTES, bool SIGNED> +struct int_t +{ + typedef typename internal::select<sizeof(signed char) == BYTES, signed char, + typename internal::select<sizeof(signed short) == BYTES, signed short, + typename internal::select<sizeof(signed int) == BYTES, signed int, + typename internal::select<sizeof(signed long) == BYTES, signed long, + typename internal::select<sizeof(signed long long) == BYTES, signed long long, + internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T; +}; + + +// Retrieves an unsigned integer type with sizeof(T) == BYTES +template<unsigned BYTES> +struct int_t<BYTES, false> +{ + typedef typename internal::select<sizeof(unsigned char) == BYTES, unsigned char, + typename internal::select<sizeof(unsigned short) == BYTES, unsigned short, + typename internal::select<sizeof(unsigned int) == BYTES, unsigned int, + typename internal::select<sizeof(unsigned long) == BYTES, unsigned long, + typename internal::select<sizeof(unsigned long long) == BYTES, unsigned long long, + internal::ERROR_inttype_not_available<BYTES> >::T>::T>::T>::T>::T T; +}; + + +// Machine independent definition of sized integer types +typedef int_t<1, true>::T Int8; +typedef int_t<2, true>::T Int16; +typedef int_t<4, true>::T Int32; +typedef int_t<8, true>::T Int64; +typedef int_t<1, false>::T UInt8; +typedef int_t<2, false>::T UInt16; +typedef int_t<4, false>::T UInt32; +typedef int_t<8, false>::T UInt64; + +typedef Int32 FixWord; +typedef UInt32 ScaledInt; + +#endif |