summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4aa2386)
raw | patch | inline | side by side (parent: 4aa2386)
author | miklosh <miklosh@users.sourceforge.net> | |
Mon, 13 Aug 2007 16:48:30 +0000 (16:48 +0000) | ||
committer | miklosh <miklosh@users.sourceforge.net> | |
Mon, 13 Aug 2007 16:48:30 +0000 (16:48 +0000) |
diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp
index a9cf2ad2ba5c19618e719d79be9aeece3d3d5c6c..bc6190b827a8282dfd539de380912ecb5fbb5398 100644 (file)
@@ -296,9 +296,9 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
// initialize
state = new GfxState(72.0, 72.0, cropBox, rotate, gTrue);
+ clipHistory = new ClipHistoryEntry();
fontChanged = gFalse;
clip = clipNone;
- lastClipPath = NULL;
ignoreUndef = 0;
operatorHistory = NULL;
builder = builderA;
@@ -329,6 +329,7 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
state->lineTo(cropBox->x1, cropBox->y2);
state->closePath();
state->clip();
+ clipHistory->setClip(state->getPath(), clipNormal);
builder->setClipPath(state);
state->clearPath();
}
@@ -352,9 +353,9 @@ PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *bui
operatorHistory = NULL;
builder = builderA;
state = new GfxState(72, 72, box, 0, gFalse);
+ clipHistory = new ClipHistoryEntry();
fontChanged = gFalse;
clip = clipNone;
- lastClipPath = NULL;
ignoreUndef = 0;
for (i = 0; i < 6; ++i) {
baseMatrix[i] = state->getCTM()[i];
if (state) {
delete state;
}
- if (lastClipPath) {
- delete lastClipPath;
+ if (clipHistory) {
+ delete clipHistory;
}
}
break;
case 2:
case 3:
- if (lastClipPath) {
- builder->addShadedFill(shading, matrix, lastClipPath,
- lastClipType == clipEO ? true : false);
+ if (clipHistory->getClipPath()) {
+ builder->addShadedFill(shading, matrix, clipHistory->getClipPath(),
+ clipHistory->getClipType() == clipEO ? true : false);
}
break;
case 4:
if (state->isCurPt() && clip != clipNone) {
state->clip();
if (clip == clipNormal) {
+ clipHistory->setClip(state->getPath(), clipNormal);
builder->clip(state);
} else {
+ clipHistory->setClip(state->getPath(), clipEO);
builder->clip(state, true);
}
}
void PdfParser::opClip(Object args[], int numArgs) {
clip = clipNormal;
- lastClipType = clipNormal;
- if (lastClipPath)
- delete lastClipPath;
- lastClipPath = state->getPath()->copy();
}
void PdfParser::opEOClip(Object args[], int numArgs) {
clip = clipEO;
- lastClipType = clipEO;
- if (lastClipPath)
- delete lastClipPath;
- lastClipPath = state->getPath()->copy();
}
//------------------------------------------------------------------------
@@ -2834,6 +2829,7 @@ void PdfParser::doForm1(Object *str, Dict *resDict, double *matrix, double *bbox
state->lineTo(bbox[0], bbox[3]);
state->closePath();
state->clip();
+ clipHistory->setClip(state->getPath());
builder->clip(state);
state->clearPath();
void PdfParser::saveState() {
builder->saveState();
state = state->save();
+ clipHistory = clipHistory->save();
}
void PdfParser::restoreState() {
+ clipHistory = clipHistory->restore();
state = state->restore();
builder->restoreState();
}
res = resPtr;
}
+//------------------------------------------------------------------------
+// ClipHistoryEntry
+//------------------------------------------------------------------------
+
+ClipHistoryEntry::ClipHistoryEntry(GfxPath *clipPathA, GfxClipType clipTypeA) {
+ if (clipPathA) {
+ clipPath = clipPathA->copy();
+ } else {
+ clipPath = NULL;
+ }
+ clipType = clipTypeA;
+ saved = NULL;
+}
+
+ClipHistoryEntry::~ClipHistoryEntry() {
+ if (clipPath) {
+ delete clipPath;
+ }
+}
+
+void ClipHistoryEntry::setClip(GfxPath *clipPathA, GfxClipType clipTypeA) {
+ // Free previous clip path
+ if (clipPath) {
+ delete clipPath;
+ }
+ if (clipPathA) {
+ clipPath = clipPathA->copy();
+ clipType = clipTypeA;
+ } else {
+ clipPath = NULL;
+ }
+}
+
+ClipHistoryEntry *ClipHistoryEntry::save() {
+ ClipHistoryEntry *newEntry = new ClipHistoryEntry(this);
+ newEntry->saved = this;
+
+ return newEntry;
+}
+
+ClipHistoryEntry *ClipHistoryEntry::restore() {
+ ClipHistoryEntry *oldEntry;
+
+ if (saved) {
+ oldEntry = saved;
+ saved = NULL;
+ delete this;
+ } else {
+ oldEntry = this;
+ }
+
+ return oldEntry;
+}
+
+ClipHistoryEntry::ClipHistoryEntry(ClipHistoryEntry *other) {
+ if (other->clipPath) {
+ this->clipPath = other->clipPath->copy();
+ this->clipType = other->clipType;
+ } else {
+ this->clipPath = NULL;
+ }
+ saved = NULL;
+}
+
#endif /* HAVE_POPPLER */
diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h
index 40457453729ba14af273071ce0ff87ecb78f34b1..dc119cbf9abd245f90ffc976ea9a2eee7e454900 100644 (file)
unsigned depth; // total number of entries descending from this
};
+//------------------------------------------------------------------------
+// ClipHistoryEntry
+//------------------------------------------------------------------------
+
+class ClipHistoryEntry {
+public:
+
+ ClipHistoryEntry(GfxPath *clipPath=NULL, GfxClipType clipType=clipNormal);
+ ~ClipHistoryEntry();
+
+ // Manipulate clip path stack
+ ClipHistoryEntry *save();
+ ClipHistoryEntry *restore();
+ GBool hasSaves() { return saved != NULL; }
+ void setClip(GfxPath *newClipPath, GfxClipType newClipType=clipNormal);
+ GfxPath *getClipPath() { return clipPath; }
+ GfxClipType getClipType() { return clipType; }
+
+private:
+
+ ClipHistoryEntry *saved; // next clip path on stack
+
+ GfxPath *clipPath; // used as the path to be filled for an 'sh' operator
+ GfxClipType clipType;
+
+ ClipHistoryEntry(ClipHistoryEntry *other);
+};
+
//------------------------------------------------------------------------
// PdfParser
//------------------------------------------------------------------------
static PdfOperator opTab[]; // table of operators
+ ClipHistoryEntry *clipHistory; // clip path stack
OpHistoryEntry *operatorHistory; // list containing the last N operators
void pushOperator(const char *name);
OpHistoryEntry *popOperator();
const char *getPreviousOperator(unsigned int look_back=1); // returns the nth previous operator's name
- GfxPath *lastClipPath; // Used as the path to be filled for an 'sh' operator
- GfxClipType lastClipType;
void go(GBool topLevel);
void execOp(Object *cmd, Object args[], int numArgs);
diff --git a/src/extension/internal/pdfinput/svg-builder.cpp b/src/extension/internal/pdfinput/svg-builder.cpp
index 7a63ba41510a4a9d27c5529e07bf97f7dc59c606..b4aaefd235acf532f19a3d4cb35dc06d77cb6148 100644 (file)
*
*/
-SvgBuilder::SvgBuilder() {
- _in_text_object = false;
- _need_font_update = true;
- _invalidated_style = true;
- _font_style = NULL;
- _current_font = NULL;
- _current_state = NULL;
-}
-
SvgBuilder::SvgBuilder(SPDocument *document, gchar *docname, XRef *xref) {
_is_top_level = true;
_doc = document;
_xml_doc = sp_document_repr_doc(_doc);
_container = _root = _doc->rroot;
_root->setAttribute("xml:space", "preserve");
- SvgBuilder();
+ _init();
}
SvgBuilder::SvgBuilder(SvgBuilder *parent, Inkscape::XML::Node *root) {
_xref = parent->_xref;
_xml_doc = parent->_xml_doc;
_container = this->_root = root;
- SvgBuilder();
+ _init();
}
SvgBuilder::~SvgBuilder() {
}
+void SvgBuilder::_init() {
+ _in_text_object = false;
+ _need_font_update = true;
+ _invalidated_style = true;
+ _font_style = NULL;
+ _current_font = NULL;
+ _current_state = NULL;
+
+ _node_stack.push_back(_container);
+}
+
void SvgBuilder::setDocumentSize(double width, double height) {
sp_repr_set_svg_double(_root, "width", width);
sp_repr_set_svg_double(_root, "height", height);
_group_depth.pop_back();
}
-Inkscape::XML::Node *SvgBuilder::pushGroup() {
- Inkscape::XML::Node *node = _xml_doc->createElement("svg:g");
- _container->appendChild(node);
+Inkscape::XML::Node *SvgBuilder::pushNode(const char *name) {
+ Inkscape::XML::Node *node = _xml_doc->createElement(name);
+ _node_stack.push_back(node);
_container = node;
+ return node;
+}
+
+Inkscape::XML::Node *SvgBuilder::popNode() {
+ Inkscape::XML::Node *node = NULL;
+ if ( _node_stack.size() > 1 ) {
+ node = _node_stack.back();
+ _node_stack.pop_back();
+ _container = _node_stack.back(); // Re-set container
+ } else {
+ TRACE(("popNode() called when stack is empty\n"));
+ node = _root;
+ }
+ return node;
+}
+
+Inkscape::XML::Node *SvgBuilder::pushGroup() {
+ Inkscape::XML::Node *saved_container = _container;
+ Inkscape::XML::Node *node = pushNode("svg:g");
+ saved_container->appendChild(node);
Inkscape::GC::release(node);
_group_depth.back()++;
// Set as a layer if this is a top-level group
Inkscape::XML::Node *SvgBuilder::popGroup() {
if (_container != _root) { // Pop if the current container isn't root
- _container = _container->parent();
+ popNode();
_group_depth[_group_depth.size()-1] = --_group_depth.back();
}
diff --git a/src/extension/internal/pdfinput/svg-builder.h b/src/extension/internal/pdfinput/svg-builder.h
index 6a5d94ee26b8d87db8bc7410dc7752e73f4f2d41..8a3687e6d03dc74c7ed8fedce9e7598c0af18ee0 100644 (file)
bool getTransform(double *transform);
private:
- SvgBuilder();
+ void _init();
// Pattern creation
gchar *_createPattern(GfxPattern *pattern, GfxState *state, bool is_stroke=false);
void _flushText(); // Write buffered text into doc
+ // Handling of node stack
+ Inkscape::XML::Node *pushNode(const char* name);
+ Inkscape::XML::Node *popNode();
+ std::vector<Inkscape::XML::Node *> _node_stack;
std::vector<int> _group_depth; // Depth of nesting groups
SPCSSAttr *_font_style; // Current font style