1 /*************************************************************************
2 ** SVGTree.h                                                            **
3 **                                                                      **
4 ** This file is part of dvisvgm -- the DVI to SVG converter             **
5 ** Copyright (C) 2005-2015 Martin Gieseking <martin.gieseking@uos.de>   **
6 **                                                                      **
7 ** This program is free software; you can redistribute it and/or        **
8 ** modify it under the terms of the GNU General Public License as       **
9 ** published by the Free Software Foundation; either version 3 of       **
10 ** the License, or (at your option) any later version.                  **
11 **                                                                      **
12 ** This program is distributed in the hope that it will be useful, but  **
13 ** WITHOUT ANY WARRANTY; without even the implied warranty of           **
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         **
15 ** GNU General Public License for more details.                         **
16 **                                                                      **
17 ** You should have received a copy of the GNU General Public License    **
18 ** along with this program; if not, see <http://www.gnu.org/licenses/>. **
19 *************************************************************************/
20 
21 #ifndef DVISVGM_SVGTREE_H
22 #define DVISVGM_SVGTREE_H
23 
24 #include <map>
25 #include <set>
26 #include <stack>
27 #include "Color.h"
28 #include "GFGlyphTracer.h"
29 #include "Matrix.h"
30 #include "XMLDocument.h"
31 #include "XMLNode.h"
32 
33 class  BoundingBox;
34 class  Color;
35 struct Font;
36 class  Matrix;
37 class  PhysicalFont;
38 
39 class SVGTree
40 {
41 	template <typename T>
42 	class Property {
43 		public:
Property(const T & v)44 			Property (const T &v) : _value(v), _changed(false) {}
45 
set(const T & v)46 			void set (const T &v) {
47 				if (v != _value) {
48 					_value = v;
49 					_changed = true;
50 				}
51 			}
52 
get()53 			const T& get () const {return _value;}
54 			operator const T& ()  {return _value;}
changed()55 			bool changed () const {return _changed;}
changed(bool c)56 			void changed (bool c) {_changed = c;}
57 
58 		private:
59 			T _value;
60 			bool _changed;
61 	};
62 
63 	public:
64 		SVGTree ();
65 		void reset ();
write(std::ostream & os)66 		void write (std::ostream &os) const    {_doc.write(os);}
67 		void newPage (int pageno);
68 		void appendToDefs (XMLNode *node);
69 		void appendToPage (XMLNode *node);
70 		void prependToPage (XMLNode *node);
appendToDoc(XMLNode * node)71 		void appendToDoc (XMLNode *node)  {_doc.append(node);}
appendToRoot(XMLNode * node)72 		void appendToRoot (XMLNode *node) {_root->append(node);}
73 		void appendChar (int c, double x, double y, const Font &font);
74 		void appendFontStyles (const std::set<const Font*> &fonts);
75 		void append (const PhysicalFont &font, const std::set<int> &chars, GFGlyphTracer::Callback *cb=0);
76 		void pushContextElement (XMLElementNode *node);
77 		void popContextElement ();
78 		void removeRedundantElements ();
79 		void setBBox (const BoundingBox &bbox);
80 		void setFont (int id, const Font *font);
setX(double x)81 		void setX (double x)              {_xchanged = true;}
setY(double y)82 		void setY (double y)              {_ychanged = true;}
setMatrix(const Matrix & m)83 		void setMatrix (const Matrix &m)  {_matrix.set(m);}
84 		void setColor (const Color &c);
setVertical(bool state)85 		void setVertical (bool state)     {_vertical.set(state);}
86 		void transformPage (const Matrix *m);
getColor()87 		const Color& getColor () const    {return _color.get();}
getMatrix()88 		const Matrix& getMatrix () const  {return _matrix.get();}
rootNode()89 		XMLElementNode* rootNode () const {return _root;}
90 
91 	public:
92 		static bool USE_FONTS;           ///< if true, create font references and don't draw paths directly
93 		static bool CREATE_STYLE;        ///<  use style elements and class attributes to reference fonts?
94 		static bool CREATE_USE_ELEMENTS; ///< allow generation of <use/> elements?
95 		static bool RELATIVE_PATH_CMDS;  ///< relative path commands rather than absolute ones?
96 		static bool MERGE_CHARS;         ///< whether to merge chars with common properties into the same <text> tag
97 		static double ZOOM_FACTOR;       ///< factor applied to width/height attribute
98 
99 	protected:
100 		void newTextNode (double x, double y);
101 
102 	private:
103 		XMLDocument _doc;
104 		XMLElementNode *_root, *_page, *_text, *_span, *_defs;
105 		bool _xchanged, _ychanged;
106 		Property<bool> _vertical;  ///< true if in vertical writing mode
107 		Property<const Font*> _font;
108 		Property<Color> _color;
109 		Property<Matrix> _matrix;
110 		int _fontnum;
111 		std::stack<XMLElementNode*> _pageContainerStack;
112 };
113 
114 #endif
115