gegl r2820 - in trunk: . gegl gegl/property-types operations/external



Author: ok
Date: Sat Dec  6 14:30:53 2008
New Revision: 2820
URL: http://svn.gnome.org/viewvc/gegl?rev=2820&view=rev

Log:
Added a transform property to the path op, that allows specifying a
transformation matrix to be applied when flattening the path.
* gegl/gegl-matrix.[ch]: (gegl_matrix3_parse_string),
(gegl_matrix3_to_string): added functions that parse from svg style
transforms, as well as serializes to that format.
* gegl/property-types/gegl-path.[ch]: (transform_data), (flatten_nop),
(flatten_copy), (flatten_rel_copy), (bezier2), (flatten_curve),
(gegl_path_list_flatten), (gegl_path_get_matrix),
(gegl_path_set_matrix), (ensure_flattened), (gegl_path_init),
(gegl_path_get_n_nodes): added a transform property to the path, this
transform is applied at the flattening stage of rendering paths.
* operations/external/path.c: (prepare), (get_bounding_box),
(gegl_path_is_closed), (process), (gegl_chant_class_init): add
transform property.


Modified:
   trunk/ChangeLog
   trunk/gegl/gegl-matrix.c
   trunk/gegl/gegl-matrix.h
   trunk/gegl/property-types/gegl-path.c
   trunk/gegl/property-types/gegl-path.h
   trunk/operations/external/path.c

Modified: trunk/gegl/gegl-matrix.c
==============================================================================
--- trunk/gegl/gegl-matrix.c	(original)
+++ trunk/gegl/gegl-matrix.c	Sat Dec  6 14:30:53 2008
@@ -22,6 +22,21 @@
 
 #include "gegl-matrix.h"
 
+
+void gegl_matrix3_debug (GeglMatrix3 matrix)
+{
+  if (matrix)
+    {
+      gchar *str = gegl_matrix3_to_string (matrix);
+      g_print("%s\n", str);
+      g_free (str);
+    }
+  else
+    {
+      g_print("NULL matrix\n");
+    }
+}
+
 void
 gegl_matrix3_identity (GeglMatrix3 matrix)
 {
@@ -184,6 +199,7 @@
 gegl_matrix3_parse_string (GeglMatrix3  matrix,
                            const gchar *string)
 {
+  gegl_matrix3_identity (matrix);
   if (strstr (string, "translate"))
     {
       gchar *p = strchr (string, '(');
@@ -210,19 +226,40 @@
       if (!p) return;
       p++;
 
-      /* last row should always be this for affine transforms */
-      matrix[0][2] = matrix[1][2] = 0;
-      matrix[2][2] = 1;
 
       for (i=0;i<3;i++)
         for (j=0;j<2;j++)
           {
             a = strtod(p, &p);
-            matrix [i][j] = a;
+            matrix [j][i] = a;
+            g_print ("%f\n", a);
             if (!p) return;
-            p = strchr (string, ',');
+            p = strchr (p, ',');
             if (!p) return;
             p++;
           }
     }
 }
+
+gchar *gegl_matrix3_to_string (GeglMatrix3 matrix)
+{
+  gchar *res;
+  GString *str = g_string_new ("matrix(");
+  gint i, j;
+  gint a=0;
+
+  for (i=0;i<3;i++)
+    for (j=0;j<2;j++)
+      {
+        if (a!=0)
+          g_string_append (str, ",");
+        a=1;
+        g_string_append_printf (str, "%f", matrix[j][i]);
+      }
+  g_string_append (str, ")");
+  res = str->str;
+  g_string_free (str, FALSE);
+
+  g_print (",,.. %s ,....\n", res);
+  return res;
+}

Modified: trunk/gegl/gegl-matrix.h
==============================================================================
--- trunk/gegl/gegl-matrix.h	(original)
+++ trunk/gegl/gegl-matrix.h	Sat Dec  6 14:30:53 2008
@@ -19,12 +19,13 @@
                                          GeglMatrix3 right,
                                          GeglMatrix3 product);
 void       gegl_matrix3_originate       (GeglMatrix3 matrix,
-                                         gdouble x,
-                                         gdouble y);
-void       gegl_matrix3_transform_point (GeglMatrix3   matrix,
-                                         gdouble *x,
-                                         gdouble *y);
+                                         gdouble     x,
+                                         gdouble     y);
+void       gegl_matrix3_transform_point (GeglMatrix3 matrix,
+                                         gdouble    *x,
+                                         gdouble    *y);
 void       gegl_matrix3_parse_string    (GeglMatrix3 matrix,
                                          const gchar *string);
+gchar *    gegl_matrix3_to_string       (GeglMatrix3 matrix);
 
 #endif

Modified: trunk/gegl/property-types/gegl-path.c
==============================================================================
--- trunk/gegl/property-types/gegl-path.c	(original)
+++ trunk/gegl/property-types/gegl-path.c	Sat Dec  6 14:30:53 2008
@@ -65,16 +65,17 @@
   /* a flatten function pointer is kept for all stored InstructionInfo's but are only
    * used for the internal ones
    */
-  GeglPathList *(*flatten) (GeglPathList *head,
+  GeglPathList *(*flatten) (GeglMatrix3   matrix,
+                            GeglPathList *head,
                             GeglPathList *prev,
                             GeglPathList *self);
 } InstructionInfo;
 
 
-static GeglPathList *flatten_copy      (GeglPathList *head, GeglPathList *prev, GeglPathList *self);
-static GeglPathList *flatten_rel_copy  (GeglPathList *head, GeglPathList *prev, GeglPathList *self);
-static GeglPathList *flatten_nop       (GeglPathList *head, GeglPathList *prev, GeglPathList *self);
-static GeglPathList *flatten_curve     (GeglPathList *head, GeglPathList *prev, GeglPathList *self);
+static GeglPathList *flatten_copy      (GeglMatrix3 matrix, GeglPathList *head, GeglPathList *prev, GeglPathList *self);
+static GeglPathList *flatten_rel_copy  (GeglMatrix3 matrix, GeglPathList *head, GeglPathList *prev, GeglPathList *self);
+static GeglPathList *flatten_nop       (GeglMatrix3 matrix, GeglPathList *head, GeglPathList *prev, GeglPathList *self);
+static GeglPathList *flatten_curve     (GeglMatrix3 matrix, GeglPathList *head, GeglPathList *prev, GeglPathList *self);
 
 /* FIXME: handling of relative commands should be moved to the flattening stage */
 
@@ -106,6 +107,24 @@
   return NULL;
 }
 
+static void transform_data (
+ GeglMatrix3         matrix,
+ GeglPathItem       *dst
+                            )
+{
+  InstructionInfo *dst_info = lookup_instruction_info(dst->type);
+  gint i;
+
+  for (i=0;i<dst_info->pairs;i++)
+    {
+      gdouble x = dst->point[i].x;
+      gdouble y = dst->point[i].y;
+      gegl_matrix3_transform_point (matrix, &x, &y);
+      dst->point[i].x=x;
+      dst->point[i].y=y;
+    }
+}
+
 static void copy_data (const GeglPathItem *src,
                        GeglPathItem       *dst)
 {
@@ -177,25 +196,29 @@
   return head;
 }
 
-static GeglPathList *flatten_nop (GeglPathList *head,
+static GeglPathList *flatten_nop (GeglMatrix3   matrix,
+                                  GeglPathList *head,
                                   GeglPathList *prev,
                                   GeglPathList *self)
 {
   return head;
 }
 
-static GeglPathList *flatten_copy (GeglPathList *head,
+static GeglPathList *flatten_copy (GeglMatrix3   matrix,
+                                   GeglPathList *head,
                                    GeglPathList *prev,
                                    GeglPathList *self)
 {
   GeglPathList *newp;
   head = gegl_path_list_append_item (head, self->d.type, &newp, NULL);
   copy_data (&self->d, &newp->d);
+  transform_data (matrix, &newp->d);
   return head;
 }
 
 static GeglPathList *
-flatten_rel_copy (GeglPathList *head,
+flatten_rel_copy (GeglMatrix3   matrix,
+                  GeglPathList *head,
                   GeglPathList *prev,
                   GeglPathList *self)
 {
@@ -217,6 +240,7 @@
       case 'm': newp->d.type = 'M'; break;
       case 'c': newp->d.type = 'C'; break;
     }
+  transform_data (matrix, &newp->d);
   return head;
 }
 
@@ -231,7 +255,7 @@
   dest->y = a->y + (b->y-a->y) * t;
 }
 
-static gfloat
+static gdouble
 point_dist (Point *a,
             Point *b)
 {
@@ -240,19 +264,19 @@
 }
 
 static void
-bezier2 (GeglPathList  *prev,
-         GeglPathList  *curve,
+bezier2 (GeglPathItem  *prev,
+         GeglPathItem  *curve,
          Point *dest,
          gfloat t)
 {
   Point ab,bc,cd,abbc,bccd;
 
-  if (prev->d.type == 'c')
-    lerp (&ab, &prev->d.point[2], &curve->d.point[0], t);
+  if (prev->type == 'c')
+    lerp (&ab, &prev->point[2], &curve->point[0], t);
   else
-    lerp (&ab, &prev->d.point[0], &curve->d.point[0], t);
-  lerp (&bc, &curve->d.point[0], &curve->d.point[1], t);
-  lerp (&cd, &curve->d.point[1], &curve->d.point[2], t);
+    lerp (&ab, &prev->point[0], &curve->point[0], t);
+  lerp (&bc, &curve->point[0], &curve->point[1], t);
+  lerp (&cd, &curve->point[1], &curve->point[2], t);
   lerp (&abbc, &ab, &bc,t);
   lerp (&bccd, &bc, &cd,t);
   lerp (dest, &abbc, &bccd, t);
@@ -260,26 +284,33 @@
 
 
 
-static GeglPathList *flatten_curve (GeglPathList *head,
+static GeglPathList *flatten_curve (GeglMatrix3   matrix,
+                                    GeglPathList *head,
                                     GeglPathList *prev,
                                     GeglPathList *self)
 { /* create piecevise linear approximation of bezier curve */
   gfloat f;
+  Point res;
+  gchar buf[64]="C";
+
+  copy_data (&self->d, (void*)buf);
+  transform_data (matrix, (void*)buf);
 
   for (f=0; f<1.0; f += 1.0 / BEZIER_SEGMENTS)
     {
-      Point res;
-
-      bezier2 (prev, self, &res, f);
-
+      bezier2 (&prev->d, (void*)buf, &res, f);
       head = gegl_path_list_append (head, 'L', res.x, res.y);
     }
-  head = gegl_path_list_append (head, 'L', self->d.point[2].x, self->d.point[2].y);
+
+  res = ((GeglPathItem*)buf)->point[2];
+  head = gegl_path_list_append (head, 'L', res.x, res.y);
+
   return head;
 }
 
 static GeglPathList *
-gegl_path_list_flatten (GeglPathList *original)
+gegl_path_list_flatten (GeglMatrix3   matrix,
+                        GeglPathList *original)
 {
   GeglPathList *iter;
   GeglPathList *prev = NULL;
@@ -294,7 +325,7 @@
     {
       InstructionInfo *info = lookup_instruction_info (iter->d.type);
       if(info)
-        self = info->flatten (self, endp, iter);
+        self = info->flatten (matrix, self, endp, iter);
       if (!endp)
         endp = self;
       while (endp && endp->next)
@@ -613,6 +644,7 @@
 typedef struct _GeglPathPrivate GeglPathPrivate;
 typedef struct _PathNameEntity  PathNameEntity;
 
+
 struct _GeglPathPrivate
 {
   GeglPathList *path;
@@ -629,6 +661,7 @@
 
   GeglRectangle dirtied;
   GeglRectangle cached_extent;
+  GeglMatrix3   matrix;
   gint frozen;
 };
 
@@ -713,6 +746,30 @@
   gegl_path_emit_changed (path, NULL); /* expose a full changed */
 }
 
+void
+gegl_path_get_matrix (GeglPath    *path,
+                      GeglMatrix3  matrix)
+{
+  GeglPathPrivate *priv = GEGL_PATH_GET_PRIVATE (path);
+  gegl_matrix3_copy (matrix, priv->matrix);
+}
+
+void
+gegl_path_set_matrix (GeglPath    *path,
+                      GeglMatrix3  matrix)
+{
+  GeglPathPrivate *priv;
+  if (!path)
+    {
+      g_warning ("EEek! no path\n");
+      return;
+    }
+  priv = GEGL_PATH_GET_PRIVATE (path);
+  gegl_matrix3_copy (priv->matrix, matrix);
+  priv->flat_path_clean = FALSE;
+  priv->length_clean = FALSE;
+}
+
 static void ensure_flattened (GeglPath *vector)
 {
   GeglPathPrivate *priv = GEGL_PATH_GET_PRIVATE (vector);
@@ -737,7 +794,7 @@
         }
     }
 
-  priv->flat_path = gegl_path_list_flatten (path);
+  priv->flat_path = gegl_path_list_flatten (priv->matrix, path);
   if (path != priv->path)
     gegl_path_list_destroy (path);
   priv->flat_path_clean = TRUE;
@@ -750,14 +807,12 @@
                   gdouble      *xs,
                   gdouble      *ys);
 
-
-
-
 static void
 gegl_path_init (GeglPath *self)
 {
   GeglPathPrivate *priv;
   priv = GEGL_PATH_GET_PRIVATE (self);
+  gegl_matrix3_identity (priv->matrix);
 }
 
 static void
@@ -1212,9 +1267,13 @@
 gint
 gegl_path_get_n_nodes  (GeglPath *vector)
 {
-  GeglPathPrivate *priv = GEGL_PATH_GET_PRIVATE (vector);
+  GeglPathPrivate *priv;
   GeglPathList *iter;
   gint count=0;
+  if (!vector)
+    return 0;
+  priv = GEGL_PATH_GET_PRIVATE (vector);
+
   for (iter = priv->path; iter; iter=iter->next)
     {
       count ++;
@@ -1799,17 +1858,6 @@
 /**************************************/
 
 #if 0
-const GeglMatrix *gegl_path_get_matrix (GeglPath *vector)
-{
-}
-GeglMatrix gegl_path_set_matrix (GeglPath *vector,
-                                   const GeglMatrix *matrix)
-{
-}
-#endif
-
-
-#if 0
 static void gen_rect (GeglRectangle *r,
                       gdouble x1, gdouble y1, gdouble x2, gdouble y2)
 {

Modified: trunk/gegl/property-types/gegl-path.h
==============================================================================
--- trunk/gegl/property-types/gegl-path.h	(original)
+++ trunk/gegl/property-types/gegl-path.h	Sat Dec  6 14:30:53 2008
@@ -20,6 +20,7 @@
 #define __GEGL_PATH_H__
 
 #include <glib-object.h>
+#include <gegl-matrix.h>
 
 G_BEGIN_DECLS
 
@@ -71,7 +72,10 @@
 const GeglPathItem * gegl_path_get_node       (GeglPath    *path,
                                                gint         pos);
 gchar              * gegl_path_to_string      (GeglPath    *path);
-
+void                 gegl_path_get_matrix     (GeglPath    *path,
+                                               GeglMatrix3  matrix);
+void                 gegl_path_set_matrix     (GeglPath    *path,
+                                               GeglMatrix3  matrix);
 gdouble              gegl_path_closest_point  (GeglPath     *path,
                                                gdouble       x,
                                                gdouble       y,
@@ -201,12 +205,6 @@
 void gegl_path_add_flattener (GeglPathList *(*func) (GeglPathList *original));
 
 
-#if 0
-const GeglMatrix *gegl_path_get_matrix (GeglPath *path);
-GeglMatrix gegl_path_set_matrix (GeglPath *path,
-                                   const GeglMatrix *matrix);
-#endif
-
 #include <gegl-buffer.h>
 
 /* this can and should be the responsiblity of cairo */

Modified: trunk/operations/external/path.c
==============================================================================
--- trunk/operations/external/path.c	(original)
+++ trunk/operations/external/path.c	Sat Dec  6 14:30:53 2008
@@ -41,6 +41,9 @@
 gegl_chant_string (fill_rule,_("Fill rule."), "nonzero",
                              _("how to determine what to fill (nonzero|evenodd"))
 
+gegl_chant_string (transform,_("Transform"), "",
+                             _("svg style description of transform."))
+
 gegl_chant_double (fill_opacity, _("Fill opacity"),  -2.0, 2.0, 1.0,
                              _("The fill opacity to use."))
 
@@ -83,7 +86,14 @@
 static void
 prepare (GeglOperation *operation)
 {
+  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
   gegl_operation_set_format (operation, "output", babl_format ("RaGaBaA float"));
+  if (o->transform && o->transform[0] != '\0')
+    {
+      GeglMatrix3 matrix;
+      gegl_matrix3_parse_string (matrix, o->transform);
+      gegl_path_set_matrix (o->d, matrix);
+    }
 }
 
 static GeglRectangle
@@ -91,17 +101,42 @@
 {
   GeglChantO    *o       = GEGL_CHANT_PROPERTIES (operation);
   GeglRectangle  defined = { 0, 0, 512, 512 };
+  GeglRectangle *in_rect;
   gdouble        x0, x1, y0, y1;
 
+  in_rect =  gegl_operation_source_get_bounding_box (operation, "input");
+
   gegl_path_get_bounds (o->d, &x0, &x1, &y0, &y1);
   defined.x      = x0 - o->stroke_width/2;
   defined.y      = y0 - o->stroke_width/2;
   defined.width  = x1 - x0 + o->stroke_width;
   defined.height = y1 - y0 + o->stroke_width;
 
+  if (in_rect)
+    {
+      gegl_rectangle_bounding_box (&defined, &defined, in_rect);
+    }
+
   return defined;
 }
 
+static gboolean gegl_path_is_closed (GeglPath *path)
+{
+  const GeglPathItem *knot;
+
+  if (!path)
+    return FALSE;
+  knot = gegl_path_get_node (path, -1);
+  if (!knot)
+    return FALSE;
+  if (knot->type == 'z')
+    {
+      return TRUE;
+    }
+  return FALSE;
+}
+
+
 #if 0
 static GeglRectangle
 get_cached_region (GeglOperation *operation)
@@ -129,6 +164,8 @@
       gegl_buffer_clear (output, result);
     }
 
+
+
   if (o->fill_opacity > 0.0001 && o->fill)
     {
       gfloat r,g,b,a;
@@ -156,6 +193,19 @@
           gegl_path_cairo_play (o->d, cr);
           cairo_set_source_rgba (cr, r,g,b,a);
           cairo_fill (cr);
+
+#if 0
+    if (o->stroke_width > 0.1 && o->stroke_opacity > 0.0001)
+      {
+        gfloat r,g,b,a;
+        gegl_color_get_rgba (o->stroke, &r,&g,&b,&a);
+        a *= o->stroke_opacity;
+
+        cairo_set_line_width (cr, o->stroke_width);
+        cairo_stroke (cr);
+      }
+#endif
+
           gegl_buffer_linear_close (output, data);
         }
     }
@@ -260,6 +310,7 @@
   operation_class->get_bounding_box = get_bounding_box;
   operation_class->prepare = prepare;
   operation_class->detect = detect;
+  /*operation_class->no_cache = TRUE;*/
 
   operation_class->name        = "gegl:path";
   operation_class->categories  = "render";



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