gegl r2619 - in trunk: . gegl/property-types
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2619 - in trunk: . gegl/property-types
- Date: Mon, 13 Oct 2008 22:26:33 +0000 (UTC)
Author: ok
Date: Mon Oct 13 22:26:32 2008
New Revision: 2619
URL: http://svn.gnome.org/viewvc/gegl?rev=2619&view=rev
Log:
* gegl/property-types/gegl-vector.c: keep an internal cached flattened
path.
Modified:
trunk/ChangeLog
trunk/gegl/property-types/gegl-vector.c
Modified: trunk/gegl/property-types/gegl-vector.c
==============================================================================
--- trunk/gegl/property-types/gegl-vector.c (original)
+++ trunk/gegl/property-types/gegl-vector.c Mon Oct 13 22:26:32 2008
@@ -492,14 +492,10 @@
gdouble *xs,
gdouble *ys)
{
- /* FIXME: flatten first */
gdouble length = path_get_length (path);
gint i;
for (i=0; i<num_samples; i++)
{
- /* FIXME: speed this up, combine with a "stroking" of the path
- * or even inlining for the fill case as well
- */
gdouble x, y;
path_calc (path, (i*1.0)/num_samples * length, &x, &y);
@@ -508,6 +504,52 @@
}
}
+static gdouble
+path_get_length (Path *path)
+{
+ Path *iter = path;
+ gfloat traveled_length = 0;
+ gfloat x = 0, y = 0;
+
+ while (iter)
+ {
+ switch (iter->d.type)
+ {
+ case 'M':
+ x = iter->d.point[0].x;
+ y = iter->d.point[0].y;
+ break;
+ case 'L':
+ {
+ Point a,b;
+ gfloat distance;
+
+ a.x = x;
+ a.y = y;
+
+ b.x = iter->d.point[0].x;
+ b.y = iter->d.point[0].y;
+
+ distance = point_dist (&a, &b);
+ traveled_length += distance;
+
+ x = b.x;
+ y = b.y;
+ }
+ break;
+ case 'u':
+ break;
+ case 's':
+ break;
+ default:
+ g_error ("can't compute length for instruction: %i\n", iter->d.type);
+ break;
+ }
+ iter=iter->next;
+ }
+ return traveled_length;
+}
+
/******************/
@@ -518,7 +560,9 @@
struct _GeglVectorPrivate
{
- Path *path;
+ Path *path;
+ Path *flat_path;
+ gboolean flat_path_clean;
Path *axis[8];
gint n_axes;
@@ -597,12 +641,24 @@
gegl_buffer_set (buffer, roi, format, buf, 0);
}
+static void ensure_flattened (GeglVector *vector)
+{
+ GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (vector);
+ if (priv->flat_path_clean)
+ return;
+ if (priv->flat_path)
+ path_destroy (priv->flat_path);
+ priv->flat_path = path_flatten (priv->path);
+ priv->flat_path_clean = TRUE;
+}
+
static void
path_calc_values (Path *path,
guint num_samples,
gdouble *xs,
gdouble *ys);
+
void gegl_vector_fill (GeglBuffer *buffer,
GeglVector *vector,
GeglColor *color,
@@ -611,14 +667,13 @@
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (vector);
gdouble xmin, xmax, ymin, ymax;
GeglRectangle extent;
- Path *flat_path;
gfloat horsub = AA;
gint versubi = horsub;
gfloat versub = versubi;
gint samples;
- flat_path = path_flatten (priv->path);
- samples = path_get_length (flat_path);
+ ensure_flattened (vector);
+ samples = path_get_length (priv->flat_path);
gegl_vector_get_bounds (vector, &xmin, &xmax, &ymin, &ymax);
extent.x = floor (xmin);
@@ -626,7 +681,6 @@
extent.width = ceil (xmax) - extent.x;
extent.height = ceil (ymax) - extent.y;
-
{
GSList *scanlines[extent.height * versubi];
@@ -641,7 +695,7 @@
gint lastline=-1;
gint lastdir=-2;
- path_calc_values (flat_path, samples, xs, ys);
+ path_calc_values (priv->flat_path, samples, xs, ys);
/* clear scanline intersection lists */
for (i=0; i < extent.height * versub; i++)
@@ -753,8 +807,6 @@
gegl_buffer_unlock (buffer);
}
}
- path_destroy (flat_path);
-
}
typedef struct StampStatic {
@@ -863,12 +915,13 @@
gfloat need_to_travel = 0;
gfloat x = 0,y = 0;
gboolean had_move_to = FALSE;
- Path *iter = priv->path;
+ Path *iter;
gdouble xmin, xmax, ymin, ymax;
GeglRectangle extent;
- /* FIXME: flatten path first */
+ ensure_flattened (vector);
+ iter = priv->flat_path;
gegl_vector_get_bounds (vector, &xmin, &xmax, &ymin, &ymax);
extent.x = floor (xmin);
extent.y = floor (ymin);
@@ -1013,6 +1066,8 @@
self = NULL;
if (priv->path)
path_destroy (priv->path);
+ if (priv->flat_path)
+ path_destroy (priv->flat_path);
priv = NULL;
G_OBJECT_CLASS (gegl_vector_parent_class)->finalize (gobject);
@@ -1053,7 +1108,7 @@
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
gegl_vector_init (self);
- priv = NULL;
+ priv->flat_path_clean = FALSE;
return self;
}
@@ -1100,6 +1155,7 @@
if (priv->path)
gegl_vector_emit_changed (self, &priv->dirtied);
+ priv->flat_path_clean = FALSE;
}
void
@@ -1111,6 +1167,7 @@
priv = GEGL_VECTOR_GET_PRIVATE (self);
priv->path = path_move_to (priv->path, x, y);
/*gegl_vector_emit_changed (self);*/
+ priv->flat_path_clean = FALSE;
}
void
@@ -1126,6 +1183,7 @@
priv = GEGL_VECTOR_GET_PRIVATE (self);
priv->path = path_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
/*gegl_vector_emit_changed (self);*/
+ priv->flat_path_clean = FALSE;
}
@@ -1137,6 +1195,7 @@
GeglVectorPrivate *priv;
priv = GEGL_VECTOR_GET_PRIVATE (self);
gegl_vector_line_to (self, priv->path->d.point[0].x + x, priv->path->d.point[0].y + y);
+ priv->flat_path_clean = FALSE;
}
void
@@ -1148,6 +1207,7 @@
priv = GEGL_VECTOR_GET_PRIVATE (self);
priv->path = path_rel_move_to (priv->path, x, y);
/* gegl_vector_emit_changed (self);*/
+ priv->flat_path_clean = FALSE;
}
void
@@ -1165,136 +1225,15 @@
priv->path->d.point[0].x + x1, priv->path->d.point[0].y + y1,
priv->path->d.point[0].x + x2, priv->path->d.point[0].y + y2,
priv->path->d.point[0].x + x3, priv->path->d.point[0].y + y3);
-}
-
-static gdouble
-path_get_length (Path *path)
-{
- Path *iter = path;
- gfloat traveled_length = 0;
- gfloat x = 0, y = 0;
-
- while (iter)
- {
- switch (iter->d.type)
- {
- case 'M':
- x = iter->d.point[0].x;
- y = iter->d.point[0].y;
- break;
- case 'C':
- {
- Point a,b;
- gfloat distance;
- g_print ("eeek computing distance of c\n");
-
- a.x = x;
- a.y = y;
-
- b.x = iter->d.point[2].x;
- b.y = iter->d.point[2].y;
-
- distance = point_dist (&a, &b);
- traveled_length += distance;
-
- x = b.x;
- y = b.y;
- }
- break;
- case 'L':
- {
- Point a,b;
- gfloat distance;
-
- a.x = x;
- a.y = y;
-
- b.x = iter->d.point[0].x;
- b.y = iter->d.point[0].y;
-
- distance = point_dist (&a, &b);
- traveled_length += distance;
-
- x = b.x;
- y = b.y;
- }
- break;
- case 'u':
- break;
- case 's':
- break;
- default:
- g_error ("can't compute length for instruction: %i\n", iter->d.type);
- break;
- }
- iter=iter->next;
- }
- return traveled_length;
+ priv->flat_path_clean = FALSE;
}
gdouble
gegl_vector_get_length (GeglVector *self)
{
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
- Path *iter = priv->path;
- gfloat traveled_length = 0;
- gfloat x = 0, y = 0;
-
- while (iter)
- {
- switch (iter->d.type)
- {
- case 'M':
- x = iter->d.point[0].x;
- y = iter->d.point[0].y;
- break;
- case 'C':
- {
- Point a,b;
- gfloat distance;
-
- a.x = x;
- a.y = y;
-
- b.x = iter->d.point[2].x;
- b.y = iter->d.point[2].y;
-
- distance = point_dist (&a, &b);
- traveled_length += distance;
-
- x = b.x;
- y = b.y;
- }
- break;
- case 'L':
- {
- Point a,b;
- gfloat distance;
-
- a.x = x;
- a.y = y;
-
- b.x = iter->d.point[0].x;
- b.y = iter->d.point[0].y;
-
- distance = point_dist (&a, &b);
- traveled_length += distance;
-
- x = b.x;
- y = b.y;
- }
- break;
- case 'u':
- break;
- case 's':
- break;
- default:
- g_error ("can't compute length for instruction: %i\n", iter->d.type);
- break;
- }
- iter=iter->next;
- }
- return traveled_length;
+ ensure_flattened (self);
+ return path_get_length (priv->flat_path);
}
void gegl_vector_get_bounds (GeglVector *self,
@@ -1304,12 +1243,16 @@
gdouble *max_y)
{
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
- Path *iter = priv->path;
+ Path *iter;
+
*min_x = 256.0;
*min_y = 256.0;
*max_x = -256.0;
*max_y = -256.0;
+ ensure_flattened (self);
+ iter = priv->flat_path;
+
if (*max_x < *min_x)
*max_x = *min_x;
if (*max_y < *min_y)
@@ -1351,7 +1294,8 @@
gdouble *yd)
{
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
- return path_calc (priv->path, pos, xd, yd);
+ ensure_flattened (self);
+ return path_calc (priv->flat_path, pos, xd, yd);
}
@@ -1361,19 +1305,9 @@
gdouble *xs,
gdouble *ys)
{
- gdouble length = gegl_vector_get_length (self);
- gint i;
- for (i=0; i<num_samples; i++)
- {
- /* FIXME: speed this up, combine with a "stroking" of the path
- * or even inlining for the fill case as well
- */
- gdouble x, y;
- gegl_vector_calc (self, (i*1.0)/num_samples * length, &x, &y);
-
- xs[i] = x;
- ys[i] = y;
- }
+ GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
+ ensure_flattened (self);
+ return path_calc_values (priv->flat_path, num_samples, xs, ys);
}
@@ -1654,6 +1588,7 @@
p++;
}
+ priv->flat_path_clean = FALSE;
{
gdouble min_x;
gdouble max_x;
@@ -1665,7 +1600,6 @@
rect.y = min_y;
rect.width = max_x - min_x;
rect.height = max_y - min_y;
-
gegl_vector_emit_changed (vector, &rect);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]