22#include <glibmm/i18n.h>
58#define noSP_GR_VERBOSE
66std::vector<Inkscape::PaintTarget> vectorOfPaintTargets(paintTargetItems, paintTargetItems + (
sizeof(paintTargetItems) /
sizeof(paintTargetItems[0])));
74 return vectorOfPaintTargets;
98 g_message(
"sp_gradient_ensure_vector_normalized(%p)", gr);
100 g_return_val_if_fail(gr !=
nullptr, NULL);
101 g_return_val_if_fail(!is<SPMeshGradient>(gr), NULL);
107 g_warning(
"file %s: line %d: Cannot normalize private gradient to vector (%s)", __FILE__, __LINE__, gr->
getId());
124 gr->
updateRepr(SP_OBJECT_WRITE_EXT | SP_OBJECT_WRITE_ALL);
141 g_message(
"sp_gradient_get_private_normalized(%p, %p, %d)", document, shared, type);
144 g_return_val_if_fail(document !=
nullptr, NULL);
145 g_return_val_if_fail(shared !=
nullptr, NULL);
163 if (prefs->
getBool(
"/option/gradient/auto_collect",
true)) {
178 g_assert(gr !=
nullptr);
195 && style->
fill.isPaintserver()
196 && is<SPGradient>(SP_STYLE_FILL_SERVER(style))
197 && cast<SPGradient>(SP_STYLE_FILL_SERVER(style)) == gr)
202 && style->
stroke.isPaintserver()
203 && is<SPGradient>(SP_STYLE_STROKE_SERVER(style))
204 && cast<SPGradient>(SP_STYLE_STROKE_SERVER(style)) == gr)
224 g_message(
"sp_gradient_fork_private_if_necessary(%p, %p, %d, %p)", gr, shared, type, o);
226 g_return_val_if_fail(gr !=
nullptr, NULL);
231 std::cerr <<
"sp_gradient_fork_private_if_necessary: Orphaned gradient" << std::endl;
239 while (is<SPTSpan>(user)) {
273 if (is<SPRadialGradient>(gr)) {
281 }
else if (is<SPLinearGradient>(gr)) {
314 g_message(
"sp_gradient_fork_vector_if_necessary(%p)", gr);
318 if (!prefs->
getBool(
"/options/forkgradientvectors/value",
true))
341 g_message(
"sp_gradient_get_forked_vector_if_necessary(%p, %d)", gradient, force_vector);
345 if ( gradient != vector && gradient->
ref->
getObject() != vector ) {
360 g_message(
"sp_gradient_reset_to_userspace(%p, %p)", gr,
item);
376 if (is<SPRadialGradient>(gr)) {
390 }
else if (is<SPLinearGradient>(gr)) {
398 double angle = prefs->
getDouble(
"/dialogs/gradienteditor/angle", 0.0);
402 Geom::Line grl(center, Geom::rad_from_deg(angle));
410 pStart = bbl1.
pointAt((*intersection(bbl1, grl)).ta);
411 pEnd = bbl3.
pointAt((*intersection(bbl3, grl)).ta);
412 if (intersection(bbl1, grl.
ray(grl.
angle()))) {
413 std::swap(pStart, pEnd);
415 }
else if (!bbl2.
isDegenerate() && intersection(bbl2, grl)) {
416 pStart = bbl2.
pointAt((*intersection(bbl2, grl)).ta);
417 pEnd = bbl4.
pointAt((*intersection(bbl4, grl)).ta);
418 if (intersection(bbl2, grl.
ray(grl.
angle()))) {
419 std::swap(pStart, pEnd);
438 auto mg = cast<SPMeshGradient>( gr );
439 mg->array.create( mg,
item, bbox );
455 g_message(
"sp_gradient_convert_to_userspace(%p, %p, \"%s\")", gr,
item, property);
457 g_return_val_if_fail(gr, NULL);
464 if (is<SPLinearGradient>(gr)) {
466 }
else if (is<SPRadialGradient>(gr)) {
482 0, bbox->dimensions()[
Geom::Y],
520 if (is<SPLinearGradient>(gr)) {
521 auto lg = cast<SPLinearGradient>(gr);
537 }
else if (is<SPRadialGradient>(gr)) {
538 auto rg = cast<SPRadialGradient>(gr);
543 double r_b = rg->r.computed;
548 double r_u = r_b * point_convert.descrim();
560 std::cerr <<
"sp_gradient_convert_to_userspace: Conversion of mesh to userspace not implemented" << std::endl;
569 if (is<SPText>(
item)) {
581 g_message(
"sp_gradient_transform_multiply(%p, , %d)", gradient,
set);
599 switch (fill_or_stroke)
602 if (style && (style->
fill.isPaintserver())) {
604 if ( is<SPGradient>(server) ) {
605 gradient = cast<SPGradient>(server);
610 if (style && (style->
stroke.isPaintserver())) {
612 if ( is<SPGradient>(server) ) {
613 gradient = cast<SPGradient>(server);
624 for (
SPStop *stop = gradient->
getFirstStop(); stop !=
nullptr; stop = stop->getNextStop()) {
625 if (stop->getNextStop() ==
nullptr)
640 return std::make_pair(before, after);
657 return std::make_pair(before, after);
661 if (!gradient)
return 0;
664 for (
SPStop* stop = gradient->
getFirstStop(); stop !=
nullptr; stop = stop->getNextStop()) {
665 if (stop == target) {
676 if (!stop)
return nullptr;
678 for (guint i = 0; i <
index; ++i) {
679 if (!stop)
return nullptr;
703 for (guint i = 0; i < stop_i; i++) {
722 g_message(
"sp_vector_add_stop(%p, %p, %p, %f)", vector, prev_stop, next_stop,
offset);
724 SPStop* newstop =
nullptr;
726 if (!prev_stop && !next_stop)
return newstop;
729 Color cnew(0x000000ff);
732 if (!prev_stop || !next_stop) {
734 SPStop* stop = prev_stop ? prev_stop : next_stop;
737 vector->
getRepr()->
addChild(new_stop_repr, prev_stop ? repr :
nullptr);
742 auto repr = prev_stop->
getRepr();
760 if (!stop || !gradient) {
772 bool modified =
false;
776 for (
auto& ochild: gradient->
children) {
777 if (is<SPStop>(&ochild)) {
779 stop = cast<SPStop>(&ochild);
816 if (!gradient || !
current)
return nullptr;
827 if (next ==
nullptr) {
829 if (prev !=
nullptr) {
835 if (next !=
nullptr) {
857 if (!gradient)
return nullptr;
865 if (stops.first || stops.second) {
880 DocumentUndo::maybeDone(document,
"gradient:stop:color", _(
"Change gradient stop color"), INKSCAPE_ICON(
"color-gradient"));
890 if (is<SPLinearGradient>(gradient) || is<SPRadialGradient>(gradient) ) {
914 g_warning(
"Bad linear/radial gradient handle type" );
926 return Colors::Color(0x000000ff);
928 if (is<SPLinearGradient>(gradient) || is<SPRadialGradient>(gradient) ) {
933 return Colors::Color(0x000000ff);
970 g_warning(
"Bad linear/radial gradient handle type" );
973 }
else if (is<SPMeshGradient>(gradient)) {
976 auto mg = cast<SPMeshGradient>(gradient);
980 if (point_i >= mg->array.corners.size()) {
981 return Colors::Color(0x000000ff);
983 SPMeshNode const* cornerpoint = mg->array.corners[ point_i ];
986 return *cornerpoint->
color;
999 g_warning(
"Bad mesh handle type" );
1002 return Colors::Color(0x000000ff);
1008 g_message(
"sp_item_gradient_stop_set_style(%p, %d, %d, %d, %p)",
item,
point_type, point_i, fill_or_stroke, stop);
1015 if (is<SPLinearGradient>(gradient) || is<SPRadialGradient>(gradient) ) {
1023 if ( gradient != vector && gradient->
ref->
getObject() != vector ) {
1062 g_warning(
"Bad linear/radial gradient handle type" );
1068 auto mg = cast<SPMeshGradient>(gradient);
1075 if (
auto color = Color::parse(color_str)) {
1077 if (*color != mg->array.corners[point_i]->color) {
1078 mg->array.corners[ point_i ]->color = *color;
1080 SPStop *stopi = mg->array.corners[ point_i ]->stop;
1084 std::cerr <<
"sp_item_gradient_stop_set_style: null stopi" << std::endl;
1099 g_warning(
"Bad mesh handle type" );
1107 g_message(
"sp_item_gradient_reverse_vector(%p, %d)",
item, fill_or_stroke);
1122 if ( gradient != vector && gradient->
ref->
getObject() != vector ) {
1126 std::vector<SPObject *> child_objects;
1127 std::vector<Inkscape::XML::Node *>child_reprs;
1128 std::vector<double> offsets;
1131 child_reprs.push_back(
child.getRepr());
1132 child_objects.push_back(&
child);
1133 offset =
child.getRepr()->getAttributeDouble(
"offset", 0);
1134 offsets.push_back(
offset);
1137 std::vector<Inkscape::XML::Node *> child_copies;
1138 for (
auto repr:child_reprs) {
1140 child_copies.push_back(repr->duplicate(xml_doc));
1144 for (
auto i:child_objects) {
1148 std::vector<double>::reverse_iterator o_it = offsets.rbegin();
1149 for (
auto c_it = child_copies.rbegin(); c_it != child_copies.rend(); ++c_it, ++o_it) {
1151 (*c_it)->setAttributeSvgDouble(
"offset", 1 - *o_it);
1159 g_message(
"sp_item_gradient_invert_vector_color(%p, %d)",
item, fill_or_stroke);
1170 if ( gradient != vector && gradient->
ref->
getObject() != vector ) {
1175 if (
auto stop = cast<SPStop>(&
child)) {
1176 auto color = stop->getColor();
1178 stop->setColor(color);
1188 const double EPS = 0.0001;
1207 g_message(
"sp_item_gradient_set_coords(%p, %d, %d, (%f, %f), ...)",
item,
point_type, point_i, p_w[
Geom::X], p_w[
Geom::Y] );
1224 if (is<SPLinearGradient>(gradient)) {
1225 auto lg = cast<SPLinearGradient>(gradient);
1229 lg->x2.computed += (lg->x1.computed - p[
Geom::X]);
1230 lg->y2.computed += (lg->y1.computed - p[
Geom::Y]);
1247 lg->x1.computed += (lg->x2.computed - p[
Geom::X]);
1248 lg->y1.computed += (lg->y2.computed - p[
Geom::Y]);
1266 Geom::Point begin(lg->x1.computed, lg->y1.computed);
1272 lg->vector.stops.at(point_i).offset =
offset;
1276 stopi->getRepr()->setAttributeCssDouble(
"offset", stopi->offset);
1278 stopi->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
1284 g_warning(
"Bad linear gradient handle type" );
1287 }
else if (is<SPRadialGradient>(gradient)) {
1288 auto rg = cast<SPRadialGradient>(gradient);
1296 bool transform_set =
false;
1300 rg->fx.computed = p[
Geom::X] + (rg->fx.computed - rg->cx.computed);
1301 rg->fy.computed = p[
Geom::Y] + (rg->fy.computed - rg->cy.computed);
1327 double move_angle =
Geom::atan2(p_w - c_w) - r1_angle;
1338 transform_set =
true;
1346 double move_angle =
Geom::atan2(p_w - c_w) - r2_angle;
1357 transform_set =
true;
1369 rg->vector.stops.at(point_i).offset =
offset;
1373 stopi->getRepr()->setAttributeCssDouble(
"offset", stopi->offset);
1375 stopi->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
1388 rg->vector.stops.at(point_i).offset =
offset;
1392 stopi->getRepr()->setAttributeCssDouble(
"offset", stopi->offset);
1394 stopi->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
1400 g_warning(
"Bad radial gradient handle type" );
1404 if (transform_set) {
1414 }
else if (is<SPMeshGradient>(gradient)) {
1415 auto mg = cast<SPMeshGradient>(gradient);
1422 if (point_i < mg->array.corners.size()) {
1423 mg->array.corners[ point_i ]->p = p;
1427 std::cerr <<
"sp_item_gradient_set_coords: bad point number" << std::endl;
1433 if (point_i < mg->array.handles.size()) {
1434 mg->array.handles[ point_i ]->p = p;
1437 std::cerr <<
"sp_item_gradient_set_coords: bad point number" << std::endl;
1443 if (point_i < mg->array.tensors.size()) {
1444 mg->array.tensors[ point_i ]->p = p;
1447 std::cerr <<
"sp_item_gradient_set_coords: bad point number" << std::endl;
1453 g_warning(
"Bad mesh handle type" );
1456 mg->array.write( mg );
1492 g_message(
"getGradientCoords(%p, %d, %d, %d, %p)",
item,
point_type, point_i, fill_or_stroke, gradient);
1500 if (is<SPLinearGradient>(gradient)) {
1501 auto lg = cast<SPLinearGradient>(gradient);
1504 p =
Geom::Point (lg->x1.computed, lg->y1.computed);
1507 p =
Geom::Point (lg->x2.computed, lg->y2.computed);
1511 if (lg->vector.stops.size() < point_i) {
1512 g_message(
"POINT_LG_MID bug trigger, see LP bug #453067");
1515 gdouble
offset = lg->vector.stops.at(point_i).offset;
1520 g_warning(
"Bad linear gradient handle type" );
1523 }
else if (is<SPRadialGradient>(gradient)) {
1524 auto rg = cast<SPRadialGradient>(gradient);
1527 p =
Geom::Point (rg->cx.computed, rg->cy.computed);
1530 p =
Geom::Point (rg->fx.computed, rg->fy.computed);
1533 p =
Geom::Point (rg->cx.computed + rg->r.computed, rg->cy.computed);
1536 p =
Geom::Point (rg->cx.computed, rg->cy.computed - rg->r.computed);
1540 if (rg->vector.stops.size() < point_i) {
1541 g_message(
"POINT_RG_MID1 bug trigger, see LP bug #453067");
1544 gdouble
offset = rg->vector.stops.at(point_i).offset;
1550 if (rg->vector.stops.size() < point_i) {
1551 g_message(
"POINT_RG_MID2 bug trigger, see LP bug #453067");
1554 gdouble
offset = rg->vector.stops.at(point_i).offset;
1559 g_warning(
"Bad radial gradient handle type" );
1562 }
else if (is<SPMeshGradient>(gradient)) {
1563 auto mg = cast<SPMeshGradient>(gradient);
1567 p = mg->array.corners[ point_i ]->p;
1571 p = mg->array.handles[ point_i ]->p;
1576 p = mg->array.tensors[ point_i ]->p;
1581 g_warning(
"Bad mesh handle type" );
1591 0, bbox->dimensions()[
Geom::Y],
1608 g_message(
"sp_item_set_gradient(%p, %p, %d, %d)",
item, gr, type, fill_or_stroke);
1610 g_return_val_if_fail(
item !=
nullptr, NULL);
1611 g_return_val_if_fail(gr !=
nullptr, NULL);
1615 g_assert(style !=
nullptr);
1619 ps = (fill_or_stroke ==
Inkscape::FOR_FILL) ? SP_STYLE_FILL_SERVER(style) : SP_STYLE_STROKE_SERVER(style);
1628 auto current = cast<SPGradient>(ps);
1633 && (
current->hrefcount == 1 ||
1652 g_return_val_if_fail(normalized !=
nullptr, NULL);
1672 SP_OBJECT_STYLE_MODIFIED_FLAG ));
1680 g_message(
"sp_gradient_repr_set_link(%p, %p)", repr, link);
1682 g_return_if_fail(repr !=
nullptr);
1685 Glib::ustring
ref(
"#");
1698 g_message(
"addStop(%p, %s, %f, %s)",
parent, color.toString().c_str(), opacity,
offset);
1700 auto doc =
parent->document();
1704 copy.addOpacity(opacity);
1707 parent->appendChild(repr);
1721 if ( !singleStop ) {
1724 if (prefs->
getBool(
"/option/gradient/auto_collect",
true)) {
1739 addStop( repr, color, opacity,
"0" );
1740 if ( !singleStop ) {
1741 addStop( repr, color, 0,
"1" );
1748 g_assert(gr !=
nullptr);
1758 Color color(0x000000ff);
1759 double opacity = 1.0;
1766 if (o && o->
style) {
1772 if ( is<SPLinearGradient>(server) || is<SPRadialGradient>(server) ) {
1773 return cast<SPGradient>(server)->getVector(
true);
1788 auto list= selection->
items();
1789 for (
auto i = list.begin(); i != list.end(); ++i) {
1809 if (drag && !drag->
selected.empty()) {
1812 auto list= selection->
items();
1813 for (
auto i = list.begin(); i != list.end(); ++i) {
1828 const std::vector<SPObject *> gradients = doc->
getResourceList(
"gradient");
1829 for (
auto gradient : gradients) {
1830 auto grad = cast<SPGradient>(gradient);
1831 if (
id == grad->getId() ) {
1832 grad->setSwatch(
false);
1850 if (is<SPLinearGradient>(item_server) || is<SPRadialGradient>(item_server) ||
1851 (is<SPGradient>(item_server) && cast<SPGradient>(item_server)->getVector()->isSwatch())) {
1853 return cast<SPGradient>(item_server)->getVector();
1863 if (is<SPItem>(&
child)) {
1864 list.push_back(cast<SPItem>(&
child));
1871 std::vector<SPItem*>
items;
1879 if (!document || !gradient)
return 0;
1887 if (fill == gradient) {
1891 if (stroke == gradient) {
3x3 matrix representing an affine transformation.
Coord descrim() const
Calculate the descriminant.
Affine inverse() const
Compute the inverse matrix.
bool isDegenerate() const override
Check whether the curve has exactly zero length.
Coord nearestTime(Point const &p, Coord from=0, Coord to=1) const override
Compute a time value at which the curve comes closest to a specified point.
Point pointAt(Coord t) const override
Evaluate the curve at a specified time value.
Infinite line on a plane.
Ray ray(Coord t)
Create a ray starting at the specified time value.
Coord angle() const
Angle the line makes with the X axis, in mathematical convention.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
Rotation around the origin.
This is the root class of the gradient dragging machinery.
std::set< GrDragger * > selected
void selected_reverse_vector()
Color averaged(Color const &other, double pos=0.5) const
Return the average between this and another color.
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
SPItemRange items()
Returns a range of selected SPItems.
Preference storage class.
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
double getDouble(Glib::ustring const &pref_path, double def=0.0, Glib::ustring const &unit="")
Retrieve a floating point value.
static Preferences * get()
Access the singleton Preferences object.
The set of selected SPObjects for a given document and layer model.
Interface for refcounted XML nodes.
virtual void addChild(Node *child, Node *after)=0
Insert another node as a child of this node.
virtual void appendChild(Node *child)=0
Append a node as the last child of this node.
void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value)
Change an attribute of this node.
virtual Node * duplicate(Document *doc) const =0
Create a duplicate of this node.
virtual Node * firstChild()=0
Get the first child of this node.
bool setAttributeCssDouble(Util::const_char_ptr key, double val)
Set a property attribute to val [slightly rounded], in the format required for CSS properties: in par...
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
void removeAttribute(Inkscape::Util::const_char_ptr key)
Remove an attribute of this node.
virtual Document * document()=0
Get the node's associated document.
virtual void removeChild(Node *child)=0
Remove a child of this node.
bool setAttributeSvgDouble(Util::const_char_ptr key, double val)
For attributes where an exponent is allowed.
To do: update description of desktop.
SPDocument * getDocument() const
Inkscape::Selection * getSelection() const
Inkscape::UI::Tools::ToolBase * getTool() const
Typed SVG document implementation.
SPRoot * getRoot()
Returns our SPRoot.
std::string generate_unique_id(char const *prefix)
Generate a document-wide unique id.
std::vector< SPObject * > const getResourceList(char const *key)
SPDefs * getDefs()
Return the main defs object for the document.
Inkscape::XML::Document * getReprDoc()
Our Inkscape::XML::Document.
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
SPObject * getObjectByRepr(Inkscape::XML::Node *repr) const
SPGradient * getObject() const
SPGradient * getArray(bool force_private=false)
Returns private mesh of given gradient (the gradient at the end of the href chain which has patches),...
unsigned int state
State in Inkscape gradient system.
SPGradientVector vector
Linear and Radial Gradients.
Geom::Affine gradientTransform
gradientTransform attribute
SPGradientSpread fetchSpread() const
Returns the effective spread of given gradient (climbing up the refs chain if needed).
SPGradientReference * ref
Reference (href)
unsigned int gradientTransform_set
SPGradient * getVector(bool force_private=false)
Returns private vector of given gradient (the gradient at the end of the href chain which has stops),...
SPGradientUnits getUnits() const
void repr_write_vector()
Writes the gradient's internal vector (whether from its own stops, or inherited from refs) into the g...
void ensureVector()
Forces vector to be built, if not present (i.e.
Paint type internal to SPStyle.
bool isPaintserver() const
Colors::Color const & getColor() const
Base class for visual SVG elements.
Geom::Affine i2dt_affine() const
Returns the transformation from item to desktop coords.
Geom::OptRect visualBounds(Geom::Affine const &transform=Geom::identity(), bool wfilter=true, bool wclip=true, bool wmask=true) const
Get item's visual bounding box in this item's coordinate system.
std::optional< Inkscape::Colors::Color > color
SPObject is an abstract base class of all of the document nodes at the SVG document level.
void setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inkscape::Util::const_char_ptr value)
void requestModified(unsigned int flags)
Requests that a modification notification signal be emitted later (e.g.
char const * getId() const
Returns the objects current ID string.
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Inkscape::XML::Node * updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT)
Updates the object's repr based on the object's state.
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
SPObject * appendChildRepr(Inkscape::XML::Node *repr)
Append repr as child of this object.
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
SPStop * getNextStop()
Virtual write: write object attributes to repr.
static void setColorRepr(Inkscape::XML::Node *node, Inkscape::Colors::Color const &color)
Set the color and opacity directly into the given xml repr.
void setColor(Inkscape::Colors::Color const &color)
Sets the stop color and stop opacity in the style attribute.
Inkscape::Colors::Color getColor() const
SPPaintServer * getFillPaintServer()
T< SPAttr::FILL, SPIPaint > fill
fill
T< SPAttr::STROKE, SPIPaint > stroke
stroke
SPPaintServer * getStrokePaintServer()
T< SPAttr::FILL_OPACITY, SPIScale24 > fill_opacity
fill-opacity
SPIPaint * getFillOrStroke(bool fill_)
Get either the fill or the stroke property.
T< SPAttr::STROKE_OPACITY, SPIScale24 > stroke_opacity
stroke-opacity
Structure representing the intersection of two curves.
TODO: insert short description here.
std::optional< Color > sp_desktop_get_color(SPDesktop *desktop, bool is_fill)
Return the desktop's current color.
Editable view implementation.
static char const *const current
static char const *const parent
TODO: insert short description here.
void sp_gradient_transform_multiply(SPGradient *gradient, Geom::Affine postmul, bool set)
SPStop * sp_get_stop_i(SPGradient *gradient, guint stop_i)
static void sp_gradient_repr_set_link(Inkscape::XML::Node *repr, SPGradient *gr)
void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTarget fill_or_stroke)
Color sp_item_gradient_stop_query_style(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke)
void sp_gradient_unset_swatch(SPDesktop *desktop, std::string const &id)
Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke)
Returns the position of point point_type of the gradient applied to item (either fill_or_stroke),...
void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke, SPCSSAttr *stop)
SPStop * sp_item_gradient_get_stop(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke)
void sp_gradient_reverse_selected_gradients(SPDesktop *desktop)
SPGradient * sp_gradient_fork_vector_if_necessary(SPGradient *gr)
int sp_get_gradient_refcount(SPDocument *document, SPGradient *gradient)
double midpoint_offset_hack(double offset)
SPGradient * sp_item_gradient_get_vector(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
static SPGradient * sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradient *shared, SPGradientType type, SPObject *o)
If gr has other users, create a new shared; also check if gr links to shared, relink if not.
std::vector< SPItem * > sp_get_all_document_items(SPDocument *document)
std::pair< SPStop *, SPStop * > sp_get_before_after_stops(SPStop *stop)
SPStop * sp_get_nth_stop(SPGradient *gradient, guint index)
void sp_set_gradient_stop_color(SPDocument *document, SPStop *stop, Color const &color)
void sp_gradient_reverse_vector(SPGradient *gradient)
static std::pair< SPStop *, SPStop * > get_before_after_stops(SPGradient *gradient, double offset)
SPStop * sp_last_stop(SPGradient *gradient)
static SPGradient * sp_gradient_get_private_normalized(SPDocument *document, SPGradient *shared, SPGradientType type)
Creates new private gradient for the given shared gradient.
SPStop * sp_gradient_add_stop_at(SPGradient *gradient, double offset)
void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint point_i, Geom::Point p_w, Inkscape::PaintTarget fill_or_stroke, bool write_repr, bool scale)
Set the position of point point_type of the gradient applied to item (either fill_or_stroke) to p_w (...
SPStop * sp_vector_add_stop(SPGradient *vector, SPStop *prev_stop, SPStop *next_stop, gfloat offset)
SPStop * sp_gradient_add_stop(SPGradient *gradient, SPStop *current)
void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
SPGradient * sp_gradient_ensure_vector_normalized(SPGradient *gr)
Either normalizes given gradient to vector, or returns fresh normalized vector - in latter case,...
SPGradientSpread sp_item_gradient_get_spread(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
void sp_gradient_delete_stop(SPGradient *gradient, SPStop *stop)
SPGradient * sp_gradient_get_forked_vector_if_necessary(SPGradient *gradient, bool force_vector)
Obtain the vector from the gradient.
SPGradient * getGradient(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
Fetches either the fill or the stroke gradient from the given item.
SPGradient * sp_document_default_gradient_vector(SPDocument *document, Color const &color, double opacity, bool singleStop)
SPGradient * sp_gradient_vector_for_object(SPDocument *const doc, SPDesktop *const desktop, SPObject *const o, Inkscape::PaintTarget const fill_or_stroke, bool singleStop)
Return the preferred vector for o, made from (in order of preference) its current vector,...
static void addStop(Inkscape::XML::Node *parent, Color const &color, double opacity, gchar const *offset)
static guint count_gradient_hrefs(SPObject *o, SPGradient *gr)
Count how many times gr is used by the styles of o and its descendants.
static bool verify_grad(SPGradient *gradient)
static void get_all_doc_items(std::vector< SPItem * > &list, SPObject *from)
SPGradient * sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *property)
Convert an item's gradient to userspace if necessary, also fork it if necessary.
guint sp_number_of_stops_before_stop(SPGradient *gradient, SPStop *target)
void sp_item_gradient_reverse_vector(SPItem *item, Inkscape::PaintTarget fill_or_stroke)
SPGradient * sp_item_set_gradient(SPItem *item, SPGradient *gr, SPGradientType type, Inkscape::PaintTarget fill_or_stroke)
Sets item fill or stroke to the gradient of the specified type with given vector, creating new privat...
SPGradient * sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item)
Convert an item's gradient to userspace without preserving coords, setting them to defaults instead.
void sp_repr_set_css_double(Inkscape::XML::Node *node, const char *key, double value)
SPGradient * sp_item_get_gradient(SPItem *item, bool fillorstroke)
BezierCurveN< 1 > LineSegment
Line segment.
double Coord
Floating point type used to store coordinates.
Macro for icon names used in Inkscape.
Inkscape::XML::Node * node
double atan2(Point const &p)
Affine identity()
Create an identity matrix.
SBasis L2(D2< SBasis > const &a, unsigned k)
static R & release(R &r)
Decrements the reference count of a anchored object.
Helper class to stream background task notifications as a series of messages.
void setHrefAttribute(XML::Node &node, Util::const_char_ptr value)
If the 'href' attribute already exists for the given node, then set a new value for it.
std::vector< PaintTarget > const & allPaintTargets()
Convenience function to access a common vector of all enum values.
static cairo_user_data_key_t key
void sp_repr_css_change(Node *repr, SPCSSAttr *css, gchar const *attr)
Creates a new SPCSAttr with the values filled from a repr, merges in properties from the given SPCSAt...
double sp_repr_css_double_property(SPCSSAttr *css, gchar const *name, double defval)
Return the value of a style property if property define, or a default value if not.
char const * sp_repr_css_property(SPCSSAttr *css, gchar const *name, gchar const *defval)
Returns a character string of the value of a given style property or a default value if the attribute...
TODO: insert short description here.
@ SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX
@ SP_GRADIENT_STATE_VECTOR
@ SP_GRADIENT_STATE_UNKNOWN
@ SP_GRADIENT_TYPE_LINEAR
@ SP_GRADIENT_TYPE_RADIAL
TODO: insert short description here.
TODO: insert short description here.
TODO: insert short description here.
SPRoot: SVG <svg> implementation.
TODO: insert short description here.
TODO: insert short description here.
Interface for XML documents.
virtual Node * createElement(char const *name)=0
void sp_style_set_property_url(SPObject *item, gchar const *property, SPObject *linked, bool recursive)
SPStyle - a style object for SPItem objects.
std::string sp_svg_transform_write(Geom::Affine const &transform)