Ejemplo n.º 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;
}
Ejemplo n.º 2
0
KnotHolder *createKnotHolder(SPItem *item, SPDesktop *desktop)
{
    KnotHolder *knotholder = NULL;

    if (SP_IS_LPE_ITEM(item) &&
            SP_LPE_ITEM(item)->getCurrentLPE() &&
            SP_LPE_ITEM(item)->getCurrentLPE()->isVisible() &&
            SP_LPE_ITEM(item)->getCurrentLPE()->providesKnotholder()) {
        knotholder = sp_lpe_knot_holder(item, desktop);
    } else if (SP_IS_RECT(item)) {
        knotholder = new RectKnotHolder(desktop, item, NULL);
    } else if (SP_IS_BOX3D(item)) {
        knotholder = new Box3DKnotHolder(desktop, item, NULL);
    } else if (SP_IS_GENERICELLIPSE(item)) {
        knotholder = new ArcKnotHolder(desktop, item, NULL);
    } else if (SP_IS_STAR(item)) {
        knotholder = new StarKnotHolder(desktop, item, NULL);
    } else if (SP_IS_SPIRAL(item)) {
        knotholder = new SpiralKnotHolder(desktop, item, NULL);
    } else if (SP_IS_OFFSET(item)) {
        knotholder = new OffsetKnotHolder(desktop, item, NULL);
    } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) {
        knotholder = new FlowtextKnotHolder(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL);
    } else if ((item->style->fill.isPaintserver())
               && SP_IS_PATTERN(item->style->getFillPaintServer())) {
        knotholder = new KnotHolder(desktop, item, NULL);
        knotholder->add_pattern_knotholder();
    }

    return knotholder;
}
Ejemplo n.º 3
0
void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *selection) {
    GSList const *items = selection->itemList();

    if (!items) { // no items
        _context.set(Inkscape::NORMAL_MESSAGE, _when_nothing);
    } else {
        SPItem *item = SP_ITEM(items->data);
        SPObject *layer = selection->desktop()->layerForObject(item);
        SPObject *root = selection->desktop()->currentRoot();

        // Layer name
        gchar *layer_name;
        if (layer == root) {
            layer_name = g_strdup(_("root"));
        } else {
            char const *layer_label;
            bool is_label = false;
            if (layer->label()) {
                layer_label = layer->label();
                is_label = true;
            } else {
                layer_label = layer->defaultLabel();
            }
            char *quoted_layer_label = xml_quote_strdup(layer_label);
            if (is_label) {
                layer_name = g_strdup_printf(_("layer <b>%s</b>"), quoted_layer_label);
            } else {
                layer_name = g_strdup_printf(_("layer <b><i>%s</i></b>"), quoted_layer_label);
            }
            g_free(quoted_layer_label);
        }

        // Parent name
        SPObject *parent = item->parent;
        gchar const *parent_label = parent->getId();
        char *quoted_parent_label = xml_quote_strdup(parent_label);
        gchar *parent_name = g_strdup_printf(_("<i>%s</i>"), quoted_parent_label);
        g_free(quoted_parent_label);

        gchar *in_phrase;
        guint num_layers = selection->numberOfLayers();
        guint num_parents = selection->numberOfParents();
        if (num_layers == 1) {
            if (num_parents == 1) {
                if (layer == parent)
                    in_phrase = g_strdup_printf(_(" in %s"), layer_name);
                else 
                    in_phrase = g_strdup_printf(_(" in group %s (%s)"), parent_name, layer_name);
            } else {
                    in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> parents (%s)", " in <b>%i</b> parents (%s)", num_parents), num_parents, layer_name);
            }
        } else {
            in_phrase = g_strdup_printf(ngettext(" in <b>%i</b> layers", " in <b>%i</b> layers", num_layers), num_layers);
        }
        g_free (layer_name);
        g_free (parent_name);

        if (!items->next) { // one item
            char *item_desc = item->description();
            if (SP_IS_USE(item) && SP_IS_SYMBOL(item->firstChild())) {
                _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.",
                              item_desc, in_phrase,
                              _("Convert symbol to group to edit"), _when_selected);
            } else if (SP_IS_USE(item) || (SP_IS_OFFSET(item) && SP_OFFSET (item)->sourceHref)) {
                _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.",
                              item_desc, in_phrase,
                              _("Use <b>Shift+D</b> to look up original"), _when_selected);
            } else if (SP_IS_TEXT_TEXTPATH(item)) {
                _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.",
                              item_desc, in_phrase,
                              _("Use <b>Shift+D</b> to look up path"), _when_selected);
            } else if (SP_IS_FLOWTEXT(item) && !SP_FLOWTEXT(item)->has_internal_frame()) {
                _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.",
                              item_desc, in_phrase,
                              _("Use <b>Shift+D</b> to look up frame"), _when_selected);
            } else {
                _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s.",
                              item_desc, in_phrase, _when_selected);
            }
            g_free(item_desc);
        } else { // multiple items
            int object_count = g_slist_length((GSList *)items);

            gchar *objects_str = NULL;
            GSList *terms = collect_terms ((GSList *)items);
            int n_terms = g_slist_length(terms);
            if (n_terms == 0) {
                objects_str = g_strdup_printf (
                    // this is only used with 2 or more objects
                    ngettext("<b>%i</b> object selected", "<b>%i</b> objects selected", object_count), 
                    object_count);
            } else if (n_terms == 1) {
                objects_str = g_strdup_printf (
                    // this is only used with 2 or more objects
                    ngettext("<b>%i</b> object of type <b>%s</b>", "<b>%i</b> objects of type <b>%s</b>", object_count),
                    object_count, (gchar *) terms->data);
            } else if (n_terms == 2) {
                objects_str = g_strdup_printf (
                    // this is only used with 2 or more objects
                    ngettext("<b>%i</b> object of types <b>%s</b>, <b>%s</b>", "<b>%i</b> objects of types <b>%s</b>, <b>%s</b>", object_count), 
                    object_count, (gchar *) terms->data, (gchar *) terms->next->data);
            } else if (n_terms == 3) {
                objects_str = g_strdup_printf (
                    // this is only used with 2 or more objects
                    ngettext("<b>%i</b> object of types <b>%s</b>, <b>%s</b>, <b>%s</b>", "<b>%i</b> objects of types <b>%s</b>, <b>%s</b>, <b>%s</b>", object_count), 
                    object_count, (gchar *) terms->data, (gchar *) terms->next->data, (gchar *) terms->next->next->data);
            } else {
                objects_str = g_strdup_printf (
                    // this is only used with 2 or more objects
                    ngettext("<b>%i</b> object of <b>%i</b> types", "<b>%i</b> objects of <b>%i</b> types", object_count), 
                    object_count, n_terms);
            }
            g_slist_free (terms);


            // indicate all, some, or none filtered
            gchar *filt_str = NULL;
            int n_filt = count_filtered((GSList *)items);  //all filtered
            if (n_filt) {
                filt_str = g_strdup_printf(ngettext("; <i>%d filtered object</i> ",
                                                     "; <i>%d filtered objects</i> ", n_filt), n_filt);
            } else {
                filt_str = g_strdup_printf("%s", "");
            }

            _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s%s. %s.", objects_str, filt_str, in_phrase, _when_selected);
            if (objects_str) {
                g_free(objects_str);
                objects_str = 0;
            }
            if (filt_str) {
                g_free(filt_str);
                objects_str = 0;
            }
        }

        g_free(in_phrase);
    }
}
Ejemplo n.º 4
0
void
text_put_on_path()
{
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        return;

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

    SPItem *text = text_or_flowtext_in_selection(selection);
    SPItem *shape = shape_in_selection(selection);

    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());

    if (!text || !shape || g_slist_length((GSList *) selection->itemList()) != 2) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>a text and a path</b> to put text on path."));
        return;
    }

    if (SP_IS_TEXT_TEXTPATH(text)) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("This text object is <b>already put on a path</b>. Remove it from the path first. Use <b>Shift+D</b> to look up its path."));
        return;
    }

    if (SP_IS_RECT(shape)) {
        // rect is the only SPShape which is not <path> yet, and thus SVG forbids us from putting text on it
        sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("You cannot put text on a rectangle in this version. Convert rectangle to path first."));
        return;
    }

    // if a flowed text is selected, convert it to a regular text object
    if (SP_IS_FLOWTEXT(text)) {

        if (!SP_FLOWTEXT(text)->layout.outputExists()) {
            sp_desktop_message_stack(desktop)->
                flash(Inkscape::WARNING_MESSAGE, 
                      _("The flowed text(s) must be <b>visible</b> in order to be put on a path."));
        }

        Inkscape::XML::Node *repr = SP_FLOWTEXT(text)->getAsText();

        if (!repr) return;

        Inkscape::XML::Node *parent = SP_OBJECT_REPR(text)->parent();
        parent->appendChild(repr);

        SPItem *new_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
        sp_item_write_transform(new_item, repr, text->transform);
        SP_OBJECT(new_item)->updateRepr();

        Inkscape::GC::release(repr);
        text->deleteObject(); // delete the orignal flowtext

        sp_document_ensure_up_to_date(sp_desktop_document(desktop));

        selection->clear();

        text = new_item; // point to the new text
    }

    Inkscape::Text::Layout const *layout = te_get_layout(text);
    Inkscape::Text::Layout::Alignment text_alignment = layout->paragraphAlignment(layout->begin());

    // remove transform from text, but recursively scale text's fontsize by the expansion
    SP_TEXT(text)->_adjustFontsizeRecursive (text, NR::expansion(SP_ITEM(text)->transform));
    SP_OBJECT_REPR(text)->setAttribute("transform", NULL);

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

    // create textPath and put it into the text
    Inkscape::XML::Node *textpath = xml_doc->createElement("svg:textPath");
    // reference the shape
    textpath->setAttribute("xlink:href", g_strdup_printf("#%s", SP_OBJECT_REPR(shape)->attribute("id")));
    if (text_alignment == Inkscape::Text::Layout::RIGHT)
        textpath->setAttribute("startOffset", "100%");
    else if (text_alignment == Inkscape::Text::Layout::CENTER)
        textpath->setAttribute("startOffset", "50%");
    SP_OBJECT_REPR(text)->addChild(textpath, NULL);

    for ( GSList *i = text_reprs ; i ; i = i->next ) {
        // Make a copy of each text child
        Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) i->data)->duplicate(xml_doc);
        // We cannot have multiline in textpath, so remove line attrs from tspans
        if (!strcmp(copy->name(), "svg:tspan")) {
            copy->setAttribute("sodipodi:role", NULL);
            copy->setAttribute("x", NULL);
            copy->setAttribute("y", NULL);
        }
        // remove the old repr from under text
        SP_OBJECT_REPR(text)->removeChild((Inkscape::XML::Node *) i->data);
        // put its copy into under textPath
        textpath->addChild(copy, NULL); // fixme: copy id
    }

    // x/y are useless with textpath, and confuse Batik 1.5
    SP_OBJECT_REPR(text)->setAttribute("x", NULL);
    SP_OBJECT_REPR(text)->setAttribute("y", NULL);

    sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, 
                     _("Put text on path"));
    g_slist_free(text_reprs);
}
Ejemplo n.º 5
0
void
flowtext_to_text()
{
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;

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

    if (selection->isEmpty()) {
        sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, 
                                                 _("Select <b>flowed text(s)</b> to convert."));
        return;
    }

    bool did = false;

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

        if (!SP_IS_FLOWTEXT(item))
            continue;

        if (!SP_FLOWTEXT(item)->layout.outputExists()) {
            sp_desktop_message_stack(desktop)->
                flash(Inkscape::WARNING_MESSAGE, 
                      _("The flowed text(s) must be <b>visible</b> in order to be converted."));
            return;
        }

        Inkscape::XML::Node *repr = SP_FLOWTEXT(item)->getAsText();

        if (!repr) break;

        did = true;

        Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent();
        parent->addChild(repr, SP_OBJECT_REPR(item));

        SPItem *new_item = (SPItem *) sp_desktop_document(desktop)->getObjectByRepr(repr);
        sp_item_write_transform(new_item, repr, item->transform);
        SP_OBJECT(new_item)->updateRepr();
    
        Inkscape::GC::release(repr);
        item->deleteObject();

        reprs = g_slist_prepend(reprs, repr);
    }

    g_slist_free(items);

    if (did) {
        sp_document_done(sp_desktop_document(desktop), 
                         SP_VERB_OBJECT_FLOWTEXT_TO_TEXT,
                         _("Convert flowed text to text"));
        selection->setReprList(reprs);        
    } else {
        sp_desktop_message_stack(desktop)->
            flash(Inkscape::ERROR_MESSAGE,
                  _("<b>No flowed text(s)</b> to convert in the selection."));
    }

    g_slist_free(reprs);
}