From 62fbbefccbe10ec11e727735e6bfe890003b0af2 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 21 Aug 2012 02:54:06 +0200 Subject: Added "virtual pad" to - SPPaintServer - SPPattern - SPGradient - SPStop - SPLinearGradient - SPMeshGradient - SPMeshPatch - SPMeshRow - SPRadialGradient As all subclasses of SPPaintServer now have "virtual pads" with correct inheritance, the virtual function call to "onCreatePattern" was converted to C++ style. (bzr r11608.1.35) --- src/sp-pattern.cpp | 91 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 24 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 03afc1bf3..5e55cbe34 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -101,9 +101,20 @@ sp_pattern_class_init (SPPatternClass *klass) ps_class->pattern_new = sp_pattern_create_pattern; } +CPattern::CPattern(SPPattern* pattern) : CPaintServer(pattern) { + this->sppattern = pattern; +} + +CPattern::~CPattern() { +} + static void sp_pattern_init (SPPattern *pat) { + pat->cpattern = new CPattern(pat); + pat->cpaintserver = pat->cpattern; + pat->cobject = pat->cpattern; + pat->ref = new SPPatternReference(pat); pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); @@ -126,11 +137,10 @@ sp_pattern_init (SPPattern *pat) new (&pat->modified_connection) sigc::connection(); } -static void -sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) -{ - if (((SPObjectClass *) pattern_parent_class)->build) - (* ((SPObjectClass *) pattern_parent_class)->build) (object, document, repr); +void CPattern::onBuild(SPDocument* doc, Inkscape::XML::Node* repr) { + SPPattern* object = this->sppattern; + + CPaintServer::onBuild(doc, repr); object->readAttr( "patternUnits" ); object->readAttr( "patternContentUnits" ); @@ -143,11 +153,18 @@ sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *r object->readAttr( "xlink:href" ); /* Register ourselves */ - document->addResource("pattern", object); + doc->addResource("pattern", object); } -static void sp_pattern_release(SPObject *object) +static void +sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { + ((SPPattern*)object)->cpattern->onBuild(document, repr); +} + +void CPattern::onRelease() { + SPPattern* object = this->sppattern; + SPPattern *pat = reinterpret_cast(object); if (object->document) { @@ -164,14 +181,17 @@ static void sp_pattern_release(SPObject *object) pat->modified_connection.~connection(); - if (((SPObjectClass *) pattern_parent_class)->release) { - ((SPObjectClass *) pattern_parent_class)->release (object); - } + CPaintServer::onRelease(); } -static void -sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) +static void sp_pattern_release(SPObject *object) { + ((SPPattern*)object)->cpattern->onRelease(); +} + +void CPattern::onSet(unsigned int key, const gchar* value) { + SPPattern* object = this->sppattern; + SPPattern *pat = SP_PATTERN (object); switch (key) { @@ -280,12 +300,17 @@ sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) } break; default: - if (((SPObjectClass *) pattern_parent_class)->set) - ((SPObjectClass *) pattern_parent_class)->set (object, key, value); + CPaintServer::onSet(key, value); break; } } +static void +sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) +{ + ((SPPattern*)object)->cpattern->onSet(key, value); +} + /* TODO: do we need a ::remove_child handler? */ /* fixme: We need ::order_changed handler too (Lauris) */ @@ -306,9 +331,9 @@ GSList *pattern_getchildren(SPPattern *pat) return l; } -static void -sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags) -{ +void CPattern::onUpdate(SPCtx* ctx, unsigned int flags) { + SPPattern* object = this->sppattern; + SPPattern *pat = SP_PATTERN (object); if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; @@ -329,8 +354,14 @@ sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags) } static void -sp_pattern_modified (SPObject *object, guint flags) +sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags) { + ((SPPattern*)object)->cpattern->onUpdate(ctx, flags); +} + +void CPattern::onModified(unsigned int flags) { + SPPattern* object = this->sppattern; + SPPattern *pat = SP_PATTERN (object); if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; @@ -350,6 +381,12 @@ sp_pattern_modified (SPObject *object, guint flags) } } +static void +sp_pattern_modified (SPObject *object, guint flags) +{ + ((SPPattern*)object)->cpattern->onModified(flags); +} + /** Gets called when the pattern is reattached to another */ @@ -601,12 +638,9 @@ bool pattern_hasItemChildren (SPPattern *pat) return hasChildren; } -static cairo_pattern_t * -sp_pattern_create_pattern(SPPaintServer *ps, - cairo_t *base_ct, - Geom::OptRect const &bbox, - double opacity) -{ +cairo_pattern_t* CPattern::onCreatePattern(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { + SPPattern* ps = this->sppattern; + SPPattern *pat = SP_PATTERN (ps); Geom::Affine ps2user; Geom::Affine vb2ps = Geom::identity(); @@ -719,6 +753,15 @@ sp_pattern_create_pattern(SPPaintServer *ps, return cp; } +static cairo_pattern_t * +sp_pattern_create_pattern(SPPaintServer *ps, + cairo_t *base_ct, + Geom::OptRect const &bbox, + double opacity) +{ + return ((SPPattern*)ps)->cpattern->onCreatePattern(base_ct, bbox, opacity); +} + /* Local Variables: mode:c++ -- cgit v1.2.3 From 370a3f5cc9e39352a081e5d5dd8c43676547a6e6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Oct 2012 11:45:44 +1000 Subject: code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere. (bzr r11735) --- src/sp-pattern.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 03afc1bf3..19c0180a7 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -290,7 +290,7 @@ sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) /* fixme: We need ::order_changed handler too (Lauris) */ -GSList *pattern_getchildren(SPPattern *pat) +static GSList *pattern_getchildren(SPPattern *pat) { GSList *l = NULL; @@ -381,7 +381,7 @@ static void pattern_ref_modified (SPObject */*ref*/, guint /*flags*/, SPPattern /** Count how many times pat is used by the styles of o and its descendants */ -guint +static guint count_pattern_hrefs(SPObject *o, SPPattern *pat) { if (!o) @@ -590,7 +590,7 @@ Geom::OptRect pattern_viewBox (SPPattern *pat) return viewbox; } -bool pattern_hasItemChildren (SPPattern *pat) +static bool pattern_hasItemChildren (SPPattern *pat) { bool hasChildren = false; for (SPObject *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) { -- cgit v1.2.3 From d56037fd9574f7235138fefd9ebf44f5fc18d466 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 9 Dec 2012 16:34:43 +0100 Subject: noop: Added some comments, rearranged some lines to make code easier to follow. (bzr r11941) --- src/sp-pattern.cpp | 52 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 19c0180a7..ba171bb05 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -608,8 +608,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, double opacity) { SPPattern *pat = SP_PATTERN (ps); - Geom::Affine ps2user; - Geom::Affine vb2ps = Geom::identity(); + bool needs_opacity = (1.0 - opacity) >= 1e-3; bool visible = opacity >= 1e-3; @@ -646,6 +645,8 @@ sp_pattern_create_pattern(SPPaintServer *ps, } } + // viewBox to pattern server + Geom::Affine vb2ps = Geom::identity(); if (pat->viewBox_set) { Geom::Rect vb = *pattern_viewBox(pat); gdouble tmp_x = pattern_width (pat) / vb.width(); @@ -655,6 +656,11 @@ sp_pattern_create_pattern(SPPaintServer *ps, vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - vb.left() * tmp_x, pattern_y(pat) - vb.top() * tmp_y); } + // We must determine the size and scaling of the pattern at the time it is displayed and render + // the pattern onto a surface with that size and at that resolution. + + // Pattern server to user + Geom::Affine ps2user; ps2user = pattern_patternTransform(pat); if (!pat->viewBox_set && pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { /* BBox to user coordinate system */ @@ -663,6 +669,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, } ps2user = Geom::Translate (pattern_x (pat), pattern_y (pat)) * ps2user; + // Pattern size in pattern space Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(pat), pattern_y(pat), pattern_width(pat), pattern_height(pat)); @@ -672,22 +679,33 @@ sp_pattern_create_pattern(SPPaintServer *ps, pattern_tile = pattern_tile * bbox2user; } + // Transform of object with pattern (includes screen scaling) cairo_matrix_t cm; cairo_get_matrix(base_ct, &cm); Geom::Affine full(cm.xx, cm.yx, cm.xy, cm.yy, 0, 0); + // The DrawingSurface class is suppose to handle the mapping from "logical space" + // (coordinates in the rendering) to "physical space" (surface pixels). + // An oversampling is done as the pattern may not pixel align with the final surface. + // The cairo surface is created when the DrawingContext is declared. + // oversample the pattern slightly // TODO: find optimum value // TODO: this is lame. instead of using descrim(), we should extract // the scaling component from the complete matrix and use it // to find the optimum tile size for rendering - Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*1.1); + // c is number of pixels in buffer x and y. + Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*2); + c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); - + + // Create drawing surface with size of pattern tile (in tile space) but with number of pixels + // based on required resolution (c). + Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil()); + Inkscape::DrawingContext ct(pattern_surface); + Geom::IntRect one_tile = pattern_tile.roundOutwards(); - Inkscape::DrawingSurface temp(pattern_tile, c.ceil()); - Inkscape::DrawingContext ct(temp); // render pattern. if (needs_opacity) { @@ -695,9 +713,13 @@ sp_pattern_create_pattern(SPPaintServer *ps, } // TODO: make sure there are no leaks. - Inkscape::UpdateContext ctx; - ctx.ctm = vb2ps; + Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! + ctx.ctm = vb2ps;// * full; + drawing.update(Geom::IntRect::infinite(), ctx); + + // Render drawing to pattern_surface via drawing context, this calls root->render + // which is really DrawingItem->render(). drawing.render(ct, one_tile); for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { @@ -705,15 +727,23 @@ sp_pattern_create_pattern(SPPaintServer *ps, } } + // Uncomment to debug + // cairo_surface_t* raw = pattern_surface.raw(); + // std::cout << " cairo_surface (sp-pattern): " + // << " width: " << cairo_image_surface_get_width( raw ) + // << " height: " << cairo_image_surface_get_height( raw ) + // << std::endl; + // cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" ); + if (needs_opacity) { ct.popGroupToSource(); // pop raw pattern ct.paint(opacity); // apply opacity } - cairo_pattern_t *cp = cairo_pattern_create_for_surface(temp.raw()); - + cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * temp.drawingTransform()); + ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform()); + cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); return cp; -- cgit v1.2.3 From a5db129462657ccdc1cea0f3319f5f812e0a8c40 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Sun, 9 Dec 2012 16:39:53 +0100 Subject: Second attempt at fix for #955141, rasterization of clipped/masked objects in patterns. (bzr r11942) --- src/sp-pattern.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index ba171bb05..137864101 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -695,7 +695,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, // the scaling component from the complete matrix and use it // to find the optimum tile size for rendering // c is number of pixels in buffer x and y. - Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*2); + Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*1.1); c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); @@ -705,6 +705,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil()); Inkscape::DrawingContext ct(pattern_surface); + pattern_tile *= pattern_surface.drawingTransform(); Geom::IntRect one_tile = pattern_tile.roundOutwards(); // render pattern. @@ -714,8 +715,8 @@ sp_pattern_create_pattern(SPPaintServer *ps, // TODO: make sure there are no leaks. Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! - ctx.ctm = vb2ps;// * full; - + ctx.ctm = vb2ps * pattern_surface.drawingTransform(); + ct.transform( pattern_surface.drawingTransform().inverse() ); drawing.update(Geom::IntRect::infinite(), ctx); // Render drawing to pattern_surface via drawing context, this calls root->render -- cgit v1.2.3 From bf58d4cb9c86682d1416c64378d1cfc8a95554e8 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Thu, 17 Jan 2013 21:02:50 +0100 Subject: const .... (bzr r12039) --- src/sp-pattern.cpp | 90 +++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 137864101..f18199e96 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -515,73 +515,73 @@ SPPattern *pattern_getroot(SPPattern *pat) // Access functions that look up fields up the chain of referenced patterns and return the first one which is set // FIXME: all of them must use chase_hrefs the same as in SPGradient, to avoid lockup on circular refs -guint pattern_patternUnits (SPPattern *pat) +guint pattern_patternUnits (SPPattern const *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternUnits_set) - return pat_i->patternUnits; - } - return pat->patternUnits; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternUnits_set) + return pat_i->patternUnits; + } + return pat->patternUnits; } -guint pattern_patternContentUnits (SPPattern *pat) +guint pattern_patternContentUnits (SPPattern const *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternContentUnits_set) - return pat_i->patternContentUnits; - } - return pat->patternContentUnits; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternContentUnits_set) + return pat_i->patternContentUnits; + } + return pat->patternContentUnits; } Geom::Affine const &pattern_patternTransform(SPPattern const *pat) { - for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->patternTransform_set) - return pat_i->patternTransform; - } - return pat->patternTransform; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternTransform_set) + return pat_i->patternTransform; + } + return pat->patternTransform; } -gdouble pattern_x (SPPattern *pat) +gdouble pattern_x (SPPattern const *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->x._set) - return pat_i->x.computed; - } - return 0; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->x._set) + return pat_i->x.computed; + } + return 0; } -gdouble pattern_y (SPPattern *pat) +gdouble pattern_y (SPPattern const *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->y._set) - return pat_i->y.computed; - } - return 0; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->y._set) + return pat_i->y.computed; + } + return 0; } -gdouble pattern_width (SPPattern *pat) +gdouble pattern_width (SPPattern const* pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->width._set) - return pat_i->width.computed; - } - return 0; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->width._set) + return pat_i->width.computed; + } + return 0; } -gdouble pattern_height (SPPattern *pat) +gdouble pattern_height (SPPattern const *pat) { - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { - if (pat_i->height._set) - return pat_i->height.computed; - } - return 0; + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->height._set) + return pat_i->height.computed; + } + return 0; } -Geom::OptRect pattern_viewBox (SPPattern *pat) +Geom::OptRect pattern_viewBox (SPPattern const *pat) { Geom::OptRect viewbox; - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->viewBox_set) { viewbox = pat_i->viewBox; break; @@ -590,10 +590,10 @@ Geom::OptRect pattern_viewBox (SPPattern *pat) return viewbox; } -static bool pattern_hasItemChildren (SPPattern *pat) +static bool pattern_hasItemChildren (SPPattern const *pat) { bool hasChildren = false; - for (SPObject *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) { + for (SPObject const *child = pat->firstChild() ; child && !hasChildren ; child = child->getNext() ) { if (SP_IS_ITEM(child)) { hasChildren = true; } -- cgit v1.2.3 From 1615436543169f305d1df4d830ed8f5ec5dc75ed Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Sat, 26 Jan 2013 19:33:04 +0000 Subject: More GObject boilerplate reduction (bzr r12065) --- src/sp-pattern.cpp | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index f18199e96..754a75e87 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -40,10 +40,6 @@ /* * Pattern */ - -static void sp_pattern_class_init (SPPatternClass *klass); -static void sp_pattern_init (SPPattern *gr); - static void sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); static void sp_pattern_release (SPObject *object); static void sp_pattern_set (SPObject *object, unsigned int key, const gchar *value); @@ -55,29 +51,7 @@ static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern static cairo_pattern_t *sp_pattern_create_pattern(SPPaintServer *ps, cairo_t *ct, Geom::OptRect const &bbox, double opacity); -static SPPaintServerClass * pattern_parent_class; - -GType -sp_pattern_get_type (void) -{ - static GType pattern_type = 0; - if (!pattern_type) { - GTypeInfo pattern_info = { - sizeof (SPPatternClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_pattern_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPPattern), - 16, /* n_preallocs */ - (GInstanceInitFunc) sp_pattern_init, - NULL, /* value_table */ - }; - pattern_type = g_type_register_static (SP_TYPE_PAINT_SERVER, "SPPattern", &pattern_info, (GTypeFlags)0); - } - return pattern_type; -} +G_DEFINE_TYPE(SPPattern, sp_pattern, SP_TYPE_PAINT_SERVER); static void sp_pattern_class_init (SPPatternClass *klass) @@ -88,8 +62,6 @@ sp_pattern_class_init (SPPatternClass *klass) sp_object_class = (SPObjectClass *) klass; ps_class = (SPPaintServerClass *) klass; - pattern_parent_class = (SPPaintServerClass*)g_type_class_ref (SP_TYPE_PAINT_SERVER); - sp_object_class->build = sp_pattern_build; sp_object_class->release = sp_pattern_release; sp_object_class->set = sp_pattern_set; @@ -129,8 +101,8 @@ sp_pattern_init (SPPattern *pat) static void sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { - if (((SPObjectClass *) pattern_parent_class)->build) - (* ((SPObjectClass *) pattern_parent_class)->build) (object, document, repr); + if (((SPObjectClass *) sp_pattern_parent_class)->build) + (* ((SPObjectClass *) sp_pattern_parent_class)->build) (object, document, repr); object->readAttr( "patternUnits" ); object->readAttr( "patternContentUnits" ); @@ -164,8 +136,8 @@ static void sp_pattern_release(SPObject *object) pat->modified_connection.~connection(); - if (((SPObjectClass *) pattern_parent_class)->release) { - ((SPObjectClass *) pattern_parent_class)->release (object); + if (((SPObjectClass *) sp_pattern_parent_class)->release) { + ((SPObjectClass *) sp_pattern_parent_class)->release (object); } } @@ -280,8 +252,8 @@ sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) } break; default: - if (((SPObjectClass *) pattern_parent_class)->set) - ((SPObjectClass *) pattern_parent_class)->set (object, key, value); + if (((SPObjectClass *) sp_pattern_parent_class)->set) + ((SPObjectClass *) sp_pattern_parent_class)->set (object, key, value); break; } } -- cgit v1.2.3 From a0a8d020201e0e38a63d9aa3dce228d7d9e6fb35 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Thu, 14 Mar 2013 12:42:39 +0100 Subject: Various changes. (bzr r11608.1.48) --- src/sp-pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 5e55cbe34..729a68dfc 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -90,7 +90,7 @@ sp_pattern_class_init (SPPatternClass *klass) pattern_parent_class = (SPPaintServerClass*)g_type_class_ref (SP_TYPE_PAINT_SERVER); - sp_object_class->build = sp_pattern_build; + //sp_object_class->build = sp_pattern_build; sp_object_class->release = sp_pattern_release; sp_object_class->set = sp_pattern_set; sp_object_class->update = sp_pattern_update; -- cgit v1.2.3 From c8e0129ab4988f2fc5cb06c56ff47b38dfde143f Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:46:44 +0100 Subject: Replaced calls to "pattern_new". (bzr r11608.1.54) --- src/sp-pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 729a68dfc..0c82c9bb8 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -98,7 +98,7 @@ sp_pattern_class_init (SPPatternClass *klass) // do we need _write? seems to work without it - ps_class->pattern_new = sp_pattern_create_pattern; + //ps_class->pattern_new = sp_pattern_create_pattern; } CPattern::CPattern(SPPattern* pattern) : CPaintServer(pattern) { -- cgit v1.2.3 From 957c3e4b7909d42c5a13f1b1dd583f877fc32259 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:46:57 +0100 Subject: Removed function pointers from SPObject and subclasses. Added some missing virtual pads for classes that were hidden by preprocessor macros. (bzr r11608.1.55) --- src/sp-pattern.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 0c82c9bb8..6a1d567dd 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -91,10 +91,10 @@ sp_pattern_class_init (SPPatternClass *klass) pattern_parent_class = (SPPaintServerClass*)g_type_class_ref (SP_TYPE_PAINT_SERVER); //sp_object_class->build = sp_pattern_build; - sp_object_class->release = sp_pattern_release; - sp_object_class->set = sp_pattern_set; - sp_object_class->update = sp_pattern_update; - sp_object_class->modified = sp_pattern_modified; +// sp_object_class->release = sp_pattern_release; +// sp_object_class->set = sp_pattern_set; +// sp_object_class->update = sp_pattern_update; +// sp_object_class->modified = sp_pattern_modified; // do we need _write? seems to work without it -- cgit v1.2.3 From 7df6616da5ea2debb86838366ddf746841549cdb Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 30 Mar 2013 00:56:13 +0100 Subject: Renamed virtual function names. (bzr r11608.1.57) --- src/sp-pattern.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 16528e129..46e1978d3 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -88,10 +88,10 @@ sp_pattern_init (SPPattern *pat) new (&pat->modified_connection) sigc::connection(); } -void CPattern::onBuild(SPDocument* doc, Inkscape::XML::Node* repr) { +void CPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPPattern* object = this->sppattern; - CPaintServer::onBuild(doc, repr); + CPaintServer::build(doc, repr); object->readAttr( "patternUnits" ); object->readAttr( "patternContentUnits" ); @@ -107,7 +107,7 @@ void CPattern::onBuild(SPDocument* doc, Inkscape::XML::Node* repr) { doc->addResource("pattern", object); } -void CPattern::onRelease() { +void CPattern::release() { SPPattern* object = this->sppattern; SPPattern *pat = reinterpret_cast(object); @@ -126,10 +126,10 @@ void CPattern::onRelease() { pat->modified_connection.~connection(); - CPaintServer::onRelease(); + CPaintServer::release(); } -void CPattern::onSet(unsigned int key, const gchar* value) { +void CPattern::set(unsigned int key, const gchar* value) { SPPattern* object = this->sppattern; SPPattern *pat = SP_PATTERN (object); @@ -240,7 +240,7 @@ void CPattern::onSet(unsigned int key, const gchar* value) { } break; default: - CPaintServer::onSet(key, value); + CPaintServer::set(key, value); break; } } @@ -266,7 +266,7 @@ static GSList *pattern_getchildren(SPPattern *pat) return l; } -void CPattern::onUpdate(SPCtx* ctx, unsigned int flags) { +void CPattern::update(SPCtx* ctx, unsigned int flags) { SPPattern* object = this->sppattern; SPPattern *pat = SP_PATTERN (object); @@ -288,7 +288,7 @@ void CPattern::onUpdate(SPCtx* ctx, unsigned int flags) { } } -void CPattern::onModified(unsigned int flags) { +void CPattern::modified(unsigned int flags) { SPPattern* object = this->sppattern; SPPattern *pat = SP_PATTERN (object); @@ -561,7 +561,7 @@ static bool pattern_hasItemChildren (SPPattern const *pat) return hasChildren; } -cairo_pattern_t* CPattern::onCreatePattern(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { +cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { SPPattern* ps = this->sppattern; SPPattern *pat = SP_PATTERN (ps); -- cgit v1.2.3 From a5d6e692d661f0bf7648e64e8fcb04588bb8f3ab Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Mon, 1 Apr 2013 00:07:00 +0200 Subject: Prepared exchange of casting macros. (bzr r11608.1.63) --- src/sp-pattern.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 46e1978d3..f04ba3f0a 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -61,6 +61,7 @@ static void sp_pattern_init (SPPattern *pat) { pat->cpattern = new CPattern(pat); + pat->typeHierarchy.insert(typeid(SPPattern)); delete pat->cpaintserver; pat->cpaintserver = pat->cpattern; -- cgit v1.2.3 From 69f3b6f1abb2bb422935d43262e1e99aab359954 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 01:41:30 +0200 Subject: Added constructors to SP classes. (bzr r11608.1.67) --- src/sp-pattern.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index f04ba3f0a..a9b8ae2ed 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -43,7 +43,7 @@ static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); -G_DEFINE_TYPE(SPPattern, sp_pattern, SP_TYPE_PAINT_SERVER); +G_DEFINE_TYPE(SPPattern, sp_pattern, G_TYPE_OBJECT); static void sp_pattern_class_init (SPPatternClass *klass) @@ -57,9 +57,9 @@ CPattern::CPattern(SPPattern* pattern) : CPaintServer(pattern) { CPattern::~CPattern() { } -static void -sp_pattern_init (SPPattern *pat) -{ +SPPattern::SPPattern() : SPPaintServer() { + SPPattern* pat = this; + pat->cpattern = new CPattern(pat); pat->typeHierarchy.insert(typeid(SPPattern)); @@ -67,6 +67,8 @@ sp_pattern_init (SPPattern *pat) pat->cpaintserver = pat->cpattern; pat->cobject = pat->cpattern; + pat->href = NULL; + pat->ref = new SPPatternReference(pat); pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); @@ -89,6 +91,12 @@ sp_pattern_init (SPPattern *pat) new (&pat->modified_connection) sigc::connection(); } +static void +sp_pattern_init (SPPattern *pat) +{ + new (pat) SPPattern(); +} + void CPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { SPPattern* object = this->sppattern; -- cgit v1.2.3 From d1af3566872dfff2aeec84859c87f1f8d13f79df Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Tue, 2 Apr 2013 19:14:36 +0200 Subject: Registered classes with new factory. Hkern, Vkern and FeFuncX have to be rewritten, as they aren't real classes. (bzr r11608.1.69) --- src/sp-pattern.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index a9b8ae2ed..e4132ac1d 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -43,6 +43,16 @@ static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); +#include "sp-factory.h" + +namespace { + SPObject* createPattern() { + return new SPPattern(); + } + + bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern); +} + G_DEFINE_TYPE(SPPattern, sp_pattern, G_TYPE_OBJECT); static void -- cgit v1.2.3 From b0cc47554b385fb68643d07efe6e42366c7121ad Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 6 Apr 2013 01:36:16 +0200 Subject: Merged PaintServer and subclasses; moved Gradient classes to own files. (bzr r11608.1.82) --- src/sp-pattern.cpp | 300 ++++++++++++++++++++++++++--------------------------- 1 file changed, 150 insertions(+), 150 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index e4132ac1d..27c5e9a25 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -53,161 +53,139 @@ namespace { bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern); } -G_DEFINE_TYPE(SPPattern, sp_pattern, G_TYPE_OBJECT); - -static void -sp_pattern_class_init (SPPatternClass *klass) -{ -} - -CPattern::CPattern(SPPattern* pattern) : CPaintServer(pattern) { - this->sppattern = pattern; -} - -CPattern::~CPattern() { -} - SPPattern::SPPattern() : SPPaintServer() { - SPPattern* pat = this; - - pat->cpattern = new CPattern(pat); - pat->typeHierarchy.insert(typeid(SPPattern)); + this->cobject = this; - delete pat->cpaintserver; - pat->cpaintserver = pat->cpattern; - pat->cobject = pat->cpattern; + this->href = NULL; - pat->href = NULL; + this->ref = new SPPatternReference(this); + this->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), this)); - pat->ref = new SPPatternReference(pat); - pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); + this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + this->patternUnits_set = FALSE; - pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - pat->patternUnits_set = FALSE; + this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + this->patternContentUnits_set = FALSE; - pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - pat->patternContentUnits_set = FALSE; + this->patternTransform = Geom::identity(); + this->patternTransform_set = FALSE; - pat->patternTransform = Geom::identity(); - pat->patternTransform_set = FALSE; + this->x.unset(); + this->y.unset(); + this->width.unset(); + this->height.unset(); - pat->x.unset(); - pat->y.unset(); - pat->width.unset(); - pat->height.unset(); + this->viewBox_set = FALSE; - pat->viewBox_set = FALSE; - - new (&pat->modified_connection) sigc::connection(); + new (&this->modified_connection) sigc::connection(); } -static void -sp_pattern_init (SPPattern *pat) -{ - new (pat) SPPattern(); +SPPattern::~SPPattern() { } -void CPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { - SPPattern* object = this->sppattern; - - CPaintServer::build(doc, repr); +void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { + SPPaintServer::build(doc, repr); - object->readAttr( "patternUnits" ); - object->readAttr( "patternContentUnits" ); - object->readAttr( "patternTransform" ); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "viewBox" ); - object->readAttr( "xlink:href" ); + this->readAttr( "patternUnits" ); + this->readAttr( "patternContentUnits" ); + this->readAttr( "patternTransform" ); + this->readAttr( "x" ); + this->readAttr( "y" ); + this->readAttr( "width" ); + this->readAttr( "height" ); + this->readAttr( "viewBox" ); + this->readAttr( "xlink:href" ); /* Register ourselves */ - doc->addResource("pattern", object); + doc->addResource("pattern", this); } -void CPattern::release() { - SPPattern* object = this->sppattern; - - SPPattern *pat = reinterpret_cast(object); - - if (object->document) { +void SPPattern::release() { + if (this->document) { // Unregister ourselves - object->document->removeResource("pattern", object); + this->document->removeResource("pattern", this); } - if (pat->ref) { - pat->modified_connection.disconnect(); - pat->ref->detach(); - delete pat->ref; - pat->ref = NULL; + if (this->ref) { + this->modified_connection.disconnect(); + this->ref->detach(); + delete this->ref; + this->ref = NULL; } - pat->modified_connection.~connection(); + this->modified_connection.~connection(); - CPaintServer::release(); + SPPaintServer::release(); } -void CPattern::set(unsigned int key, const gchar* value) { - SPPattern* object = this->sppattern; - - SPPattern *pat = SP_PATTERN (object); - +void SPPattern::set(unsigned int key, const gchar* value) { switch (key) { case SP_ATTR_PATTERNUNITS: if (value) { if (!strcmp (value, "userSpaceOnUse")) { - pat->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + this->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; } else { - pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + this->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; } - pat->patternUnits_set = TRUE; + + this->patternUnits_set = TRUE; } else { - pat->patternUnits_set = FALSE; + this->patternUnits_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_PATTERNCONTENTUNITS: if (value) { if (!strcmp (value, "userSpaceOnUse")) { - pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + this->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; } else { - pat->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + this->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; } - pat->patternContentUnits_set = TRUE; + + this->patternContentUnits_set = TRUE; } else { - pat->patternContentUnits_set = FALSE; + this->patternContentUnits_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_PATTERNTRANSFORM: { Geom::Affine t; + if (value && sp_svg_transform_read (value, &t)) { - pat->patternTransform = t; - pat->patternTransform_set = TRUE; + this->patternTransform = t; + this->patternTransform_set = TRUE; } else { - pat->patternTransform = Geom::identity(); - pat->patternTransform_set = FALSE; + this->patternTransform = Geom::identity(); + this->patternTransform_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; } case SP_ATTR_X: - pat->x.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->x.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_Y: - pat->y.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->y.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_WIDTH: - pat->width.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->width.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_HEIGHT: - pat->height.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); + this->height.readOrUnset(value); + this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; + case SP_ATTR_VIEWBOX: { /* fixme: Think (Lauris) */ double x, y, width, height; @@ -216,50 +194,69 @@ void CPattern::set(unsigned int key, const gchar* value) { if (value) { eptr = (gchar *) value; x = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } + y = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } + width = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } + height = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { + eptr++; + } + if ((width > 0) && (height > 0)) { - pat->viewBox = Geom::Rect::from_xywh(x, y, width, height); - pat->viewBox_set = TRUE; + this->viewBox = Geom::Rect::from_xywh(x, y, width, height); + this->viewBox_set = TRUE; } else { - pat->viewBox_set = FALSE; + this->viewBox_set = FALSE; } } else { - pat->viewBox_set = FALSE; + this->viewBox_set = FALSE; } - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); break; } case SP_ATTR_XLINK_HREF: - if ( value && pat->href && ( strcmp(value, pat->href) == 0 ) ) { + if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* Href unchanged, do nothing. */ } else { - g_free(pat->href); - pat->href = NULL; + g_free(this->href); + this->href = NULL; + if (value) { // First, set the href field; it's only used in the "unchanged" check above. - pat->href = g_strdup(value); + this->href = g_strdup(value); // Now do the attaching, which emits the changed signal. if (value) { try { - pat->ref->attach(Inkscape::URI(value)); + this->ref->attach(Inkscape::URI(value)); } catch (Inkscape::BadURIException &e) { g_warning("%s", e.what()); - pat->ref->detach(); + this->ref->detach(); } } else { - pat->ref->detach(); + this->ref->detach(); } } } break; + default: - CPaintServer::set(key, value); + SPPaintServer::set(key, value); break; } } @@ -275,56 +272,60 @@ static GSList *pattern_getchildren(SPPattern *pat) for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->firstChild()) { // find the first one with children - for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { - l = g_slist_prepend (l, child); - } - break; // do not go further up the chain if children are found - } + for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { + l = g_slist_prepend (l, child); + } + break; // do not go further up the chain if children are found + } } - return l; + return l; } -void CPattern::update(SPCtx* ctx, unsigned int flags) { - SPPattern* object = this->sppattern; - - SPPattern *pat = SP_PATTERN (object); +void SPPattern::update(SPCtx* ctx, unsigned int flags) { + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = pattern_getchildren (pat); + GSList *l = pattern_getchildren (this); l = g_slist_reverse (l); while (l) { SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->updateDisplay(ctx, flags); } + sp_object_unref (child, NULL); } } -void CPattern::modified(unsigned int flags) { - SPPattern* object = this->sppattern; - - SPPattern *pat = SP_PATTERN (object); +void SPPattern::modified(unsigned int flags) { + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; flags &= SP_OBJECT_MODIFIED_CASCADE; - GSList *l = pattern_getchildren (pat); + GSList *l = pattern_getchildren (this); l = g_slist_reverse (l); while (l) { SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->emitModified(flags); } + sp_object_unref (child, NULL); } } @@ -338,6 +339,7 @@ pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat) if (old_ref) { pat->modified_connection.disconnect(); } + if (SP_IS_PATTERN (ref)) { pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat)); } @@ -580,20 +582,18 @@ static bool pattern_hasItemChildren (SPPattern const *pat) return hasChildren; } -cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { - SPPattern* ps = this->sppattern; - - SPPattern *pat = SP_PATTERN (ps); - +cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { bool needs_opacity = (1.0 - opacity) >= 1e-3; bool visible = opacity >= 1e-3; - if (!visible) + if (!visible) { return NULL; + } /* Show items */ SPPattern *shown = NULL; - for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + + for (SPPattern *pat_i = this; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { // find the first one with item children if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { shown = pat_i; @@ -623,13 +623,13 @@ cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bb // viewBox to pattern server Geom::Affine vb2ps = Geom::identity(); - if (pat->viewBox_set) { - Geom::Rect vb = *pattern_viewBox(pat); - gdouble tmp_x = pattern_width (pat) / vb.width(); - gdouble tmp_y = pattern_height (pat) / vb.height(); + if (this->viewBox_set) { + Geom::Rect vb = *pattern_viewBox(this); + gdouble tmp_x = pattern_width (this) / vb.width(); + gdouble tmp_y = pattern_height (this) / vb.height(); // FIXME: preserveAspectRatio must be taken into account here too! - vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - vb.left() * tmp_x, pattern_y(pat) - vb.top() * tmp_y); + vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(this) - vb.left() * tmp_x, pattern_y(this) - vb.top() * tmp_y); } // We must determine the size and scaling of the pattern at the time it is displayed and render @@ -637,19 +637,19 @@ cairo_pattern_t* CPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bb // Pattern server to user Geom::Affine ps2user; - ps2user = pattern_patternTransform(pat); - if (!pat->viewBox_set && pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + ps2user = pattern_patternTransform(this); + if (!this->viewBox_set && pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { /* BBox to user coordinate system */ Geom::Affine bbox2user (bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top()); ps2user *= bbox2user; } - ps2user = Geom::Translate (pattern_x (pat), pattern_y (pat)) * ps2user; + ps2user = Geom::Translate (pattern_x (this), pattern_y (this)) * ps2user; // Pattern size in pattern space - Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(pat), pattern_y(pat), - pattern_width(pat), pattern_height(pat)); + Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(this), pattern_y(this), + pattern_width(this), pattern_height(this)); - if (pattern_patternUnits(pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { // interpret x, y, width, height in relation to bbox Geom::Affine bbox2user(bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top()); pattern_tile = pattern_tile * bbox2user; -- cgit v1.2.3 From 27e2102f96a5554bcd5310ec11435d155773b279 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sun, 7 Apr 2013 18:28:22 +0200 Subject: Merge Object and subclasses. Merging of SP- and C-classes complete. (bzr r11608.1.86) --- src/sp-pattern.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 27c5e9a25..e88bd2886 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -54,8 +54,6 @@ namespace { } SPPattern::SPPattern() : SPPaintServer() { - this->cobject = this; - this->href = NULL; this->ref = new SPPatternReference(this); -- cgit v1.2.3 From d2f51524a231765aefad3d0bc3fea6c0bf3d570a Mon Sep 17 00:00:00 2001 From: Alex Valavanis Date: Thu, 11 Apr 2013 10:58:39 +0100 Subject: Fix some broken Vim modelines (bzr r12275) --- src/sp-pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 754a75e87..23cd3d32e 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -731,4 +731,4 @@ sp_pattern_create_pattern(SPPaintServer *ps, fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3 From c317c1f79519f0ee961842ffb9feac4494af5377 Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 28 Apr 2013 17:51:29 -0700 Subject: Fixed logic error confusing bitwise and with logical and. Whitespace cleanup to make the issue easier to spot. (bzr r12311) --- src/sp-pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 23cd3d32e..c4308a1a9 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -591,7 +591,7 @@ sp_pattern_create_pattern(SPPaintServer *ps, SPPattern *shown = NULL; for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { // find the first one with item children - if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { + if (pat_i && SP_IS_OBJECT(pat_i) && pattern_hasItemChildren(pat_i)) { shown = pat_i; break; // do not go further up the chain if children are found } -- cgit v1.2.3 From 127543bae3c0a76770e197c7058a783dea18fe3e Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Wed, 31 Jul 2013 23:23:10 +0200 Subject: Removed placement news / explicit destructor calls. (bzr r11608.1.113) --- src/sp-pattern.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 34063cb16..1aec904ae 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -75,7 +75,7 @@ SPPattern::SPPattern() : SPPaintServer() { this->viewBox_set = FALSE; - new (&this->modified_connection) sigc::connection(); + //new (&this->modified_connection) sigc::connection(); } SPPattern::~SPPattern() { @@ -111,7 +111,7 @@ void SPPattern::release() { this->ref = NULL; } - this->modified_connection.~connection(); + //this->modified_connection.~connection(); SPPaintServer::release(); } -- cgit v1.2.3 From bf4a1d2d49850170b936c30cfe2b30e798716406 Mon Sep 17 00:00:00 2001 From: Markus Engel Date: Sat, 3 Aug 2013 03:03:43 +0200 Subject: Cleaned up. (bzr r11608.1.117) --- src/sp-pattern.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 1aec904ae..408a57195 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -74,8 +74,6 @@ SPPattern::SPPattern() : SPPaintServer() { this->height.unset(); this->viewBox_set = FALSE; - - //new (&this->modified_connection) sigc::connection(); } SPPattern::~SPPattern() { @@ -111,8 +109,6 @@ void SPPattern::release() { this->ref = NULL; } - //this->modified_connection.~connection(); - SPPaintServer::release(); } -- cgit v1.2.3 From dd957026bd798ebe34eff033b4a839d63b790b04 Mon Sep 17 00:00:00 2001 From: Kris De Gussem Date: Sun, 4 Aug 2013 16:27:59 +0200 Subject: cppcheck (bzr r12467) --- src/sp-pattern.cpp | 503 ++++++++++++++++++++++++++--------------------------- 1 file changed, 250 insertions(+), 253 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index c4308a1a9..62811d51a 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -56,19 +56,19 @@ G_DEFINE_TYPE(SPPattern, sp_pattern, SP_TYPE_PAINT_SERVER); static void sp_pattern_class_init (SPPatternClass *klass) { - SPObjectClass *sp_object_class; - SPPaintServerClass *ps_class; + SPObjectClass *sp_object_class; + SPPaintServerClass *ps_class; - sp_object_class = (SPObjectClass *) klass; - ps_class = (SPPaintServerClass *) klass; + sp_object_class = (SPObjectClass *) klass; + ps_class = (SPPaintServerClass *) klass; - sp_object_class->build = sp_pattern_build; - sp_object_class->release = sp_pattern_release; - sp_object_class->set = sp_pattern_set; - sp_object_class->update = sp_pattern_update; - sp_object_class->modified = sp_pattern_modified; + sp_object_class->build = sp_pattern_build; + sp_object_class->release = sp_pattern_release; + sp_object_class->set = sp_pattern_set; + sp_object_class->update = sp_pattern_update; + sp_object_class->modified = sp_pattern_modified; - // do we need _write? seems to work without it + // do we need _write? seems to work without it ps_class->pattern_new = sp_pattern_create_pattern; } @@ -76,46 +76,46 @@ sp_pattern_class_init (SPPatternClass *klass) static void sp_pattern_init (SPPattern *pat) { - pat->ref = new SPPatternReference(pat); - pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); + pat->ref = new SPPatternReference(pat); + pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); - pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - pat->patternUnits_set = FALSE; + pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + pat->patternUnits_set = FALSE; - pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - pat->patternContentUnits_set = FALSE; + pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + pat->patternContentUnits_set = FALSE; - pat->patternTransform = Geom::identity(); - pat->patternTransform_set = FALSE; + pat->patternTransform = Geom::identity(); + pat->patternTransform_set = FALSE; - pat->x.unset(); - pat->y.unset(); - pat->width.unset(); - pat->height.unset(); + pat->x.unset(); + pat->y.unset(); + pat->width.unset(); + pat->height.unset(); - pat->viewBox_set = FALSE; + pat->viewBox_set = FALSE; - new (&pat->modified_connection) sigc::connection(); + new (&pat->modified_connection) sigc::connection(); } static void sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) { - if (((SPObjectClass *) sp_pattern_parent_class)->build) - (* ((SPObjectClass *) sp_pattern_parent_class)->build) (object, document, repr); - - object->readAttr( "patternUnits" ); - object->readAttr( "patternContentUnits" ); - object->readAttr( "patternTransform" ); - object->readAttr( "x" ); - object->readAttr( "y" ); - object->readAttr( "width" ); - object->readAttr( "height" ); - object->readAttr( "viewBox" ); - object->readAttr( "xlink:href" ); - - /* Register ourselves */ - document->addResource("pattern", object); + if (((SPObjectClass *) sp_pattern_parent_class)->build) + (* ((SPObjectClass *) sp_pattern_parent_class)->build) (object, document, repr); + + object->readAttr( "patternUnits" ); + object->readAttr( "patternContentUnits" ); + object->readAttr( "patternTransform" ); + object->readAttr( "x" ); + object->readAttr( "y" ); + object->readAttr( "width" ); + object->readAttr( "height" ); + object->readAttr( "viewBox" ); + object->readAttr( "xlink:href" ); + + /* Register ourselves */ + document->addResource("pattern", object); } static void sp_pattern_release(SPObject *object) @@ -144,118 +144,115 @@ static void sp_pattern_release(SPObject *object) static void sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) { - SPPattern *pat = SP_PATTERN (object); - - switch (key) { - case SP_ATTR_PATTERNUNITS: - if (value) { - if (!strcmp (value, "userSpaceOnUse")) { - pat->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - } else { - pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - } - pat->patternUnits_set = TRUE; - } else { - pat->patternUnits_set = FALSE; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_PATTERNCONTENTUNITS: - if (value) { - if (!strcmp (value, "userSpaceOnUse")) { - pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; - } else { - pat->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; - } - pat->patternContentUnits_set = TRUE; - } else { - pat->patternContentUnits_set = FALSE; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_PATTERNTRANSFORM: { - Geom::Affine t; - if (value && sp_svg_transform_read (value, &t)) { - pat->patternTransform = t; - pat->patternTransform_set = TRUE; - } else { - pat->patternTransform = Geom::identity(); - pat->patternTransform_set = FALSE; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - } - case SP_ATTR_X: - pat->x.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_Y: - pat->y.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_WIDTH: - pat->width.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_HEIGHT: - pat->height.readOrUnset(value); - object->requestModified(SP_OBJECT_MODIFIED_FLAG); - break; - case SP_ATTR_VIEWBOX: { - /* fixme: Think (Lauris) */ - double x, y, width, height; - char *eptr; - - if (value) { - eptr = (gchar *) value; - x = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; - y = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; - width = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; - height = g_ascii_strtod (eptr, &eptr); - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; - if ((width > 0) && (height > 0)) { - pat->viewBox = Geom::Rect::from_xywh(x, y, width, height); - pat->viewBox_set = TRUE; - } else { - pat->viewBox_set = FALSE; - } - } else { - pat->viewBox_set = FALSE; - } - object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - } - case SP_ATTR_XLINK_HREF: - if ( value && pat->href && ( strcmp(value, pat->href) == 0 ) ) { - /* Href unchanged, do nothing. */ - } else { - g_free(pat->href); - pat->href = NULL; - if (value) { - // First, set the href field; it's only used in the "unchanged" check above. - pat->href = g_strdup(value); - // Now do the attaching, which emits the changed signal. - if (value) { - try { - pat->ref->attach(Inkscape::URI(value)); - } catch (Inkscape::BadURIException &e) { - g_warning("%s", e.what()); - pat->ref->detach(); - } - } else { - pat->ref->detach(); - } - } - } - break; - default: - if (((SPObjectClass *) sp_pattern_parent_class)->set) - ((SPObjectClass *) sp_pattern_parent_class)->set (object, key, value); - break; - } + SPPattern *pat = SP_PATTERN (object); + + switch (key) { + case SP_ATTR_PATTERNUNITS: + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + pat->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + } else { + pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + } + pat->patternUnits_set = TRUE; + } else { + pat->patternUnits_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PATTERNCONTENTUNITS: + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + } else { + pat->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + } + pat->patternContentUnits_set = TRUE; + } else { + pat->patternContentUnits_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PATTERNTRANSFORM: { + Geom::Affine t; + if (value && sp_svg_transform_read (value, &t)) { + pat->patternTransform = t; + pat->patternTransform_set = TRUE; + } else { + pat->patternTransform = Geom::identity(); + pat->patternTransform_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_X: + pat->x.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y: + pat->y.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_WIDTH: + pat->width.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_HEIGHT: + pat->height.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_VIEWBOX: { + /* fixme: Think (Lauris) */ + if (value) { + char *eptr = const_cast(value); + double x = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + double y = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + double width = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + double height = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + if ((width > 0) && (height > 0)) { + pat->viewBox = Geom::Rect::from_xywh(x, y, width, height); + pat->viewBox_set = TRUE; + } else { + pat->viewBox_set = FALSE; + } + } else { + pat->viewBox_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + } + case SP_ATTR_XLINK_HREF: + if ( value && pat->href && ( strcmp(value, pat->href) == 0 ) ) { + /* Href unchanged, do nothing. */ + } else { + g_free(pat->href); + pat->href = NULL; + if (value) { + // First, set the href field; it's only used in the "unchanged" check above. + pat->href = g_strdup(value); + // Now do the attaching, which emits the changed signal. + if (value) { + try { + pat->ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + pat->ref->detach(); + } + } else { + pat->ref->detach(); + } + } + } + break; + default: + if (((SPObjectClass *) sp_pattern_parent_class)->set) + ((SPObjectClass *) sp_pattern_parent_class)->set (object, key, value); + break; + } } /* TODO: do we need a ::remove_child handler? */ @@ -268,11 +265,11 @@ static GSList *pattern_getchildren(SPPattern *pat) for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { if (pat_i->firstChild()) { // find the first one with children - for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { - l = g_slist_prepend (l, child); - } - break; // do not go further up the chain if children are found - } + for (SPObject *child = pat->firstChild() ; child ; child = child->getNext() ) { + l = g_slist_prepend (l, child); + } + break; // do not go further up the chain if children are found + } } return l; @@ -281,45 +278,45 @@ static GSList *pattern_getchildren(SPPattern *pat) static void sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags) { - SPPattern *pat = SP_PATTERN (object); - - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - flags &= SP_OBJECT_MODIFIED_CASCADE; - - GSList *l = pattern_getchildren (pat); - l = g_slist_reverse (l); - - while (l) { - SPObject *child = SP_OBJECT (l->data); - sp_object_ref (child, NULL); - l = g_slist_remove (l, child); - if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->updateDisplay(ctx, flags); - } - sp_object_unref (child, NULL); - } + SPPattern *pat = SP_PATTERN (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = pattern_getchildren (pat); + l = g_slist_reverse (l); + + while (l) { + SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->updateDisplay(ctx, flags); + } + sp_object_unref (child, NULL); + } } static void sp_pattern_modified (SPObject *object, guint flags) { - SPPattern *pat = SP_PATTERN (object); - - if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; - flags &= SP_OBJECT_MODIFIED_CASCADE; - - GSList *l = pattern_getchildren (pat); - l = g_slist_reverse (l); - - while (l) { - SPObject *child = SP_OBJECT (l->data); - sp_object_ref (child, NULL); - l = g_slist_remove (l, child); - if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { - child->emitModified(flags); - } - sp_object_unref (child, NULL); - } + SPPattern *pat = SP_PATTERN (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = pattern_getchildren (pat); + l = g_slist_reverse (l); + + while (l) { + SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + sp_object_unref (child, NULL); + } } /** @@ -328,14 +325,14 @@ Gets called when the pattern is reattached to another static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat) { - if (old_ref) { - pat->modified_connection.disconnect(); - } - if (SP_IS_PATTERN (ref)) { - pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat)); - } - - pattern_ref_modified (ref, 0, pat); + if (old_ref) { + pat->modified_connection.disconnect(); + } + if (SP_IS_PATTERN (ref)) { + pat->modified_connection = ref->connectModified(sigc::bind<2>(sigc::ptr_fun(&pattern_ref_modified), pat)); + } + + pattern_ref_modified (ref, 0, pat); } /** @@ -386,56 +383,56 @@ count_pattern_hrefs(SPObject *o, SPPattern *pat) SPPattern *pattern_chain(SPPattern *pattern) { - SPDocument *document = pattern->document; + SPDocument *document = pattern->document; Inkscape::XML::Document *xml_doc = document->getReprDoc(); - Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); + Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); - Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); - repr->setAttribute("inkscape:collect", "always"); - gchar *parent_ref = g_strconcat("#", pattern->getRepr()->attribute("id"), NULL); - repr->setAttribute("xlink:href", parent_ref); - g_free (parent_ref); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); + repr->setAttribute("inkscape:collect", "always"); + gchar *parent_ref = g_strconcat("#", pattern->getRepr()->attribute("id"), NULL); + repr->setAttribute("xlink:href", parent_ref); + g_free (parent_ref); - defsrepr->addChild(repr, NULL); - const gchar *child_id = repr->attribute("id"); - SPObject *child = document->getObjectById(child_id); - g_assert (SP_IS_PATTERN (child)); + defsrepr->addChild(repr, NULL); + const gchar *child_id = repr->attribute("id"); + SPObject *child = document->getObjectById(child_id); + g_assert (SP_IS_PATTERN (child)); - return SP_PATTERN (child); + return SP_PATTERN (child); } SPPattern * sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property) { - if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) { - pattern = pattern_chain (pattern); - gchar *href = g_strconcat("url(#", pattern->getRepr()->attribute("id"), ")", NULL); - - SPCSSAttr *css = sp_repr_css_attr_new (); - sp_repr_css_set_property (css, property, href); - sp_repr_css_change_recursive(item->getRepr(), css, "style"); - } - return pattern; + if (!pattern->href || pattern->hrefcount > count_pattern_hrefs(item, pattern)) { + pattern = pattern_chain (pattern); + gchar *href = g_strconcat("url(#", pattern->getRepr()->attribute("id"), ")", NULL); + + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, property, href); + sp_repr_css_change_recursive(item->getRepr(), css, "style"); + } + return pattern; } void sp_pattern_transform_multiply (SPPattern *pattern, Geom::Affine postmul, bool set) { - // this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp - // for it to work, we also need sp_object_read_attr( item, "transform"); - //pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul; - - // otherwise the formula is much simpler - if (set) { - pattern->patternTransform = postmul; - } else { - pattern->patternTransform = pattern_patternTransform(pattern) * postmul; - } - pattern->patternTransform_set = TRUE; - - gchar *c=sp_svg_transform_write(pattern->patternTransform); - pattern->getRepr()->setAttribute("patternTransform", c); - g_free(c); + // this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp + // for it to work, we also need sp_object_read_attr( item, "transform"); + //pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul; + + // otherwise the formula is much simpler + if (set) { + pattern->patternTransform = postmul; + } else { + pattern->patternTransform = pattern_patternTransform(pattern) * postmul; + } + pattern->patternTransform_set = TRUE; + + gchar *c=sp_svg_transform_write(pattern->patternTransform); + pattern->getRepr()->setAttribute("patternTransform", c); + g_free(c); } const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document, Geom::Affine transform, Geom::Affine move) @@ -443,33 +440,33 @@ const gchar *pattern_tile(GSList *reprs, Geom::Rect bounds, SPDocument *document Inkscape::XML::Document *xml_doc = document->getReprDoc(); Inkscape::XML::Node *defsrepr = document->getDefs()->getRepr(); - Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); - repr->setAttribute("patternUnits", "userSpaceOnUse"); - sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]); - sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]); + Inkscape::XML::Node *repr = xml_doc->createElement("svg:pattern"); + repr->setAttribute("patternUnits", "userSpaceOnUse"); + sp_repr_set_svg_double(repr, "width", bounds.dimensions()[Geom::X]); + sp_repr_set_svg_double(repr, "height", bounds.dimensions()[Geom::Y]); - gchar *t=sp_svg_transform_write(transform); - repr->setAttribute("patternTransform", t); - g_free(t); + gchar *t=sp_svg_transform_write(transform); + repr->setAttribute("patternTransform", t); + g_free(t); - defsrepr->appendChild(repr); - const gchar *pat_id = repr->attribute("id"); - SPObject *pat_object = document->getObjectById(pat_id); + defsrepr->appendChild(repr); + const gchar *pat_id = repr->attribute("id"); + SPObject *pat_object = document->getObjectById(pat_id); - for (GSList *i = reprs; i != NULL; i = i->next) { - Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data); - SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node)); + for (GSList *i = reprs; i != NULL; i = i->next) { + Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data); + SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node)); - Geom::Affine dup_transform; - if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform)) - dup_transform = Geom::identity(); - dup_transform *= move; + Geom::Affine dup_transform; + if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform)) + dup_transform = Geom::identity(); + dup_transform *= move; copy->doWriteTransform(copy->getRepr(), dup_transform, NULL, false); } - Inkscape::GC::release(repr); - return pat_id; + Inkscape::GC::release(repr); + return pat_id; } SPPattern *pattern_getroot(SPPattern *pat) -- cgit v1.2.3 From d2f932ed15e276fda44e80d5d6139ed42c0f706a Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 19 Nov 2013 13:38:19 +0100 Subject: Increased pattern resolution to fix blocker bug #1251039. (bzr r12824) --- src/sp-pattern.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 213b57559..ad5449f34 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -665,7 +665,8 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // the scaling component from the complete matrix and use it // to find the optimum tile size for rendering // c is number of pixels in buffer x and y. - Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*1.1); + // Scale factor of 1.1 is too small... see bug #1251039 + Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*2.0); c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); -- cgit v1.2.3 From 7dd239eed97761b22ef635b6896a8f65c4939462 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Feb 2014 15:29:15 +0100 Subject: Added new base class to handle viewBox and preserveAspectRatio. Updated sp-root, sp-symbol, sp-image, sp-pattern, marker to use new class. Fixed some viewport issues when % used. (bzr r13002) --- src/sp-pattern.cpp | 55 ++++++++++-------------------------------------------- 1 file changed, 10 insertions(+), 45 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index ad5449f34..711f26428 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -53,7 +53,7 @@ namespace { bool patternRegistered = SPFactory::instance().registerObject("svg:pattern", createPattern); } -SPPattern::SPPattern() : SPPaintServer() { +SPPattern::SPPattern() : SPPaintServer(), SPViewBox() { this->href = NULL; this->ref = new SPPatternReference(this); @@ -72,8 +72,6 @@ SPPattern::SPPattern() : SPPaintServer() { this->y.unset(); this->width.unset(); this->height.unset(); - - this->viewBox_set = FALSE; } SPPattern::~SPPattern() { @@ -90,6 +88,7 @@ void SPPattern::build(SPDocument* doc, Inkscape::XML::Node* repr) { this->readAttr( "width" ); this->readAttr( "height" ); this->readAttr( "viewBox" ); + this->readAttr( "preserveAspectRatio" ); this->readAttr( "xlink:href" ); /* Register ourselves */ @@ -180,50 +179,16 @@ void SPPattern::set(unsigned int key, const gchar* value) { this->requestModified(SP_OBJECT_MODIFIED_FLAG); break; - case SP_ATTR_VIEWBOX: { - /* fixme: Think (Lauris) */ - double x, y, width, height; - char *eptr; - - if (value) { - eptr = (gchar *) value; - x = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - y = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - width = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } - - height = g_ascii_strtod (eptr, &eptr); - - while (*eptr && ((*eptr == ',') || (*eptr == ' '))) { - eptr++; - } + case SP_ATTR_VIEWBOX: + set_viewBox( value ); + this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - if ((width > 0) && (height > 0)) { - this->viewBox = Geom::Rect::from_xywh(x, y, width, height); - this->viewBox_set = TRUE; - } else { - this->viewBox_set = FALSE; - } - } else { - this->viewBox_set = FALSE; - } + case SP_ATTR_PRESERVEASPECTRATIO: + set_preserveAspectRatio( value ); + this->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; - this->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); - break; - } case SP_ATTR_XLINK_HREF: if ( value && this->href && ( strcmp(value, this->href) == 0 ) ) { /* Href unchanged, do nothing. */ -- cgit v1.2.3 From d4ba8eaa4a621ac60d99a4aad7531d080cece2cd Mon Sep 17 00:00:00 2001 From: David Mathog Date: Sat, 8 Feb 2014 09:44:12 +0100 Subject: DrawingContext: change variable names ct to dc (bug #1272073) Fixed bugs: - https://launchpad.net/bugs/1272073 (bzr r13009) --- src/sp-pattern.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 711f26428..425ca9efa 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -639,25 +639,25 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // Create drawing surface with size of pattern tile (in tile space) but with number of pixels // based on required resolution (c). Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil()); - Inkscape::DrawingContext ct(pattern_surface); + Inkscape::DrawingContext dc(pattern_surface); pattern_tile *= pattern_surface.drawingTransform(); Geom::IntRect one_tile = pattern_tile.roundOutwards(); // render pattern. if (needs_opacity) { - ct.pushGroup(); // this group is for pattern + opacity + dc.pushGroup(); // this group is for pattern + opacity } // TODO: make sure there are no leaks. Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! ctx.ctm = vb2ps * pattern_surface.drawingTransform(); - ct.transform( pattern_surface.drawingTransform().inverse() ); + dc.transform( pattern_surface.drawingTransform().inverse() ); drawing.update(Geom::IntRect::infinite(), ctx); // Render drawing to pattern_surface via drawing context, this calls root->render // which is really DrawingItem->render(). - drawing.render(ct, one_tile); + drawing.render(dc, one_tile); for (SPObject *child = shown->firstChild() ; child != NULL; child = child->getNext() ) { if (SP_IS_ITEM (child)) { SP_ITEM(child)->invoke_hide(dkey); @@ -673,8 +673,8 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" ); if (needs_opacity) { - ct.popGroupToSource(); // pop raw pattern - ct.paint(opacity); // apply opacity + dc.popGroupToSource(); // pop raw pattern + dc.paint(opacity); // apply opacity } cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); -- cgit v1.2.3 From ffc148e454cf8d8e1f4f3d7650d20472b04b1511 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 4 Mar 2014 12:37:39 +0100 Subject: Fix for W3C test suite coords-units-01-b.svg. Fixes pattern positioning. (bzr r13111) --- src/sp-pattern.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 425ca9efa..8e67141fb 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -595,8 +595,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // the pattern onto a surface with that size and at that resolution. // Pattern server to user - Geom::Affine ps2user; - ps2user = pattern_patternTransform(this); + Geom::Affine ps2user = pattern_patternTransform(this); if (!this->viewBox_set && pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { /* BBox to user coordinate system */ Geom::Affine bbox2user (bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top()); @@ -631,7 +630,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // to find the optimum tile size for rendering // c is number of pixels in buffer x and y. // Scale factor of 1.1 is too small... see bug #1251039 - Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*ps2user.descrim()*full.descrim()*2.0); + Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*full.descrim()*2.0); c[Geom::X] = ceil(c[Geom::X]); c[Geom::Y] = ceil(c[Geom::Y]); @@ -651,7 +650,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // TODO: make sure there are no leaks. Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! - ctx.ctm = vb2ps * pattern_surface.drawingTransform(); + ctx.ctm = ps2user * pattern_surface.drawingTransform(); // vb2ps? dc.transform( pattern_surface.drawingTransform().inverse() ); drawing.update(Geom::IntRect::infinite(), ctx); @@ -679,7 +678,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform()); + ink_cairo_pattern_set_matrix(cp, pattern_surface.drawingTransform() ); cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); -- cgit v1.2.3 From 678436c3b81d9a1bdd347707e14fff54e5c056b1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Mar 2014 11:33:08 +0100 Subject: Rewrite of pattern geometry code. Fix for 1288489. (bzr r13120) --- src/sp-pattern.cpp | 84 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 35 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 8e67141fb..62cb0b2a9 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -542,6 +542,7 @@ static bool pattern_hasItemChildren (SPPattern const *pat) } cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &bbox, double opacity) { + bool needs_opacity = (1.0 - opacity) >= 1e-3; bool visible = opacity >= 1e-3; @@ -580,62 +581,74 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b } } - // viewBox to pattern server - Geom::Affine vb2ps = Geom::identity(); + // ****** Geometry ****** + // + // * "width" and "height" determine tile size. + // * "viewBox" (if defined) or "patternContentUnits" determines placement of content inside + // tile. + // * "x", "y", and "patternTransform" transform tile to user space after tile is generated. + + // These functions recursively search up the tree to find the values. + double tile_x = pattern_x(this); + double tile_y = pattern_y(this); + double tile_width = pattern_width(this); + double tile_height = pattern_height(this); + if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + tile_x *= bbox->width(); + tile_y *= bbox->height(); + tile_width *= bbox->width(); + tile_height *= bbox->height(); + } + + // Pattern size in pattern space + Geom::Rect pattern_tile = Geom::Rect::from_xywh(0, 0, tile_width, tile_height); + + // Content to tile (pattern space) + Geom::Affine content2ps; if (this->viewBox_set) { + // viewBox to pattern server Geom::Rect vb = *pattern_viewBox(this); - gdouble tmp_x = pattern_width (this) / vb.width(); - gdouble tmp_y = pattern_height (this) / vb.height(); + gdouble tmp_x = tile_width / vb.width(); + gdouble tmp_y = tile_height / vb.height(); // FIXME: preserveAspectRatio must be taken into account here too! - vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, pattern_x(this) - vb.left() * tmp_x, pattern_y(this) - vb.top() * tmp_y); - } - - // We must determine the size and scaling of the pattern at the time it is displayed and render - // the pattern onto a surface with that size and at that resolution. + Geom::Affine vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, + /*tile_x*/ - vb.left() * tmp_x, + /*tile_y*/ - vb.top() * tmp_y); + content2ps = vb2ps; + } else { - // Pattern server to user - Geom::Affine ps2user = pattern_patternTransform(this); - if (!this->viewBox_set && pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - /* BBox to user coordinate system */ - Geom::Affine bbox2user (bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top()); - ps2user *= bbox2user; + // Content to bbox + if (pattern_patternContentUnits (this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + content2ps = Geom::Affine(bbox->width(), 0.0, 0.0, bbox->height(), 0,0); + } } - ps2user = Geom::Translate (pattern_x (this), pattern_y (this)) * ps2user; - // Pattern size in pattern space - Geom::Rect pattern_tile = Geom::Rect::from_xywh(pattern_x(this), pattern_y(this), - pattern_width(this), pattern_height(this)); - if (pattern_patternUnits(this) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { - // interpret x, y, width, height in relation to bbox - Geom::Affine bbox2user(bbox->width(), 0.0, 0.0, bbox->height(), bbox->left(), bbox->top()); - pattern_tile = pattern_tile * bbox2user; - } + // Tile (pattern space) to user. + Geom::Affine ps2user = Geom::Translate(tile_x,tile_y) * pattern_patternTransform(this); + // Transform of object with pattern (includes screen scaling) cairo_matrix_t cm; cairo_get_matrix(base_ct, &cm); Geom::Affine full(cm.xx, cm.yx, cm.xy, cm.yy, 0, 0); - // The DrawingSurface class is suppose to handle the mapping from "logical space" + // The DrawingSurface class handles the mapping from "logical space" // (coordinates in the rendering) to "physical space" (surface pixels). // An oversampling is done as the pattern may not pixel align with the final surface. // The cairo surface is created when the DrawingContext is declared. - // oversample the pattern slightly + // Oversample the pattern // TODO: find optimum value // TODO: this is lame. instead of using descrim(), we should extract // the scaling component from the complete matrix and use it // to find the optimum tile size for rendering // c is number of pixels in buffer x and y. // Scale factor of 1.1 is too small... see bug #1251039 - Geom::Point c(pattern_tile.dimensions()*vb2ps.descrim()*full.descrim()*2.0); - - c[Geom::X] = ceil(c[Geom::X]); - c[Geom::Y] = ceil(c[Geom::Y]); + Geom::Point c(pattern_tile.dimensions()*ps2user.descrim()*full.descrim()*2.0); - // Create drawing surface with size of pattern tile (in tile space) but with number of pixels + // Create drawing surface with size of pattern tile (in pattern space) but with number of pixels // based on required resolution (c). Inkscape::DrawingSurface pattern_surface(pattern_tile, c.ceil()); Inkscape::DrawingContext dc(pattern_surface); @@ -643,14 +656,14 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b pattern_tile *= pattern_surface.drawingTransform(); Geom::IntRect one_tile = pattern_tile.roundOutwards(); - // render pattern. + // Render pattern. if (needs_opacity) { dc.pushGroup(); // this group is for pattern + opacity } // TODO: make sure there are no leaks. Inkscape::UpdateContext ctx; // UpdateContext is structure with only ctm! - ctx.ctm = ps2user * pattern_surface.drawingTransform(); // vb2ps? + ctx.ctm = content2ps * pattern_surface.drawingTransform(); dc.transform( pattern_surface.drawingTransform().inverse() ); drawing.update(Geom::IntRect::infinite(), ctx); @@ -669,7 +682,8 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // << " width: " << cairo_image_surface_get_width( raw ) // << " height: " << cairo_image_surface_get_height( raw ) // << std::endl; - // cairo_surface_write_to_png( pattern_surface.raw(), "sp-pattern.png" ); + // std::string filename = "sp-pattern-" + (std::string)getId() + ".png"; + // cairo_surface_write_to_png( pattern_surface.raw(), filename.c_str() ); if (needs_opacity) { dc.popGroupToSource(); // pop raw pattern @@ -678,7 +692,7 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); // Apply transformation to user space. Also compensate for oversampling. - ink_cairo_pattern_set_matrix(cp, pattern_surface.drawingTransform() ); + ink_cairo_pattern_set_matrix(cp, ps2user.inverse() * pattern_surface.drawingTransform() ); cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); -- cgit v1.2.3 From 908626dbefcefb35c8cef0971ca3db2eec06b2d1 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 6 Mar 2014 14:32:52 +0100 Subject: Take "preserveAspectRatio" into account in pattern. (bzr r13121) --- src/sp-pattern.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'src/sp-pattern.cpp') diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp index 62cb0b2a9..e465565c4 100644 --- a/src/sp-pattern.cpp +++ b/src/sp-pattern.cpp @@ -606,16 +606,11 @@ cairo_pattern_t* SPPattern::pattern_new(cairo_t *base_ct, Geom::OptRect const &b // Content to tile (pattern space) Geom::Affine content2ps; if (this->viewBox_set) { - // viewBox to pattern server - Geom::Rect vb = *pattern_viewBox(this); - gdouble tmp_x = tile_width / vb.width(); - gdouble tmp_y = tile_height / vb.height(); - - // FIXME: preserveAspectRatio must be taken into account here too! - Geom::Affine vb2ps = Geom::Affine(tmp_x, 0.0, 0.0, tmp_y, - /*tile_x*/ - vb.left() * tmp_x, - /*tile_y*/ - vb.top() * tmp_y); - content2ps = vb2ps; + // viewBox to pattern server (using SPViewBox) + viewBox = *pattern_viewBox(this); + c2p.setIdentity(); + apply_viewbox( pattern_tile ); + content2ps = c2p; } else { // Content to bbox -- cgit v1.2.3