gegl r2820 - in trunk: . gegl gegl/property-types operations/external
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2820 - in trunk: . gegl gegl/property-types operations/external
- Date: Sat, 6 Dec 2008 14:30:53 +0000 (UTC)
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]