예제 #1
0
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;
}
예제 #2
0
void SPFlowtext::modified(unsigned int flags) {
    SPObject *region = NULL;

    if (flags & SP_OBJECT_MODIFIED_FLAG) {
    	flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
    }

    flags &= SP_OBJECT_MODIFIED_CASCADE;

    // FIXME: the below stanza is copied over from sp_text_modified, consider factoring it out
    if (flags & ( SP_OBJECT_STYLE_MODIFIED_FLAG )) {
        SPFlowtext *text = SP_FLOWTEXT(this);
        Geom::OptRect pbox = text->geometricBounds();

        for (SPItemView* v = text->display; v != NULL; v = v->next) {
            Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
            text->_clearFlow(g);
            g->setStyle(this->style);
            text->layout.show(g, pbox);
        }
    }

    for ( SPObject *o = this->firstChild() ; o ; o = o->getNext() ) {
        if (SP_IS_FLOWREGION(o)) {
            region = o;
            break;
        }
    }

    if (region) {
        if (flags || (region->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
            region->emitModified(flags); // pass down to the region only
        }
    }
}
예제 #3
0
void SPUse::modified(unsigned int flags) {
    // std::cout << "SPUse::modified: " << (getId()?getId():"null") << std::endl;
    if (flags & SP_OBJECT_MODIFIED_FLAG) {
        flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
    }

    flags &= SP_OBJECT_MODIFIED_CASCADE;

    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);
      }
    }

    if (child) {
        sp_object_ref(child);

        if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
            child->emitModified(flags);
        }

        sp_object_unref(child);
    }
}
예제 #4
0
static void
sp_canvas_arena_init (SPCanvasArena *arena)
{
    arena->sticky = FALSE;

    new (&arena->drawing) Inkscape::Drawing(arena);

    Inkscape::DrawingGroup *root = new DrawingGroup(arena->drawing);
    root->setPickChildren(true);
    arena->drawing.setRoot(root);

    arena->observer = new CachePrefObserver(arena);

    arena->drawing.signal_request_update.connect(
        sigc::bind<0>(
            sigc::ptr_fun(&sp_canvas_arena_request_update),
            arena));
    arena->drawing.signal_request_render.connect(
        sigc::bind<0>(
            sigc::ptr_fun(&sp_canvas_arena_request_render),
            arena));
    arena->drawing.signal_item_deleted.connect(
        sigc::bind<0>(
            sigc::ptr_fun(&sp_canvas_arena_item_deleted),
            arena));

    arena->active = NULL;
}
예제 #5
0
Inkscape::DrawingItem *CGroup::show (Inkscape::Drawing &drawing, unsigned int key, unsigned int flags) {
    Inkscape::DrawingGroup *ai;
    SPObject *object = _group;

    ai = new Inkscape::DrawingGroup(drawing);
    ai->setPickChildren(_group->effectiveLayerMode(key) == SPGroup::LAYER);
    ai->setStyle(object->style);

    _showChildren(drawing, ai, key, flags);
    return ai;
}
예제 #6
0
void SPGroup::_updateLayerMode(unsigned int display_key) {
    SPItemView *view;
    for ( view = this->display ; view ; view = view->next ) {
        if ( !display_key || view->key == display_key ) {
            Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(view->arenaitem);
            if (g) {
                g->setPickChildren(effectiveLayerMode(view->key) == SPGroup::LAYER);
            }
        }
    }
}
예제 #7
0
Inkscape::DrawingItem* SPFlowtext::show(Inkscape::Drawing &drawing, unsigned int /*key*/, unsigned int /*flags*/) {
    Inkscape::DrawingGroup *flowed = new Inkscape::DrawingGroup(drawing);
    flowed->setPickChildren(false);
    flowed->setStyle(this->style);

    // pass the bbox of the flowtext object as paintbox (used for paintserver fills)
    Geom::OptRect bbox = this->geometricBounds();
    this->layout.show(flowed, bbox);

    return flowed;
}
예제 #8
0
void SPFlowtext::update(SPCtx* ctx, unsigned int 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;

    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 (childflags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
            if (SP_IS_ITEM(child)) {
                SPItem const &chi = *SP_ITEM(child);
                cctx.i2doc = chi.transform * ictx->i2doc;
                cctx.i2vp = chi.transform * ictx->i2vp;
                child->updateDisplay((SPCtx *)&cctx, childflags);
            } else {
                child->updateDisplay(ctx, childflags);
            }
        }

        sp_object_unref(child);
    }

    SPItem::update(ctx, flags);

    this->rebuildLayout();

    Geom::OptRect pbox = this->geometricBounds();

    for (SPItemView *v = this->display; v != NULL; v = v->next) {
        Inkscape::DrawingGroup *g = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
        this->_clearFlow(g);
        g->setStyle(this->style);
        // pass the bbox of the flowtext object as paintbox (used for paintserver fills)
        this->layout.show(g, pbox);
    }
}
예제 #9
0
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;
}
예제 #10
0
/**
 * 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;
}
예제 #11
0
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;
}
예제 #12
0
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());
        }
    }
}
예제 #13
0
void CGroup::onUpdate(SPCtx *ctx, unsigned int flags) {
    SPItemCtx *ictx, cctx;

    ictx = (SPItemCtx *) ctx;
    cctx = *ictx;

    if (flags & SP_OBJECT_MODIFIED_FLAG) {
      flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
    }

    flags &= SP_OBJECT_MODIFIED_CASCADE;

    if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
        SPObject *object = _group;
        for (SPItemView *v = _group->display; v != NULL; v = v->next) {
            Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
            group->setStyle(object->style);
        }
    }

    GSList *l = g_slist_reverse(_group->childList(true, SPObject::ActionUpdate));
    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))) {
            if (SP_IS_ITEM (child)) {
                SPItem const &chi = *SP_ITEM(child);
                cctx.i2doc = chi.transform * ictx->i2doc;
                cctx.i2vp = chi.transform * ictx->i2vp;
                child->updateDisplay((SPCtx *)&cctx, flags);
            } else {
                child->updateDisplay(ctx, flags);
            }
        }
        g_object_unref (G_OBJECT (child));
    }
}
예제 #14
0
void CGroup::onModified(guint flags) {
    SPObject *child;

    if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG;
    flags &= SP_OBJECT_MODIFIED_CASCADE;

    if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) {
        SPObject *object = _group;
        for (SPItemView *v = _group->display; v != NULL; v = v->next) {
            Inkscape::DrawingGroup *group = dynamic_cast<Inkscape::DrawingGroup *>(v->arenaitem);
            group->setStyle(object->style);
        }
    }

    GSList *l = g_slist_reverse(_group->childList(true));
    while (l) {
        child = SP_OBJECT (l->data);
        l = g_slist_remove (l, child);
        if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) {
            child->emitModified(flags);
        }
        g_object_unref (G_OBJECT (child));
    }
}
예제 #15
0
/**
 * 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);
    }
}
예제 #16
0
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);
    }
}
예제 #17
0
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);
    }
}