gegl r2267 - in trunk: . gegl/property-types
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2267 - in trunk: . gegl/property-types
- Date: Wed, 30 Apr 2008 23:00:02 +0100 (BST)
Author: ok
Date: Wed Apr 30 22:00:02 2008
New Revision: 2267
URL: http://svn.gnome.org/viewvc/gegl?rev=2267&view=rev
Log:
* gegl/property-types/gegl-vector.[ch]: expanded the drawing commands
set to be more complete, also added gegl_vector_fill which does a
simple alias fill of a GeglColor for a single path.
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 Wed Apr 30 22:00:02 2008
@@ -13,8 +13,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
*
+ * Copyright 2008 Ãyvind KolÃs <pippin gimp org>
* Copyright 2006 Mark Probst <mark probst gmail com>
- * Spline Code Copyright 1997 David Mosberger
*/
#include "config.h"
@@ -26,6 +26,7 @@
#include "gegl-types.h"
#include "gegl-vector.h"
+#include "gegl-color.h"
/* ###################################################################### */
/* path code copied from horizon */
@@ -123,8 +124,8 @@
lerp (dest, &abbc, &bccd, t);
}
-
-gint
+#if 0
+static gint
path_last_x (Path *path)
{
if (path)
@@ -132,13 +133,14 @@
return 0;
}
-gint
+static gint
path_last_y (Path *path)
{
if (path)
return path->point.y;
return 0;
}
+#endif
/* types:
* 'u' : unitilitlalized state
@@ -260,7 +262,7 @@
/* chop off unneeded elements */
curve[0]->next = NULL;
- { /* create piecevize linear approximation of bezier curve */
+ { /* create piecevise linear approximation of bezier curve */
gint i;
Point foo[4];
Point *pts[4];
@@ -303,13 +305,15 @@
return head;
}
-Path *
+#if 0
+static Path *
path_new (void)
{
return path_add (NULL, 'u', 0, 0);
}
+#endif
-Path *
+static Path *
path_destroy (Path *path)
{
g_slice_free_chain (Path, path, next);
@@ -317,7 +321,7 @@
return NULL;
}
-Path *
+static Path *
path_move_to (Path *path,
gint x,
gint y)
@@ -326,7 +330,7 @@
return path;
}
-Path *
+static Path *
path_line_to (Path *path,
gint x,
gint y)
@@ -335,7 +339,7 @@
return path;
}
-Path *
+static Path *
path_curve_to (Path *path,
gint x1,
gint y1,
@@ -350,7 +354,7 @@
return path;
}
-Path *
+static Path *
path_rel_move_to (Path *path,
gint x,
gint y)
@@ -358,7 +362,7 @@
return path_move_to (path, path->point.x + x, path->point.y + y);
}
-Path *
+static Path *
path_rel_line_to (Path *path,
gint x,
gint y)
@@ -366,7 +370,7 @@
return path_line_to (path, path->point.x + x, path->point.y + y);
}
-Path *
+static Path *
path_rel_curve_to (Path *path,
gint x1,
gint y1,
@@ -381,6 +385,167 @@
path->point.x + x3, path->point.y + y3);
}
+#include <gegl-buffer.h>
+
+static gint compare_ints (gconstpointer a,
+ gconstpointer b)
+{
+ return GPOINTER_TO_INT (a)-GPOINTER_TO_INT (b);
+}
+
+/* speedy way of doing vectors on gegl, would be to build a runlength
+ * encoded instruction stream for fill n pixels which could be used on
+ * linear buffers.
+ */
+
+
+void gegl_vector_fill (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gboolean winding)
+{
+ gdouble xmin, xmax, ymin, ymax;
+ GeglRectangle extent;
+ gint samples = gegl_vector_get_length (vector);
+ 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;
+
+ {
+ GSList *scanlines[extent.height];
+
+ gdouble xs[samples];
+ gdouble ys[samples];
+
+ gint i;
+ gdouble prev_x;
+ gint prev_y;
+ gdouble first_x;
+ gint first_y;
+ gint lastline=-1;
+ gint lastdir=-2;
+
+ gegl_vector_calc_values (vector, samples, xs, ys);
+
+ /* clear scanline intersection lists */
+ for (i=0; i < extent.height; i++)
+ scanlines[i]=NULL;
+
+ first_x = prev_x = xs[0];
+ first_y = prev_y = ys[0];
+
+
+ /* saturate scanline intersection list */
+ for (i=1; i<samples; i++)
+ {
+ gint dest_x = xs[i];
+ gint dest_y = ys[i];
+ gint ydir;
+ gint dx;
+ gint dy;
+ gint y;
+fill_close: /* label used for goto to close last segment */
+ dx = dest_x - prev_x;
+ dy = dest_y - prev_y;
+
+ if (dy < 0)
+ ydir = -1;
+ else
+ ydir = 1;
+
+ /* do linear interpolation between vertexes */
+ for (y=prev_y; y!= dest_y; y += ydir)
+ {
+ if (y-extent.y >= 0 &&
+ y-extent.y < extent.height &&
+ lastline != y)
+ {
+ gint x = prev_x + (dx * (y-prev_y)) / dy;
+
+ scanlines[ y - extent.y ]=
+ g_slist_insert_sorted (scanlines[ y - extent.y],
+ GINT_TO_POINTER(x),
+ compare_ints);
+ if (ydir != lastdir &&
+ lastdir != -2)
+ scanlines[ y - extent.y ]=
+ g_slist_insert_sorted (scanlines[ y - extent.y],
+ GINT_TO_POINTER(x),
+ compare_ints);
+ lastdir = ydir;
+ lastline = y;
+ }
+ }
+
+ prev_x = dest_x;
+ prev_y = dest_y;
+
+ /* if we're on the last knot, fake the first vertex being a next one */
+ if (i+1 == samples)
+ {
+ dest_x = first_x;
+ dest_y = first_y;
+ i++; /* to make the loop finally end */
+ goto fill_close;
+ }
+ }
+
+ /* for each scanline */
+{
+ gfloat *buf = NULL;
+ const gfloat *col = gegl_color_float4 (color);
+ Babl *format = babl_format ("RGBA float");
+ buf = g_malloc (extent.width * 4 *4);
+ for (i=0; i < extent.width; i++)
+ {
+ buf[i*4+0] = col[0];
+ buf[i*4+1] = col[1];
+ buf[i*4+2] = col[2];
+ buf[i*4+3] = col[3];
+ }
+
+ for (i=0; i < extent.height; i++)
+ {
+ GSList *iter = scanlines[i];
+ while (iter)
+ {
+ GSList *next = iter->next;
+ gint startx, endx;
+ if (!next)
+ break;
+
+ startx = GPOINTER_TO_INT (iter->data);
+ endx = GPOINTER_TO_INT (next->data);
+
+ {
+ GeglRectangle roi={startx, extent.y + i, endx - startx, 1};
+ gegl_buffer_set (buffer, &roi, format, buf, 0);
+ }
+
+ iter = next->next;
+ }
+ if (scanlines[i])
+ g_slist_free (scanlines[i]);
+ }
+ g_free (buf);
+}
+ }
+
+}
+
+void gegl_vector_stroke (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gdouble linewidth,
+ gint linecap,
+ gint linejoin)
+{
+
+}
+
#if 0
/* drawing code follows */
@@ -623,6 +788,8 @@
GeglVectorPrivate *priv = GEGL_VECTOR_GET_PRIVATE (self);
self = NULL;
+ if (priv->path)
+ path_destroy (priv->path);
priv = NULL;
G_OBJECT_CLASS (gegl_vector_parent_class)->finalize (gobject);
@@ -679,6 +846,71 @@
gegl_vector_emit_changed (self);
}
+void
+gegl_vector_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_move_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
+ gegl_vector_emit_changed (self);
+}
+
+
+void
+gegl_vector_rel_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_line_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_rel_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_move_to (priv->path, x, y);
+ gegl_vector_emit_changed (self);
+}
+
+void
+gegl_vector_rel_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3)
+{
+ GeglVectorPrivate *priv;
+ priv = GEGL_VECTOR_GET_PRIVATE (self);
+ priv->path = path_rel_curve_to (priv->path, x1, y1, x2, y2, x3, y3);
+ gegl_vector_emit_changed (self);
+}
+
+
gdouble
gegl_vector_get_length (GeglVector *self)
{
Modified: trunk/gegl/property-types/gegl-vector.h
==============================================================================
--- trunk/gegl/property-types/gegl-vector.h (original)
+++ trunk/gegl/property-types/gegl-vector.h Wed Apr 30 22:00:02 2008
@@ -46,6 +46,39 @@
GeglVector * gegl_vector_new (void);
+
+void gegl_vector_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3);
+
+void gegl_vector_rel_line_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_rel_move_to (GeglVector *self,
+ gdouble x,
+ gdouble y);
+
+void gegl_vector_rel_curve_to (GeglVector *self,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2,
+ gdouble x3,
+ gdouble y3);
+
void gegl_vector_get_bounds (GeglVector *self,
gdouble *min_x,
gdouble *max_x,
@@ -54,9 +87,6 @@
gdouble gegl_vector_get_length (GeglVector *self);
-void gegl_vector_line_to (GeglVector *self,
- gdouble x,
- gdouble y);
void gegl_vector_calc (GeglVector *self,
gdouble pos,
@@ -80,6 +110,20 @@
GeglVector *default_vector,
GParamFlags flags);
+#include <gegl-buffer.h>
+
+void gegl_vector_fill (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gboolean winding);
+
+void gegl_vector_stroke (GeglBuffer *buffer,
+ GeglVector *vector,
+ GeglColor *color,
+ gdouble linewidth,
+ gint linecap,
+ gint linejoin);
+
G_END_DECLS
#endif /* __GEGL_VECTOR_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]