summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: cd20f44)
raw | patch | inline | side by side (parent: cd20f44)
author | miklosh <miklosh@users.sourceforge.net> | |
Mon, 23 Jul 2007 18:02:43 +0000 (18:02 +0000) | ||
committer | miklosh <miklosh@users.sourceforge.net> | |
Mon, 23 Jul 2007 18:02:43 +0000 (18:02 +0000) |
diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp
index 2fe6c73d31122b76fe6e8624ee0956026e0129a6..9adf1958f99b74bd1e4700c711f601331cd326cc 100644 (file)
sp_document_set_undo_sensitive(doc, false); // No need to undo in this temporary document
// Create builder and parser
- SvgBuilder *builder = new SvgBuilder(doc);
+ SvgBuilder *builder = new SvgBuilder(doc, pdf_doc->getXRef());
PdfParser *pdf_parser = new PdfParser(pdf_doc->getXRef(), builder, page_num-1, page->getRotate(),
page->getResourceDict(), page->getCropBox());
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index c76b4927b73058bc2ae1d07e85a14565a73c107b..0e614206f5e85b55c9d02b0e118302d132d5e6d3 100644 (file)
@@ -335,6 +335,31 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
pushOperator("startPage");
}
+PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
+ Dict *resDict, PDFRectangle *box) {
+
+ int i;
+
+ xref = xrefA;
+ subPage = gTrue;
+ printCommands = false;
+
+ // start the resource stack
+ res = new GfxResources(xref, resDict, NULL);
+
+ // initialize
+ operatorHistory = NULL;
+ builder = builderA;
+ state = new GfxState(72, 72, box, 0, gFalse);
+ fontChanged = gFalse;
+ clip = clipNone;
+ ignoreUndef = 0;
+ for (i = 0; i < 6; ++i) {
+ baseMatrix[i] = state->getCTM()[i];
+ }
+ formDepth = 0;
+}
+
PdfParser::~PdfParser() {
while (state->hasSaves()) {
restoreState();
diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h
index 394c9ca830e092fabb84b95c750fee089efdf202..5747dcc9a0acd95b6974f726790096fd480d7c8f 100644 (file)
PdfParser(XRef *xrefA, SvgBuilder *builderA, int pageNum, int rotate,
Dict *resDict, PDFRectangle *cropBox);
+ // Constructor for a sub-page object.
+ PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA,
+ Dict *resDict, PDFRectangle *box);
+
~PdfParser();
// Interpret a stream or array of streams.
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index fc013674be3c5a534688c0eba9e024c441ff968e..7ca8eb0fef5b6a466f270a4bf6d10cacd4e50295 100644 (file)
#include "GfxState.h"
#include "GfxFont.h"
#include "Stream.h"
+#include "Page.h"
#include "UnicodeMap.h"
#include "GlobalParams.h"
_current_state = NULL;
}
-SvgBuilder::SvgBuilder(SPDocument *document) {
+SvgBuilder::SvgBuilder(SPDocument *document, XRef *xref) {
_doc = document;
+ _xref = xref;
_xml_doc = sp_document_repr_doc(_doc);
_container = _root = _doc->rroot;
SvgBuilder();
SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) {
_doc = parent->_doc;
+ _xref = parent->_xref;
_xml_doc = parent->_xml_doc;
_container = this->_root = root;
SvgBuilder();
// Stroke color/pattern
if ( state->getStrokeColorSpace()->getMode() == csPattern ) {
- gchar *urltext = _createPattern(state->getStrokePattern());
+ gchar *urltext = _createPattern(state->getStrokePattern(), state, true);
sp_repr_css_set_property(css, "stroke", urltext);
if (urltext) {
g_free(urltext);
@@ -289,7 +292,7 @@ void SvgBuilder::_setFillStyle(SPCSSAttr *css, GfxState *state, bool even_odd) {
// Fill color/pattern
if ( state->getFillColorSpace()->getMode() == csPattern ) {
- gchar *urltext = _createPattern(state->getFillPattern());
+ gchar *urltext = _createPattern(state->getFillPattern(), state);
sp_repr_css_set_property(css, "fill", urltext);
if (urltext) {
g_free(urltext);
* build a tiling pattern.
* \return an url pointing to the created pattern
*/
-gchar *SvgBuilder::_createPattern(GfxPattern *pattern) {
+gchar *SvgBuilder::_createPattern(GfxPattern *pattern, GfxState *state, bool is_stroke) {
gchar *id = NULL;
if ( pattern != NULL ) {
if ( pattern->getType() == 2 ) { // Shading pattern
id = _createGradient((GfxShadingPattern*)pattern);
} else if ( pattern->getType() == 1 ) { // Tiling pattern
- id = _createTilingPattern((GfxTilingPattern*)pattern);
+ id = _createTilingPattern((GfxTilingPattern*)pattern, state, is_stroke);
}
} else {
return NULL;
return urltext;
}
-gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern) {
- return NULL;
+/**
+ * \brief Creates a tiling pattern from poppler's data structure
+ * Creates a sub-page PdfParser and uses it to parse the pattern's content stream.
+ * \return id of the created pattern
+ */
+gchar *SvgBuilder::_createTilingPattern(GfxTilingPattern *tiling_pattern,
+ GfxState *state, bool is_stroke) {
+
+ Inkscape::XML::Node *pattern_node = _xml_doc->createElement("svg:pattern");
+ // Set pattern transform matrix
+ double *p2u = tiling_pattern->getMatrix();
+ NR::Matrix pat_matrix(p2u[0], p2u[1], p2u[2], p2u[3], p2u[4], p2u[5]);
+ gchar *transform_text = sp_svg_transform_write(pat_matrix);
+ pattern_node->setAttribute("patternTransform", transform_text);
+ g_free(transform_text);
+ pattern_node->setAttribute("patternUnits", "userSpaceOnUse");
+ // Set pattern tiling
+ // FIXME: don't ignore XStep and YStep
+ double *bbox = tiling_pattern->getBBox();
+ sp_repr_set_svg_double(pattern_node, "x", 0.0);
+ sp_repr_set_svg_double(pattern_node, "y", 0.0);
+ sp_repr_set_svg_double(pattern_node, "width", bbox[2] - bbox[0]);
+ sp_repr_set_svg_double(pattern_node, "height", bbox[3] - bbox[1]);
+
+ // Convert BBox for PdfParser
+ PDFRectangle box;
+ box.x1 = bbox[0];
+ box.y1 = bbox[1];
+ box.x2 = bbox[2];
+ box.y2 = bbox[3];
+ // Create new SvgBuilder and sub-page PdfParser
+ SvgBuilder *pattern_builder = new SvgBuilder(this, pattern_node);
+ PdfParser *pdf_parser = new PdfParser(_xref, pattern_builder, tiling_pattern->getResDict(),
+ &box);
+ // Get pattern color space
+ GfxPatternColorSpace *pat_cs = (GfxPatternColorSpace *)( is_stroke ? state->getStrokeColorSpace()
+ : state->getFillColorSpace() );
+ // Set fill/stroke colors if this is an uncolored tiling pattern
+ GfxColorSpace *cs = NULL;
+ if ( tiling_pattern->getPaintType() == 2 && ( cs = pat_cs->getUnder() ) ) {
+ GfxState *pattern_state = pdf_parser->getState();
+ pattern_state->setFillColorSpace(cs->copy());
+ pattern_state->setFillColor(state->getFillColor());
+ pattern_state->setStrokeColorSpace(cs->copy());
+ pattern_state->setStrokeColor(state->getFillColor());
+ }
+
+ // Generate the SVG pattern
+ pdf_parser->parse(tiling_pattern->getContentStream());
+
+ // Cleanup
+ delete pdf_parser;
+ delete pattern_builder;
+
+ // Append the pattern to defs
+ SP_OBJECT_REPR (SP_DOCUMENT_DEFS (_doc))->appendChild(pattern_node);
+ gchar *id = g_strdup(pattern_node->attribute("id"));
+ Inkscape::GC::release(pattern_node);
+
+ return id;
}
/**
diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h
index 8145a45224a99c460de6c2c67cddc8ec9beecb46..8888989e95a0ce85ccd0df38d2955a5ee42a7436 100644 (file)
class GfxFont;
class GfxImageColorMap;
class Stream;
+class XRef;
class SPCSSAttr;
*/
class SvgBuilder {
public:
- SvgBuilder(SPDocument *document);
+ SvgBuilder(SPDocument *document, XRef *xref);
SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root);
~SvgBuilder();
SvgBuilder();
// Pattern creation
- gchar *_createPattern(GfxPattern *pattern);
+ gchar *_createPattern(GfxPattern *pattern, GfxState *state, bool is_stroke=false);
gchar *_createGradient(GfxShadingPattern *shading_pattern);
bool _addStopsToGradient(Inkscape::XML::Node *gradient, Function *func, double opacity);
bool _addSamplesToGradient(Inkscape::XML::Node *gradient, SampledFunction *func,
double offset0, double offset1, double opacity);
- gchar *_createTilingPattern(GfxTilingPattern *tiling_pattern);
+ 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, int *mask_colors,
GfxState *_current_state;
SPDocument *_doc;
+ 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)