From 1636c1dd1651780d01759676b194312529f211f7 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Sat, 25 Jun 2016 22:24:26 +0200 Subject: Moved next functions, added namespace, renamed range functions (bzr r14954.1.10) --- src/gradient-chemistry.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index edeb523d7..698cf5012 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1570,7 +1570,7 @@ void sp_gradient_invert_selected_gradients(SPDesktop *desktop, Inkscape::PaintTa { Inkscape::Selection *selection = desktop->getSelection(); - const std::vector list=selection->itemList(); + const std::vector list= selection->items(); for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { sp_item_gradient_invert_vector_color(*i, fill_or_stroke); } @@ -1595,7 +1595,7 @@ void sp_gradient_reverse_selected_gradients(SPDesktop *desktop) if (drag && !drag->selected.empty()) { drag->selected_reverse_vector(); } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) - const std::vector list=selection->itemList(); + const std::vector list= selection->items(); for (std::vector::const_iterator i = list.begin(); i != list.end(); ++i) { sp_item_gradient_reverse_vector(*i, Inkscape::FOR_FILL); sp_item_gradient_reverse_vector(*i, Inkscape::FOR_STROKE); -- cgit v1.2.3 From d1947e768272c703674129d5c583204ff2b59251 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 13 Jul 2016 13:36:19 +0200 Subject: Second part of new SPObject children list (bzr r14954.1.19) --- src/gradient-chemistry.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 59d715149..9c46a2efb 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -199,8 +199,8 @@ static guint count_gradient_hrefs(SPObject *o, SPGradient *gr) i ++; } - for ( SPObject *child = o->firstChild(); child; child = child->getNext() ) { - i += count_gradient_hrefs(child, gr); + for (auto& child: o->_children) { + i += count_gradient_hrefs(&child, gr); } return i; @@ -926,11 +926,11 @@ void sp_item_gradient_reverse_vector(SPItem *item, Inkscape::PaintTarget fill_or GSList *child_objects = NULL; std::vector offsets; double offset; - for ( SPObject *child = vector->firstChild(); child; child = child->getNext()) { - child_reprs = g_slist_prepend (child_reprs, child->getRepr()); - child_objects = g_slist_prepend (child_objects, child); + for (auto& child: vector->_children) { + child_reprs = g_slist_prepend (child_reprs, child.getRepr()); + child_objects = g_slist_prepend (child_objects, &child); offset=0; - sp_repr_get_double(child->getRepr(), "offset", &offset); + sp_repr_get_double(child.getRepr(), "offset", &offset); offsets.push_back(offset); } @@ -979,9 +979,9 @@ void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fi sp_gradient_repr_set_link(gradient->getRepr(), vector); } - for ( SPObject *child = vector->firstChild(); child; child = child->getNext()) { - if (SP_IS_STOP(child)) { - guint32 color = SP_STOP(child)->get_rgba32(); + for (auto& child: vector->_children) { + if (SP_IS_STOP(&child)) { + guint32 color = SP_STOP(&child)->get_rgba32(); //g_message("Stop color %d", color); gchar c[64]; sp_svg_write_color (c, sizeof(c), @@ -994,7 +994,7 @@ void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fi ); SPCSSAttr *css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "stop-color", c); - sp_repr_css_change(child->getRepr(), css, "style"); + sp_repr_css_change(child.getRepr(), css, "style"); sp_repr_css_attr_unref (css); } } -- cgit v1.2.3 From 24d3f50003ca3cec6a03a7f5267cc4fe5588c69f Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 14 Jul 2016 13:17:21 +0200 Subject: Renamed children list in SPObject (bzr r14954.1.21) --- src/gradient-chemistry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 9c46a2efb..b6ea0d8c1 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -199,7 +199,7 @@ static guint count_gradient_hrefs(SPObject *o, SPGradient *gr) i ++; } - for (auto& child: o->_children) { + for (auto& child: o->children) { i += count_gradient_hrefs(&child, gr); } @@ -926,7 +926,7 @@ void sp_item_gradient_reverse_vector(SPItem *item, Inkscape::PaintTarget fill_or GSList *child_objects = NULL; std::vector offsets; double offset; - for (auto& child: vector->_children) { + for (auto& child: vector->children) { child_reprs = g_slist_prepend (child_reprs, child.getRepr()); child_objects = g_slist_prepend (child_objects, &child); offset=0; @@ -979,7 +979,7 @@ void sp_item_gradient_invert_vector_color(SPItem *item, Inkscape::PaintTarget fi sp_gradient_repr_set_link(gradient->getRepr(), vector); } - for (auto& child: vector->_children) { + for (auto& child: vector->children) { if (SP_IS_STOP(&child)) { guint32 color = SP_STOP(&child)->get_rgba32(); //g_message("Stop color %d", color); -- cgit v1.2.3 From f35bb1f74a0ffeb5c6477a25e3c4cde87a97bcf1 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 12:06:06 +0200 Subject: Removed unused includes, decrease compilation time (bzr r15025) --- src/gradient-chemistry.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index edeb523d7..ae82499de 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -24,7 +24,6 @@ #include <2geom/bezier-curve.h> #include <2geom/crossing.h> #include <2geom/line.h> -#include <2geom/angle.h> #include "style.h" #include "document-private.h" @@ -38,7 +37,6 @@ #include #include "sp-gradient-reference.h" -#include "sp-gradient-vector.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" #include "sp-mesh.h" @@ -48,11 +46,9 @@ #include "sp-text.h" #include "sp-tspan.h" -#include "xml/repr.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" -#include "preferences.h" #define noSP_GR_VERBOSE -- cgit v1.2.3 From 43b49e325db73cc19b1731db6c69545664ee8fbe Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 13:26:17 +0200 Subject: Reverted changes to r15024 after many building problems (bzr r15027) --- src/gradient-chemistry.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index ae82499de..edeb523d7 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -24,6 +24,7 @@ #include <2geom/bezier-curve.h> #include <2geom/crossing.h> #include <2geom/line.h> +#include <2geom/angle.h> #include "style.h" #include "document-private.h" @@ -37,6 +38,7 @@ #include #include "sp-gradient-reference.h" +#include "sp-gradient-vector.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" #include "sp-mesh.h" @@ -46,9 +48,11 @@ #include "sp-text.h" #include "sp-tspan.h" +#include "xml/repr.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" +#include "preferences.h" #define noSP_GR_VERBOSE -- cgit v1.2.3 From 35830f456cadaecf8b8e3944e3031a1a93f6cb41 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 3 Aug 2016 15:29:38 +0200 Subject: Removed unused includes, decreased compilation time. Once again (bzr r15034) --- src/gradient-chemistry.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index edeb523d7..ae82499de 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -24,7 +24,6 @@ #include <2geom/bezier-curve.h> #include <2geom/crossing.h> #include <2geom/line.h> -#include <2geom/angle.h> #include "style.h" #include "document-private.h" @@ -38,7 +37,6 @@ #include #include "sp-gradient-reference.h" -#include "sp-gradient-vector.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" #include "sp-mesh.h" @@ -48,11 +46,9 @@ #include "sp-text.h" #include "sp-tspan.h" -#include "xml/repr.h" #include "svg/svg.h" #include "svg/svg-color.h" #include "svg/css-ostringstream.h" -#include "preferences.h" #define noSP_GR_VERBOSE -- cgit v1.2.3 From f273f14eb1b54861f1b3a7eb622cb481ee33cec9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 26 Sep 2016 13:26:47 +0200 Subject: Fix undo/redo for mesh gradients. (bzr r15135) --- src/gradient-chemistry.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 4521d72fd..28fdda483 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -271,7 +271,7 @@ static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradi repr_new->setAttribute("x2", repr->attribute("x2")); repr_new->setAttribute("y2", repr->attribute("y2")); } else { - std::cout << "sp_gradient_fork_private_if_necessary: mesh not implemented" << std::endl; + std::cerr << "sp_gradient_fork_private_if_necessary: mesh not implemented" << std::endl; } return gr_new; @@ -861,6 +861,7 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint switch (point_type) { case POINT_MG_CORNER: { + // Update mesh array (which is not updated automatically when stop is changed?) gchar const* color_str = sp_repr_css_property( stop, "stop-color", NULL ); if( color_str ) { SPColor color( 0 ); @@ -880,9 +881,14 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint mg->array.corners[ point_i ]->opacity = opacity; changed = true; } + // Update stop if( changed ) { - gradient->requestModified(SP_OBJECT_MODIFIED_FLAG); - mg->array.write( mg ); + SPStop *stopi = mg->array.corners[ point_i ]->stop; + if (stopi) { + sp_repr_css_change(stopi->getRepr(), stop, "style"); + } else { + std::cerr << "sp_item_gradient_stop_set_style: null stopi" << std::endl; + } } break; } -- cgit v1.2.3 From f9ec83dbb254701f39d3b7a30c0bacb5eaae9ee9 Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Tue, 27 Sep 2016 10:51:26 +0200 Subject: Rename to per SVG 2 CR specificiation. Note: has been repurposed to be a special shape that tightly wraps a mesh gradient. (bzr r15137) --- src/gradient-chemistry.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 28fdda483..061fadbaa 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -39,7 +39,7 @@ #include "sp-gradient-reference.h" #include "sp-linear-gradient.h" #include "sp-radial-gradient.h" -#include "sp-mesh.h" +#include "sp-mesh-gradient.h" #include "sp-stop.h" #include "gradient-drag.h" #include "gradient-chemistry.h" @@ -147,7 +147,7 @@ static SPGradient *sp_gradient_get_private_normalized(SPDocument *document, SPGr repr = xml_doc->createElement("svg:radialGradient"); } else { // Rows/patches added in sp_gradient_reset_to_userspace for new meshes. - repr = xml_doc->createElement("svg:mesh"); + repr = xml_doc->createElement("svg:meshgradient"); } // privates are garbage-collectable @@ -409,7 +409,7 @@ SPGradient *sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item) // IN SPMeshNodeArray::create() //sp_repr_set_svg_double(repr, "x", bbox->min()[Geom::X]); //sp_repr_set_svg_double(repr, "y", bbox->min()[Geom::Y]); - SPMesh* mg = SP_MESH( gr ); + SPMeshGradient* mg = SP_MESHGRADIENT( gr ); mg->array.create( mg, item, bbox ); } @@ -754,10 +754,10 @@ guint32 sp_item_gradient_stop_query_style(SPItem *item, GrPointType point_type, break; } return 0; - } else if (SP_IS_MESH(gradient)) { + } else if (SP_IS_MESHGRADIENT(gradient)) { // Mesh gradient - SPMesh *mg = SP_MESH(gradient); + SPMeshGradient *mg = SP_MESHGRADIENT(gradient); switch (point_type) { case POINT_MG_CORNER: { @@ -855,7 +855,7 @@ void sp_item_gradient_stop_set_style(SPItem *item, GrPointType point_type, guint } else { // Mesh gradient - SPMesh *mg = SP_MESH(gradient); + SPMeshGradient *mg = SP_MESHGRADIENT(gradient); bool changed = false; switch (point_type) { @@ -1211,8 +1211,8 @@ void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint poi gradient->requestModified(SP_OBJECT_MODIFIED_FLAG); } } - } else if (SP_IS_MESH(gradient)) { - SPMesh *mg = SP_MESH(gradient); + } else if (SP_IS_MESHGRADIENT(gradient)) { + SPMeshGradient *mg = SP_MESHGRADIENT(gradient); //Geom::Affine new_transform; //bool transform_set = false; @@ -1242,7 +1242,7 @@ void sp_item_gradient_set_coords(SPItem *item, GrPointType point_type, guint poi } if( write_repr ) { //std::cout << "Write mesh repr" << std::endl; - sp_mesh_repr_write( mg ); + mg->array.write( mg ); } } @@ -1348,8 +1348,8 @@ Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_ g_warning( "Bad radial gradient handle type" ); break; } - } else if (SP_IS_MESH(gradient)) { - SPMesh *mg = SP_MESH(gradient); + } else if (SP_IS_MESHGRADIENT(gradient)) { + SPMeshGradient *mg = SP_MESHGRADIENT(gradient); switch (point_type) { case POINT_MG_CORNER: -- cgit v1.2.3 From 647462662a4267c58306e49ec841abe92a958cca Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 3 Oct 2016 15:29:34 +0200 Subject: Prevent a crash if a mesh is defined in bounding box coordinates. (bzr r15144) --- src/gradient-chemistry.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index 061fadbaa..cf5cda180 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -434,6 +434,11 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar return gr; } + // FIXME Transforming a mesh gradient is more complicated... probably need to add function to SPMeshArray.wq + if ( gr && SP_IS_MESHGRADIENT( gr ) ) { + return gr; + } + // First, fork it if it is shared gr = sp_gradient_fork_private_if_necessary(gr, gr->getVector(), SP_IS_RADIALGRADIENT(gr) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, item); -- cgit v1.2.3 From 32442aec84cc13f0a22fa1f07f3de701c6938e5d Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Fri, 14 Oct 2016 22:01:57 +0200 Subject: Implement copying of objects with mesh gradients. (bzr r15171) --- src/gradient-chemistry.cpp | 140 +++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 57 deletions(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index cf5cda180..c133bfa7c 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -76,9 +76,14 @@ std::vector const &allPaintTargets() // "vector" is a gradient that has stops but not position coords. It can be referenced by one or // more privates. Objects should not refer to it directly. It has no radial/linear distinction. // -// "private" is a gradient that has no stops but has position coords (e.g. center, radius etc for a -// radial). It references a vector for the actual colors. Each private is only used by one -// object. It is either linear or radial. +// "array" is a gradient that has mesh rows and patches. It may or may not have "x" and "y" attributes. +// An array does have spacial information so it cannot be normalized like a "vector". +// +// "shared" is either a "vector" or "array" that is shared between multiple objects. +// +// "private" is a gradient that is not shared. A private linear or radial gradient has no stops but +// has position coords (e.g. center, radius etc for a radial); it references a "vector" for the +// actual colors. A mesh may or may not reference an array. Each private is only used by one object. static void sp_gradient_repr_set_link(Inkscape::XML::Node *repr, SPGradient *gr); @@ -89,6 +94,7 @@ SPGradient *sp_gradient_ensure_vector_normalized(SPGradient *gr) #endif g_return_val_if_fail(gr != NULL, NULL); g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); + g_return_val_if_fail(!SP_IS_MESHGRADIENT(gr), NULL); /* If we are already normalized vector, just return */ if (gr->state == SP_GRADIENT_STATE_VECTOR) return gr; @@ -122,19 +128,19 @@ SPGradient *sp_gradient_ensure_vector_normalized(SPGradient *gr) } /** - * Creates new private gradient for the given vector + * Creates new private gradient for the given shared gradient. */ -static SPGradient *sp_gradient_get_private_normalized(SPDocument *document, SPGradient *vector, SPGradientType type) +static SPGradient *sp_gradient_get_private_normalized(SPDocument *document, SPGradient *shared, SPGradientType type) { #ifdef SP_GR_VERBOSE - g_message("sp_gradient_get_private_normalized(%p, %p, %d)", document, vector, type); + g_message("sp_gradient_get_private_normalized(%p, %p, %d)", document, shared, type); #endif g_return_val_if_fail(document != NULL, NULL); - g_return_val_if_fail(vector != NULL, NULL); - g_return_val_if_fail(SP_IS_GRADIENT(vector), NULL); - g_return_val_if_fail(vector->hasStops(), NULL); + g_return_val_if_fail(shared != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(shared), NULL); + g_return_val_if_fail(shared->hasStops() || shared->hasPatches(), NULL); SPDefs *defs = document->getDefs(); @@ -146,16 +152,14 @@ static SPGradient *sp_gradient_get_private_normalized(SPDocument *document, SPGr } else if(type == SP_GRADIENT_TYPE_RADIAL) { repr = xml_doc->createElement("svg:radialGradient"); } else { - // Rows/patches added in sp_gradient_reset_to_userspace for new meshes. repr = xml_doc->createElement("svg:meshgradient"); } // privates are garbage-collectable repr->setAttribute("inkscape:collect", "always"); - // link to vector - // MESH FIXME: Meshes don't used vector... but meshes simulating gradient across/along path might. - sp_gradient_repr_set_link(repr, vector); + // link to shared + sp_gradient_repr_set_link(repr, shared); /* Append the new private gradient to defs */ defs->getRepr()->appendChild(repr); @@ -204,21 +208,21 @@ static guint count_gradient_hrefs(SPObject *o, SPGradient *gr) /** - * If gr has other users, create a new private; also check if gr links to vector, relink if not + * If gr has other users, create a new shared; also check if gr links to shared, relink if not */ -static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradient *vector, +static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradient *shared, SPGradientType type, SPObject *o) { #ifdef SP_GR_VERBOSE - g_message("sp_gradient_fork_private_if_necessary(%p, %p, %d, %p)", gr, vector, type, o); + g_message("sp_gradient_fork_private_if_necessary(%p, %p, %d, %p)", gr, shared, type, o); #endif g_return_val_if_fail(gr != NULL, NULL); g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); - // Orphaned gradient, no vector with stops at the end of the line; this used to be an assert - // but i think we should not abort on this - maybe just write a validity warning into some sort - // of log - if ( !vector || !vector->hasStops() ) { + // Orphaned gradient, no shared with stops or patches at the end of the line; this used to be + // an assert + if ( !shared || !(shared->hasStops() || shared->hasPatches()) ) { + std::cerr << "sp_gradient_fork_private_if_necessary: Orphaned gradient" << std::endl; return (gr); } @@ -232,11 +236,11 @@ static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradi // Check the number of uses of the gradient within this object; // if we are private and there are no other users, - if (!vector->isSwatch() && (gr->hrefcount <= count_gradient_hrefs(user, gr))) { - // check vector - if ( gr != vector && gr->ref->getObject() != vector ) { - /* our href is not the vector, and vector is different from gr; relink */ - sp_gradient_repr_set_link(gr->getRepr(), vector); + if (!shared->isSwatch() && (gr->hrefcount <= count_gradient_hrefs(user, gr))) { + // check shared + if ( gr != shared && gr->ref->getObject() != shared ) { + /* our href is not the shared, and shared is different from gr; relink */ + sp_gradient_repr_set_link(gr->getRepr(), shared); } return gr; } @@ -245,35 +249,49 @@ static SPGradient *sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradi SPObject *defs = doc->getDefs(); if ((gr->hasStops()) || + (gr->hasPatches()) || (gr->state != SP_GRADIENT_STATE_UNKNOWN) || (gr->parent != SP_OBJECT(defs)) || (gr->hrefcount > 1)) { - // we have to clone a fresh new private gradient for the given vector + + // we have to clone a fresh new private gradient for the given shared // create an empty one - SPGradient *gr_new = sp_gradient_get_private_normalized(doc, vector, type); + SPGradient *gr_new = sp_gradient_get_private_normalized(doc, shared, type); // copy all the attributes to it Inkscape::XML::Node *repr_new = gr_new->getRepr(); Inkscape::XML::Node *repr = gr->getRepr(); repr_new->setAttribute("gradientUnits", repr->attribute("gradientUnits")); repr_new->setAttribute("gradientTransform", repr->attribute("gradientTransform")); - repr_new->setAttribute("spreadMethod", repr->attribute("spreadMethod")); if (SP_IS_RADIALGRADIENT(gr)) { repr_new->setAttribute("cx", repr->attribute("cx")); repr_new->setAttribute("cy", repr->attribute("cy")); repr_new->setAttribute("fx", repr->attribute("fx")); repr_new->setAttribute("fy", repr->attribute("fy")); - repr_new->setAttribute("r", repr->attribute("r")); + repr_new->setAttribute("r", repr->attribute("r" )); + repr_new->setAttribute("fr", repr->attribute("fr")); + repr_new->setAttribute("spreadMethod", repr->attribute("spreadMethod")); } else if (SP_IS_LINEARGRADIENT(gr)) { repr_new->setAttribute("x1", repr->attribute("x1")); repr_new->setAttribute("y1", repr->attribute("y1")); repr_new->setAttribute("x2", repr->attribute("x2")); repr_new->setAttribute("y2", repr->attribute("y2")); - } else { - std::cerr << "sp_gradient_fork_private_if_necessary: mesh not implemented" << std::endl; + repr_new->setAttribute("spreadMethod", repr->attribute("spreadMethod")); + } else { // Mesh + repr_new->setAttribute("x", repr->attribute("x")); + repr_new->setAttribute("y", repr->attribute("y")); + repr_new->setAttribute("type", repr->attribute("type")); + + // We probably want a completely separate mesh gradient so + // copy the children and unset the link to the shared. + for ( Inkscape::XML::Node *child = repr->firstChild() ; child ; child = child->next() ) { + Inkscape::XML::Node *copy = child->duplicate(doc->getReprDoc()); + repr_new->appendChild( copy ); + Inkscape::GC::release( copy ); + } + sp_gradient_repr_set_link(repr_new, NULL); } - return gr_new; } else { return gr; @@ -409,6 +427,8 @@ SPGradient *sp_gradient_reset_to_userspace(SPGradient *gr, SPItem *item) // IN SPMeshNodeArray::create() //sp_repr_set_svg_double(repr, "x", bbox->min()[Geom::X]); //sp_repr_set_svg_double(repr, "y", bbox->min()[Geom::Y]); + + // We don't create a shared array gradient. SPMeshGradient* mg = SP_MESHGRADIENT( gr ); mg->array.create( mg, item, bbox ); } @@ -434,14 +454,14 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar return gr; } - // FIXME Transforming a mesh gradient is more complicated... probably need to add function to SPMeshArray.wq - if ( gr && SP_IS_MESHGRADIENT( gr ) ) { - return gr; - } - // First, fork it if it is shared - gr = sp_gradient_fork_private_if_necessary(gr, gr->getVector(), - SP_IS_RADIALGRADIENT(gr) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, item); + if (SP_IS_LINEARGRADIENT(gr)) { + gr = sp_gradient_fork_private_if_necessary(gr, gr->getVector(), SP_GRADIENT_TYPE_LINEAR, item); + } else if (SP_IS_RADIALGRADIENT(gr)) { + gr = sp_gradient_fork_private_if_necessary(gr, gr->getVector(), SP_GRADIENT_TYPE_RADIAL, item); + } else { + gr = sp_gradient_fork_private_if_necessary(gr, gr->getArray(), SP_GRADIENT_TYPE_MESH, item); + } if (gr->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { @@ -495,7 +515,24 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar // as to cancel it out when it's applied to the gradient during rendering Geom::Affine point_convert = bbox2user * skew.inverse(); - if (SP_IS_RADIALGRADIENT(gr)) { + if (SP_IS_LINEARGRADIENT(gr)) { + SPLinearGradient *lg = SP_LINEARGRADIENT(gr); + + Geom::Point p1_b = Geom::Point(lg->x1.computed, lg->y1.computed); + Geom::Point p2_b = Geom::Point(lg->x2.computed, lg->y2.computed); + + Geom::Point p1_u = p1_b * point_convert; + Geom::Point p2_u = p2_b * point_convert; + + sp_repr_set_svg_double(repr, "x1", p1_u[Geom::X]); + sp_repr_set_svg_double(repr, "y1", p1_u[Geom::Y]); + sp_repr_set_svg_double(repr, "x2", p2_u[Geom::X]); + sp_repr_set_svg_double(repr, "y2", p2_u[Geom::Y]); + + // set the gradientUnits + repr->setAttribute("gradientUnits", "userSpaceOnUse"); + + } else if (SP_IS_RADIALGRADIENT(gr)) { SPRadialGradient *rg = SP_RADIALGRADIENT(gr); // original points in the bbox coords @@ -514,23 +551,12 @@ SPGradient *sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar sp_repr_set_svg_double(repr, "fy", f_u[Geom::Y]); sp_repr_set_svg_double(repr, "r", r_u); - } else { - SPLinearGradient *lg = SP_LINEARGRADIENT(gr); + // set the gradientUnits + repr->setAttribute("gradientUnits", "userSpaceOnUse"); - Geom::Point p1_b = Geom::Point(lg->x1.computed, lg->y1.computed); - Geom::Point p2_b = Geom::Point(lg->x2.computed, lg->y2.computed); - - Geom::Point p1_u = p1_b * point_convert; - Geom::Point p2_u = p2_b * point_convert; - - sp_repr_set_svg_double(repr, "x1", p1_u[Geom::X]); - sp_repr_set_svg_double(repr, "y1", p1_u[Geom::Y]); - sp_repr_set_svg_double(repr, "x2", p2_u[Geom::X]); - sp_repr_set_svg_double(repr, "y2", p2_u[Geom::Y]); + } else { + std::cerr << "sp_gradient_convert_to_userspace: Conversion of mesh to userspace not implemented" << std::endl; } - - // set the gradientUnits - repr->setAttribute("gradientUnits", "userSpaceOnUse"); } // apply the gradient to the item (may be necessary if we forked it); not recursive @@ -1281,10 +1307,10 @@ in desktop coordinates. */ Geom::Point getGradientCoords(SPItem *item, GrPointType point_type, guint point_i, Inkscape::PaintTarget fill_or_stroke) { + SPGradient *gradient = getGradient(item, fill_or_stroke); #ifdef SP_GR_VERBOSE - g_message("getGradientCoords(%p, %d, %d, %d)", item, point_type, point_i, fill_or_stroke); + g_message("getGradientCoords(%p, %d, %d, %d, %p)", item, point_type, point_i, fill_or_stroke, gradient); #endif - SPGradient *gradient = getGradient(item, fill_or_stroke); Geom::Point p (0, 0); -- cgit v1.2.3 From caa14088e66284be4944ea282175958bd384044e Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Thu, 17 Nov 2016 12:28:29 +0100 Subject: Do not return invalid vector gradient when switching from mesh to linear/radial gradient. (bzr r15254) --- src/gradient-chemistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gradient-chemistry.cpp') diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp index c133bfa7c..05f594f86 100644 --- a/src/gradient-chemistry.cpp +++ b/src/gradient-chemistry.cpp @@ -1583,7 +1583,7 @@ SPGradient *sp_gradient_vector_for_object( SPDocument *const doc, SPDesktop *con SPIPaint const &paint = ( (fill_or_stroke == Inkscape::FOR_FILL) ? style.fill : style.stroke ); if (paint.isPaintserver()) { SPObject *server = (fill_or_stroke == Inkscape::FOR_FILL) ? o->style->getFillPaintServer() : o->style->getStrokePaintServer(); - if ( SP_IS_GRADIENT(server) ) { + if ( SP_IS_LINEARGRADIENT(server) || SP_IS_RADIALGRADIENT(server) ) { return SP_GRADIENT(server)->getVector(true); } else { color = sp_desktop_get_color(desktop, (fill_or_stroke == Inkscape::FOR_FILL)); -- cgit v1.2.3