diff options
| author | Liam P. White <inkscapebrony@gmail.com> | 2014-10-18 21:44:39 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebrony@gmail.com> | 2014-10-18 21:44:39 +0000 |
| commit | 68136c8b24a6995976db963a790207858e9baba5 (patch) | |
| tree | 550e81af7c8d626ec80a2be5efec66dd10d84bc4 /src/extension/internal | |
| parent | Update to experimental r13598 (diff) | |
| parent | Update to trunk r13621 (diff) | |
| download | inkscape-68136c8b24a6995976db963a790207858e9baba5.tar.gz inkscape-68136c8b24a6995976db963a790207858e9baba5.zip | |
Update to experimental r13619
(bzr r13341.5.18)
Diffstat (limited to 'src/extension/internal')
| -rw-r--r-- | src/extension/internal/cairo-render-context.cpp | 116 | ||||
| -rw-r--r-- | src/extension/internal/cairo-render-context.h | 1 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.cpp | 16 | ||||
| -rw-r--r-- | src/extension/internal/cairo-renderer.h | 2 | ||||
| -rw-r--r-- | src/extension/internal/cdr-input.cpp | 36 | ||||
| -rw-r--r-- | src/extension/internal/pdfinput/pdf-input.cpp | 24 | ||||
| -rw-r--r-- | src/extension/internal/pdfinput/pdf-parser.cpp | 182 | ||||
| -rw-r--r-- | src/extension/internal/pdfinput/pdf-parser.h | 30 | ||||
| -rw-r--r-- | src/extension/internal/vsd-input.cpp | 37 | ||||
| -rw-r--r-- | src/extension/internal/wpg-input.cpp | 57 |
10 files changed, 359 insertions, 142 deletions
diff --git a/src/extension/internal/cairo-render-context.cpp b/src/extension/internal/cairo-render-context.cpp index c09b8e9c8..7e61cdbbb 100644 --- a/src/extension/internal/cairo-render-context.cpp +++ b/src/extension/internal/cairo-render-context.cpp @@ -39,6 +39,7 @@ #include "sp-item.h" #include "sp-item-group.h" #include "style.h" +#include "sp-hatch.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" #include "sp-pattern.h" @@ -1130,6 +1131,82 @@ CairoRenderContext::_createPatternPainter(SPPaintServer const *const paintserver } cairo_pattern_t* +CairoRenderContext::_createHatchPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox) { + g_assert( SP_IS_HATCH(paintserver) ); + SPHatch *hatch = SP_HATCH(paintserver); + + g_assert(hatch->pitch() > 0); + + // create drawing and group + Inkscape::Drawing drawing; + unsigned dkey = SPItem::display_key_new(1); + + hatch->show(drawing, dkey, pbox); + + SPHatch::RenderInfo render_info = hatch->calculateRenderInfo(dkey); + Geom::Rect tile_rect = render_info.tile_rect; + + // Cairo requires an integer pattern surface width/height. + // Subtract 0.5 to prevent small rounding errors from increasing pattern size by one pixel. + // Multiply by SUBPIX_SCALE to allow for less than a pixel precision + const int subpix_scale = 10; + double surface_width = MAX(ceil(subpix_scale * tile_rect.width() - 0.5), 1); + double surface_height = MAX(ceil(subpix_scale * tile_rect.height() - 0.5), 1); + Geom::Affine drawing_scale = Geom::Scale(surface_width / tile_rect.width(), surface_height / tile_rect.height()); + Geom::Affine drawing_transform = Geom::Translate(-tile_rect.min()) * drawing_scale; + + Geom::Affine child_transform = render_info.child_transform; + child_transform *= drawing_transform; + + //The rendering of hatch overflow is implemented by repeated drawing + //of hatch paths over one strip. Within each iteration paths are moved by pitch value. + //The movement progresses from right to left. This gives the same result + //as drawing whole strips in left-to-right order. + gdouble overflow_right_strip = 0.0; + int overflow_steps = 1; + Geom::Affine overflow_transform; + if (hatch->style->overflow.computed == SP_CSS_OVERFLOW_VISIBLE) { + Geom::Interval bounds = hatch->bounds(); + overflow_right_strip = floor(bounds.max() / hatch->pitch()) * hatch->pitch(); + overflow_steps = ceil((overflow_right_strip - bounds.min()) / hatch->pitch()) + 1; + overflow_transform = Geom::Translate(hatch->pitch(), 0.0); + } + + CairoRenderContext *pattern_ctx = cloneMe(surface_width, surface_height); + pattern_ctx->setTransform(child_transform); + pattern_ctx->transform(Geom::Translate(-overflow_right_strip, 0.0)); + pattern_ctx->pushState(); + + std::vector<SPHatchPath *> children; + hatch->hatchPaths(children); + + for (int i = 0; i < overflow_steps; i++) { + for (std::vector<SPHatchPath *>::iterator iter = children.begin(); iter != children.end(); iter++) { + SPHatchPath *path = *iter; + _renderer->renderHatchPath(pattern_ctx, *path, dkey); + } + pattern_ctx->transform(overflow_transform); + } + + pattern_ctx->popState(); + + // setup a cairo_pattern_t + cairo_surface_t *pattern_surface = pattern_ctx->getSurface(); + TEST(pattern_ctx->saveAsPng("hatch.png")); + cairo_pattern_t *result = cairo_pattern_create_for_surface(pattern_surface); + cairo_pattern_set_extend(result, CAIRO_EXTEND_REPEAT); + + Geom::Affine pattern_transform; + pattern_transform = render_info.pattern_to_user_transform.inverse() * drawing_transform; + ink_cairo_pattern_set_matrix(result, pattern_transform); + + hatch->hide(dkey); + + delete pattern_ctx; + return result; +} + +cairo_pattern_t* CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const paintserver, Geom::OptRect const &pbox, float alpha) { @@ -1182,8 +1259,9 @@ CairoRenderContext::_createPatternForPaintServer(SPPaintServer const *const pain cairo_pattern_add_color_stop_rgba(pattern, rg->vector.stops[i].offset, rgb[0], rgb[1], rgb[2], rg->vector.stops[i].opacity * alpha); } } else if (SP_IS_PATTERN (paintserver)) { - pattern = _createPatternPainter(paintserver, pbox); + } else if (SP_IS_HATCH (paintserver)) { + pattern = _createHatchPainter(paintserver, pbox); } else { return NULL; } @@ -1249,26 +1327,29 @@ CairoRenderContext::_setFillStyle(SPStyle const *const style, Geom::OptRect cons TRACE(("merged op=%f\n", alpha)); } - if (style->fill.isColor()) { - float rgb[3]; - sp_color_get_rgb_floatv(&style->fill.value.color, rgb); + SPPaintServer const *paint_server = style->getFillPaintServer(); + if (paint_server && paint_server->isValid()) { - cairo_set_source_rgba(_cr, rgb[0], rgb[1], rgb[2], alpha); - - } else if (!style->fill.set) { // unset fill is black - cairo_set_source_rgba(_cr, 0, 0, 0, alpha); - - } else { - g_assert( style->fill.isPaintserver() - || SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) - || SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) ); - - cairo_pattern_t *pattern = _createPatternForPaintServer(SP_STYLE_FILL_SERVER(style), pbox, alpha); + g_assert(SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) + || SP_IS_PATTERN(SP_STYLE_FILL_SERVER(style)) + || SP_IS_HATCH(SP_STYLE_FILL_SERVER(style))); + cairo_pattern_t *pattern = _createPatternForPaintServer(paint_server, pbox, alpha); if (pattern) { cairo_set_source(_cr, pattern); cairo_pattern_destroy(pattern); } + } else if (style->fill.colorSet) { + float rgb[3]; + sp_color_get_rgb_floatv(&style->fill.value.color, rgb); + + cairo_set_source_rgba(_cr, rgb[0], rgb[1], rgb[2], alpha); + + } else { // unset fill is black + g_assert(!style->fill.set + || (paint_server && !paint_server->isValid())); + + cairo_set_source_rgba(_cr, 0, 0, 0, alpha); } } @@ -1279,7 +1360,7 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, Geom::OptRect const &p if (_state->merge_opacity) alpha *= _state->opacity; - if (style->stroke.isColor()) { + if (style->stroke.isColor() || (style->stroke.isPaintserver() && !style->getStrokePaintServer()->isValid())) { float rgb[3]; sp_color_get_rgb_floatv(&style->stroke.value.color, rgb); @@ -1287,7 +1368,8 @@ CairoRenderContext::_setStrokeStyle(SPStyle const *style, Geom::OptRect const &p } else { g_assert( style->stroke.isPaintserver() || SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) - || SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) ); + || SP_IS_PATTERN(SP_STYLE_STROKE_SERVER(style)) + || SP_IS_HATCH(SP_STYLE_STROKE_SERVER(style))); cairo_pattern_t *pattern = _createPatternForPaintServer(SP_STYLE_STROKE_SERVER(style), pbox, alpha); diff --git a/src/extension/internal/cairo-render-context.h b/src/extension/internal/cairo-render-context.h index 8071cae36..57d155b60 100644 --- a/src/extension/internal/cairo-render-context.h +++ b/src/extension/internal/cairo-render-context.h @@ -204,6 +204,7 @@ protected: cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver, Geom::OptRect const &pbox, float alpha); cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox); + cairo_pattern_t *_createHatchPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox); unsigned int _showGlyphs(cairo_t *cr, PangoFont *font, std::vector<CairoGlyphInfo> const &glyphtext, bool is_stroke); diff --git a/src/extension/internal/cairo-renderer.cpp b/src/extension/internal/cairo-renderer.cpp index 8196e34fb..a725685d4 100644 --- a/src/extension/internal/cairo-renderer.cpp +++ b/src/extension/internal/cairo-renderer.cpp @@ -50,6 +50,7 @@ #include "sp-use.h" #include "sp-text.h" #include "sp-flowtext.h" +#include "sp-hatch-path.h" #include "sp-image.h" #include "sp-symbol.h" #include "sp-pattern.h" @@ -598,6 +599,21 @@ void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item) ctx->popState(); } +void CairoRenderer::renderHatchPath(CairoRenderContext *ctx, SPHatchPath const &hatchPath, unsigned key) { + ctx->pushState(); + ctx->setStateForStyle(hatchPath.style); + ctx->transform(Geom::Translate(hatchPath.offset.computed, 0)); + + SPCurve *curve = hatchPath.calculateRenderCurve(key); + Geom::PathVector const & pathv =curve->get_pathvector(); + if (!pathv.empty()) { + ctx->renderPathVector(pathv, hatchPath.style, Geom::OptRect()); + } + + curve->unref(); + ctx->popState(); +} + bool CairoRenderer::setupDocument(CairoRenderContext *ctx, SPDocument *doc, bool pageBoundingBox, float bleedmargin_px, SPItem *base) { diff --git a/src/extension/internal/cairo-renderer.h b/src/extension/internal/cairo-renderer.h index cfef6bdea..abc0447d8 100644 --- a/src/extension/internal/cairo-renderer.h +++ b/src/extension/internal/cairo-renderer.h @@ -29,6 +29,7 @@ class SPClipPath; class SPMask; +class SPHatchPath; namespace Inkscape { namespace Extension { @@ -57,6 +58,7 @@ public: /** Traverses the object tree and invokes the render methods. */ void renderItem(CairoRenderContext *ctx, SPItem *item); + void renderHatchPath(CairoRenderContext *ctx, SPHatchPath const &hatchPath, unsigned key); }; // FIXME: this should be a static method of CairoRenderer diff --git a/src/extension/internal/cdr-input.cpp b/src/extension/internal/cdr-input.cpp index 1de3f304b..fb58887c9 100644 --- a/src/extension/internal/cdr-input.cpp +++ b/src/extension/internal/cdr-input.cpp @@ -24,7 +24,21 @@ #include <cstring> #include <libcdr/libcdr.h> -#include <libwpd-stream/libwpd-stream.h> + +// TODO: Drop this check when librevenge is widespread. +#if WITH_LIBCDR01 + #include <librevenge-stream/librevenge-stream.h> + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; +#else + #include <libwpd-stream/libwpd-stream.h> + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef libcdr::CDRStringVector RVNGStringVector; +#endif #include <gtkmm/alignment.h> #include <gtkmm/comboboxtext.h> @@ -60,7 +74,7 @@ namespace Internal { class CdrImportDialog : public Gtk::Dialog { public: - CdrImportDialog(const std::vector<WPXString> &vec); + CdrImportDialog(const std::vector<RVNGString> &vec); virtual ~CdrImportDialog(); bool showDialog(); @@ -86,12 +100,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector<WPXString> &_vec; // Document to be imported + const std::vector<RVNGString> &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -CdrImportDialog::CdrImportDialog(const std::vector<WPXString> &vec) +CdrImportDialog::CdrImportDialog(const std::vector<RVNGString> &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -216,14 +230,20 @@ void CdrImportDialog::_setPreviewPage(unsigned page) SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - WPXFileStream input(uri); + RVNGFileStream input(uri); if (!libcdr::CDRDocument::isSupported(&input)) { return NULL; } - libcdr::CDRStringVector output; + RVNGStringVector output; +#if WITH_LIBCDR01 + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libcdr::CDRDocument::parse(&input, &generator)) { +#else if (!libcdr::CDRDocument::generateSVG(&input, output)) { +#endif return NULL; } @@ -231,9 +251,9 @@ SPDocument *CdrInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector<WPXString> tmpSVGOutput; + std::vector<RVNGString> tmpSVGOutput; for (unsigned i=0; i<output.size(); ++i) { - WPXString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); + RVNGString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index e18d898f5..defb15754 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -647,7 +647,31 @@ PdfInput::open(::Inkscape::Extension::Input * /*mod*/, const gchar * uri) { // Initialize the globalParams variable for poppler if (!globalParams) { +#ifdef ENABLE_OSX_APP_LOCATIONS + // + // data files for poppler are not relocatable (loaded from + // path defined at build time). This fails to work with relocatable + // application bundles for OS X. + // + // Workaround: + // 1. define $POPPLER_DATADIR env variable in app launcher script + // 2. pass custom $POPPLER_DATADIR via poppler's GlobalParams() + // + // relevant poppler commit: + // <http://cgit.freedesktop.org/poppler/poppler/commit/?id=869584a84eed507775ff1c3183fe484c14b6f77b> + // + // FIXES: Inkscape bug #956282, #1264793 + // TODO: report RFE upstream (full relocation support for OS X packaging) + // + gchar const *poppler_datadir = g_getenv("POPPLER_DATADIR"); + if (poppler_datadir != NULL) { + globalParams = new GlobalParams(poppler_datadir); + } else { + globalParams = new GlobalParams(); + } +#else globalParams = new GlobalParams(); +#endif // ENABLE_OSX_APP_LOCATIONS } // poppler does not use glib g_open. So on win32 we must use unicode call. code was copied from glib gstdio.c #ifndef WIN32 diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index c5f03e5aa..0b7dc7905 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -247,30 +247,74 @@ PdfOperator PdfParser::opTab[] = { #define numOps (sizeof(opTab) / sizeof(PdfOperator)) +namespace { + +GfxPatch blankPatch() +{ + GfxPatch patch; + memset(&patch, 0, sizeof(patch)); // quick-n-dirty + return patch; +} + +} // namespace + //------------------------------------------------------------------------ -// PdfParser +// ClipHistoryEntry //------------------------------------------------------------------------ -PdfParser::PdfParser(XRef *xrefA, Inkscape::Extension::Internal::SvgBuilder *builderA, - int /*pageNum*/, int rotate, Dict *resDict, - PDFRectangle *box, PDFRectangle *cropBox) -{ - xref = xrefA; - subPage = gFalse; - printCommands = false; +class ClipHistoryEntry { +public: + + ClipHistoryEntry(GfxPath *clipPath = NULL, GfxClipType clipType = clipNormal); + virtual ~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; } - // start the resource stack - res = new GfxResources(xref, resDict, NULL); +private: - // initialize - state = new GfxState(72.0, 72.0, box, rotate, gTrue); - clipHistory = new ClipHistoryEntry(); + 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 +//------------------------------------------------------------------------ + +PdfParser::PdfParser(XRef *xrefA, + Inkscape::Extension::Internal::SvgBuilder *builderA, + int /*pageNum*/, + int rotate, + Dict *resDict, + PDFRectangle *box, + PDFRectangle *cropBox) : + xref(xrefA), + builder(builderA), + subPage(gFalse), + printCommands(false), + res(new GfxResources(xref, resDict, NULL)), // start the resource stack + state(new GfxState(72.0, 72.0, box, rotate, gTrue)), + fontChanged(gFalse), + clip(clipNone), + ignoreUndef(0), + baseMatrix(), + formDepth(0), + parser(NULL), + colorDeltas(), + maxDepths(), + clipHistory(new ClipHistoryEntry()), + operatorHistory(NULL) +{ setDefaultApproximationPrecision(); - fontChanged = gFalse; - clip = clipNone; - ignoreUndef = 0; - operatorHistory = NULL; - builder = builderA; builder->setDocumentSize(Inkscape::Util::Quantity::convert(state->getPageWidth(), "pt", "px"), Inkscape::Util::Quantity::convert(state->getPageHeight(), "pt", "px")); @@ -306,50 +350,62 @@ 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; - parser = NULL; - - 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); - clipHistory = new ClipHistoryEntry(); +PdfParser::PdfParser(XRef *xrefA, + Inkscape::Extension::Internal::SvgBuilder *builderA, + Dict *resDict, + PDFRectangle *box) : + xref(xrefA), + builder(builderA), + subPage(gTrue), + printCommands(false), + res(new GfxResources(xref, resDict, NULL)), // start the resource stack + state(new GfxState(72, 72, box, 0, gFalse)), + fontChanged(gFalse), + clip(clipNone), + ignoreUndef(0), + baseMatrix(), + formDepth(0), + parser(NULL), + colorDeltas(), + maxDepths(), + clipHistory(new ClipHistoryEntry()), + operatorHistory(NULL) +{ setDefaultApproximationPrecision(); - fontChanged = gFalse; - clip = clipNone; - ignoreUndef = 0; - for (i = 0; i < 6; ++i) { + for (int i = 0; i < 6; ++i) { baseMatrix[i] = state->getCTM()[i]; } formDepth = 0; } PdfParser::~PdfParser() { - while (state->hasSaves()) { + while(operatorHistory) { + OpHistoryEntry *tmp = operatorHistory->next; + delete operatorHistory; + operatorHistory = tmp; + } + + while (state && state->hasSaves()) { restoreState(); } + if (!subPage) { //out->endPage(); } + while (res) { popResources(); } + if (state) { delete state; + state = NULL; } + if (clipHistory) { delete clipHistory; + clipHistory = NULL; } } @@ -460,7 +516,8 @@ void PdfParser::go(GBool /*topLevel*/) } } -void PdfParser::pushOperator(const char *name) { +void PdfParser::pushOperator(const char *name) +{ OpHistoryEntry *newEntry = new OpHistoryEntry; newEntry->name = name; newEntry->state = NULL; @@ -2086,13 +2143,19 @@ void PdfParser::doPatchMeshShFill(GfxPatchMeshShading *shading) { } void PdfParser::fillPatch(GfxPatch *patch, int nComps, int depth) { - GfxPatch patch00, patch01, patch10, patch11; + GfxPatch patch00 = blankPatch(); + GfxPatch patch01 = blankPatch(); + GfxPatch patch10 = blankPatch(); + GfxPatch patch11 = blankPatch(); #ifdef POPPLER_NEW_GFXPATCH - GfxColor color; + GfxColor color = {{0}}; #endif - double xx[4][8], yy[4][8]; - double xxm, yym; - double patchColorDelta = colorDeltas[pdfPatchMeshShading-1]; + double xx[4][8]; + double yy[4][8]; + double xxm; + double yym; + double patchColorDelta = colorDeltas[pdfPatchMeshShading - 1]; + int i; for (i = 0; i < nComps; ++i) { @@ -3463,9 +3526,7 @@ void PdfParser::popResources() { } void PdfParser::setDefaultApproximationPrecision() { - int i; - - for (i = 1; i <= pdfNumShadingTypes; ++i) { + for (int i = 1; i <= pdfNumShadingTypes; ++i) { setApproximationPrecision(i, defaultShadingColorDelta, defaultShadingMaxDepth); } } @@ -3484,19 +3545,18 @@ void PdfParser::setApproximationPrecision(int shadingType, double colorDelta, // ClipHistoryEntry //------------------------------------------------------------------------ -ClipHistoryEntry::ClipHistoryEntry(GfxPath *clipPathA, GfxClipType clipTypeA) { - if (clipPathA) { - clipPath = clipPathA->copy(); - } else { - clipPath = NULL; - } - clipType = clipTypeA; - saved = NULL; +ClipHistoryEntry::ClipHistoryEntry(GfxPath *clipPathA, GfxClipType clipTypeA) : + saved(NULL), + clipPath((clipPathA) ? clipPathA->copy() : NULL), + clipType(clipTypeA) +{ } -ClipHistoryEntry::~ClipHistoryEntry() { +ClipHistoryEntry::~ClipHistoryEntry() +{ if (clipPath) { delete clipPath; + clipPath = NULL; } } @@ -3510,6 +3570,7 @@ void ClipHistoryEntry::setClip(GfxPath *clipPathA, GfxClipType clipTypeA) { clipType = clipTypeA; } else { clipPath = NULL; + clipType = clipNormal; } } @@ -3526,7 +3587,7 @@ ClipHistoryEntry *ClipHistoryEntry::restore() { if (saved) { oldEntry = saved; saved = NULL; - delete this; + delete this; // TODO really should avoid deleting from inside. } else { oldEntry = this; } @@ -3540,6 +3601,7 @@ ClipHistoryEntry::ClipHistoryEntry(ClipHistoryEntry *other) { this->clipType = other->clipType; } else { this->clipPath = NULL; + this->clipType = clipNormal; } saved = NULL; } diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h index a63d669c7..e28fecc2e 100644 --- a/src/extension/internal/pdfinput/pdf-parser.h +++ b/src/extension/internal/pdfinput/pdf-parser.h @@ -58,6 +58,8 @@ class AnnotBorderStyle; class PdfParser; +class ClipHistoryEntry; + //------------------------------------------------------------------------ #ifndef GFX_H @@ -101,34 +103,6 @@ struct OpHistoryEntry { }; //------------------------------------------------------------------------ -// ClipHistoryEntry -//------------------------------------------------------------------------ - -class ClipHistoryEntry { -public: - - ClipHistoryEntry(GfxPath *clipPath=NULL, GfxClipType clipType=clipNormal); - virtual ~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 //------------------------------------------------------------------------ diff --git a/src/extension/internal/vsd-input.cpp b/src/extension/internal/vsd-input.cpp index 2623d1ca7..25815e64f 100644 --- a/src/extension/internal/vsd-input.cpp +++ b/src/extension/internal/vsd-input.cpp @@ -24,7 +24,22 @@ #include <cstring> #include <libvisio/libvisio.h> -#include <libwpd-stream/libwpd-stream.h> + +// TODO: Drop this check when librevenge is widespread. +#if WITH_LIBVISIO01 + #include <librevenge-stream/librevenge-stream.h> + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGStringVector; +#else + #include <libwpd-stream/libwpd-stream.h> + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef libvisio::VSDStringVector RVNGStringVector; +#endif + #include <gtkmm/alignment.h> #include <gtkmm/comboboxtext.h> @@ -59,7 +74,7 @@ namespace Internal { class VsdImportDialog : public Gtk::Dialog { public: - VsdImportDialog(const std::vector<WPXString> &vec); + VsdImportDialog(const std::vector<RVNGString> &vec); virtual ~VsdImportDialog(); bool showDialog(); @@ -85,12 +100,12 @@ private: class Gtk::VBox * vbox2; class Gtk::Widget * _previewArea; - const std::vector<WPXString> &_vec; // Document to be imported + const std::vector<RVNGString> &_vec; // Document to be imported unsigned _current_page; // Current selected page int _preview_width, _preview_height; // Size of the preview area }; -VsdImportDialog::VsdImportDialog(const std::vector<WPXString> &vec) +VsdImportDialog::VsdImportDialog(const std::vector<RVNGString> &vec) : _vec(vec), _current_page(1) { int num_pages = _vec.size(); @@ -215,14 +230,20 @@ void VsdImportDialog::_setPreviewPage(unsigned page) SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { - WPXFileStream input(uri); + RVNGFileStream input(uri); if (!libvisio::VisioDocument::isSupported(&input)) { return NULL; } - libvisio::VSDStringVector output; + RVNGStringVector output; +#if WITH_LIBVISIO01 + librevenge::RVNGSVGDrawingGenerator generator(output, "svg"); + + if (!libvisio::VisioDocument::parse(&input, &generator)) { +#else if (!libvisio::VisioDocument::generateSVG(&input, output)) { +#endif return NULL; } @@ -230,9 +251,9 @@ SPDocument *VsdInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } - std::vector<WPXString> tmpSVGOutput; + std::vector<RVNGString> tmpSVGOutput; for (unsigned i=0; i<output.size(); ++i) { - WPXString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); + RVNGString tmpString("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); tmpString.append(output[i]); tmpSVGOutput.push_back(tmpString); } diff --git a/src/extension/internal/wpg-input.cpp b/src/extension/internal/wpg-input.cpp index 14ff3ec77..12d86a99a 100644 --- a/src/extension/internal/wpg-input.cpp +++ b/src/extension/internal/wpg-input.cpp @@ -52,16 +52,24 @@ #include "util/units.h" #include <cstring> -// Take a guess and fallback to 0.1.x if no configure has run -#if !defined(WITH_LIBWPG01) && !defined(WITH_LIBWPG02) -#define WITH_LIBWPG01 1 +// Take a guess and fallback to 0.2.x if no configure has run +#if !defined(WITH_LIBWPG03) && !defined(WITH_LIBWPG02) +#define WITH_LIBWPG02 1 #endif #include "libwpg/libwpg.h" -#if WITH_LIBWPG01 -#include "libwpg/WPGStreamImplementation.h" -#elif WITH_LIBWPG02 -#include "libwpd-stream/libwpd-stream.h" +#if WITH_LIBWPG03 + #include <librevenge-stream/librevenge-stream.h> + + using librevenge::RVNGString; + using librevenge::RVNGFileStream; + using librevenge::RVNGInputStream; +#else + #include "libwpd-stream/libwpd-stream.h" + + typedef WPXString RVNGString; + typedef WPXFileStream RVNGFileStream; + typedef WPXInputStream RVNGInputStream; #endif using namespace libwpg; @@ -73,17 +81,15 @@ namespace Internal { SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * uri) { -#if WITH_LIBWPG01 - WPXInputStream* input = new libwpg::WPGFileStream(uri); -#elif WITH_LIBWPG02 - WPXInputStream* input = new WPXFileStream(uri); -#endif + RVNGInputStream* input = new RVNGFileStream(uri); +#if WITH_LIBWPG03 + if (input->isStructured()) { + RVNGInputStream* olestream = input->getSubStreamByName("PerfectOffice_MAIN"); +#else if (input->isOLEStream()) { -#if WITH_LIBWPG01 - WPXInputStream* olestream = input->getDocumentOLEStream(); -#elif WITH_LIBWPG02 - WPXInputStream* olestream = input->getDocumentOLEStream("PerfectOffice_MAIN"); + RVNGInputStream* olestream = input->getDocumentOLEStream("PerfectOffice_MAIN"); #endif + if (olestream) { delete input; input = olestream; @@ -98,15 +104,24 @@ SPDocument *WpgInput::open(Inkscape::Extension::Input * /*mod*/, const gchar * u return NULL; } -#if WITH_LIBWPG01 - libwpg::WPGString output; -#elif WITH_LIBWPG02 - WPXString output; -#endif +#if WITH_LIBWPG03 + librevenge::RVNGStringVector vec; + librevenge::RVNGSVGDrawingGenerator generator(vec, ""); + + if (!libwpg::WPGraphics::parse(input, &generator) || vec.empty() || vec[0].empty()) { + delete input; + return NULL; + } + + RVNGString output("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); + output.append(vec[0]); +#else + RVNGString output; if (!libwpg::WPGraphics::generateSVG(input, output)) { delete input; return NULL; } +#endif //printf("I've got a doc: \n%s", painter.document.c_str()); |
