gegl r2273 - in trunk: . gegl/property-types



Author: ok
Date: Mon May  5 21:46:04 2008
New Revision: 2273
URL: http://svn.gnome.org/viewvc/gegl?rev=2273&view=rev

Log:
* gegl/property-types/gegl-vector.[ch]: ported to use floating point
instead of fixedpoint/integer for coordinates. Initial port of brush
stamping core from horizon for a gegl_vector_stroke method.


Modified:
   trunk/ChangeLog
   trunk/gegl/property-types/gegl-vector.c
   trunk/gegl/property-types/gegl-vector.h

Modified: trunk/gegl/property-types/gegl-vector.c
==============================================================================
--- trunk/gegl/property-types/gegl-vector.c	(original)
+++ trunk/gegl/property-types/gegl-vector.c	Mon May  5 21:46:04 2008
@@ -25,9 +25,12 @@
 
 #include "gegl-types.h"
 
+#include "gegl-buffer-private.h"
 #include "gegl-vector.h"
 #include "gegl-color.h"
 
+
+
 /* ###################################################################### */
 /* path code copied from horizon */
 
@@ -51,8 +54,8 @@
 
 typedef struct Point
 {
-  gint x;
-  gint y;
+  gfloat x;
+  gfloat y;
 } Point;
 
 struct _Path
@@ -62,45 +65,71 @@
   gchar  type;
 };
 
+
+
 typedef struct _Path Head;
 
+typedef struct _GeglVectorPrivate GeglVectorPrivate;
+typedef struct _VectorNameEntity  VectorNameEntity;
 
-/*** fixed point subdivision bezier ***/
+struct _GeglVectorPrivate
+{
+  Path *path;
+
+  Path *axis[8];
+  gint  n_axes;
+};
+
+enum
+{
+  PROP_0,
+};
+
+
+enum
+{
+  GEGL_VECTOR_CHANGED,
+  GEGL_VECTOR_LAST_SIGNAL
+};
+
+guint gegl_vector_signals[GEGL_VECTOR_LAST_SIGNAL] = { 0 };
+
+
+static void finalize     (GObject      *self);
+static void set_property (GObject      *gobject,
+                          guint         prop_id,
+                          const GValue *value,
+                          GParamSpec   *pspec);
+static void get_property (GObject      *gobject,
+                          guint         prop_id,
+                          GValue       *value,
+                          GParamSpec   *pspec);
+
+G_DEFINE_TYPE (GeglVector, gegl_vector, G_TYPE_OBJECT);
+
+#define GEGL_VECTOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),\
+                                   GEGL_TYPE_VECTOR, GeglVectorPrivate))
+
+
+/*** subdivision bezier approximation: ***/
 
 /* linear interpolation between two point */
 static void
 lerp (Point *dest,
       Point *a,
       Point *b,
-      gint   t)
-{
-  dest->x = a->x + (b->x-a->x) * t / 65536;
-  dest->y = a->y + (b->y-a->y) * t / 65536;
-}
-
-#define iter1(N) \
-    try = root + (1 << (N)); \
-    if (n >= try << (N))   \
-    {   n -= try << (N);   \
-        root |= 2 << (N); \
-    }
-
-static inline guint isqrt (guint n)
+      gfloat   t)
 {
-    guint root = 0, try;
-    iter1 (15);    iter1 (14);    iter1 (13);    iter1 (12);
-    iter1 (11);    iter1 (10);    iter1 ( 9);    iter1 ( 8);
-    iter1 ( 7);    iter1 ( 6);    iter1 ( 5);    iter1 ( 4);
-    iter1 ( 3);    iter1 ( 2);    iter1 ( 1);    iter1 ( 0);
-    return root >> 1;
+  dest->x = a->x + (b->x-a->x) * t;
+  dest->y = a->y + (b->y-a->y) * t;
 }
 
-static gint
+static gfloat
 point_dist (Point *a,
             Point *b)
 {
-  return isqrt ((a->x-b->x)*(a->x-b->x) +
-                (a->y-b->y)*(a->y-b->y));
+  return sqrt ((a->x-b->x)*(a->x-b->x) +
+               (a->y-b->y)*(a->y-b->y));
 }
 
 
@@ -112,7 +141,7 @@
 static void
 bezier (Point **curve,
         Point *dest,
-        gint   t)
+        gfloat t)
 {
   Point ab,bc,cd,abbc,bccd;
 
@@ -153,10 +182,10 @@
  */
 
 static Path *
-path_add (Path *head,
-          gchar type,
-          gint  x,
-          gint  y)
+path_add (Path   *head,
+          gchar   type,
+          gfloat  x,
+          gfloat  y)
 {
   Path *iter = head;
   Path *prev = NULL;
@@ -264,6 +293,7 @@
 
         { /* create piecevise linear approximation of bezier curve */
            gint   i;
+           gfloat f;
            Point  foo[4];
            Point *pts[4];
 
@@ -274,11 +304,11 @@
                pts[i]->y = curve[i]->point.y;
              }
 
-           for (i=0;i<65536;i+=65536 / BEZIER_SEGMENTS)
+           for (f=0; f<1.0; f += 1.0 / BEZIER_SEGMENTS)
              {
                 Point iter;
 
-                bezier (pts, &iter, i);
+                bezier (pts, &iter, f);
 
                 head = path_add (head, 'l', iter.x, iter.y);
              }
@@ -322,31 +352,31 @@
 }
 
 static Path *
-path_move_to (Path *path,
-              gint  x,
-              gint  y)
+path_move_to (Path   *path,
+              gfloat  x,
+              gfloat  y)
 {
   path = path_add (path, 'm', x, y);
   return path;
 }
 
 static Path *
-path_line_to (Path *path,
-              gint  x,
-              gint  y)
+path_line_to (Path   *path,
+              gfloat  x,
+              gfloat  y)
 {
   path = path_add (path, 'l', x, y);
   return path;
 }
 
 static Path *
-path_curve_to (Path *path,
-               gint  x1,
-               gint  y1,
-               gint  x2,
-               gint  y2,
-               gint  x3,
-               gint  y3)
+path_curve_to (Path   *path,
+               gfloat  x1,
+               gfloat  y1,
+               gfloat  x2,
+               gfloat  y2,
+               gfloat  x3,
+               gfloat  y3)
 {
   path = path_add (path, 'c', x1, y1);
   path = path_add (path, '.', x2, y2);
@@ -355,29 +385,29 @@
 }
 
 static Path *
-path_rel_move_to (Path *path,
-                  gint  x,
-                  gint  y)
+path_rel_move_to (Path   *path,
+                  gfloat  x,
+                  gfloat  y)
 {
   return path_move_to (path, path->point.x + x, path->point.y + y);
 }
 
 static Path *
-path_rel_line_to (Path *path,
-                  gint  x,
-                  gint  y)
+path_rel_line_to (Path   *path,
+                  gfloat  x,
+                  gfloat  y)
 {
   return path_line_to (path, path->point.x + x, path->point.y + y);
 }
 
 static Path *
-path_rel_curve_to (Path *path,
-                   gint  x1,
-                   gint  y1,
-                   gint  x2,
-                   gint  y2,
-                   gint  x3,
-                   gint  y3)
+path_rel_curve_to (Path   *path,
+                   gfloat  x1,
+                   gfloat  y1,
+                   gfloat  x2,
+                   gfloat  y2,
+                   gfloat  x3,
+                   gfloat  y3)
 {
   return path_curve_to (path,
                         path->point.x + x1, path->point.y + y1,
@@ -507,6 +537,8 @@
         buf[i*4+3] = col[3];
       }
 
+    if (gegl_buffer_is_shared (buffer))
+    while (!gegl_buffer_try_lock (buffer));
     for (i=0; i < extent.height; i++)
       {
         GSList *iter = scanlines[i];
@@ -530,46 +562,122 @@
         if (scanlines[i])
           g_slist_free (scanlines[i]);
       }
+    if (gegl_buffer_is_shared (buffer))
+    gegl_buffer_unlock (buffer);
     g_free (buf);
 }
   }
 
 }
 
-void gegl_vector_stroke (GeglBuffer *buffer,
-                         GeglVector *vector,
-                         GeglColor  *color,
-                         gdouble     linewidth,
-                         gint        linecap,
-                         gint        linejoin)
-{
-
-}
+typedef struct StampStatic {
+  gboolean  valid;
+  Babl     *format;
+  gfloat   *buf;
+  gdouble   radius;
+}StampStatic;
+
+void gegl_vector_stamp (GeglBuffer *buffer,
+                        gdouble     x,
+                        gdouble     y,
+                        gdouble     radius,
+                        gdouble     hardness,
+                        GeglColor  *color);
+
+void gegl_vector_stamp (GeglBuffer *buffer,
+                        gdouble     x,
+                        gdouble     y,
+                        gdouble     radius,
+                        gdouble     hardness,
+                        GeglColor  *color)
+{
+  const gfloat *col = gegl_color_float4 (color);
+  static StampStatic s = {FALSE,}; /* XXX: 
+                                      we will ultimately leak the last valid
+                                      cached brush. */
+
+  GeglRectangle roi = {floor(x-radius),
+                       floor(y-radius),
+                       ceil (x+radius) - floor (x-radius),
+                       ceil (y+radius) - floor (y-radius)};
+
+  if (s.format == NULL)
+    s.format = babl_format ("RGBA float");
+  if (s.buf == NULL ||
+      s.radius != radius)
+    {
+      if (s.buf != NULL)
+        g_free (s.buf);
+      s.buf = g_malloc (4*4* roi.width * roi.height);
+      s.radius = radius;
+      s.valid = TRUE;  
+    }
+  g_assert (s.buf);
 
-#if 0
+  gegl_buffer_get (buffer, 1.0, &roi, s.format, s.buf, 0);
 
-/* drawing code follows */
+  {
+    gint u, v;
+    gint i=0;
 
-#include "canvas/canvas.h"
-#include "brush.h"
-#include "tools/tool_library.h"
+    gfloat radius_squared = radius * radius;
+    gfloat inner_radius_squared = (radius * hardness)*(radius * hardness);
+    gfloat soft_range = radius_squared - inner_radius_squared;
 
-/* code to stroke with a specified tool */
+    for (u= roi.x; u < roi.x + roi.width; u++)
+      for (v= roi.y; v < roi.y + roi.height ; v++)
+        {
+          gfloat o = (u-x) * (u-x) + (v-y) * (v-y);
 
-void
-path_stroke_tool (Path   *path,
-                  Canvas *canvas,
-                  Tool   *tool)
-{
-  Path *iter = path;
-  gint traveled_length = 0;
-  gint need_to_travel = 0;
-  gint x = 0,y = 0;
+          if (o < inner_radius_squared)
+             o = col[3];
+          else if (o < radius_squared)
+            {
+              o = (1.0 - (o-inner_radius_squared) / (soft_range)) * col[3];
+            }
+          else
+            {
+              o=0.0;
+            }
+         if (o!=0.0)
+           {
+             gint c;
+             for (c=0;c<4;c++)
+               s.buf[i*4+c] = (s.buf[i*4+c] * (1.0-o) + col[c] * o);
+             /*s.buf[i*4+3] = s.buf[i*4+3] + o * (1.0-o);*/
+           }
+         i++;
+        }
+  }
+  gegl_buffer_set (buffer, &roi, s.format, s.buf, 0);
+}
 
-  if (!tool)
-    tool = lookup_tool ("Paint");
 
+void gegl_vector_stroke (GeglBuffer *buffer,
+                         GeglVector *vector,
+                         GeglColor  *color,
+                         gdouble     linewidth,
+                         gdouble     hardness)
+{
+  GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (vector);
+  gfloat traveled_length = 0;
+  gfloat need_to_travel = 0;
+  gfloat x = 0,y = 0;
   gboolean had_move_to = FALSE;
+  Path *iter = priv->path;
+  gdouble       xmin, xmax, ymin, ymax;
+  GeglRectangle extent;
+
+  gegl_vector_get_bounds (vector, &xmin, &xmax, &ymin, &ymax);
+  extent.x = floor (xmin);
+  extent.y = floor (ymin);
+  extent.width = ceil (xmax) - extent.x;
+  extent.height = ceil (ymax) - extent.y;
+
+  if (gegl_buffer_is_shared (buffer))
+  while (!gegl_buffer_try_lock (buffer));
+
+  gegl_buffer_clear (buffer, &extent);
 
   while (iter)
     {
@@ -586,13 +694,13 @@
           case 'l':
             {
               Point a,b;
-              ToolSetting *ts = tool_with_brush_get_toolsetting (tool);
 
-              gint spacing;
-              gint local_pos;
-              gint distance;
-              gint offset;
-              gint leftover;
+              gfloat spacing;
+              gfloat local_pos;
+              gfloat distance;
+              gfloat offset;
+              gfloat leftover;
+              gfloat radius = linewidth / 2.0;
 
 
               a.x = x;
@@ -601,10 +709,7 @@
               b.x = iter->point.x;
               b.y = iter->point.y;
 
-              spacing = ts->spacing * (ts->radius * MAX_RADIUS / 65536) / 65536;
-
-              if (spacing < MIN_SPACING * SPP / 65536)
-                spacing = MIN_SPACING * SPP / 65536;
+              spacing = 0.2 * radius;
 
               distance = point_dist (&a, &b);
 
@@ -619,18 +724,17 @@
                      local_pos += spacing)
                   {
                     Point spot;
-                    gint ratio = 65536 * local_pos / distance;
-                    gint radius;
+                    gfloat ratio = local_pos / distance;
+                    gfloat radius = linewidth / 2;
+                                 /* horizon used to refetch the radius
+                                  * for each step from the tool, to be
+                                  * able to have variable line width
+                                  */
 
                     lerp (&spot, &a, &b, ratio);
 
-                    radius = ts->radius  * MAX_RADIUS  / 65536,
-
-                    canvas_stamp (canvas,
-                      spot.x, spot.y, radius,
-                      ts->opacity * MAX_OPACITY / 65536,
-                      ts->hardness,
-                      ts->red, ts->green, ts->blue);
+                    gegl_vector_stamp (buffer,
+                      spot.x, spot.y, radius, hardness, color);
 
                     traveled_length += spacing;
                   }
@@ -653,98 +757,11 @@
         }
       iter=iter->next;
     }
-}
 
-extern Tool *tool_paint_new ();
-
-static Tool *path_tool (Path *path)
-{
-  Head *head = (Head*)path;
-  if (!head)
-    return NULL;
-  if (head->tool == NULL)
-    head->tool = tool_paint_new ();
-  return head->tool;
+  if (gegl_buffer_is_shared (buffer))
+  gegl_buffer_unlock (buffer);
 }
 
-void
-path_set_line_width (Path *path,
-                     gint  line_width)
-{
-  ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
-  ts->radius = line_width / 2;
-}
-
-void
-path_set_rgba (Path *path,
-               gint  red,
-               gint  green,
-               gint  blue,
-               gint  alpha)
-{
-  ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
-  ts->red   = red;
-  ts->green = green;
-  ts->blue  = blue;
-  ts->opacity = alpha;
-}
-
-void
-path_set_hardness (Path *path,
-                   gint  hardness)
-{
-  ToolSetting *ts = tool_with_brush_get_toolsetting (path_tool (path));
-  ts->hardness = hardness;
-}
-
-void
-path_stroke (Path   *path,
-             Canvas *canvas)
-{
-  path_stroke_tool (path, canvas, path_tool (path));
-}
-#endif
-
-/* ###################################################################### */
-
-
-
-enum
-{
-  PROP_0,
-};
-
-typedef struct _GeglVectorPrivate GeglVectorPrivate;
-typedef struct _VectorNameEntity  VectorNameEntity;
-
-struct _GeglVectorPrivate
-{
-  Path *path;
-};
-
-enum
-{
-  GEGL_VECTOR_CHANGED,
-  GEGL_VECTOR_LAST_SIGNAL
-};
-
-guint gegl_vector_signals[GEGL_VECTOR_LAST_SIGNAL] = { 0 };
-
-
-static void finalize     (GObject      *self);
-static void set_property (GObject      *gobject,
-                          guint         prop_id,
-                          const GValue *value,
-                          GParamSpec   *pspec);
-static void get_property (GObject      *gobject,
-                          guint         prop_id,
-                          GValue       *value,
-                          GParamSpec   *pspec);
-
-G_DEFINE_TYPE (GeglVector, gegl_vector, G_TYPE_OBJECT);
-
-#define GEGL_VECTOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),\
-                                   GEGL_TYPE_VECTOR, GeglVectorPrivate))
 
 static void
 gegl_vector_init (GeglVector *self)
@@ -867,9 +884,11 @@
                       gdouble     y3)
 {
   GeglVectorPrivate *priv;
+  g_print ("foo\n");
   priv = GEGL_VECTOR_GET_PRIVATE (self);
   priv->path = path_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
   gegl_vector_emit_changed (self);
+  g_print ("bar\n");
 }
 
 
@@ -916,8 +935,8 @@
 {
   GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
   Path *iter = priv->path;
-  gint traveled_length = 0;
-  gint x = 0, y = 0;
+  gfloat traveled_length = 0;
+  gfloat x = 0, y = 0;
 
   while (iter)
     {
@@ -930,7 +949,7 @@
           case 'l':
             {
               Point a,b;
-              gint distance;
+              gfloat distance;
 
               a.x = x;
               a.y = y;
@@ -1001,9 +1020,9 @@
 {
   GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
   Path *iter = priv->path;
-  gint traveled_length = 0;
-  gint need_to_travel = 0;
-  gint x = 0, y = 0;
+  gfloat traveled_length = 0;
+  gfloat need_to_travel = 0;
+  gfloat x = 0, y = 0;
 
   gboolean had_move_to = FALSE;
 
@@ -1023,11 +1042,11 @@
             {
               Point a,b;
 
-              gint spacing;
-              gint local_pos;
-              gint distance;
-              gint offset;
-              gint leftover;
+              gfloat spacing;
+              gfloat local_pos;
+              gfloat distance;
+              gfloat offset;
+              gfloat leftover;
 
 
               a.x = x;
@@ -1036,7 +1055,7 @@
               b.x = iter->point.x;
               b.y = iter->point.y;
 
-              spacing = 10;
+              spacing = 0.2;
 
               distance = point_dist (&a, &b);
 
@@ -1051,7 +1070,7 @@
                      local_pos += spacing)
                   {
                     Point spot;
-                    gint ratio = 65536 * local_pos / distance;
+                    gfloat ratio = local_pos / distance;
 
                     lerp (&spot, &a, &b, ratio);
 

Modified: trunk/gegl/property-types/gegl-vector.h
==============================================================================
--- trunk/gegl/property-types/gegl-vector.h	(original)
+++ trunk/gegl/property-types/gegl-vector.h	Mon May  5 21:46:04 2008
@@ -121,8 +121,7 @@
                          GeglVector *vector,
                          GeglColor  *color,
                          gdouble     linewidth,
-                         gint        linecap,
-                         gint        linejoin);
+                         gdouble     hardness);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]