diff options
Diffstat (limited to 'Build/source/texk/dvisvgm/dvisvgm-1.0.1/src/SVGTree.cpp')
-rw-r--r-- | Build/source/texk/dvisvgm/dvisvgm-1.0.1/src/SVGTree.cpp | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/Build/source/texk/dvisvgm/dvisvgm-1.0.1/src/SVGTree.cpp b/Build/source/texk/dvisvgm/dvisvgm-1.0.1/src/SVGTree.cpp deleted file mode 100644 index c1af13f4f3a..00000000000 --- a/Build/source/texk/dvisvgm/dvisvgm-1.0.1/src/SVGTree.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/************************************************************************* -** SVGTree.cpp ** -** ** -** This file is part of dvisvgm -- the DVI to SVG converter ** -** Copyright (C) 2005-2010 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 <string> -#include "BoundingBox.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; - - -// static class variables -bool SVGTree::CREATE_STYLE=true; -bool SVGTree::USE_FONTS=true; - - -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] font font to be used */ -void SVGTree::appendChar (int c, double x, double y, const Font &font) { - XMLElementNode *node=_span; - if (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(font.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::instance().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 (USE_FONTS) { - const Font *font = _font.get(); - if (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()); -} - - -/** Creates an SVG element for a single glyph. - * @param[in] c character number - * @param[in] font font to extract the glyph from - * @return pointer to element node if glyph exists, 0 otherwise */ -static XMLElementNode* createGlyphNode (int c, const PhysicalFont &font, GFGlyphTracer::Callback *cb) { - Glyph glyph; - if (!font.getGlyph(c, glyph, cb)) - return 0; - - double sx=1.0, sy=1.0; - double upem = font.unitsPerEm(); - XMLElementNode *glyph_node=0; - if (SVGTree::USE_FONTS) { - glyph_node = new XMLElementNode("glyph"); - glyph_node->addAttribute("unicode", XMLString(font.unicode(c), false)); - glyph_node->addAttribute("horiz-adv-x", XMLString(font.hAdvance(c))); - string name = font.glyphName(c); - if (!name.empty()) - glyph_node->addAttribute("glyph-name", name); - } - else { - ostringstream oss; - oss << 'g' << FontManager::instance().fontID(&font) << c; - glyph_node = new XMLElementNode("path"); - glyph_node->addAttribute("id", oss.str()); - sx = font.scaledSize()/upem; - sy = -sx; - } - ostringstream oss; - glyph.writeSVG(oss, sx, sy); - glyph_node->addAttribute("d", oss.str()); - return glyph_node; -} - - -void SVGTree::appendFontStyles (const set<const Font*> &fonts) { - if (CREATE_STYLE && USE_FONTS && !fonts.empty() && _defs) { - XMLElementNode *styleNode = new XMLElementNode("style"); - styleNode->addAttribute("type", "text/css"); - _root->insertAfter(styleNode, _defs); - typedef map<int, const Font*> SortMap; - SortMap sortmap; - FORALL(fonts, set<const Font*>::const_iterator, it) - if (!dynamic_cast<const VirtualFont*>(*it)) // skip virtual fonts - sortmap[FontManager::instance().fontID(*it)] = *it; - ostringstream style; - // add font style definitions in ascending order - FORALL(sortmap, SortMap::const_iterator, it) { - style << "text.f" << it->first << ' ' - << "{font-family:" << it->second->name() - << ";font-size:" << it->second->scaledSize() << "}\n"; - } - XMLCDataNode *cdata = new XMLCDataNode(style.str()); - styleNode->append(cdata); - } -} - - -/** Appends glyph definitions of a given font to the defs section of the SVG tree. - * @param[in] font font to be appended - * @param[in] chars codes of the characters whose glyph outlines should be appended */ -void SVGTree::append (const PhysicalFont &font, const set<int> &chars, GFGlyphTracer::Callback *cb) { - if (chars.empty()) - return; - - if (USE_FONTS) { - XMLElementNode *fontNode = new XMLElementNode("font"); - string fontname = font.name(); - fontNode->addAttribute("id", fontname); - fontNode->addAttribute("horiz-adv-x", XMLString(font.hAdvance())); - appendToDefs(fontNode); - - XMLElementNode *faceNode = new XMLElementNode("font-face"); - faceNode->addAttribute("font-family", fontname); - faceNode->addAttribute("units-per-em", XMLString(font.unitsPerEm())); - if (font.type() != PhysicalFont::MF) { - faceNode->addAttribute("ascent", XMLString(font.ascent())); - faceNode->addAttribute("descent", XMLString(font.descent())); - } - fontNode->append(faceNode); - - // add required missing-glyph element - XMLElementNode *missing = new XMLElementNode("missing-glyph"); - missing->addAttribute("d", ""); - fontNode->append(missing); - FORALL(chars, set<int>::const_iterator, i) - fontNode->append(createGlyphNode(*i, font, cb)); - } - else if (&font != font.uniqueFont()) { - // 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. - FORALL(chars, set<int>::const_iterator, it) { - ostringstream oss; - XMLElementNode *use = new XMLElementNode("use"); - oss << 'g' << FontManager::instance().fontID(&font) << *it; - use->addAttribute("id", oss.str()); - oss.str(""); - oss << "#g" << FontManager::instance().fontID(font.uniqueFont()) << *it; - use->addAttribute("xlink:href", oss.str()); - double scale = font.scaledSize()/font.uniqueFont()->scaledSize(); - if (scale != 1.0) { - oss.str(""); - oss << "scale(" << scale << ')'; - use->addAttribute("transform", oss.str()); - } - appendToDefs(use); - } - } - else { - FORALL(chars, set<int>::const_iterator, i) - appendToDefs(createGlyphNode(*i, font, cb)); - } -} - - |