summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/svg-builder.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/pdfinput/svg-builder.h')
-rw-r--r--src/extension/internal/pdfinput/svg-builder.h296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h
new file mode 100644
index 0000000..6d43095
--- /dev/null
+++ b/src/extension/internal/pdfinput/svg-builder.h
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef SEEN_EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H
+#define SEEN_EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H
+
+/*
+ * Authors:
+ * miklos erdelyi
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h" // only include where actually required!
+#endif
+
+#ifdef HAVE_POPPLER
+#include "poppler-transition-api.h"
+
+class SPDocument;
+namespace Inkscape {
+ namespace XML {
+ struct Document;
+ class Node;
+ }
+}
+
+#define Operator Operator_Gfx
+#include <Gfx.h>
+#undef Operator
+
+#include <2geom/affine.h>
+#include <2geom/point.h>
+#include <cairo-ft.h>
+#include <glibmm/ustring.h>
+#include <lcms2.h>
+
+#include "CharTypes.h"
+#include "enums.h"
+#include "poppler-utils.h"
+class Function;
+class GfxState;
+struct GfxColor;
+class GfxColorSpace;
+enum GfxClipType;
+struct GfxRGB;
+class GfxPath;
+class GfxPattern;
+class GfxTilingPattern;
+class GfxShading;
+class GfxFont;
+class GfxImageColorMap;
+class Stream;
+class XRef;
+
+class CairoFont;
+class SPCSSAttr;
+class ClipHistoryEntry;
+
+#include <glib.h>
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace Inkscape {
+namespace Extension {
+namespace Internal {
+
+/**
+ * Holds information about glyphs added by PdfParser which haven't been added
+ * to the document yet.
+ */
+struct SvgGlyph {
+ Geom::Point position; // Absolute glyph coords
+ Geom::Point text_position; // Absolute glyph coords in text space
+ Geom::Point delta; // X, Y advance values
+ double rise; // Text rise parameter
+ Glib::ustring code; // UTF-8 coded character
+ bool is_space;
+
+ bool style_changed; // Set to true if style has to be reset
+ GfxState *state; // A promise of the future text style
+ double text_size; // Text size
+
+ const char *font_specification; // Pointer to current font specification
+ SPCSSAttr *css_font; // The font style as a css style
+ unsigned int cairo_index; // The index into the selected cairo font
+ std::shared_ptr<CairoFont> cairo_font; // A pointer to the selected cairo font
+};
+
+/**
+ * Builds the inner SVG representation using libpoppler from the calls of PdfParser.
+ */
+class SvgBuilder {
+public:
+ SvgBuilder(SPDocument *document, gchar *docname, XRef *xref);
+ SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root);
+ virtual ~SvgBuilder();
+
+ // Property setting
+ void setDocumentSize(double width, double height); // Document size in px
+ void setMargins(const Geom::Rect &page, const Geom::Rect &margins, const Geom::Rect &bleed);
+ void cropPage(const Geom::Rect &bbox);
+ void setAsLayer(const char *layer_name = nullptr, bool visible = true);
+ void setGroupOpacity(double opacity);
+ Inkscape::XML::Node *getPreferences() {
+ return _preferences;
+ }
+ void pushPage(const std::string &label, GfxState *state);
+
+ // Path adding
+ bool shouldMergePath(bool is_fill, const std::string &path);
+ bool mergePath(GfxState *state, bool is_fill, const std::string &path, bool even_odd = false);
+ void addPath(GfxState *state, bool fill, bool stroke, bool even_odd=false);
+ void addClippedFill(GfxShading *shading, const Geom::Affine shading_tr);
+ void addShadedFill(GfxShading *shading, const Geom::Affine shading_tr, GfxPath *path, const Geom::Affine tr,
+ bool even_odd = false);
+
+ // Image handling
+ void addImage(GfxState *state, Stream *str, int width, int height,
+ GfxImageColorMap *color_map, bool interpolate, int *mask_colors);
+ void addImageMask(GfxState *state, Stream *str, int width, int height,
+ bool invert, bool interpolate);
+ void addMaskedImage(GfxState *state, Stream *str, int width, int height,
+ GfxImageColorMap *color_map, bool interpolate,
+ Stream *mask_str, int mask_width, int mask_height,
+ bool invert_mask, bool mask_interpolate);
+ void addSoftMaskedImage(GfxState *state, Stream *str, int width, int height,
+ GfxImageColorMap *color_map, bool interpolate,
+ Stream *mask_str, int mask_width, int mask_height,
+ GfxImageColorMap *mask_color_map, bool mask_interpolate);
+ void applyOptionalMask(Inkscape::XML::Node *mask, Inkscape::XML::Node *target);
+
+ // Groups, Transparency group and soft mask handling
+ void startGroup(GfxState *state, double *bbox, GfxColorSpace *blending_color_space, bool isolated, bool knockout,
+ bool for_softmask);
+ void finishGroup(GfxState *state, bool for_softmask);
+ void popGroup(GfxState *state);
+
+ // Text handling
+ void beginString(GfxState *state, int len);
+ void endString(GfxState *state);
+ void addChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode const *u, int uLen);
+ void beginTextObject(GfxState *state);
+ void endTextObject(GfxState *state);
+
+ bool isPatternTypeSupported(GfxPattern *pattern);
+ void setFontStrategies(FontStrategies fs) { _font_strategies = fs; }
+ static FontStrategies autoFontStrategies(FontStrategy s, FontList fonts);
+
+ // State manipulation
+ void saveState(GfxState *state);
+ void restoreState(GfxState *state);
+ void updateStyle(GfxState *state);
+ void updateFont(GfxState *state, std::shared_ptr<CairoFont> cairo_font, bool flip);
+ void updateTextPosition(double tx, double ty);
+ void updateTextShift(GfxState *state, double shift);
+ void updateTextMatrix(GfxState *state, bool flip);
+
+ // Clipping
+ void setClip(GfxState *state, GfxClipType clip, bool is_bbox = false);
+
+ // Layers i.e Optional Groups
+ void addOptionalGroup(const std::string &oc, const std::string &label, bool visible = true);
+ void beginMarkedContent(const char *name = nullptr, const char *group = nullptr);
+ void endMarkedContent();
+
+ void addColorProfile(unsigned char *profBuf, int length);
+
+private:
+ void _init();
+
+ // Pattern creation
+ gchar *_createPattern(GfxPattern *pattern, GfxState *state, bool is_stroke=false);
+ gchar *_createGradient(GfxShading *shading, const Geom::Affine pat_matrix, bool for_shading = false);
+ void _addStopToGradient(Inkscape::XML::Node *gradient, double offset, GfxColor *color, GfxColorSpace *space,
+ double opacity);
+ bool _addGradientStops(Inkscape::XML::Node *gradient, GfxShading *shading,
+ _POPPLER_CONST Function *func);
+ gchar *_createTilingPattern(GfxTilingPattern *tiling_pattern, GfxState *state,
+ bool is_stroke=false);
+ // Image/mask creation
+ Inkscape::XML::Node *_createImage(Stream *str, int width, int height,
+ GfxImageColorMap *color_map, bool interpolate,
+ int *mask_colors, bool alpha_only=false,
+ bool invert_alpha=false);
+ Inkscape::XML::Node *_createMask(double width, double height);
+ Inkscape::XML::Node *_createClip(const std::string &d, const Geom::Affine tr, bool even_odd);
+
+ // Style setting
+ SPCSSAttr *_setStyle(GfxState *state, bool fill, bool stroke, bool even_odd=false);
+ void _setStrokeStyle(SPCSSAttr *css, GfxState *state);
+ void _setFillStyle(SPCSSAttr *css, GfxState *state, bool even_odd);
+ void _setTextStyle(Inkscape::XML::Node *node, GfxState *state, SPCSSAttr *font_style, Geom::Affine text_affine);
+ void _setBlendMode(Inkscape::XML::Node *node, GfxState *state);
+ void _setTransform(Inkscape::XML::Node *node, GfxState *state, Geom::Affine extra = Geom::identity());
+ // Write buffered text into doc
+ void _flushText(GfxState *state);
+ std::string _aria_label;
+ bool _aria_space = false;
+
+ // Handling of node stack
+ Inkscape::XML::Node *_pushGroup();
+ Inkscape::XML::Node *_popGroup();
+ Inkscape::XML::Node *_pushContainer(const char *name);
+ Inkscape::XML::Node *_pushContainer(Inkscape::XML::Node *node);
+ Inkscape::XML::Node *_popContainer();
+ std::vector<Inkscape::XML::Node *> _node_stack;
+ std::vector<GfxState *> _mask_groups;
+ int _clip_groups = 0;
+
+ Inkscape::XML::Node *_getClip(const Geom::Affine &node_tr);
+ Inkscape::XML::Node *_addToContainer(const char *name);
+ Inkscape::XML::Node *_renderText(std::shared_ptr<CairoFont> cairo_font, double font_size,
+ const Geom::Affine &transform,
+ cairo_glyph_t *cairo_glyphs, unsigned int count);
+
+ void _setClipPath(Inkscape::XML::Node *node);
+ void _addToContainer(Inkscape::XML::Node *node, bool release = true);
+
+ Inkscape::XML::Node *_getGradientNode(Inkscape::XML::Node *node, bool is_fill);
+ static bool _attrEqual(Inkscape::XML::Node *a, Inkscape::XML::Node *b, char const *attr);
+
+ // Colors
+ std::string convertGfxColor(const GfxColor *color, GfxColorSpace *space);
+ std::string _getColorProfile(cmsHPROFILE hp);
+
+ // The calculated font style, if not set, the text must be rendered with cairo instead.
+ FontStrategies _font_strategies;
+ double _css_font_size = 1.0;
+ SPCSSAttr *_css_font;
+ const char *_font_specification;
+ double _text_size;
+ Geom::Affine _text_matrix;
+ Geom::Point _text_position;
+ std::vector<SvgGlyph> _glyphs; // Added characters
+
+ // The font when drawing the text into vector glyphs instead of text elements.
+ std::shared_ptr<CairoFont> _cairo_font;
+
+ bool _in_text_object; // Whether we are inside a text object
+ bool _invalidated_style;
+ bool _invalidated_strategy = false;
+ bool _for_softmask = false;
+
+ bool _is_top_level; // Whether this SvgBuilder is the top-level one
+ SPDocument *_doc;
+ gchar *_docname; // Basename of the URI from which this document is created
+ XRef *_xref; // Cross-reference table from the PDF doc we're converting from
+ Inkscape::XML::Document *_xml_doc;
+ Inkscape::XML::Node *_root; // Root node from the point of view of this SvgBuilder
+ Inkscape::XML::Node *_container; // Current container (group/pattern/mask)
+ Inkscape::XML::Node *_preferences; // Preferences container node
+ double _width; // Document size in px
+ double _height; // Document size in px
+
+ Inkscape::XML::Node *_page = nullptr; // XML Page definition
+ int _page_num = 0; // Are we on a page
+ double _page_left = 0 ; // Move to the left for more pages
+ double _page_top = 0 ; // Move to the top (maybe)
+ bool _page_offset = false;
+ Geom::Affine _page_affine = Geom::identity();
+
+ std::map<std::string, std::pair<std::string, bool>> _ocgs;
+
+ std::string _icc_profile;
+ std::map<cmsHPROFILE, std::string> _icc_profiles;
+
+ ClipHistoryEntry *_clip_history; // clip path stack
+ Inkscape::XML::Node *_clip_text = nullptr;
+ Inkscape::XML::Node *_clip_text_group = nullptr;
+};
+
+
+} // namespace Internal
+} // namespace Extension
+} // namespace Inkscape
+
+#endif // HAVE_POPPLER
+
+#endif // SEEN_EXTENSION_INTERNAL_PDFINPUT_SVGBUILDER_H
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :