Inkscape::DrawingItem *SPClipPath::show(Inkscape::Drawing &drawing, unsigned int key) { Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); display = sp_clippath_view_new_prepend(display, key, ai); for ( SPObject *child = firstChild() ; child ; child = child->getNext() ) { if (SP_IS_ITEM(child)) { Inkscape::DrawingItem *ac = SP_ITEM(child)->invoke_show(drawing, key, SP_ITEM_REFERENCE_FLAGS); if (ac) { /* The order is not important in clippath */ ai->appendChild(ac); } } } if (clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && display->bbox) { Geom::Affine t = Geom::Scale(display->bbox->dimensions()); t.setTranslation(display->bbox->min()); ai->setChildTransform(t); } ai->setStyle(this->style); return ai; }
void SPClipPath::update(SPCtx* ctx, unsigned int flags) { if (flags & SP_OBJECT_MODIFIED_FLAG) { flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } flags &= SP_OBJECT_MODIFIED_CASCADE; GSList *l = NULL; for ( SPObject *child = this->firstChild(); child; child = child->getNext()) { sp_object_ref(child); l = g_slist_prepend(l, child); } l = g_slist_reverse(l); while (l) { SPObject *child = SP_OBJECT(l->data); l = g_slist_remove(l, child); if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { child->updateDisplay(ctx, flags); } sp_object_unref(child); } for (SPClipPathView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); if (this->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX && v->bbox) { Geom::Affine t = Geom::Scale(v->bbox->dimensions()); t.setTranslation(v->bbox->min()); g->setChildTransform(t); } else { g->setChildTransform(Geom::identity()); } } }
Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); ai->setStyle(this->style); if (this->child) { Inkscape::DrawingItem *ac = this->child->invoke_show(drawing, key, flags); if (ac) { ai->prependChild(ac); } Geom::Translate t(this->x.computed, this->y.computed); ai->setChildTransform(t); } return ai; }
/** * Displays the SPRoot item on the drawing. */ static Inkscape::DrawingItem * sp_root_show(SPItem *item, Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { SPRoot *root = SP_ROOT(item); Inkscape::DrawingItem *ai; if (((SPItemClass *) (parent_class))->show) { ai = ((SPItemClass *) (parent_class))->show(item, drawing, key, flags); if (ai) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(ai); g->setChildTransform(root->c2p); } } else { ai = NULL; } return ai; }
Inkscape::DrawingItem* SPUse::show(Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) { // std::cout << "SPUse::show: " << (getId()?getId():"null") << std::endl; Inkscape::DrawingGroup *ai = new Inkscape::DrawingGroup(drawing); ai->setPickChildren(false); this->context_style = this->style; ai->setStyle(this->style, this->context_style); if (this->child) { Inkscape::DrawingItem *ac = this->child->invoke_show(drawing, key, flags); if (ac) { ai->prependChild(ac); } Geom::Translate t(this->x.computed, this->y.computed); ai->setChildTransform(t); } return ai; }
void SPUse::update(SPCtx *ctx, unsigned flags) { // std::cout << "SPUse::update: " << (getId()?getId():"null") << std::endl; SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } childflags &= SP_OBJECT_MODIFIED_CASCADE; /* Set up child viewport */ if (this->x.unit == SVGLength::PERCENT) { this->x.computed = this->x.value * ictx->viewport.width(); } if (this->y.unit == SVGLength::PERCENT) { this->y.computed = this->y.value * ictx->viewport.height(); } if (this->width.unit == SVGLength::PERCENT) { this->width.computed = this->width.value * ictx->viewport.width(); } if (this->height.unit == SVGLength::PERCENT) { this->height.computed = this->height.value * ictx->viewport.height(); } childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); // viewport is only changed if referencing a symbol or svg element if( SP_IS_SYMBOL(this->child) || SP_IS_ROOT(this->child) ) { cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); } if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { SPItem const *chi = dynamic_cast<SPItem const *>(child); g_assert(chi != NULL); cctx.i2doc = chi->transform * ictx->i2doc; cctx.i2vp = chi->transform * ictx->i2vp; this->child->updateDisplay((SPCtx *)&cctx, childflags); } sp_object_unref(this->child); } SPItem::update(ctx, flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); this->context_style = this->style; g->setStyle(this->style, this->context_style); } } /* As last step set additional transform of arena group */ for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); Geom::Affine t(Geom::Translate(this->x.computed, this->y.computed)); g->setChildTransform(t); } }
void SPUse::update(SPCtx *ctx, unsigned flags) { SPItemCtx *ictx = (SPItemCtx *) ctx; SPItemCtx cctx = *ictx; unsigned childflags = flags; if (flags & SP_OBJECT_MODIFIED_FLAG) { childflags |= SP_OBJECT_PARENT_MODIFIED_FLAG; } childflags &= SP_OBJECT_MODIFIED_CASCADE; /* Set up child viewport */ if (this->x.unit == SVGLength::PERCENT) { this->x.computed = this->x.value * ictx->viewport.width(); } if (this->y.unit == SVGLength::PERCENT) { this->y.computed = this->y.value * ictx->viewport.height(); } if (this->width.unit == SVGLength::PERCENT) { this->width.computed = this->width.value * ictx->viewport.width(); } if (this->height.unit == SVGLength::PERCENT) { this->height.computed = this->height.value * ictx->viewport.height(); } cctx.viewport = Geom::Rect::from_xywh(0, 0, this->width.computed, this->height.computed); cctx.i2vp = Geom::identity(); childflags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; if (this->child) { sp_object_ref(this->child); if (childflags || (this->child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { SPItem const &chi = *SP_ITEM(this->child); cctx.i2doc = chi.transform * ictx->i2doc; cctx.i2vp = chi.transform * ictx->i2vp; this->child->updateDisplay((SPCtx *)&cctx, childflags); } sp_object_unref(this->child); } SPItem::update(ctx, flags); if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); g->setStyle(this->style); } } /* As last step set additional transform of arena group */ for (SPItemView *v = this->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); Geom::Affine t(Geom::Translate(this->x.computed, this->y.computed)); g->setChildTransform(t); } }
/** * This callback routine updates the SPRoot object when its attributes have been changed. */ static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags) { SPRoot *root = SP_ROOT(object); SPItemCtx *ictx = (SPItemCtx *) ctx; /* fixme: This will be invoked too often (Lauris) */ /* fixme: We should calculate only if parent viewport has changed (Lauris) */ /* If position is specified as percentage, calculate actual values */ if (root->x.unit == SVGLength::PERCENT) { root->x.computed = root->x.value * ictx->viewport.width(); } if (root->y.unit == SVGLength::PERCENT) { root->y.computed = root->y.value * ictx->viewport.height(); } if (root->width.unit == SVGLength::PERCENT) { root->width.computed = root->width.value * ictx->viewport.width(); } if (root->height.unit == SVGLength::PERCENT) { root->height.computed = root->height.value * ictx->viewport.height(); } /* Create copy of item context */ SPItemCtx rctx = *ictx; /* Calculate child to parent transformation */ root->c2p.setIdentity(); if (object->parent) { /* * fixme: I am not sure whether setting x and y does or does not * fixme: translate the content of inner SVG. * fixme: Still applying translation and setting viewport to width and * fixme: height seems natural, as this makes the inner svg element * fixme: self-contained. The spec is vague here. */ root->c2p = Geom::Affine(Geom::Translate(root->x.computed, root->y.computed)); } if (root->viewBox_set) { double x, y, width, height; /* Determine actual viewbox in viewport coordinates */ if (root->aspect_align == SP_ASPECT_NONE) { x = 0.0; y = 0.0; width = root->width.computed; height = root->height.computed; } else { double scalex, scaley, scale; /* Things are getting interesting */ scalex = root->width.computed / root->viewBox.width(); scaley = root->height.computed / root->viewBox.height(); scale = (root->aspect_clip == SP_ASPECT_MEET) ? MIN(scalex, scaley) : MAX(scalex, scaley); width = root->viewBox.width() * scale; height = root->viewBox.height() * scale; /* Now place viewbox to requested position */ /* todo: Use an array lookup to find the 0.0/0.5/1.0 coefficients, as is done for dialogs/align.cpp. */ switch (root->aspect_align) { case SP_ASPECT_XMIN_YMIN: x = 0.0; y = 0.0; break; case SP_ASPECT_XMID_YMIN: x = 0.5 * (root->width.computed - width); y = 0.0; break; case SP_ASPECT_XMAX_YMIN: x = 1.0 * (root->width.computed - width); y = 0.0; break; case SP_ASPECT_XMIN_YMID: x = 0.0; y = 0.5 * (root->height.computed - height); break; case SP_ASPECT_XMID_YMID: x = 0.5 * (root->width.computed - width); y = 0.5 * (root->height.computed - height); break; case SP_ASPECT_XMAX_YMID: x = 1.0 * (root->width.computed - width); y = 0.5 * (root->height.computed - height); break; case SP_ASPECT_XMIN_YMAX: x = 0.0; y = 1.0 * (root->height.computed - height); break; case SP_ASPECT_XMID_YMAX: x = 0.5 * (root->width.computed - width); y = 1.0 * (root->height.computed - height); break; case SP_ASPECT_XMAX_YMAX: x = 1.0 * (root->width.computed - width); y = 1.0 * (root->height.computed - height); break; default: x = 0.0; y = 0.0; break; } } /* Compose additional transformation from scale and position */ Geom::Scale const viewBox_length( root->viewBox.dimensions() ); Geom::Scale const new_length(width, height); /* Append viewbox transformation */ /* TODO: The below looks suspicious to me (pjrm): I wonder whether the RHS expression should have c2p at the beginning rather than at the end. Test it. */ root->c2p = Geom::Translate(-root->viewBox.min()) * ( new_length * viewBox_length.inverse() ) * Geom::Translate(x, y) * root->c2p; } rctx.i2doc = root->c2p * rctx.i2doc; /* Initialize child viewport */ if (root->viewBox_set) { rctx.viewport = root->viewBox; } else { /* fixme: I wonder whether this logic is correct (Lauris) */ Geom::Point minp(0,0); if (object->parent) { minp = Geom::Point(root->x.computed, root->y.computed); } rctx.viewport = Geom::Rect::from_xywh(minp[Geom::X], minp[Geom::Y], root->width.computed, root->height.computed); } rctx.i2vp = Geom::identity(); /* And invoke parent method */ if (((SPObjectClass *) (parent_class))->update) ((SPObjectClass *) (parent_class))->update(object, (SPCtx *) &rctx, flags); /* As last step set additional transform of drawing group */ for (SPItemView *v = root->display; v != NULL; v = v->next) { Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem); g->setChildTransform(root->c2p); } }