summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvisvgm/dvisvgm-0.8.7/src/SVGFontEmitter.cpp
blob: 88bae2b38133aa2dd242b359b01e1d813c2ca7f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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;
}