Code

NR::Maybe => boost::optional
[inkscape.git] / src / gradient-chemistry.cpp
index 37b50eca019205c07945ca0a50e7622bb449b5bd..c6dd26712c10a17eb6e782dcf9358ac1852f76a9 100644 (file)
@@ -30,6 +30,7 @@
 #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"
@@ -74,7 +75,7 @@ sp_gradient_ensure_vector_normalized(SPGradient *gr)
     /* 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);
     }
 
@@ -280,7 +281,7 @@ sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item)
 
     // 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;
@@ -341,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],
@@ -366,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;
@@ -397,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]);
@@ -554,6 +555,12 @@ SPStop*
 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;  
@@ -803,21 +810,6 @@ sp_item_gradient_reverse_vector (SPItem *item, bool fill_or_stroke)
 }
 
 
-// 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.
@@ -832,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
@@ -1102,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) * from_2geom(sp_item_i2d_affine(item));
     return p;
 }