Beispiel #1
0
Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:use");
    }

    SPItem::write(xml_doc, repr, flags);

    sp_repr_set_svg_double(repr, "x", this->x.computed);
    sp_repr_set_svg_double(repr, "y", this->y.computed);
    repr->setAttribute("width", sp_svg_length_write_with_units(this->width).c_str());
    repr->setAttribute("height", sp_svg_length_write_with_units(this->height).c_str());

    if (this->ref->getURI()) {
        gchar *uri_string = this->ref->getURI()->toString();
        repr->setAttribute("xlink:href", uri_string);
        g_free(uri_string);
    }

    if (SP_IS_SHAPE(this->child)) {
        SP_SHAPE(this->child)->set_shape(); // evaluate SPCurve of child
    } else if (SP_IS_TEXT(this->child)) {
        SP_TEXT(this->child)->rebuildLayout(); // refresh Layout, LP Bug 1339305
    } else if (SP_IS_FLOWTEXT(this->child)) {
        if (SP_IS_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild()))
            SP_FLOWREGION(SP_FLOWTEXT(this->child)->firstChild())->UpdateComputed();
        SP_FLOWTEXT(this->child)->rebuildLayout();
    }

    return repr;
}
Beispiel #2
0
void
sp_textpath_to_text(SPObject *tp)
{
    SPObject *text = SP_OBJECT_PARENT(tp);

    NRRect bbox;
    sp_item_invoke_bbox(SP_ITEM(text), &bbox, sp_item_i2doc_affine(SP_ITEM(text)), TRUE);
    Geom::Point xy(bbox.x0, bbox.y0);

    // make a list of textpath children
    GSList *tp_reprs = NULL;
    for (SPObject *o = SP_OBJECT(tp)->firstChild() ; o != NULL; o = o->next) {
        tp_reprs = g_slist_prepend(tp_reprs, SP_OBJECT_REPR(o));
    }

    for ( GSList *i = tp_reprs ; i ; i = i->next ) {
        // make a copy of each textpath child
        Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(SP_OBJECT_REPR(text)->document());
        // remove the old repr from under textpath
        SP_OBJECT_REPR(tp)->removeChild((Inkscape::XML::Node *) i->data);
        // put its copy under text
        SP_OBJECT_REPR(text)->addChild(copy, NULL); // fixme: copy id
    }

    //remove textpath
    tp->deleteObject();
    g_slist_free(tp_reprs);

    // set x/y on text
    /* fixme: Yuck, is this really the right test? */
    if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) {
        sp_repr_set_svg_double(SP_OBJECT_REPR(text), "x", xy[Geom::X]);
        sp_repr_set_svg_double(SP_OBJECT_REPR(text), "y", xy[Geom::Y]);
    }
}
Beispiel #3
0
Inkscape::XML::Node* SPStar::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:path");
    }

    if (flags & SP_OBJECT_WRITE_EXT) {
        repr->setAttribute("sodipodi:type", "star");
        sp_repr_set_int (repr, "sodipodi:sides", this->sides);
        sp_repr_set_svg_double(repr, "sodipodi:cx", this->center[Geom::X]);
        sp_repr_set_svg_double(repr, "sodipodi:cy", this->center[Geom::Y]);
        sp_repr_set_svg_double(repr, "sodipodi:r1", this->r[0]);
        sp_repr_set_svg_double(repr, "sodipodi:r2", this->r[1]);
        sp_repr_set_svg_double(repr, "sodipodi:arg1", this->arg[0]);
        sp_repr_set_svg_double(repr, "sodipodi:arg2", this->arg[1]);
        sp_repr_set_boolean (repr, "inkscape:flatsided", this->flatsided);
        sp_repr_set_svg_double(repr, "inkscape:rounded", this->rounded);
        sp_repr_set_svg_double(repr, "inkscape:randomized", this->randomized);
    }

    this->set_shape();

    char *d = sp_svg_write_path (this->_curve->get_pathvector());
    repr->setAttribute("d", d);
    g_free(d);

    // CPPIFY: see header file
    SPShape::write(xml_doc, repr, flags);

    return repr;
}
Beispiel #4
0
static Inkscape::XML::Node *
sp_textpath_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
    SPTextPath *textpath = SP_TEXTPATH(object);

    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:textPath");
    }
	
    textpath->attributes.writeTo(repr);
    if (textpath->startOffset._set) {
        if (textpath->startOffset.unit == SVGLength::PERCENT) {
	        Inkscape::SVGOStringStream os;
            os << (textpath->startOffset.computed * 100.0) << "%";
            SP_OBJECT_REPR(textpath)->setAttribute("startOffset", os.str().c_str());
        } else {
            /* FIXME: This logic looks rather undesirable if e.g. startOffset is to be
               in ems. */
            sp_repr_set_svg_double(repr, "startOffset", textpath->startOffset.computed);
        }
    }

    if ( textpath->sourcePath->sourceHref ) repr->setAttribute("xlink:href", textpath->sourcePath->sourceHref);
	
    if ( flags&SP_OBJECT_WRITE_BUILD ) {
        GSList *l = NULL;
        for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
            Inkscape::XML::Node* c_repr=NULL;
            if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) {
                c_repr = child->updateRepr(xml_doc, NULL, flags);
            } else if ( SP_IS_TEXTPATH(child) ) {
                //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen
            } else if ( SP_IS_STRING(child) ) {
                c_repr = xml_doc->createTextNode(SP_STRING(child)->string.c_str());
            }
            if ( c_repr ) l = g_slist_prepend(l, c_repr);
        }
        while ( l ) {
            repr->addChild((Inkscape::XML::Node *) l->data, NULL);
            Inkscape::GC::release((Inkscape::XML::Node *) l->data);
            l = g_slist_remove(l, l->data);
        }
    } else {
        for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) {
            if ( SP_IS_TSPAN(child) || SP_IS_TREF(child) ) {
                child->updateRepr(flags);
            } else if ( SP_IS_TEXTPATH(child) ) {
                //c_repr = child->updateRepr(xml_doc, NULL, flags); // shouldn't happen
            } else if ( SP_IS_STRING(child) ) {
                SP_OBJECT_REPR(child)->setContent(SP_STRING(child)->string.c_str());
            }
        }
    }
	
    if (((SPObjectClass *) textpath_parent_class)->write)
        ((SPObjectClass *) textpath_parent_class)->write(object, xml_doc, repr, flags);
	
    return repr;
}
Beispiel #5
0
Inkscape::XML::Node* SPLine::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:line");
    }

    if (repr != this->getRepr()) {
        repr->mergeFrom(this->getRepr(), "id");
    }

    sp_repr_set_svg_double(repr, "x1", this->x1.computed);
    sp_repr_set_svg_double(repr, "y1", this->y1.computed);
    sp_repr_set_svg_double(repr, "x2", this->x2.computed);
    sp_repr_set_svg_double(repr, "y2", this->y2.computed);

    SPShape::write(xml_doc, repr, flags);

    return repr;
}
Beispiel #6
0
/**
 * Writes the object into the repr object, then calls the parent's write routine.
 */
static Inkscape::XML::Node *
sp_root_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
    SPRoot *root = SP_ROOT(object);

    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:svg");
    }

    if (flags & SP_OBJECT_WRITE_EXT) {
        repr->setAttribute("inkscape:version", Inkscape::version_string);
    }

    if ( !repr->attribute("version") ) {
        gchar* myversion = sp_version_to_string(root->version.svg);
        repr->setAttribute("version", myversion);
        g_free(myversion);
    }

    if (fabs(root->x.computed) > 1e-9)
        sp_repr_set_svg_double(repr, "x", root->x.computed);
    if (fabs(root->y.computed) > 1e-9)
        sp_repr_set_svg_double(repr, "y", root->y.computed);

    /* Unlike all other SPObject, here we want to preserve absolute units too (and only here,
     * according to the recommendation in http://www.w3.org/TR/SVG11/coords.html#Units).
     */
    repr->setAttribute("width", sp_svg_length_write_with_units(root->width).c_str());
    repr->setAttribute("height", sp_svg_length_write_with_units(root->height).c_str());

    if (root->viewBox_set) {
        Inkscape::SVGOStringStream os;
        os << root->viewBox.left() << " " << root->viewBox.top() << " "
           << root->viewBox.width() << " " << root->viewBox.height();
        repr->setAttribute("viewBox", os.str().c_str());
    }

    if (((SPObjectClass *) (parent_class))->write)
        ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags);

    return repr;
}
Beispiel #7
0
void sp_textpath_to_text(SPObject *tp)
{
    SPObject *text = tp->parent;

    Geom::OptRect bbox = SP_ITEM(text)->geometricBounds(SP_ITEM(text)->i2doc_affine());

    if (!bbox) {
    	return;
    }

    Geom::Point xy = bbox->min();
    xy *= tp->document->getDocumentScale().inverse(); // Convert to user-units.
    
    // make a list of textpath children
    GSList *tp_reprs = NULL;

    for (SPObject *o = tp->firstChild() ; o != NULL; o = o->next) {
        tp_reprs = g_slist_prepend(tp_reprs, o->getRepr());
    }

    for ( GSList *i = tp_reprs ; i ; i = i->next ) {
        // make a copy of each textpath child
        Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(text->getRepr()->document());
        // remove the old repr from under textpath
        tp->getRepr()->removeChild((Inkscape::XML::Node *) i->data);
        // put its copy under text
        text->getRepr()->addChild(copy, NULL); // fixme: copy id
    }

    //remove textpath
    tp->deleteObject();
    g_slist_free(tp_reprs);

    // set x/y on text (to be near where it was when on path)
    /* fixme: Yuck, is this really the right test? */
    if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) {
        sp_repr_set_svg_double(text->getRepr(), "x", xy[Geom::X]);
        sp_repr_set_svg_double(text->getRepr(), "y", xy[Geom::Y]);
    }
}
Beispiel #8
0
Inkscape::XML::Node* SPUse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) {
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:use");
    }

    SPItem::write(xml_doc, repr, flags);

    sp_repr_set_svg_double(repr, "x", this->x.computed);
    sp_repr_set_svg_double(repr, "y", this->y.computed);
    repr->setAttribute("width", sp_svg_length_write_with_units(this->width).c_str());
    repr->setAttribute("height", sp_svg_length_write_with_units(this->height).c_str());

    if (this->ref->getURI()) {
        gchar *uri_string = this->ref->getURI()->toString();
        repr->setAttribute("xlink:href", uri_string);
        g_free(uri_string);
    }

    SPShape *shape = dynamic_cast<SPShape *>(child);
    if (shape) {
        shape->set_shape(); // evaluate SPCurve of child
    } else {
        SPText *text = dynamic_cast<SPText *>(child);
        if (text) {
            text->rebuildLayout(); // refresh Layout, LP Bug 1339305
        } else {
            SPFlowtext *flowtext = dynamic_cast<SPFlowtext *>(child);
            if (flowtext) {
                SPFlowregion *flowregion = dynamic_cast<SPFlowregion *>(flowtext->firstChild());
                if (flowregion) {
                    flowregion->UpdateComputed();
                }
                flowtext->rebuildLayout();
            }
        }
    }

    return repr;
}
Beispiel #9
0
Inkscape::XML::Node * SPLine::write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
    SPLine *line  = SP_LINE(object);

    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:line");
    }

    if (repr != object->getRepr()) {
        repr->mergeFrom(object->getRepr(), "id");
    }

    sp_repr_set_svg_double(repr, "x1", line->x1.computed);
    sp_repr_set_svg_double(repr, "y1", line->y1.computed);
    sp_repr_set_svg_double(repr, "x2", line->x2.computed);
    sp_repr_set_svg_double(repr, "y2", line->y2.computed);

    if (((SPObjectClass *) (SPLineClass::static_parent_class))->write) {
        ((SPObjectClass *) (SPLineClass::static_parent_class))->write(object, xml_doc, repr, flags);
    }

    return repr;
}
Beispiel #10
0
Inkscape::XML::Node *SPImage::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags ) {
    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:image");
    }

    repr->setAttribute("xlink:href", this->href);

    /* fixme: Reset attribute if needed (Lauris) */
    if (this->x._set) {
        sp_repr_set_svg_double(repr, "x", this->x.computed);
    }

    if (this->y._set) {
        sp_repr_set_svg_double(repr, "y", this->y.computed);
    }

    if (this->width._set) {
        sp_repr_set_svg_double(repr, "width", this->width.computed);
    }

    if (this->height._set) {
        sp_repr_set_svg_double(repr, "height", this->height.computed);
    }

    //XML Tree being used directly here while it shouldn't be...
    repr->setAttribute("preserveAspectRatio", this->getRepr()->attribute("preserveAspectRatio"));
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
    if (this->color_profile) {
        repr->setAttribute("color-profile", this->color_profile);
    }
#endif // defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)

    SPItem::write(xml_doc, repr, flags);

    return repr;
}
Beispiel #11
0
/**
 * Writes its settings to an incoming repr object, if any.
 */
Inkscape::XML::Node* SPFeDisplacementMap::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) {
    SPFilter *parent = SP_FILTER(this->parent);

    if (!repr) {
        repr = doc->createElement("svg:feDisplacementMap");
    }

    gchar const *in2_name = sp_filter_name_for_image(parent, this->in2);

    if( !in2_name ) {

        // This code is very similar to sp_filter_primtive_name_previous_out()
        SPObject *i = parent->children;

        // Find previous filter primitive
        while (i && i->next != this) {
        	i = i->next;
        }

        if( i ) {
            SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
            in2_name = sp_filter_name_for_image(parent, i_prim->image_out);
        }
    }

    if (in2_name) {
        repr->setAttribute("in2", in2_name);
    } else {
        g_warning("Unable to set in2 for feDisplacementMap");
    }

    sp_repr_set_svg_double(repr, "scale", this->scale);
    repr->setAttribute("xChannelSelector",
                       get_channelselector_name(this->xChannelSelector));
    repr->setAttribute("yChannelSelector",
                       get_channelselector_name(this->yChannelSelector));

    SPFilterPrimitive::write(doc, repr, flags);

    return repr;
}
Beispiel #12
0
/**
 * Writes its settings to an incoming repr object, if any.
 */
static Inkscape::XML::Node *
sp_feComposite_write(SPObject *object, Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags)
{
    SPFeComposite *comp = SP_FECOMPOSITE(object);
    SPFilter *parent = SP_FILTER(object->parent);

    if (!repr) {
        repr = doc->createElement("svg:feComposite");
    }

    gchar const *out_name = sp_filter_name_for_image(parent, comp->in2);
    if (out_name) {
        repr->setAttribute("in2", out_name);
    } else {
        SPObject *i = parent->children;
        while (i && i->next != object) i = i->next;
        SPFilterPrimitive *i_prim = SP_FILTER_PRIMITIVE(i);
        out_name = sp_filter_name_for_image(parent, i_prim->image_out);
        repr->setAttribute("in2", out_name);
        if (!out_name) {
            g_warning("Unable to set in2 for feComposite");
        }
    }

    char const *comp_op;
    switch (comp->composite_operator) {
        case COMPOSITE_OVER:
            comp_op = "over"; break;
        case COMPOSITE_IN:
            comp_op = "in"; break;
        case COMPOSITE_OUT:
            comp_op = "out"; break;
        case COMPOSITE_ATOP:
            comp_op = "atop"; break;
        case COMPOSITE_XOR:
            comp_op = "xor"; break;
        case COMPOSITE_ARITHMETIC:
            comp_op = "arithmetic"; break;
        default:
            comp_op = 0;
    }
    repr->setAttribute("operator", comp_op);

    if (comp->composite_operator == COMPOSITE_ARITHMETIC) {
        sp_repr_set_svg_double(repr, "k1", comp->k1);
        sp_repr_set_svg_double(repr, "k2", comp->k2);
        sp_repr_set_svg_double(repr, "k3", comp->k3);
        sp_repr_set_svg_double(repr, "k4", comp->k4);
    } else {
        repr->setAttribute("k1", 0);
        repr->setAttribute("k2", 0);
        repr->setAttribute("k3", 0);
        repr->setAttribute("k4", 0);
    }

    if (((SPObjectClass *) feComposite_parent_class)->write) {
        ((SPObjectClass *) feComposite_parent_class)->write(object, doc, repr, flags);
    }

    return repr;
}
Beispiel #13
0
SPDocument *
GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri)
{
    // Determine whether the image should be embedded
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    bool ask = prefs->getBool("/dialogs/import/ask");
    Glib::ustring link  = prefs->getString("/dialogs/import/link");
    bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi");
    Glib::ustring scale = prefs->getString("/dialogs/import/scale");
    // std::cout << "GkdpixbufInput::open: "
    //           << " ask: " << ask
    //           << ", link: " << link
    //           << ", forcexdpi: " << forcexdpi
    //           << ", scale: " << scale << std::endl;
    // std::cout << "     in  preferences: "
    //           << " ask: " << !mod->get_param_bool("do_not_ask")
    //           << ", link: " << mod->get_param_optiongroup("link")
    //           << ", mod_dpi: " << mod->get_param_optiongroup("dpi")
    //           << ", scale: " << mod->get_param_optiongroup("scale") << std::endl;
    if( ask ) {
        Glib::ustring mod_link = mod->get_param_optiongroup("link");
        Glib::ustring mod_dpi = mod->get_param_optiongroup("dpi");
        bool mod_forcexdpi = ( mod_dpi.compare( "from_default" ) == 0 );
        Glib::ustring mod_scale = mod->get_param_optiongroup("scale");
        if( link.compare( mod_link ) != 0 ) {
            link = mod_link;
        }
        prefs->setString("/dialogs/import/link", link );
        if( forcexdpi != mod_forcexdpi ) {
            forcexdpi = mod_forcexdpi;
        }
        prefs->setBool("/dialogs/import/forcexdpi", forcexdpi );
        if( scale.compare( mod_scale ) != 0 ) {
            scale = mod_scale;
        }
        prefs->setString("/dialogs/import/scale", scale );
        prefs->setBool("/dialogs/import/ask", !mod->get_param_bool("do_not_ask") );
    }
    bool embed = ( link.compare( "embed" ) == 0 );

    SPDocument *doc = NULL;
    boost::scoped_ptr<Inkscape::Pixbuf> pb(Inkscape::Pixbuf::create_from_file(uri));

    // TODO: the pixbuf is created again from the base64-encoded attribute in SPImage.
    // Find a way to create the pixbuf only once.

    if (pb) {
        doc = SPDocument::createNewDoc(NULL, TRUE, TRUE);
        bool saved = DocumentUndo::getUndoSensitive(doc);
        DocumentUndo::setUndoSensitive(doc, false); // no need to undo in this temporary document

        double width = pb->width();
        double height = pb->height();
        double defaultxdpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", Inkscape::Util::Quantity::convert(1, "in", "px"));
        //bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi");
        ImageResolution *ir = 0;
        double xscale = 1;
        double yscale = 1;


        if (!ir && !forcexdpi) {
            ir = new ImageResolution(uri);
        }
        if (ir && ir->ok()) {
            xscale = 900.0 / floor(10.*ir->x() + .5);  // round-off to 0.1 dpi
            yscale = 900.0 / floor(10.*ir->y() + .5);
        } else {
            xscale = 90.0 / defaultxdpi;
            yscale = 90.0 / defaultxdpi;
        }

        width *= xscale;
        height *= yscale;

        delete ir; // deleting NULL is safe

        // Create image node
        Inkscape::XML::Document *xml_doc = doc->getReprDoc();
        Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image");
        sp_repr_set_svg_double(image_node, "width", width);
        sp_repr_set_svg_double(image_node, "height", height);

        // Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is
        // what Inkscaper's expect.
        image_node->setAttribute("preserveAspectRatio", "none");

        if( scale.compare( "auto" ) != 0 ) {
            SPCSSAttr *css = sp_repr_css_attr_new();
            sp_repr_css_set_property(css, "image-rendering", scale.c_str());
            sp_repr_css_set(image_node, css, "style");
            sp_repr_css_attr_unref( css );
        }

        if (embed) {
            sp_embed_image(image_node, pb.get());
        } else {
            // convert filename to uri
            gchar* _uri = g_filename_to_uri(uri, NULL, NULL);
            if(_uri) {
                image_node->setAttribute("xlink:href", _uri);
                g_free(_uri);
            } else {
                image_node->setAttribute("xlink:href", uri);
            }
        }

        // Add it to the current layer
        doc->getRoot()->appendChildRepr(image_node);
        Inkscape::GC::release(image_node);
        fit_canvas_to_drawing(doc);

        // Set viewBox if it doesn't exist
        if (!doc->getRoot()->viewBox_set) {
            //std::cout << "Viewbox not set, setting" << std::endl;
            doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit())));
        }

        // restore undo, as now this document may be shown to the user if a bitmap was opened
        DocumentUndo::setUndoSensitive(doc, saved);
    } else {
        printf("GdkPixbuf loader failed\n");
    }

    return doc;
}
Beispiel #14
0
Inkscape::XML::Node *SPGenericEllipse::write(Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
    // std::cout << "\nSPGenericEllipse::write: Entrance ("
    //           << (repr == NULL ? " NULL" : g_quark_to_string(repr->code()))
    //           << ")" << std::endl;

    GenericEllipseType new_type = SP_GENERIC_ELLIPSE_UNDEFINED;
    if (this->_isSlice() || hasPathEffect() ) {
        new_type = SP_GENERIC_ELLIPSE_ARC;
    } else if ( rx.computed == ry.computed ) {
        new_type = SP_GENERIC_ELLIPSE_CIRCLE;
    } else {
        new_type = SP_GENERIC_ELLIPSE_ELLIPSE;
    }
    // std::cout << "  new_type: " << new_type << std::endl;

    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {

        switch ( new_type ) {

            case SP_GENERIC_ELLIPSE_ARC:
                repr = xml_doc->createElement("svg:path");
                break;
            case SP_GENERIC_ELLIPSE_CIRCLE:
                repr = xml_doc->createElement("svg:circle");
                break;
            case SP_GENERIC_ELLIPSE_ELLIPSE:
                repr = xml_doc->createElement("svg:ellipse");
                break;
            case SP_GENERIC_ELLIPSE_UNDEFINED:
            default:
                std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl;
        }
    }

    if( type != new_type ) {
        switch( new_type ) {
            case SP_GENERIC_ELLIPSE_ARC:
                repr->setCodeUnsafe(g_quark_from_string("svg:path"));
                break;
            case SP_GENERIC_ELLIPSE_CIRCLE:
                repr->setCodeUnsafe(g_quark_from_string("svg:circle"));
                break;
            case SP_GENERIC_ELLIPSE_ELLIPSE:
                repr->setCodeUnsafe(g_quark_from_string("svg:ellipse"));
                break;
            default:
                std::cerr << "SPGenericEllipse::write(): unknown type." << std::endl;
        }
        type = new_type;

        // FIXME: The XML dialog won't update the element name. We need
        // a notifyElementNameChanged callback added to the XML observers
        // to trigger a refresh.
    }

    // std::cout << "  type: " << g_quark_to_string( repr->code() ) << std::endl;
    // std::cout << "  cx: " << cx.computed
    //           << "  cy: " << cy.computed
    //           << "  rx: " << rx.computed
    //           << "  ry: " << ry.computed << std::endl;

    switch ( type ) {
        case SP_GENERIC_ELLIPSE_UNDEFINED:
        case SP_GENERIC_ELLIPSE_ARC:

            repr->setAttribute("cx", NULL );
            repr->setAttribute("cy", NULL );
            repr->setAttribute("rx", NULL );
            repr->setAttribute("ry", NULL );
            repr->setAttribute("r", NULL );

            if (flags & SP_OBJECT_WRITE_EXT) {

                repr->setAttribute("sodipodi:type", "arc");
                sp_repr_set_svg_double(repr, "sodipodi:cx", this->cx.computed);
                sp_repr_set_svg_double(repr, "sodipodi:cy", this->cy.computed);
                sp_repr_set_svg_double(repr, "sodipodi:rx", this->rx.computed);
                sp_repr_set_svg_double(repr, "sodipodi:ry", this->ry.computed);

                // write start and end only if they are non-trivial; otherwise remove
                if (this->_isSlice()) {
                    sp_repr_set_svg_double(repr, "sodipodi:start", this->start);
                    sp_repr_set_svg_double(repr, "sodipodi:end", this->end);

                    repr->setAttribute("sodipodi:open", (!this->_closed) ? "true" : NULL);
                } else {
                    repr->setAttribute("sodipodi:end", NULL);
                    repr->setAttribute("sodipodi:start", NULL);
                    repr->setAttribute("sodipodi:open", NULL);
                }
            }

            // write d=
            this->set_elliptical_path_attribute(repr);
            break;

        case SP_GENERIC_ELLIPSE_CIRCLE:
            sp_repr_set_svg_double(repr, "cx", this->cx.computed);
            sp_repr_set_svg_double(repr, "cy", this->cy.computed);
            sp_repr_set_svg_double(repr, "r",  this->rx.computed);
            repr->setAttribute("rx", NULL );
            repr->setAttribute("ry", NULL );
            repr->setAttribute("sodipodi:cx", NULL );
            repr->setAttribute("sodipodi:cy", NULL );
            repr->setAttribute("sodipodi:rx", NULL );
            repr->setAttribute("sodipodi:ry", NULL );
            repr->setAttribute("sodipodi:end", NULL );
            repr->setAttribute("sodipodi:start", NULL );
            repr->setAttribute("sodipodi:open", NULL );
            repr->setAttribute("sodipodi:type", NULL );
            repr->setAttribute("d", NULL );
            break;

        case SP_GENERIC_ELLIPSE_ELLIPSE:
            sp_repr_set_svg_double(repr, "cx", this->cx.computed);
            sp_repr_set_svg_double(repr, "cy", this->cy.computed);
            sp_repr_set_svg_double(repr, "rx", this->rx.computed);
            sp_repr_set_svg_double(repr, "ry", this->ry.computed);
            repr->setAttribute("r", NULL );
            repr->setAttribute("sodipodi:cx", NULL );
            repr->setAttribute("sodipodi:cy", NULL );
            repr->setAttribute("sodipodi:rx", NULL );
            repr->setAttribute("sodipodi:ry", NULL );
            repr->setAttribute("sodipodi:end", NULL );
            repr->setAttribute("sodipodi:start", NULL );
            repr->setAttribute("sodipodi:open", NULL );
            repr->setAttribute("sodipodi:type", NULL );
            repr->setAttribute("d", NULL );
            break;

        default:
            std::cerr << "SPGenericEllipse::write: unknown type." << std::endl;
    }

    this->set_shape(); // evaluate SPCurve

    SPShape::write(xml_doc, repr, flags);

    // std::cout << "SPGenericEllipse::write: Exit: " << g_quark_to_string(repr->code()) << "\n" << std::endl;
    return repr;
}
Beispiel #15
0
static Inkscape::XML::Node *sp_fontface_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags)
{
    SPFontFace *face = SP_FONTFACE(object);

    if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) {
        repr = xml_doc->createElement("svg:font-face");
    }

    //TODO:
    //sp_repr_set_svg_double(repr, "font-family", face->font_family);
    //sp_repr_set_svg_double(repr, "font-style", face->font_style);
    //sp_repr_set_svg_double(repr, "font-variant", face->font_variant);
    //sp_repr_set_svg_double(repr, "font-weight", face->font_weight);
    //sp_repr_set_svg_double(repr, "font-stretch", face->font_stretch);
    //sp_repr_set_svg_double(repr, "font-size", face->font_size);
    //sp_repr_set_svg_double(repr, "unicode-range", face->unicode_range);
    sp_repr_set_svg_double(repr, "units-per-em", face->units_per_em);
    //sp_repr_set_svg_double(repr, "panose-1", face->panose_1);
    sp_repr_set_svg_double(repr, "stemv", face->stemv);
    sp_repr_set_svg_double(repr, "stemh", face->stemh);
    sp_repr_set_svg_double(repr, "slope", face->slope);
    sp_repr_set_svg_double(repr, "cap-height", face->cap_height);
    sp_repr_set_svg_double(repr, "x-height", face->x_height);
    sp_repr_set_svg_double(repr, "accent-height", face->accent_height);
    sp_repr_set_svg_double(repr, "ascent", face->ascent);
    sp_repr_set_svg_double(repr, "descent", face->descent);
    //sp_repr_set_svg_double(repr, "widths", face->widths);
    //sp_repr_set_svg_double(repr, "bbox", face->bbox);
    sp_repr_set_svg_double(repr, "ideographic", face->ideographic);
    sp_repr_set_svg_double(repr, "alphabetic", face->alphabetic);
    sp_repr_set_svg_double(repr, "mathematical", face->mathematical);
    sp_repr_set_svg_double(repr, "hanging", face->hanging);
    sp_repr_set_svg_double(repr, "v-ideographic", face->v_ideographic);
    sp_repr_set_svg_double(repr, "v-alphabetic", face->v_alphabetic);
    sp_repr_set_svg_double(repr, "v-mathematical", face->v_mathematical);
    sp_repr_set_svg_double(repr, "v-hanging", face->v_hanging);
    sp_repr_set_svg_double(repr, "underline-position", face->underline_position);
    sp_repr_set_svg_double(repr, "underline-thickness", face->underline_thickness);
    sp_repr_set_svg_double(repr, "strikethrough-position", face->strikethrough_position);
    sp_repr_set_svg_double(repr, "strikethrough-thickness", face->strikethrough_thickness);
    sp_repr_set_svg_double(repr, "overline-position", face->overline_position);
    sp_repr_set_svg_double(repr, "overline-thickness", face->overline_thickness);

    if (repr != object->getRepr()) {
        // In all COPY_ATTR given below the XML tree is 
        //  being used directly while it shouldn't be.
        COPY_ATTR(repr, object->getRepr(), "font-family");
        COPY_ATTR(repr, object->getRepr(), "font-style");
        COPY_ATTR(repr, object->getRepr(), "font-variant");
        COPY_ATTR(repr, object->getRepr(), "font-weight");
        COPY_ATTR(repr, object->getRepr(), "font-stretch");
        COPY_ATTR(repr, object->getRepr(), "font-size");
        COPY_ATTR(repr, object->getRepr(), "unicode-range");
        COPY_ATTR(repr, object->getRepr(), "units-per-em");
        COPY_ATTR(repr, object->getRepr(), "panose-1");
        COPY_ATTR(repr, object->getRepr(), "stemv");
        COPY_ATTR(repr, object->getRepr(), "stemh");
        COPY_ATTR(repr, object->getRepr(), "slope");
        COPY_ATTR(repr, object->getRepr(), "cap-height");
        COPY_ATTR(repr, object->getRepr(), "x-height");
        COPY_ATTR(repr, object->getRepr(), "accent-height");
        COPY_ATTR(repr, object->getRepr(), "ascent");
        COPY_ATTR(repr, object->getRepr(), "descent");
        COPY_ATTR(repr, object->getRepr(), "widths");
        COPY_ATTR(repr, object->getRepr(), "bbox");
        COPY_ATTR(repr, object->getRepr(), "ideographic");
        COPY_ATTR(repr, object->getRepr(), "alphabetic");
        COPY_ATTR(repr, object->getRepr(), "mathematical");
        COPY_ATTR(repr, object->getRepr(), "hanging");
        COPY_ATTR(repr, object->getRepr(), "v-ideographic");
        COPY_ATTR(repr, object->getRepr(), "v-alphabetic");
        COPY_ATTR(repr, object->getRepr(), "v-mathematical");
        COPY_ATTR(repr, object->getRepr(), "v-hanging");
        COPY_ATTR(repr, object->getRepr(), "underline-position");
        COPY_ATTR(repr, object->getRepr(), "underline-thickness");
        COPY_ATTR(repr, object->getRepr(), "strikethrough-position");
        COPY_ATTR(repr, object->getRepr(), "strikethrough-thickness");
        COPY_ATTR(repr, object->getRepr(), "overline-position");
        COPY_ATTR(repr, object->getRepr(), "overline-thickness");
    }

    if (((SPObjectClass *) (parent_class))->write) {
        ((SPObjectClass *) (parent_class))->write(object, xml_doc, repr, flags);
    }

    return repr;
}
Beispiel #16
0
void
text_unflow ()
{
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        return;

    SPDocument *doc = sp_desktop_document (desktop);
    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);

    Inkscape::Selection *selection = sp_desktop_selection(desktop);


    if (!flowtext_in_selection(selection) || g_slist_length((GSList *) selection->itemList()) < 1) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a flowed text</b> to unflow it."));
        return;
    }

    GSList *new_objs = NULL;
    GSList *old_objs = NULL;

    for (GSList *items = g_slist_copy((GSList *) selection->itemList());
         items != NULL;
         items = items->next) {

        if (!SP_IS_FLOWTEXT(SP_OBJECT(items->data))) {
            continue;
        }

        SPItem *flowtext = SP_ITEM(items->data);

        if (sp_te_get_string_multiline(flowtext) == NULL) { // flowtext is empty
            continue;
        }

        /* Create <text> */
        Inkscape::XML::Node *rtext = xml_doc->createElement("svg:text");
        rtext->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create

        /* Set style */
        rtext->setAttribute("style", SP_OBJECT_REPR(flowtext)->attribute("style")); // fixme: transfer style attrs too; and from descendants

        NRRect bbox;
        sp_item_invoke_bbox(SP_ITEM(flowtext), &bbox, sp_item_i2doc_affine(SP_ITEM(flowtext)), TRUE);
        Geom::Point xy(bbox.x0, bbox.y0);
        if (xy[Geom::X] != 1e18 && xy[Geom::Y] != 1e18) {
            sp_repr_set_svg_double(rtext, "x", xy[Geom::X]);
            sp_repr_set_svg_double(rtext, "y", xy[Geom::Y]);
        }

        /* Create <tspan> */
        Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan");
        rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan?
        rtext->addChild(rtspan, NULL);

        gchar *text_string = sp_te_get_string_multiline(flowtext);
        Inkscape::XML::Node *text_repr = xml_doc->createTextNode(text_string); // FIXME: transfer all formatting!!!
        free(text_string);
        rtspan->appendChild(text_repr);

        SP_OBJECT_REPR(SP_OBJECT_PARENT(flowtext))->appendChild(rtext);
        SPObject *text_object = doc->getObjectByRepr(rtext);

        new_objs = g_slist_prepend (new_objs, text_object);
        old_objs = g_slist_prepend (old_objs, flowtext);

        Inkscape::GC::release(rtext);
        Inkscape::GC::release(rtspan);
        Inkscape::GC::release(text_repr);
    }

    selection->clear();
    selection->setList(new_objs);
    for (GSList *i = old_objs; i; i = i->next) {
        SP_OBJECT(i->data)->deleteObject (true);
    }

    g_slist_free (old_objs);
    g_slist_free (new_objs);

    sp_document_done(doc, SP_VERB_CONTEXT_TEXT, 
                     _("Unflow flowed text"));
}
SPDocument *
sp_document_create(Inkscape::XML::Document *rdoc,
                   gchar const *uri,
                   gchar const *base,
                   gchar const *name,
                   unsigned int keepalive)
{
    SPDocument *document;
    Inkscape::XML::Node *rroot;
    Inkscape::Version sodipodi_version;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();

    rroot = rdoc->root();

    document = new SPDocument();

    document->keepalive = keepalive;

    document->rdoc = rdoc;
    document->rroot = rroot;

#ifndef WIN32
    prepend_current_dir_if_relative(&(document->uri), uri);
#else
    // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test!
    document->uri = uri? g_strdup(uri) : NULL;
#endif

    // base is simply the part of the path before filename; e.g. when running "inkscape ../file.svg" the base is "../"
    // which is why we use g_get_current_dir() in calculating the abs path above
    //This is NULL for a new document
    if (base)
        document->base = g_strdup(base);
    else
        document->base = NULL;
    document->name = g_strdup(name);

    document->root = sp_object_repr_build_tree(document, rroot);

    sodipodi_version = SP_ROOT(document->root)->version.sodipodi;

    /* fixme: Not sure about this, but lets assume ::build updates */
    rroot->setAttribute("sodipodi:version", SODIPODI_VERSION);
    rroot->setAttribute("inkscape:version", Inkscape::version_string);
    /* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */

    /* Quick hack 2 - get default image size into document */
    if (!rroot->attribute("width")) rroot->setAttribute("width", "100%");
    if (!rroot->attribute("height")) rroot->setAttribute("height", "100%");
    /* End of quick hack 2 */

    /* Quick hack 3 - Set uri attributes */
    if (uri) {
        rroot->setAttribute("sodipodi:docname", uri);
    }
    /* End of quick hack 3 */

    /* Eliminate obsolete sodipodi:docbase, for privacy reasons */
    rroot->setAttribute("sodipodi:docbase", NULL);
    
    /* Eliminate any claim to adhere to a profile, as we don't try to */
    rroot->setAttribute("baseProfile", NULL);

    // creating namedview
    if (!sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview")) {
        // if there's none in the document already,
        Inkscape::XML::Node *rnew = NULL;
        
        rnew = rdoc->createElement("sodipodi:namedview");
        //rnew->setAttribute("id", "base");

        // Add namedview data from the preferences
        // we can't use getAllEntries because this could produce non-SVG doubles
        Glib::ustring pagecolor = prefs->getString("/template/base/pagecolor");
        if (!pagecolor.empty()) {
            rnew->setAttribute("pagecolor", pagecolor.data());
        }
        Glib::ustring bordercolor = prefs->getString("/template/base/bordercolor");
        if (!bordercolor.empty()) {
            rnew->setAttribute("bordercolor", bordercolor.data());
        }
        sp_repr_set_svg_double(rnew, "borderopacity",
            prefs->getDouble("/template/base/borderopacity", 1.0));
        sp_repr_set_svg_double(rnew, "objecttolerance",
            prefs->getDouble("/template/base/objecttolerance", 10.0));
        sp_repr_set_svg_double(rnew, "gridtolerance",
            prefs->getDouble("/template/base/gridtolerance", 10.0));
        sp_repr_set_svg_double(rnew, "guidetolerance",
            prefs->getDouble("/template/base/guidetolerance", 10.0));
        sp_repr_set_svg_double(rnew, "inkscape:pageopacity",
            prefs->getDouble("/template/base/inkscape:pageopacity", 0.0));
        sp_repr_set_int(rnew, "inkscape:pageshadow",
            prefs->getInt("/template/base/inkscape:pageshadow", 2));
        sp_repr_set_int(rnew, "inkscape:window-width",
            prefs->getInt("/template/base/inkscape:window-width", 640));
        sp_repr_set_int(rnew, "inkscape:window-height",
            prefs->getInt("/template/base/inkscape:window-height", 480));
        
        // insert into the document
        rroot->addChild(rnew, NULL);
        // clean up
        Inkscape::GC::release(rnew);
    }

    /* Defs */
    if (!SP_ROOT(document->root)->defs) {
        Inkscape::XML::Node *r;
        r = rdoc->createElement("svg:defs");
        rroot->addChild(r, NULL);
        Inkscape::GC::release(r);
        g_assert(SP_ROOT(document->root)->defs);
    }

    /* Default RDF */
    rdf_set_defaults( document );

    if (keepalive) {
        inkscape_ref();
    }

    // Remark: Here, we used to create a "currentpersp3d" element in the document defs.
    // But this is probably a bad idea since we need to adapt it for every change of selection, which will
    // completely clutter the undo history. Maybe rather save it to prefs on exit and re-read it on startup?

    document->current_persp3d = persp3d_document_first_persp(document);
    if (!document->current_persp3d) {
        document->current_persp3d = persp3d_create_xml_element (document);
    }

    sp_document_set_undo_sensitive(document, true);

    // reset undo key when selection changes, so that same-key actions on different objects are not coalesced
    if (!Inkscape::NSApplication::Application::getNewGui()) {
        g_signal_connect(G_OBJECT(INKSCAPE), "change_selection",
                         G_CALLBACK(sp_document_reset_key), document);
        g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
                         G_CALLBACK(sp_document_reset_key), document);
    } else {
        document->_selection_changed_connection = Inkscape::NSApplication::Editor::connectSelectionChanged (sigc::mem_fun (*document, &SPDocument::reset_key));
        document->_desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::mem_fun (*document, &SPDocument::reset_key));
    }

    return document;
}