summaryrefslogtreecommitdiffstats
path: root/src/extension/internal/pdfinput/svg-builder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/internal/pdfinput/svg-builder.cpp')
-rw-r--r--src/extension/internal/pdfinput/svg-builder.cpp103
1 files changed, 71 insertions, 32 deletions
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index 94edf826e..e8d6363f0 100644
--- a/src/extension/internal/pdfinput/svg-builder.cpp
+++ b/src/extension/internal/pdfinput/svg-builder.cpp
@@ -1,4 +1,4 @@
- /** \file
+ /*
* Native PDF import using libpoppler.
*
* Authors:
@@ -37,7 +37,6 @@
#include "io/stringstream.h"
#include "io/base64stream.h"
#include "display/nr-filter-utils.h"
-#include "libnr/nr-macros.h"
#include "libnrtype/font-instance.h"
#include "Function.h"
@@ -57,6 +56,7 @@ namespace Internal {
#define TRACE(_args) IFTRACE(g_print _args)
+static double ttm[6] = {1, 0, 0, 1, 0, 0}; // temporary transform matrix
/**
* \struct SvgTransparencyGroup
@@ -110,19 +110,23 @@ SvgBuilder::~SvgBuilder() {
}
void SvgBuilder::_init() {
- _in_text_object = false;
- _need_font_update = true;
- _invalidated_style = true;
_font_style = NULL;
_current_font = NULL;
+ _font_specification = NULL;
+ _font_scaling = 1;
+ _need_font_update = true;
+ _in_text_object = false;
+ _invalidated_style = true;
_current_state = NULL;
+ _width = 0;
+ _height = 0;
// Fill _availableFontNames (Bug LP #179589) (code cfr. FontLister)
FamilyToStylesMap familyStyleMap;
font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap);
for (FamilyToStylesMap::iterator iter = familyStyleMap.begin();
iter != familyStyleMap.end();
- iter++) {
+ ++iter) {
_availableFontNames.push_back(iter->first.c_str());
}
@@ -531,7 +535,7 @@ void SvgBuilder::setClipPath(GfxState *state, bool even_odd) {
clip_path->appendChild(path);
Inkscape::GC::release(path);
// Append clipPath to defs and get id
- SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(clip_path);
+ _doc->getDefs()->getRepr()->appendChild(clip_path);
gchar *urltext = g_strdup_printf ("url(#%s)", clip_path->attribute("id"));
Inkscape::GC::release(clip_path);
_container->setAttribute("clip-path", urltext);
@@ -562,6 +566,19 @@ bool SvgBuilder::getTransform(double *transform) {
*/
void SvgBuilder::setTransform(double c0, double c1, double c2, double c3,
double c4, double c5) {
+ // do not remember the group which is a layer
+ if (_container->attribute("inkscape:groupmode") != NULL) {
+ ttm[0] = ttm[3] = 1.0;
+ ttm[1] = ttm[2] = ttm[4] = ttm[5] = 0.0;
+ }
+ else {
+ ttm[0] = c0;
+ ttm[1] = c1;
+ ttm[2] = c2;
+ ttm[3] = c3;
+ ttm[4] = c4;
+ ttm[5] = c5;
+ }
// Avoid transforming a group with an already set clip-path
if ( _container->attribute("clip-path") != NULL ) {
@@ -609,8 +626,31 @@ gchar *SvgBuilder::_createPattern(GfxPattern *pattern, GfxState *state, bool is_
if ( pattern != NULL ) {
if ( pattern->getType() == 2 ) { // Shading pattern
GfxShadingPattern *shading_pattern = (GfxShadingPattern*)pattern;
+ double *ptm;
+ double ittm[6]; // invert ttm
+ double m[6] = {1, 0, 0, 1, 0, 0};
+ double det;
+
+ // construct a (pattern space) -> (current space) transform matrix
+
+ ptm = shading_pattern->getMatrix();
+ det = ttm[0] * ttm[3] - ttm[1] * ttm[2];
+ if (det) {
+ ittm[0] = ttm[3] / det;
+ ittm[1] = -ttm[1] / det;
+ ittm[2] = -ttm[2] / det;
+ ittm[3] = ttm[0] / det;
+ ittm[4] = (ttm[2] * ttm[5] - ttm[3] * ttm[4]) / det;
+ ittm[5] = (ttm[1] * ttm[4] - ttm[0] * ttm[5]) / det;
+ m[0] = ptm[0] * ittm[0] + ptm[1] * ittm[2];
+ m[1] = ptm[0] * ittm[1] + ptm[1] * ittm[3];
+ m[2] = ptm[2] * ittm[0] + ptm[3] * ittm[2];
+ m[3] = ptm[2] * ittm[1] + ptm[3] * ittm[3];
+ m[4] = ptm[4] * ittm[0] + ptm[5] * ittm[2] + ittm[4];
+ m[5] = ptm[4] * ittm[1] + ptm[5] * ittm[3] + ittm[5];
+ }
id = _createGradient(shading_pattern->getShading(),
- shading_pattern->getMatrix(),
+ m,
!is_stroke);
} else if ( pattern->getType() == 1 ) { // Tiling pattern
id = _createTilingPattern((GfxTilingPattern*)pattern, state, is_stroke);
@@ -678,7 +718,7 @@ gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern,
delete pattern_builder;
// Append the pattern to defs
- SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(pattern_node);
+ _doc->getDefs()->getRepr()->appendChild(pattern_node);
gchar *id = g_strdup(pattern_node->attribute("id"));
Inkscape::GC::release(pattern_node);
@@ -752,7 +792,7 @@ gchar *SvgBuilder::_createGradient(GfxShading *shading, double *matrix, bool for
return NULL;
}
- Inkscape::XML::Node *defs = SP_DOCUMENT_DEFS(_doc)->getRepr();
+ Inkscape::XML::Node *defs = _doc->getDefs()->getRepr();
defs->appendChild(gradient);
gchar *id = g_strdup(gradient->attribute("id"));
Inkscape::GC::release(gradient);
@@ -1298,7 +1338,7 @@ void SvgBuilder::_flushText() {
}
glyphs_in_a_row++;
- i++;
+ ++i;
}
_container->appendChild(text_node);
Inkscape::GC::release(text_node);
@@ -1306,7 +1346,7 @@ void SvgBuilder::_flushText() {
_glyphs.clear();
}
-void SvgBuilder::beginString(GfxState *state, GooString *s) {
+void SvgBuilder::beginString(GfxState *state, GooString * /*s*/) {
if (_need_font_update) {
updateFont(state);
}
@@ -1324,12 +1364,12 @@ void SvgBuilder::beginString(GfxState *state, GooString *s) {
void SvgBuilder::addChar(GfxState *state, double x, double y,
double dx, double dy,
double originX, double originY,
- CharCode code, int nBytes, Unicode *u, int uLen) {
+ CharCode /*code*/, int /*nBytes*/, Unicode *u, int uLen) {
bool is_space = ( uLen == 1 && u[0] == 32 );
// Skip beginning space
- if ( is_space && _glyphs.size() < 1 ) {
+ if ( is_space && _glyphs.empty()) {
Geom::Point delta(dx, dy);
_text_position += delta;
return;
@@ -1369,7 +1409,7 @@ void SvgBuilder::addChar(GfxState *state, double x, double y,
}
// Copy current style if it has changed since the previous glyph
- if (_invalidated_style || _glyphs.size() == 0 ) {
+ if (_invalidated_style || _glyphs.empty()) {
new_glyph.style_changed = true;
int render_mode = state->getRender();
// Set style
@@ -1392,7 +1432,7 @@ void SvgBuilder::addChar(GfxState *state, double x, double y,
_glyphs.push_back(new_glyph);
}
-void SvgBuilder::endString(GfxState *state) {
+void SvgBuilder::endString(GfxState * /*state*/) {
}
void SvgBuilder::beginTextObject(GfxState *state) {
@@ -1401,7 +1441,7 @@ void SvgBuilder::beginTextObject(GfxState *state) {
_current_state = state;
}
-void SvgBuilder::endTextObject(GfxState *state) {
+void SvgBuilder::endTextObject(GfxState * /*state*/) {
_flushText();
// TODO: clip if render_mode >= 4
_in_text_object = false;
@@ -1445,7 +1485,7 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height
return NULL;
}
// Set error handler
- if (setjmp(png_ptr->jmpbuf)) {
+ if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr);
return NULL;
}
@@ -1602,9 +1642,8 @@ Inkscape::XML::Node *SvgBuilder::_createImage(Stream *str, int width, int height
sp_repr_set_svg_double(image_node, "width", 1);
sp_repr_set_svg_double(image_node, "height", 1);
// Set transformation
- if (_is_top_level) {
+
svgSetTransform(image_node, 1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
- }
// Create href
if (embed_image) {
@@ -1635,9 +1674,9 @@ Inkscape::XML::Node *SvgBuilder::_createMask(double width, double height) {
sp_repr_set_svg_double(mask_node, "height", height);
// Append mask to defs
if (_is_top_level) {
- SP_DOCUMENT_DEFS(_doc)->getRepr()->appendChild(mask_node);
+ _doc->getDefs()->getRepr()->appendChild(mask_node);
Inkscape::GC::release(mask_node);
- return SP_DOCUMENT_DEFS(_doc)->getRepr()->lastChild();
+ return _doc->getDefs()->getRepr()->lastChild();
} else { // Work around for renderer bug when mask isn't defined in pattern
static int mask_count = 0;
Inkscape::XML::Node *defs = _root->firstChild();
@@ -1657,7 +1696,7 @@ Inkscape::XML::Node *SvgBuilder::_createMask(double width, double height) {
}
}
-void SvgBuilder::addImage(GfxState *state, Stream *str, int width, int height,
+void SvgBuilder::addImage(GfxState * /*state*/, Stream *str, int width, int height,
GfxImageColorMap *color_map, int *mask_colors) {
Inkscape::XML::Node *image_node = _createImage(str, width, height, color_map, mask_colors);
@@ -1704,7 +1743,7 @@ void SvgBuilder::addImageMask(GfxState *state, Stream *str, int width, int heigh
Inkscape::GC::release(rect);
}
-void SvgBuilder::addMaskedImage(GfxState *state, Stream *str, int width, int height,
+void SvgBuilder::addMaskedImage(GfxState * /*state*/, Stream *str, int width, int height,
GfxImageColorMap *color_map,
Stream *mask_str, int mask_width, int mask_height,
bool invert_mask) {
@@ -1737,7 +1776,7 @@ void SvgBuilder::addMaskedImage(GfxState *state, Stream *str, int width, int hei
}
}
-void SvgBuilder::addSoftMaskedImage(GfxState *state, Stream *str, int width, int height,
+void SvgBuilder::addSoftMaskedImage(GfxState * /*state*/, Stream *str, int width, int height,
GfxImageColorMap *color_map,
Stream *mask_str, int mask_width, int mask_height,
GfxImageColorMap *mask_color_map) {
@@ -1768,8 +1807,8 @@ void SvgBuilder::addSoftMaskedImage(GfxState *state, Stream *str, int width, int
/**
* \brief Starts building a new transparency group
*/
-void SvgBuilder::pushTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blending_color_space,
+void SvgBuilder::pushTransparencyGroup(GfxState * /*state*/, double *bbox,
+ GfxColorSpace * /*blending_color_space*/,
bool isolated, bool knockout,
bool for_softmask) {
@@ -1789,7 +1828,7 @@ void SvgBuilder::pushTransparencyGroup(GfxState *state, double *bbox,
_transp_group_stack = transpGroup;
}
-void SvgBuilder::popTransparencyGroup(GfxState *state) {
+void SvgBuilder::popTransparencyGroup(GfxState * /*state*/) {
// Restore node stack
popNode();
}
@@ -1797,7 +1836,7 @@ void SvgBuilder::popTransparencyGroup(GfxState *state) {
/**
* \brief Places the current transparency group into the current container
*/
-void SvgBuilder::paintTransparencyGroup(GfxState *state, double *bbox) {
+void SvgBuilder::paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {
SvgTransparencyGroup *transpGroup = _transp_group_stack;
_container->appendChild(transpGroup->container);
Inkscape::GC::release(transpGroup->container);
@@ -1809,8 +1848,8 @@ void SvgBuilder::paintTransparencyGroup(GfxState *state, double *bbox) {
/**
* \brief Creates a mask using the current transparency group as its content
*/
-void SvgBuilder::setSoftMask(GfxState *state, double *bbox, bool alpha,
- Function *transfer_func, GfxColor *backdrop_color) {
+void SvgBuilder::setSoftMask(GfxState * /*state*/, double * /*bbox*/, bool /*alpha*/,
+ Function * /*transfer_func*/, GfxColor * /*backdrop_color*/) {
// Create mask
Inkscape::XML::Node *mask_node = _createMask(1.0, 1.0);
@@ -1829,7 +1868,7 @@ void SvgBuilder::setSoftMask(GfxState *state, double *bbox, bool alpha,
delete transpGroup;
}
-void SvgBuilder::clearSoftMask(GfxState *state) {
+void SvgBuilder::clearSoftMask(GfxState * /*state*/) {
if (_state_stack.back().softmask) {
_state_stack.back().softmask = NULL;
popGroup();