index df013fdfc95516ee08924d1ae08cc194bffc89d0..afbf1600944cbaef69ff4e1ab7461e8a9d860cfd 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);
// calculate the bbox of the item
sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item));
- NR::Maybe<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
+ boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
if ( !bbox || bbox->isEmpty() )
return gr;
@@ -336,7 +342,7 @@ sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *prop
// calculate the bbox of the item
sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item));
NR::Matrix bbox2user;
- NR::Maybe<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
+ boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
if ( bbox && !bbox->isEmpty() ) {
bbox2user = NR::Matrix(bbox->dimensions()[NR::X], 0,
0, bbox->dimensions()[NR::Y],
@@ -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;
return stop;
}
-static guint32
-average_color (guint32 c1, guint32 c2, gdouble p = 0.5)
+guint32
+average_color (guint32 c1, guint32 c2, gdouble p)
{
guint32 r = (guint32) (SP_RGBA32_R_U (c1) * (1 - p) + SP_RGBA32_R_U (c2) * p);
guint32 g = (guint32) (SP_RGBA32_G_U (c1) * (1 - p) + SP_RGBA32_G_U (c2) * p);
}
-// 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 (sp_item_i2d_affine (item));
NR::Point p = p_w * i2d.inverse();
p *= (gradient->gradientTransform).inverse();
// now p is in gradient's original coordinates
@@ -1097,14 +1094,14 @@ sp_item_gradient_get_coords (SPItem *item, guint point_type, guint point_i, bool
if (SP_GRADIENT(gradient)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) {
sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item));
- NR::Maybe<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
+ boost::optional<NR::Rect> bbox = item->getBounds(NR::identity()); // we need "true" bbox without item_i2d_affine
if (bbox) {
p *= NR::Matrix(bbox->dimensions()[NR::X], 0,
0, bbox->dimensions()[NR::Y],
bbox->min()[NR::X], bbox->min()[NR::Y]);
}
}
- p *= NR::Matrix(gradient->gradientTransform) * sp_item_i2d_affine(item);
+ p *= NR::Matrix(gradient->gradientTransform) * (NR::Matrix)sp_item_i2d_affine(item);
return p;
}