Пример #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 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());
        }
    }
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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);
    }
}
Пример #7
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);
    }
}
Пример #8
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);
    }
}