index 486d38167f5e0e55bdbe8ff10aec94f8725f3718..9fade37ecdcb042f5b430aad95b9989a6ccfc84d 100644 (file)
#include "sp-text.h"
#include "sp-tspan.h"
#include <libnr/nr-matrix-fns.h>
+#include <libnr/nr-point-fns.h>
#include "xml/repr.h"
#include "svg/svg.h"
#include "svg/svg-color.h"
#include "svg/css-ostringstream.h"
+#include "prefs-utils.h"
// Terminology:
/* If gr hrefs some other gradient, remove the href */
if (gr->ref->getObject()) {
/* We are hrefing someone, so require flattening */
- SP_OBJECT(gr)->updateRepr(((SPObject *) gr)->repr, SP_OBJECT_WRITE_EXT | SP_OBJECT_WRITE_ALL);
+ SP_OBJECT(gr)->updateRepr(SP_OBJECT_WRITE_EXT | SP_OBJECT_WRITE_ALL);
sp_gradient_repr_set_link(SP_OBJECT_REPR(gr), NULL);
}
SPGradient *
sp_gradient_fork_vector_if_necessary (SPGradient *gr)
{
+ // Some people actually prefer their gradient vectors to be shared...
+ if (prefs_get_int_attribute("options.forkgradientvectors", "value", 1) == 0)
+ return gr;
+
if (SP_OBJECT_HREFCOUNT(gr) > 1) {
SPDocument *doc = SP_OBJECT_DOCUMENT(gr);
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
@@ -361,7 +367,7 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop
* transformation from bounding box space to user space.
*/
NR::Matrix skew = bbox2user;
- double exp = skew.expansion();
+ double exp = NR::expansion(skew);
skew[0] /= exp;
skew[1] /= exp;
skew[2] /= exp;
@@ -392,7 +398,7 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop
// converted points in userspace coords
NR::Point c_u = c_b * point_convert;
NR::Point f_u = f_b * point_convert;
- double r_u = r_b * point_convert.expansion();
+ double r_u = r_b * NR::expansion(point_convert);
sp_repr_set_svg_double(repr, "cx", c_u[NR::X]);
sp_repr_set_svg_double(repr, "cy", c_u[NR::Y]);
sp_get_stop_i(SPGradient *gradient, guint stop_i)
{
SPStop *stop = sp_first_stop (gradient);
+
+ // if this is valid but weird gradient without an offset-zero stop element,
+ // inkscape has created a handle for the start of gradient anyway,
+ // so when it asks for stop N that corresponds to stop element N-1
+ if (stop->offset != 0)
+ stop_i --;
for (guint i=0; i < stop_i; i++) {
if (!stop) return NULL;
}
-// FIXME: make general global function
-static double
-get_offset_between_points (NR::Point p, NR::Point begin, NR::Point end)
-{
- double length = NR::L2(end - begin);
- NR::Point be = (end - begin) / length;
- double r = NR::dot(p - begin, be);
-
- if (r < 0.0) return 0.0;
- if (r > length) return 1.0;
-
- return (r / length);
-}
-
-
/**
Set the position of point point_type of the gradient applied to item (either fill_or_stroke) to
p_w (in desktop coordinates). Write_repr if you want the change to become permanent.
@@ -827,7 +824,7 @@ sp_item_gradient_set_coords (SPItem *item, guint point_type, guint point_i, NR::
gradient = sp_gradient_convert_to_userspace (gradient, item, fill_or_stroke? "fill" : "stroke");
- NR::Matrix i2d = sp_item_i2d_affine (item);
+ NR::Matrix i2d = from_2geom(sp_item_i2d_affine (item));
NR::Point p = p_w * i2d.inverse();
p *= (gradient->gradientTransform).inverse();
// now p is in gradient's original coordinates
@@ -1104,7 +1101,7 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool
bbox->min()[NR::X], bbox->min()[NR::Y]);
}
}
- p *= NR::Matrix(gradient->gradientTransform) * sp_item_i2d_affine(item);
+ p *= NR::Matrix(gradient->gradientTransform) * from_2geom(sp_item_i2d_affine(item));
return p;
}