gimp r25645 - in trunk: . app/vectors app/widgets



Author: simon
Date: Mon May 12 21:47:07 2008
New Revision: 25645
URL: http://svn.gnome.org/viewvc/gimp?rev=25645&view=rev

Log:
2008-05-12  Simon Budig  <simon gimp org>

	* app/vectors/gimpvectors.[ch]
	* app/vectors/gimpstroke.[ch]
	* app/vectors/gimpbezierstroke.c: Implement functionality to
	get a bezier description a la moveto/curveto/closepath.

	* app/vectors/vectors-types.h: implement an evil hack to avoid
	the inclusion of cairo.h in most C files...

	* app/vectors/Makefile.am: link against cairo

	* app/widgets/gimpviewrenderervectors.c: use the new functionality
	for preview rendering.



Modified:
   trunk/ChangeLog
   trunk/app/vectors/Makefile.am
   trunk/app/vectors/gimpbezierstroke.c
   trunk/app/vectors/gimpstroke.c
   trunk/app/vectors/gimpstroke.h
   trunk/app/vectors/gimpvectors.c
   trunk/app/vectors/gimpvectors.h
   trunk/app/vectors/vectors-types.h
   trunk/app/widgets/gimpviewrenderervectors.c

Modified: trunk/app/vectors/Makefile.am
==============================================================================
--- trunk/app/vectors/Makefile.am	(original)
+++ trunk/app/vectors/Makefile.am	Mon May 12 21:47:07 2008
@@ -9,7 +9,7 @@
 	-I$(top_builddir)/app	\
 	-I$(top_srcdir)/app	\
 	$(GDK_PIXBUF_CFLAGS)	\
-	$(LIBART_CFLAGS)	\
+	$(CAIRO_CFLAGS)		\
 	$(GLIB_CFLAGS)		\
 	-I$(includedir)
 

Modified: trunk/app/vectors/gimpbezierstroke.c
==============================================================================
--- trunk/app/vectors/gimpbezierstroke.c	(original)
+++ trunk/app/vectors/gimpbezierstroke.c	Mon May 12 21:47:07 2008
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include <glib-object.h>
+#include <cairo/cairo.h>
 
 #include "libgimpmath/gimpmath.h"
 
@@ -130,6 +131,8 @@
     gimp_bezier_stroke_interpolate         (const GimpStroke      *stroke,
                                             const gdouble          precision,
                                             gboolean              *closed);
+static GimpBezierDesc *
+    gimp_bezier_stroke_make_bezier         (const GimpStroke      *stroke);
 
 static void gimp_bezier_stroke_finalize    (GObject               *object);
 
@@ -185,6 +188,7 @@
   stroke_class->extend               = gimp_bezier_stroke_extend;
   stroke_class->connect_stroke       = gimp_bezier_stroke_connect_stroke;
   stroke_class->interpolate          = gimp_bezier_stroke_interpolate;
+  stroke_class->make_bezier          = gimp_bezier_stroke_make_bezier;
 }
 
 static void
@@ -1438,6 +1442,94 @@
     }
 }
 
+
+static GimpBezierDesc *
+gimp_bezier_stroke_make_bezier (const GimpStroke *stroke)
+{
+  GArray *points, *cmd_array;
+  GimpBezierDesc *bezdesc;
+  cairo_path_data_t  pathdata;
+  gint num_cmds, i;
+
+  points = gimp_stroke_control_points_get (stroke, NULL);
+
+  g_return_val_if_fail (points && points->len % 3 == 0, NULL);
+  if (points->len < 3)
+    return NULL;
+
+  /* Moveto + (n-1) * curveto + (if closed) curveto + closepath */
+  num_cmds = 2 + (points->len / 3 - 1) * 4;
+  if (stroke->closed)
+    num_cmds += 1 + 4;
+
+  cmd_array = g_array_sized_new (FALSE, FALSE,
+                                 sizeof (cairo_path_data_t),
+                                 num_cmds);
+
+  pathdata.header.type = CAIRO_PATH_MOVE_TO;
+  pathdata.header.length = 2;
+  g_array_append_val (cmd_array, pathdata);
+  pathdata.point.x = g_array_index (points, GimpAnchor, 1).position.x;
+  pathdata.point.y = g_array_index (points, GimpAnchor, 1).position.y;
+  g_array_append_val (cmd_array, pathdata);
+
+  for (i = 2; i+2 < points->len; i += 3)
+    {
+      pathdata.header.type = CAIRO_PATH_CURVE_TO;
+      pathdata.header.length = 4;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, i).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, i).position.y;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, i+1).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, i+1).position.y;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, i+2).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, i+2).position.y;
+      g_array_append_val (cmd_array, pathdata);
+    }
+
+  if (stroke->closed)
+    {
+      pathdata.header.type = CAIRO_PATH_CURVE_TO;
+      pathdata.header.length = 4;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, i).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, i).position.y;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, 0).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, 0).position.y;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.point.x = g_array_index (points, GimpAnchor, 1).position.x;
+      pathdata.point.y = g_array_index (points, GimpAnchor, 1).position.y;
+      g_array_append_val (cmd_array, pathdata);
+
+      pathdata.header.type = CAIRO_PATH_CLOSE_PATH;
+      pathdata.header.length = 1;
+      g_array_append_val (cmd_array, pathdata);
+    }
+
+  if (cmd_array->len != num_cmds)
+    g_printerr ("miscalculated path cmd length! (%d vs. %d)\n",
+                cmd_array->len, num_cmds);
+
+  bezdesc = g_new (GimpBezierDesc, 1);
+  bezdesc->status = CAIRO_STATUS_SUCCESS;
+  bezdesc->data = (cairo_path_data_t *) cmd_array->data;
+  bezdesc->num_data = cmd_array->len;
+  g_array_free (points, TRUE);
+  g_array_free (cmd_array, FALSE);
+
+  return bezdesc;
+}
+
+
 static GArray *
 gimp_bezier_stroke_interpolate (const GimpStroke  *stroke,
                                 gdouble            precision,

Modified: trunk/app/vectors/gimpstroke.c
==============================================================================
--- trunk/app/vectors/gimpstroke.c	(original)
+++ trunk/app/vectors/gimpstroke.c	Mon May 12 21:47:07 2008
@@ -129,7 +129,7 @@
                                                       gdouble           precision,
                                                       gboolean         *closed);
 static GimpStroke * gimp_stroke_real_duplicate       (const GimpStroke *stroke);
-static GimpStroke * gimp_stroke_real_make_bezier     (const GimpStroke *stroke);
+static GimpBezierDesc * gimp_stroke_real_make_bezier (const GimpStroke *stroke);
 
 static void         gimp_stroke_real_translate       (GimpStroke       *stroke,
                                                       gdouble           offset_x,
@@ -1006,7 +1006,7 @@
 }
 
 
-GimpStroke *
+GimpBezierDesc *
 gimp_stroke_make_bezier (const GimpStroke *stroke)
 {
   g_return_val_if_fail (GIMP_IS_STROKE (stroke), NULL);
@@ -1014,7 +1014,7 @@
   return GIMP_STROKE_GET_CLASS (stroke)->make_bezier (stroke);
 }
 
-static GimpStroke *
+static GimpBezierDesc *
 gimp_stroke_real_make_bezier (const GimpStroke *stroke)
 {
   g_printerr ("gimp_stroke_make_bezier: default implementation\n");

Modified: trunk/app/vectors/gimpstroke.h
==============================================================================
--- trunk/app/vectors/gimpstroke.h	(original)
+++ trunk/app/vectors/gimpstroke.h	Mon May 12 21:47:07 2008
@@ -149,7 +149,7 @@
 
   GimpStroke  * (* duplicate)            (const GimpStroke      *stroke);
 
-  GimpStroke  * (* make_bezier)          (const GimpStroke      *stroke);
+  GimpBezierDesc * (* make_bezier)       (const GimpStroke      *stroke);
 
   void          (* translate)            (GimpStroke            *stroke,
                                           gdouble                offset_x,
@@ -177,8 +177,6 @@
   GArray      * (* get_draw_lines)       (const GimpStroke      *stroke);
   GArray      * (* control_points_get)   (const GimpStroke      *stroke,
                                           gboolean              *ret_closed);
-
-  void          (* art_stroke)           (const GimpStroke      *stroke);
 };
 
 
@@ -312,7 +310,7 @@
 GimpStroke * gimp_stroke_duplicate            (const GimpStroke      *stroke);
 
 /* creates a bezier approximation. */
-GimpStroke * gimp_stroke_make_bezier          (const GimpStroke      *stroke);
+GimpBezierDesc * gimp_stroke_make_bezier      (const GimpStroke      *stroke);
 
 void         gimp_stroke_translate            (GimpStroke            *stroke,
                                                gdouble                offset_x,

Modified: trunk/app/vectors/gimpvectors.c
==============================================================================
--- trunk/app/vectors/gimpvectors.c	(original)
+++ trunk/app/vectors/gimpvectors.c	Mon May 12 21:47:07 2008
@@ -22,6 +22,7 @@
 #include "config.h"
 
 #include <glib-object.h>
+#include <cairo/cairo.h>
 
 #include "libgimpcolor/gimpcolor.h"
 #include "libgimpmath/gimpmath.h"
@@ -135,7 +136,7 @@
                                                      gdouble            precision,
                                                      gint               max_points,
                                                      GimpCoords        *ret_coords);
-static GimpVectors * gimp_vectors_real_make_bezier  (const GimpVectors *vectors);
+static GimpBezierDesc * gimp_vectors_real_make_bezier (const GimpVectors *vectors);
 
 
 G_DEFINE_TYPE (GimpVectors, gimp_vectors, GIMP_TYPE_ITEM)
@@ -1013,7 +1014,7 @@
 }
 
 
-GimpVectors *
+GimpBezierDesc *
 gimp_vectors_make_bezier (const GimpVectors *vectors)
 {
   g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
@@ -1021,11 +1022,38 @@
   return GIMP_VECTORS_GET_CLASS (vectors)->make_bezier (vectors);
 }
 
-static GimpVectors *
+static GimpBezierDesc *
 gimp_vectors_real_make_bezier (const GimpVectors *vectors)
 {
-  g_printerr ("gimp_vectors_make_bezier: default implementation\n");
+  GimpStroke     *cur_stroke;
+  GArray         *cmd_array;
+  GimpBezierDesc *bezdesc;
+  GimpBezierDesc *ret_bezdesc = NULL;
 
-  return NULL;
+  cmd_array = g_array_new (FALSE, FALSE, sizeof (cairo_path_data_t));
+
+  for (cur_stroke = gimp_vectors_stroke_get_next (vectors, NULL);
+       cur_stroke;
+       cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke))
+    {
+      bezdesc = gimp_stroke_make_bezier (cur_stroke);
+      if (bezdesc)
+        {
+          cmd_array = g_array_append_vals (cmd_array, bezdesc->data,
+                                           bezdesc->num_data);
+          g_free (bezdesc->data);
+          g_free (bezdesc);
+        }
+    }
+
+  if (cmd_array->len > 0)
+    {
+      ret_bezdesc = g_new (GimpBezierDesc, 1);
+      ret_bezdesc->num_data = cmd_array->len;
+      ret_bezdesc->data = (cairo_path_data_t *) cmd_array->data;
+      g_array_free (cmd_array, FALSE);
+    }
+
+  return ret_bezdesc;
 }
 

Modified: trunk/app/vectors/gimpvectors.h
==============================================================================
--- trunk/app/vectors/gimpvectors.h	(original)
+++ trunk/app/vectors/gimpvectors.h	Mon May 12 21:47:07 2008
@@ -24,7 +24,6 @@
 
 #include "core/gimpitem.h"
 
-
 #define GIMP_TYPE_VECTORS            (gimp_vectors_get_type ())
 #define GIMP_VECTORS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTORS, GimpVectors))
 #define GIMP_VECTORS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTORS, GimpVectorsClass))
@@ -79,7 +78,7 @@
                                        gdouble            precision,
                                        gint               max_points,
                                        GimpCoords        *ret_coords);
-  GimpVectors * (* make_bezier)       (const GimpVectors *vectors);
+  GimpBezierDesc * (* make_bezier)    (const GimpVectors *vectors);
 };
 
 
@@ -173,8 +172,8 @@
 
 /* usually overloaded */
 
-/* creates a bezier approximation. */
+/* creates a bezier representation. */
 
-GimpVectors   * gimp_vectors_make_bezier        (const GimpVectors  *vectors);
+GimpBezierDesc * gimp_vectors_make_bezier       (const GimpVectors  *vectors);
 
 #endif /* __GIMP_VECTORS_H__ */

Modified: trunk/app/vectors/vectors-types.h
==============================================================================
--- trunk/app/vectors/vectors-types.h	(original)
+++ trunk/app/vectors/vectors-types.h	Mon May 12 21:47:07 2008
@@ -35,5 +35,10 @@
 typedef struct _GimpStroke          GimpStroke;
 typedef struct _GimpBezierStroke    GimpBezierStroke;
 
+#ifdef CAIRO_VERSION
+typedef cairo_path_t GimpBezierDesc;
+#else
+typedef void * GimpBezierDesc;
+#endif
 
 #endif /* __VECTORS_TYPES_H__ */

Modified: trunk/app/widgets/gimpviewrenderervectors.c
==============================================================================
--- trunk/app/widgets/gimpviewrenderervectors.c	(original)
+++ trunk/app/widgets/gimpviewrenderervectors.c	Mon May 12 21:47:07 2008
@@ -69,61 +69,40 @@
                                  cairo_t            *cr,
                                  const GdkRectangle *area)
 {
-  GimpVectors  *vectors = GIMP_VECTORS (renderer->viewable);
-  GimpStroke   *stroke;
-  gdouble       xscale;
-  gdouble       yscale;
-  gint          x, y;
+  GimpVectors    *vectors = GIMP_VECTORS (renderer->viewable);
+  GimpBezierDesc *bezdesc;
+  gdouble         xscale;
+  gdouble         yscale;
+  gint            x, y;
 
   gdk_cairo_set_source_color (cr, &widget->style->white);
 
   x = area->x + (area->width  - renderer->width)  / 2;
   y = area->y + (area->height - renderer->height) / 2;
 
-  cairo_rectangle (cr, x, y, renderer->width, renderer->height);
+  cairo_translate (cr, x, y);
+  cairo_rectangle (cr, 0, 0, renderer->width, renderer->height);
   cairo_clip_preserve (cr);
   cairo_fill (cr);
 
-  cairo_set_line_width (cr, 1.0);
+  xscale = (gdouble) renderer->width / (gdouble) gimp_item_width  (GIMP_ITEM (vectors));
+  yscale = (gdouble) renderer->height / (gdouble) gimp_item_height (GIMP_ITEM (vectors));
+  cairo_scale (cr, xscale, yscale);
+
+  /* determine line width */
+  xscale = yscale = 0.5;
+  cairo_device_to_user_distance (cr, &xscale, &yscale);
+
+  cairo_set_line_width (cr, MAX (xscale, yscale));
   gdk_cairo_set_source_color (cr, &widget->style->black);
 
-  xscale = (gdouble) gimp_item_width  (GIMP_ITEM (vectors)) / (gdouble) renderer->width;
-  yscale = (gdouble) gimp_item_height (GIMP_ITEM (vectors)) / (gdouble) renderer->height;
+  bezdesc = gimp_vectors_make_bezier (vectors);
 
-  for (stroke = gimp_vectors_stroke_get_next (vectors, NULL);
-       stroke != NULL;
-       stroke = gimp_vectors_stroke_get_next (vectors, stroke))
+  if (bezdesc)
     {
-      GArray *coordinates;
-
-      coordinates = gimp_stroke_interpolate (stroke,
-                                             MIN (xscale, yscale) / 2,
-                                             NULL);
-      if (! coordinates)
-        continue;
-
-      if (coordinates->len > 0)
-        {
-          GimpCoords *coords = &(g_array_index (coordinates, GimpCoords, 0));
-          gdouble     cx     = x + ROUND (coords->x / xscale);
-          gdouble     cy     = y + ROUND (coords->y / yscale);
-          gint        i;
-
-          cairo_move_to (cr, cx, cy);
-
-          for (i = 1; i < coordinates->len; i++)
-            {
-              coords = &(g_array_index (coordinates, GimpCoords, i));
-
-              cx = x + ROUND (coords->x / xscale) + 0.5;
-              cy = y + ROUND (coords->y / yscale) + 0.5;
-
-              cairo_line_to (cr, cx, cy);
-            }
-
-          cairo_stroke (cr);
-        }
-
-      g_array_free (coordinates, TRUE);
+      cairo_append_path (cr, (cairo_path_t *) bezdesc);
+      cairo_stroke (cr);
+      g_free (bezdesc->data);
+      g_free (bezdesc);
     }
 }



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