1 #ifndef __EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H__
2 #define __EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H__
4 /** \file
5 * SVG representation creator using libpoppler.
6 *
7 * Authors:
8 * miklos erdelyi
9 *
10 * Copyright (C) 2007 Authors
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #ifdef HAVE_POPPLER
21 class SPDocument;
22 namespace Inkscape {
23 namespace XML {
24 class Document;
25 class Node;
26 }
27 }
29 #include <2geom/point.h>
30 #include <2geom/matrix.h>
31 #include <glibmm/ustring.h>
33 #include "CharTypes.h"
34 class GooString;
35 class Function;
36 struct GfxState;
37 class GfxColor;
38 class GfxColorSpace;
39 class GfxRGB;
40 class GfxPath;
41 class GfxPattern;
42 class GfxTilingPattern;
43 class GfxShading;
44 class GfxFont;
45 class GfxImageColorMap;
46 class Stream;
47 class XRef;
49 class SPCSSAttr;
51 #include <vector>
52 #include <glib/gtypes.h>
54 namespace Inkscape {
55 namespace Extension {
56 namespace Internal {
58 struct SvgTransparencyGroup;
60 /**
61 * \struct SvgGraphicsState
62 * Holds information about the current softmask and group depth.
63 * Could be later used to store other graphics state parameters so that we could
64 * emit only the differences in style settings from the parent state.
65 */
66 struct SvgGraphicsState {
67 Inkscape::XML::Node *softmask; // Points to current softmask node
68 int group_depth; // Depth of nesting groups at this level
69 };
71 /**
72 * \struct SvgGlyph
73 * Holds information about glyphs added by PdfParser which haven't been added
74 * to the document yet.
75 */
76 struct SvgGlyph {
77 Geom::Point position; // Absolute glyph coords
78 Geom::Point text_position; // Absolute glyph coords in text space
79 double dx; // X advance value
80 double dy; // Y advance value
81 double rise; // Text rise parameter
82 Glib::ustring code; // UTF-8 coded character
83 bool is_space;
85 bool style_changed; // Set to true if style has to be reset
86 SPCSSAttr *style;
87 int render_mode; // Text render mode
88 char *font_specification; // Pointer to current font specification
89 };
91 /**
92 * \class SvgBuilder
93 *
94 * Builds the inner SVG representation from the calls of PdfParser
95 *
96 */
97 class SvgBuilder {
98 public:
99 SvgBuilder(SPDocument *document, gchar *docname, XRef *xref);
100 SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root);
101 virtual ~SvgBuilder();
103 // Property setting
104 void setDocumentSize(double width, double height); // Document size in px
105 void setAsLayer(char *layer_name=NULL);
106 void setGroupOpacity(double opacity);
107 Inkscape::XML::Node *getPreferences() {
108 return _preferences;
109 }
111 // Handling the node stack
112 Inkscape::XML::Node *pushGroup();
113 Inkscape::XML::Node *popGroup();
114 Inkscape::XML::Node *getContainer(); // Returns current group node
116 // Path adding
117 void addPath(GfxState *state, bool fill, bool stroke, bool even_odd=false);
118 void addShadedFill(GfxShading *shading, double *matrix, GfxPath *path, bool even_odd=false);
120 // Image handling
121 void addImage(GfxState *state, Stream *str, int width, int height,
122 GfxImageColorMap *color_map, int *mask_colors);
123 void addImageMask(GfxState *state, Stream *str, int width, int height,
124 bool invert);
125 void addMaskedImage(GfxState *state, Stream *str, int width, int height,
126 GfxImageColorMap *color_map,
127 Stream *mask_str, int mask_width, int mask_height,
128 bool invert_mask);
129 void addSoftMaskedImage(GfxState *state, Stream *str, int width, int height,
130 GfxImageColorMap *color_map,
131 Stream *mask_str, int mask_width, int mask_height,
132 GfxImageColorMap *mask_color_map);
134 // Transparency group and soft mask handling
135 void pushTransparencyGroup(GfxState *state, double *bbox,
136 GfxColorSpace *blending_color_space,
137 bool isolated, bool knockout,
138 bool for_softmask);
139 void popTransparencyGroup(GfxState *state);
140 void paintTransparencyGroup(GfxState *state, double *bbox);
141 void setSoftMask(GfxState *state, double *bbox, bool alpha,
142 Function *transfer_func, GfxColor *backdrop_color);
143 void clearSoftMask(GfxState *state);
145 // Text handling
146 void beginString(GfxState *state, GooString *s);
147 void endString(GfxState *state);
148 void addChar(GfxState *state, double x, double y,
149 double dx, double dy,
150 double originX, double originY,
151 CharCode code, int nBytes, Unicode *u, int uLen);
152 void beginTextObject(GfxState *state);
153 void endTextObject(GfxState *state);
155 bool isPatternTypeSupported(GfxPattern *pattern);
157 // State manipulation
158 void saveState();
159 void restoreState();
160 void updateStyle(GfxState *state);
161 void updateFont(GfxState *state);
162 void updateTextPosition(double tx, double ty);
163 void updateTextShift(GfxState *state, double shift);
164 void updateTextMatrix(GfxState *state);
166 // Clipping
167 void clip(GfxState *state, bool even_odd=false);
168 void setClipPath(GfxState *state, bool even_odd=false);
170 // Transforming
171 void setTransform(double c0, double c1, double c2, double c3, double c4,
172 double c5);
173 void setTransform(double const *transform);
174 bool getTransform(double *transform);
176 private:
177 void _init();
179 // Pattern creation
180 gchar *_createPattern(GfxPattern *pattern, GfxState *state, bool is_stroke=false);
181 gchar *_createGradient(GfxShading *shading, double *matrix, bool for_shading=false);
182 void _addStopToGradient(Inkscape::XML::Node *gradient, double offset,
183 GfxRGB *color, double opacity);
184 bool _addGradientStops(Inkscape::XML::Node *gradient, GfxShading *shading,
185 Function *func);
186 gchar *_createTilingPattern(GfxTilingPattern *tiling_pattern, GfxState *state,
187 bool is_stroke=false);
188 // Image/mask creation
189 Inkscape::XML::Node *_createImage(Stream *str, int width, int height,
190 GfxImageColorMap *color_map, int *mask_colors,
191 bool alpha_only=false, bool invert_alpha=false);
192 Inkscape::XML::Node *_createMask(double width, double height);
193 // Style setting
194 SPCSSAttr *_setStyle(GfxState *state, bool fill, bool stroke, bool even_odd=false);
195 void _setStrokeStyle(SPCSSAttr *css, GfxState *state);
196 void _setFillStyle(SPCSSAttr *css, GfxState *state, bool even_odd);
198 void _flushText(); // Write buffered text into doc
200 std::string _BestMatchingFont(std::string PDFname);
202 // Handling of node stack
203 Inkscape::XML::Node *pushNode(const char* name);
204 Inkscape::XML::Node *popNode();
205 std::vector<Inkscape::XML::Node *> _node_stack;
206 std::vector<int> _group_depth; // Depth of nesting groups
207 SvgTransparencyGroup *_transp_group_stack; // Transparency group stack
208 std::vector<SvgGraphicsState> _state_stack;
210 SPCSSAttr *_font_style; // Current font style
211 GfxFont *_current_font;
212 char *_font_specification;
213 double _font_scaling;
214 bool _need_font_update;
215 Geom::Matrix _text_matrix;
216 Geom::Point _text_position;
217 std::vector<SvgGlyph> _glyphs; // Added characters
218 bool _in_text_object; // Whether we are inside a text object
219 bool _invalidated_style;
220 GfxState *_current_state;
221 std::vector<std::string> _availableFontNames; // Full names, used for matching font names (Bug LP #179589).
223 bool _is_top_level; // Whether this SvgBuilder is the top-level one
224 SPDocument *_doc;
225 gchar *_docname; // Basename of the URI from which this document is created
226 XRef *_xref; // Cross-reference table from the PDF doc we're converting from
227 Inkscape::XML::Document *_xml_doc;
228 Inkscape::XML::Node *_root; // Root node from the point of view of this SvgBuilder
229 Inkscape::XML::Node *_container; // Current container (group/pattern/mask)
230 Inkscape::XML::Node *_preferences; // Preferences container node
231 double _width, _height; // Document size in px
232 };
235 } } } /* namespace Inkscape, Extension, Internal */
237 #endif /* HAVE_POPPLER */
239 #endif /* __EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H__ */
241 /*
242 Local Variables:
243 mode:c++
244 c-file-style:"stroustrup"
245 c-file-offsets:((innamespace . 0)(inline-open . 0))
246 indent-tabs-mode:nil
247 fill-column:99
248 End:
249 */
250 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :