/*
 * Get the gradient of the selected desktop item
 * This is gradient containing the repeat settings, not the underlying "getVector" href linked gradient.
 */
void gr_get_dt_selected_gradient(Inkscape::Selection *selection, SPGradient *&gr_selected)
{
    SPGradient *gradient = 0;

    for (GSList const* i = selection->itemList(); i; i = i->next) {
         SPItem *item = SP_ITEM(i->data); // get the items gradient, not the getVector() version
         SPStyle *style = item->style;
         SPPaintServer *server = 0;

         if (style && (style->fill.isPaintserver())) {
             server = item->style->getFillPaintServer();
         }
         if (style && (style->stroke.isPaintserver())) {
             server = item->style->getStrokePaintServer();
         }

         if ( SP_IS_GRADIENT(server) ) {
             gradient = SP_GRADIENT(server);
         }
    }

    if (gradient && gradient->isSolid()) {
        gradient = 0;
    }

    if (gradient) {
        gr_selected = gradient;
    }
}
Exemple #2
0
static void sp_grd_ed_del_stop(GtkWidget */*widget*/,  GtkWidget *vb)
{
    SPGradient *gradient = static_cast<SPGradient *>(g_object_get_data(G_OBJECT(vb), "gradient"));

    SPStop *stop = get_selected_stop(vb);
    if (!stop) {
        return;
    }

    if (gradient->vector.stops.size() > 2) { // 2 is the minimum

        // if we delete first or last stop, move the next/previous to the edge
        if (stop->offset == 0) {
            SPStop *next = stop->getNextStop();
            if (next) {
                next->offset = 0;
                sp_repr_set_css_double(next->getRepr(), "offset", 0);
            }
        } else if (stop->offset == 1) {
            SPStop *prev = stop->getPrevStop();
            if (prev) {
                prev->offset = 1;
                sp_repr_set_css_double(prev->getRepr(), "offset", 1);
            }
        }

        gradient->getRepr()->removeChild(stop->getRepr());
        sp_gradient_vector_widget_load_gradient(vb, gradient);
        update_stop_list(GTK_WIDGET(vb), gradient, NULL);
        DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT,
                           _("Delete gradient stop"));
    }

}
Exemple #3
0
static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs)
{

    gvs->tree_select_connection.block();

    /* Clear old list, if there is any */
    gvs->store->clear();

    /* Pick up all gradients with vectors */
    GSList *gl = NULL;
    if (gvs->gr) {
        const GSList *gradients = gvs->gr->document->getResourceList("gradient");
        for (const GSList *curr = gradients; curr; curr = curr->next) {
            SPGradient* grad = SP_GRADIENT(curr->data);
            if ( grad->hasStops() && (grad->isSwatch() == gvs->swatched) ) {
                gl = g_slist_prepend(gl, curr->data);
            }
        }
    }
    gl = g_slist_reverse(gl);

    /* Get usage count of all the gradients */
    std::map<SPGradient *, gint> usageCount;
    gr_get_usage_counts(gvs->doc, &usageCount);

    if (!gvs->doc) {
        Gtk::TreeModel::Row row = *(gvs->store->append());
        row[gvs->columns->name] = _("No document selected");

    } else if (!gl) {
        Gtk::TreeModel::Row row = *(gvs->store->append());
        row[gvs->columns->name] = _("No gradients in document");

    } else if (!gvs->gr) {
        Gtk::TreeModel::Row row = *(gvs->store->append());
        row[gvs->columns->name] =  _("No gradient selected");

    } else {
        while (gl) {
            SPGradient *gr;
            gr = SP_GRADIENT(gl->data);
            gl = g_slist_remove(gl, gr);

            unsigned long hhssll = sp_gradient_to_hhssll(gr);
            GdkPixbuf *pixb = sp_gradient_to_pixbuf (gr, 64, 18);
            Glib::ustring label = gr_prepare_label(gr);

            Gtk::TreeModel::Row row = *(gvs->store->append());
            row[gvs->columns->name] = label.c_str();
            row[gvs->columns->color] = hhssll;
            row[gvs->columns->refcount] = usageCount[gr];
            row[gvs->columns->data] = gr;
            row[gvs->columns->pixbuf] = Glib::wrap(pixb);

        }
    }

    gvs->tree_select_connection.unblock();

}
Exemple #4
0
static void sp_grd_ed_add_stop(GtkWidget */*widget*/,  GtkWidget *vb)
{
    SPGradient *gradient = static_cast<SPGradient *>(g_object_get_data(G_OBJECT(vb), "gradient"));
    verify_grad(gradient);

    SPStop *stop = get_selected_stop(vb);
    if (!stop) {
        return;
    }

    Inkscape::XML::Node *new_stop_repr = NULL;

    SPStop *next = stop->getNextStop();

    if (next == NULL) {
        SPStop *prev = stop->getPrevStop();
        if (prev != NULL) {
            next = stop;
            stop = prev;
        }
    }

    if (next != NULL) {
        new_stop_repr = stop->getRepr()->duplicate(gradient->getRepr()->document());
        gradient->getRepr()->addChild(new_stop_repr, stop->getRepr());
    } else {
        next = stop;
        new_stop_repr = stop->getPrevStop()->getRepr()->duplicate(gradient->getRepr()->document());
        gradient->getRepr()->addChild(new_stop_repr, stop->getPrevStop()->getRepr());
    }

    SPStop *newstop = reinterpret_cast<SPStop *>(gradient->document->getObjectByRepr(new_stop_repr));

    newstop->offset = (stop->offset + next->offset) * 0.5 ;

    guint32 const c1 = stop->get_rgba32();
    guint32 const c2 = next->get_rgba32();
    guint32 cnew = sp_average_color(c1, c2);

    Inkscape::CSSOStringStream os;
    gchar c[64];
    sp_svg_write_color(c, sizeof(c), cnew);
    gdouble opacity = static_cast<gdouble>(SP_RGBA32_A_F(cnew));
    os << "stop-color:" << c << ";stop-opacity:" << opacity <<";";
    newstop->getRepr()->setAttribute("style", os.str().c_str());
    sp_repr_set_css_double( newstop->getRepr(), "offset", (double)newstop->offset);

    sp_gradient_vector_widget_load_gradient(vb, gradient);
    Inkscape::GC::release(new_stop_repr);
    update_stop_list(GTK_WIDGET(vb), gradient, newstop);
    GtkWidget *offspin = GTK_WIDGET(g_object_get_data(G_OBJECT(vb), "offspn"));
    GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(vb), "offslide"));
    gtk_widget_set_sensitive(offslide, TRUE);
    gtk_widget_set_sensitive(GTK_WIDGET(offspin), TRUE);
    DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT,
                       _("Add gradient stop"));
}
Exemple #5
0
// TODO: So a solid brush is a gradient with a swatch and zero stops?
// Should we derive a new class for that? Or at least make this method
// virtual and move it out of the way?
bool SPPaintServer::isSolid() const
{
    bool solid = false;
    if (swatch && SP_IS_GRADIENT(this)) {
        SPGradient *grad = SP_GRADIENT(this);
        if ( grad->hasStops() && (grad->getStopCount() == 0) ) {
            solid = true;
        }
    }
    return solid;
}
static void
sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *sel)
{
    SPDocument *doc = sp_gradient_vector_selector_get_document (SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));

    if (!doc)
        return;

    SPGradient *gr = sp_gradient_vector_selector_get_gradient( SP_GRADIENT_VECTOR_SELECTOR (sel->vectors));
    Inkscape::XML::Document *xml_doc = doc->getReprDoc();

    Inkscape::XML::Node *repr = NULL;

    if (gr) {
        repr = gr->getRepr()->duplicate(xml_doc);
    } else {
        repr = xml_doc->createElement("svg:linearGradient");
        Inkscape::XML::Node *stop = xml_doc->createElement("svg:stop");
        stop->setAttribute("offset", "0");
        stop->setAttribute("style", "stop-color:#000;stop-opacity:1;");
        repr->appendChild(stop);
        Inkscape::GC::release(stop);
        stop = xml_doc->createElement("svg:stop");
        stop->setAttribute("offset", "1");
        stop->setAttribute("style", "stop-color:#fff;stop-opacity:1;");
        repr->appendChild(stop);
        Inkscape::GC::release(stop);
    }

    doc->getDefs()->getRepr()->addChild(repr, NULL);

    Glib::ustring old_id = gr->getId();

    gr = SP_GRADIENT(doc->getObjectByRepr(repr));

    // Rename the new gradients id to be similar to the cloned gradients
    rename_id(gr, old_id);

    sp_gradient_vector_selector_set_gradient( SP_GRADIENT_VECTOR_SELECTOR (sel->vectors), doc, gr);

    sel->selectGradientInTree(gr);

    Inkscape::GC::release(repr);
}
static void gr_spread_change(EgeSelectOneAction *act, GtkWidget *widget)
{
    if (blocked) {
        return;
    }

    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
    SPGradient *gradient = 0;
    gr_get_dt_selected_gradient(selection, gradient);

    if (gradient) {
        SPGradientSpread spread = (SPGradientSpread) ege_select_one_action_get_active(act);
        gradient->setSpread(spread);
        gradient->updateRepr();

        DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_GRADIENT,
                   _("Set gradient repeat"));
    }
}
static void
sp_gradient_selector_delete_vector_clicked (GtkWidget */*w*/, SPGradientSelector *sel)
{
    const Glib::RefPtr<Gtk::TreeSelection> selection = sel->treeview->get_selection();
    if (!selection) {
        return;
    }

    SPGradient *obj = NULL;
    /* Single selection */
    Gtk::TreeModel::iterator iter = selection->get_selected();
    if ( iter ) {
        Gtk::TreeModel::Row row = *iter;
        obj = row[sel->columns->data];
    }

    if (obj) {
        sp_gradient_unset_swatch(SP_ACTIVE_DESKTOP, obj->getId());
    }

}
Exemple #9
0
/** Creates normalized color mesh patch array */
void SPGradient::rebuildArray()
{
    // std::cout << "SPGradient::rebuildArray()" << std::endl;

    if( !SP_IS_MESH(this) ) {
        g_warning( "SPGradient::rebuildArray() called for non-mesh gradient" );
        return;
    }

    array.read( SP_MESH( this ) );

    has_patches = false;
    for ( SPObject *ro = firstChild() ; ro ; ro = ro->getNext() ) {
        if (SP_IS_MESHROW(ro)) {
            has_patches = true;
            // std::cout << "  Has Patches" << std::endl;
            break;
        }
    }

    // MESH_FIXME: TO PROPERLY COPY
    SPGradient *reffed = ref->getObject();
    if ( !hasPatches() && reffed ) {
        std::cout << "SPGradient::rebuildArray(): reffed array    NOT IMPLEMENTED!!!" << std::endl;
        /* Copy array from referenced gradient */
        array.built = true;   // Prevent infinite recursion.
        reffed->ensureArray();
        // if (!reffed->array.nodes.empty()) {
        //     array.built = reffed->array.built;
        //     for( uint i = 0; i < reffed->array.nodes.size(); ++i ) {
        //         array.nodes[i].assign(reffed->array.nodes[i].begin(), reffed->array.nodes[i].end());

        //         // FILL ME
        //     }
        //     return;
        // }
    }
}
static void select_stop_by_drag(GtkWidget *combo_box, SPGradient *gradient, ToolBase *ev, GtkWidget *data)
{
    if (blocked || !ev || !gradient)
        return;

    GrDrag *drag = ev->get_drag();

    if (!drag || !drag->selected) {
        blocked = TRUE;
        gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , 0);
        gr_stop_set_offset(GTK_COMBO_BOX(combo_box), data);
        blocked = FALSE;
        return;
    }

    gint n = 0;

    // for all selected draggers
    for (GList *i = drag->selected; i != NULL; i = i->next) {
        GrDragger *dragger = static_cast<GrDragger*>(i->data);
        // for all draggables of dragger
        for (GSList const* j = dragger->draggables; j != NULL; j = j->next) {
            GrDraggable *draggable = static_cast<GrDraggable*>(j->data);

            if (draggable->point_type != POINT_RG_FOCUS) {
                n++;
            }
            if (n > 1) {

                // Mulitple stops selected
                GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box));
                if (!store) {
                    return;
                }
                GtkTreeIter iter;
                gtk_list_store_prepend(store, &iter);
                gtk_list_store_set(store, &iter, 0, _("Multiple stops"), 1, NULL, 2, NULL, -1);
                gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , 0);

                EgeAdjustmentAction* act = (EgeAdjustmentAction *)g_object_get_data( G_OBJECT(data), "offset_action");
                if (act) {
                    gtk_action_set_sensitive( GTK_ACTION(act), FALSE);
                }

                return;
            }


            SPGradient *vector = gradient->getVector();
            if (!vector)
                return;

            SPStop *stop = vector->getFirstStop();

            switch (draggable->point_type) {
                case POINT_LG_MID:
                case POINT_RG_MID1:
                case POINT_RG_MID2:
                    {
                        stop = sp_get_stop_i(vector, draggable->point_i);
                    }
                    break;
                 case POINT_LG_END:
                 case POINT_RG_R1:
                 case POINT_RG_R2:
                     {
                        stop = sp_last_stop(vector);
                     }
                     break;
                 default:
                     break;
            }

            select_stop_in_list( combo_box, gradient, stop, data, TRUE);
        }
    }
}
/*
 * Get the current selection and dragger status from the desktop
 */
void gr_read_selection( Inkscape::Selection *selection,
                        GrDrag *drag,
                        SPGradient *&gr_selected,
                        bool &gr_multi,
                        SPGradientSpread &spr_selected,
                        bool &spr_multi )
{
    if (drag && drag->selected) {
        // GRADIENTFIXME: make this work for more than one selected dragger?
        GrDragger *dragger = static_cast<GrDragger*>(drag->selected->data);
        for (GSList const* i = dragger->draggables; i; i = i->next) { // for all draggables of dragger
            GrDraggable *draggable = static_cast<GrDraggable *>(i->data);
            SPGradient *gradient = sp_item_gradient_get_vector(draggable->item, draggable->fill_or_stroke);
            SPGradientSpread spread = sp_item_gradient_get_spread(draggable->item, draggable->fill_or_stroke);

            if (gradient && gradient->isSolid()) {
                gradient = 0;
            }

            if (gradient && (gradient != gr_selected)) {
                if (gr_selected) {
                    gr_multi = true;
                } else {
                    gr_selected = gradient;
                }
            }
            if (spread != spr_selected) {
                if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) {
                    spr_multi = true;
                } else {
                    spr_selected = spread;
                }
            }
         }
        return;
    }

   // If no selected dragger, read desktop selection
   for (GSList const* i = selection->itemList(); i; i = i->next) {
        SPItem *item = SP_ITEM(i->data);
        SPStyle *style = item->style;

        if (style && (style->fill.isPaintserver())) {
            SPPaintServer *server = item->style->getFillPaintServer();
            if ( SP_IS_GRADIENT(server) ) {
                SPGradient *gradient = SP_GRADIENT(server)->getVector();
                SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();

                if (gradient && gradient->isSolid()) {
                    gradient = 0;
                }

                if (gradient && (gradient != gr_selected)) {
                    if (gr_selected) {
                        gr_multi = true;
                    } else {
                        gr_selected = gradient;
                    }
                }
                if (spread != spr_selected) {
                    if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) {
                        spr_multi = true;
                    } else {
                        spr_selected = spread;
                    }
                }
            }
        }
        if (style && (style->stroke.isPaintserver())) {
            SPPaintServer *server = item->style->getStrokePaintServer();
            if ( SP_IS_GRADIENT(server) ) {
                SPGradient *gradient = SP_GRADIENT(server)->getVector();
                SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();

                if (gradient && gradient->isSolid()) {
                    gradient = 0;
                }

                if (gradient && (gradient != gr_selected)) {
                    if (gr_selected) {
                        gr_multi = true;
                    } else {
                        gr_selected = gradient;
                    }
                }
                if (spread != spr_selected) {
                    if (spr_selected != SP_GRADIENT_SPREAD_UNDEFINED) {
                        spr_multi = true;
                    } else {
                        spr_selected = spread;
                    }
                }
            }
        }
    }
 }
gboolean gr_vector_list(GtkWidget *combo_box, SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
{
    gboolean sensitive = FALSE;
    if (blocked) {
        return sensitive;
    }

    SPDocument *document = sp_desktop_document(desktop);

    GtkTreeIter iter;
    GtkListStore *store = (GtkListStore *)gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box));

    blocked = TRUE;

    /* Clear old list, if there is any */
    gtk_list_store_clear(store);

    GSList *gl = NULL;
    const GSList *gradients = document->getResourceList("gradient");
    for (const GSList *i = gradients; i != NULL; i = i->next) {
        SPGradient *grad = SP_GRADIENT(i->data);
        if ( grad->hasStops() && !grad->isSolid() ) {
            gl = g_slist_prepend(gl, i->data);
        }
    }
    gl = g_slist_reverse(gl);

    guint pos = 0;

    if (!gl) {
        // The document has no gradients
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
        sensitive = FALSE;

    } else if (selection_empty) {
        // Document has gradients, but nothing is currently selected.
        gtk_list_store_append(store, &iter);
        gtk_list_store_set(store, &iter, 0, _("Nothing selected"), 1, NULL, 2, NULL, -1);
        sensitive = FALSE;

    } else {

        if (gr_selected == NULL) {
            gtk_list_store_append(store, &iter);
            gtk_list_store_set(store, &iter, 0, _("No gradient"), 1, NULL, 2, NULL, -1);
            sensitive = FALSE;
        }

        if (gr_multi) {
            gtk_list_store_append(store, &iter);
            gtk_list_store_set(store, &iter, 0, _("Multiple gradients"), 1, NULL, 2, NULL, -1);
            sensitive = FALSE;
        }

        guint idx = 0;
        while (gl) {
            SPGradient *gradient = SP_GRADIENT(gl->data);
            gl = g_slist_remove(gl, gradient);

            Glib::ustring label = gr_prepare_label(gradient);
            GdkPixbuf *pixb = sp_gradient_to_pixbuf(gradient, 64, 16);
            gtk_list_store_append(store, &iter);
            gtk_list_store_set(store, &iter, 0, label.c_str(), 1, pixb, 2, gradient, -1);

            if (gradient == gr_selected) {
                pos = idx;
            }
            idx ++;
        }
        sensitive = TRUE;

    }

    /* Select the current gradient, or the Multi/Nothing line */
    if (gr_multi || gr_selected == NULL) {
        gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , 0);
    }
    else {
        gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box) , pos);
    }

    blocked = FALSE;
    return sensitive;
}
Exemple #13
0
static void sp_gradient_vector_color_changed(Inkscape::UI::SelectedColor *selected_color, GObject *object)
{
    (void)selected_color;

    void* updating_color = g_object_get_data(G_OBJECT(object), "updating_color");
    if (updating_color) {
        return;
    }

    if (blocked) {
        return;
    }

    SPGradient *gradient = static_cast<SPGradient*>(g_object_get_data(G_OBJECT(object), "gradient"));
    if (!gradient) {
        return;
    }

    blocked = TRUE;

    SPGradient *ngr = sp_gradient_ensure_vector_normalized(gradient);
    if (ngr != gradient) {
        /* Our master gradient has changed */
        sp_gradient_vector_widget_load_gradient(GTK_WIDGET(object), ngr);
    }

    ngr->ensureVector();

    /* Set start parameters */
    /* We rely on normalized vector, i.e. stops HAVE to exist */
    g_return_if_fail(ngr->getFirstStop() != NULL);

    SPStop *stop = get_selected_stop(GTK_WIDGET(object));
    if (!stop) {
        return;
    }

    SelectedColor *csel = static_cast<SelectedColor *>(g_object_get_data(G_OBJECT(object), "cselector"));
    SPColor color;
    float alpha = 0;
    csel->colorAlpha(color, alpha);

    sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset);
    Inkscape::CSSOStringStream os;
    os << "stop-color:" << color.toString() << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";";
    stop->getRepr()->setAttribute("style", os.str().c_str());
    // g_snprintf(c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, static_cast<gdouble>(alpha));
    //stop->getRepr()->setAttribute("style", c);

    DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT,
                       _("Change gradient stop color"));

    blocked = FALSE;

    // Set the color in the selected stop after change
    GtkWidget *combo_box = static_cast<GtkWidget *>(g_object_get_data(G_OBJECT(object), "combo_box"));
    if (combo_box) {
        GtkTreeIter  iter;
        if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(combo_box), &iter)) {
            GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box)));

            Inkscape::UI::Widget::ColorPreview *cp = Gtk::manage(new Inkscape::UI::Widget::ColorPreview(stop->get_rgba32()));
            GdkPixbuf *pb = cp->toPixbuf(64, 16);

            gtk_list_store_set (store, &iter, 0, pb, /*1, repr->attribute("id"),*/ 2, stop, -1);
        }
    }

}
Exemple #14
0
/** Creates normalized color vector */
void SPGradient::rebuildVector()
{
    gint len = 0;
    for ( SPObject *child = firstChild() ; child ; child = child->getNext() ) {
        if (SP_IS_STOP(child)) {
            len ++;
        }
    }

    has_stops = (len != 0);

    vector.stops.clear();

    SPGradient *reffed = ref ? ref->getObject() : NULL;
    if ( !hasStops() && reffed ) {
        /* Copy vector from referenced gradient */
        vector.built = true;   // Prevent infinite recursion.
        reffed->ensureVector();
        if (!reffed->vector.stops.empty()) {
            vector.built = reffed->vector.built;
            vector.stops.assign(reffed->vector.stops.begin(), reffed->vector.stops.end());
            return;
        }
    }

    for ( SPObject *child = firstChild(); child; child = child->getNext() ) {
        if (SP_IS_STOP(child)) {
            SPStop *stop = SP_STOP(child);

            SPGradientStop gstop;
            if (!vector.stops.empty()) {
                // "Each gradient offset value is required to be equal to or greater than the
                // previous gradient stop's offset value. If a given gradient stop's offset
                // value is not equal to or greater than all previous offset values, then the
                // offset value is adjusted to be equal to the largest of all previous offset
                // values."
                gstop.offset = MAX(stop->offset, vector.stops.back().offset);
            } else {
                gstop.offset = stop->offset;
            }

            // "Gradient offset values less than 0 (or less than 0%) are rounded up to
            // 0%. Gradient offset values greater than 1 (or greater than 100%) are rounded
            // down to 100%."
            gstop.offset = CLAMP(gstop.offset, 0, 1);

            gstop.color = stop->getEffectiveColor();
            gstop.opacity = stop->opacity;

            vector.stops.push_back(gstop);
        }
    }

    // Normalize per section 13.2.4 of SVG 1.1.
    if (vector.stops.empty()) {
        /* "If no stops are defined, then painting shall occur as if 'none' were specified as the
         * paint style."
         */
        {
            SPGradientStop gstop;
            gstop.offset = 0.0;
            gstop.color.set( 0x00000000 );
            gstop.opacity = 0.0;
            vector.stops.push_back(gstop);
        }
        {
            SPGradientStop gstop;
            gstop.offset = 1.0;
            gstop.color.set( 0x00000000 );
            gstop.opacity = 0.0;
            vector.stops.push_back(gstop);
        }
    } else {
        /* "If one stop is defined, then paint with the solid color fill using the color defined
         * for that gradient stop."
         */
        if (vector.stops.front().offset > 0.0) {
            // If the first one is not at 0, then insert a copy of the first at 0.
            SPGradientStop gstop;
            gstop.offset = 0.0;
            gstop.color = vector.stops.front().color;
            gstop.opacity = vector.stops.front().opacity;
            vector.stops.insert(vector.stops.begin(), gstop);
        }
        if (vector.stops.back().offset < 1.0) {
            // If the last one is not at 1, then insert a copy of the last at 1.
            SPGradientStop gstop;
            gstop.offset = 1.0;
            gstop.color = vector.stops.back().color;
            gstop.opacity = vector.stops.back().opacity;
            vector.stops.push_back(gstop);
        }
    }

    vector.built = true;
}