gimp r27399 - in trunk: . app/core



Author: mitch
Date: Sat Oct 25 13:12:48 2008
New Revision: 27399
URL: http://svn.gnome.org/viewvc/gimp?rev=27399&view=rev

Log:
2008-10-25  Michael Natterer  <mitch gimp org>

	Merge a modified and enhanced patch from the vector layer branch:

	* app/core/gimpdrawable-stroke.[ch]: add new public API
	gimp_drawable_fill_boundary() and gimp_drawable_fill_vectors().

	Split the internal code up so that there are functions which turn
	the BoundSegs and GimpVectors into a GimpScanConvert and changed
	gimp_drawable_stroke_scan_convert() so it can either fill the
	shape or stroke it.



Modified:
   trunk/ChangeLog
   trunk/app/core/gimpdrawable-stroke.c
   trunk/app/core/gimpdrawable-stroke.h

Modified: trunk/app/core/gimpdrawable-stroke.c
==============================================================================
--- trunk/app/core/gimpdrawable-stroke.c	(original)
+++ trunk/app/core/gimpdrawable-stroke.c	Sat Oct 25 13:12:48 2008
@@ -53,16 +53,54 @@
 
 /*  local function prototypes  */
 
-static void gimp_drawable_stroke_scan_convert (GimpDrawable      *drawable,
-                                               GimpStrokeOptions *options,
-                                               GimpScanConvert   *scan_convert,
-                                               gboolean           push_undo);
-
+static GimpScanConvert * gimp_drawable_render_boundary     (GimpDrawable    *drawable,
+                                                            const BoundSeg  *bound_segs,
+                                                            gint             n_bound_segs,
+                                                            gint             offset_x,
+                                                            gint             offset_y);
+static GimpScanConvert * gimp_drawable_render_vectors      (GimpDrawable    *drawable,
+                                                            GimpVectors     *vectors,
+                                                            gboolean         do_stroke);
+static void              gimp_drawable_stroke_scan_convert (GimpDrawable    *drawable,
+                                                            GimpFillOptions *options,
+                                                            GimpScanConvert *scan_convert,
+                                                            gboolean         do_stroke,
+                                                            gboolean         push_undo);
 
 
 /*  public functions  */
 
 void
+gimp_drawable_fill_boundary (GimpDrawable    *drawable,
+                             GimpFillOptions *options,
+                             const BoundSeg  *bound_segs,
+                             gint             n_bound_segs,
+                             gint             offset_x,
+                             gint             offset_y,
+                             gboolean         push_undo)
+{
+  GimpScanConvert *scan_convert;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
+  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
+  g_return_if_fail (bound_segs == NULL || n_bound_segs != 0);
+  g_return_if_fail (options->style != GIMP_FILL_STYLE_PATTERN ||
+                    gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL);
+
+  scan_convert = gimp_drawable_render_boundary (drawable,
+                                                bound_segs, n_bound_segs,
+                                                offset_x, offset_y);
+
+  if (scan_convert)
+    {
+      gimp_drawable_stroke_scan_convert (drawable, options,
+                                         scan_convert, FALSE, push_undo);
+      gimp_scan_convert_free (scan_convert);
+    }
+}
+
+void
 gimp_drawable_stroke_boundary (GimpDrawable      *drawable,
                                GimpStrokeOptions *options,
                                const BoundSeg    *bound_segs,
@@ -72,6 +110,87 @@
                                gboolean           push_undo)
 {
   GimpScanConvert *scan_convert;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
+  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
+  g_return_if_fail (bound_segs == NULL || n_bound_segs != 0);
+  g_return_if_fail (GIMP_FILL_OPTIONS (options)->style != GIMP_FILL_STYLE_PATTERN ||
+                    gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL);
+
+  scan_convert = gimp_drawable_render_boundary (drawable,
+                                                bound_segs, n_bound_segs,
+                                                offset_x, offset_y);
+
+  if (scan_convert)
+    {
+      gimp_drawable_stroke_scan_convert (drawable, GIMP_FILL_OPTIONS (options),
+                                         scan_convert, TRUE, push_undo);
+      gimp_scan_convert_free (scan_convert);
+    }
+}
+
+void
+gimp_drawable_fill_vectors (GimpDrawable    *drawable,
+                            GimpFillOptions *options,
+                            GimpVectors     *vectors,
+                            gboolean         push_undo)
+{
+  GimpScanConvert *scan_convert;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
+  g_return_if_fail (GIMP_IS_FILL_OPTIONS (options));
+  g_return_if_fail (GIMP_IS_VECTORS (vectors));
+  g_return_if_fail (options->style != GIMP_FILL_STYLE_PATTERN ||
+                    gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL);
+
+  scan_convert = gimp_drawable_render_vectors (drawable, vectors, FALSE);
+
+  if (scan_convert)
+    {
+      gimp_drawable_stroke_scan_convert (drawable, options,
+                                         scan_convert, FALSE, push_undo);
+      gimp_scan_convert_free (scan_convert);
+    }
+}
+
+void
+gimp_drawable_stroke_vectors (GimpDrawable      *drawable,
+                              GimpStrokeOptions *options,
+                              GimpVectors       *vectors,
+                              gboolean           push_undo)
+{
+  GimpScanConvert *scan_convert;
+
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
+  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
+  g_return_if_fail (GIMP_IS_VECTORS (vectors));
+  g_return_if_fail (GIMP_FILL_OPTIONS (options)->style != GIMP_FILL_STYLE_PATTERN ||
+                    gimp_context_get_pattern (GIMP_CONTEXT (options)) != NULL);
+
+  scan_convert = gimp_drawable_render_vectors (drawable, vectors, TRUE);
+
+  if (scan_convert)
+    {
+      gimp_drawable_stroke_scan_convert (drawable, GIMP_FILL_OPTIONS (options),
+                                         scan_convert, TRUE, push_undo);
+      gimp_scan_convert_free (scan_convert);
+    }
+}
+
+
+/*  private functions  */
+
+static GimpScanConvert *
+gimp_drawable_render_boundary (GimpDrawable    *drawable,
+                               const BoundSeg  *bound_segs,
+                               gint             n_bound_segs,
+                               gint             offset_x,
+                               gint             offset_y)
+{
+  GimpScanConvert *scan_convert;
   BoundSeg        *stroke_segs;
   gint             n_stroke_segs;
   GimpVector2     *points;
@@ -79,19 +198,13 @@
   gint             seg;
   gint             i;
 
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
-  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
-  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
-
   if (n_bound_segs == 0)
-    return;
-
-  g_return_if_fail (bound_segs != NULL);
+    return NULL;
 
   stroke_segs = boundary_sort (bound_segs, n_bound_segs, &n_stroke_segs);
 
   if (n_stroke_segs == 0)
-    return;
+    return NULL;
 
   scan_convert = gimp_scan_convert_new ();
 
@@ -138,28 +251,18 @@
   g_free (points);
   g_free (stroke_segs);
 
-  gimp_drawable_stroke_scan_convert (drawable, options, scan_convert,
-                                     push_undo);
-
-  gimp_scan_convert_free (scan_convert);
+  return scan_convert;
 }
 
-void
-gimp_drawable_stroke_vectors (GimpDrawable      *drawable,
-                              GimpStrokeOptions *options,
-                              GimpVectors       *vectors,
-                              gboolean           push_undo)
-
+static GimpScanConvert *
+gimp_drawable_render_vectors (GimpDrawable *drawable,
+                              GimpVectors  *vectors,
+                              gboolean      do_stroke)
 {
   GimpScanConvert *scan_convert;
   GimpStroke      *stroke;
   gint             num_coords = 0;
 
-  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
-  g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)));
-  g_return_if_fail (GIMP_IS_STROKE_OPTIONS (options));
-  g_return_if_fail (GIMP_IS_VECTORS (vectors));
-
   scan_convert = gimp_scan_convert_new ();
 
   /* For each Stroke in the vector, interpolate it, and add it to the
@@ -190,7 +293,7 @@
             }
 
           gimp_scan_convert_add_polyline (scan_convert, coords->len,
-                                          points, closed);
+                                          points, closed || !do_stroke);
 
           g_free (points);
         }
@@ -200,24 +303,22 @@
     }
 
   if (num_coords > 0)
-    gimp_drawable_stroke_scan_convert (drawable, options, scan_convert,
-                                       push_undo);
+    return scan_convert;
 
   gimp_scan_convert_free (scan_convert);
-}
-
 
-/*  private functions  */
+  return NULL;
+}
 
 static void
-gimp_drawable_stroke_scan_convert (GimpDrawable      *drawable,
-                                   GimpStrokeOptions *options,
-                                   GimpScanConvert   *scan_convert,
-                                   gboolean           push_undo)
+gimp_drawable_stroke_scan_convert (GimpDrawable    *drawable,
+                                   GimpFillOptions *options,
+                                   GimpScanConvert *scan_convert,
+                                   gboolean         do_stroke,
+                                   gboolean         push_undo)
 {
   GimpContext *context = GIMP_CONTEXT (options);
-  GimpImage   *image;
-  gdouble      width;
+  GimpImage   *image   = gimp_item_get_image (GIMP_ITEM (drawable));
   TileManager *base;
   TileManager *mask;
   gint         x, y, w, h;
@@ -228,8 +329,6 @@
   PixelRegion  maskPR;
   PixelRegion  basePR;
 
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
-
   /*  must call gimp_channel_is_empty() instead of relying on
    *  gimp_drawable_mask_intersect() because the selection pretends to
    *  be empty while it is being stroked, to prevent masking itself.
@@ -246,29 +345,32 @@
       return;
     }
 
-  gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y);
+  if (do_stroke)
+    {
+      GimpStrokeOptions *stroke_options = GIMP_STROKE_OPTIONS (options);
+      gdouble            width          = stroke_options->width;
 
-  width = options->width;
+      if (stroke_options->unit != GIMP_UNIT_PIXEL)
+        {
+          gdouble xres;
+          gdouble yres;
 
-  if (options->unit != GIMP_UNIT_PIXEL)
-    {
-      gdouble xres;
-      gdouble yres;
+          gimp_image_get_resolution (image, &xres, &yres);
 
-      gimp_image_get_resolution (image, &xres, &yres);
+          gimp_scan_convert_set_pixel_ratio (scan_convert, yres / xres);
 
-      gimp_scan_convert_set_pixel_ratio (scan_convert, yres / xres);
+          width *= (image->yresolution /
+                    _gimp_unit_get_factor (image->gimp, stroke_options->unit));
+        }
 
-      width *= (yres / _gimp_unit_get_factor (image->gimp, options->unit));
+      gimp_scan_convert_stroke (scan_convert, width,
+                                stroke_options->join_style,
+                                stroke_options->cap_style,
+                                stroke_options->miter_limit,
+                                stroke_options->dash_offset,
+                                stroke_options->dash_info);
     }
 
-  gimp_scan_convert_stroke (scan_convert, width,
-                            options->join_style,
-                            options->cap_style,
-                            options->miter_limit,
-                            options->dash_offset,
-                            options->dash_info);
-
   /* fill a 1-bpp Tilemanager with black, this will describe the shape
    * of the stroke.
    */
@@ -277,6 +379,8 @@
   color_region (&maskPR, bg);
 
   /* render the stroke into it */
+  gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y);
+
   gimp_scan_convert_render (scan_convert, mask,
                             x + off_x, y + off_y,
                             GIMP_FILL_OPTIONS (options)->antialias);
@@ -287,7 +391,7 @@
   pixel_region_init (&basePR, base, 0, 0, w, h, TRUE);
   pixel_region_init (&maskPR, mask, 0, 0, w, h, FALSE);
 
-  switch (GIMP_FILL_OPTIONS (options)->style)
+  switch (options->style)
     {
     case GIMP_FILL_STYLE_SOLID:
       {

Modified: trunk/app/core/gimpdrawable-stroke.h
==============================================================================
--- trunk/app/core/gimpdrawable-stroke.h	(original)
+++ trunk/app/core/gimpdrawable-stroke.h	Sat Oct 25 13:12:48 2008
@@ -23,6 +23,13 @@
 #define  __GIMP_DRAWABLE_STROKE_H__
 
 
+void   gimp_drawable_fill_boundary   (GimpDrawable      *drawable,
+                                      GimpFillOptions   *options,
+                                      const BoundSeg    *bound_segs,
+                                      gint               n_bound_segs,
+                                      gint               offset_x,
+                                      gint               offset_y,
+                                      gboolean           push_undo);
 void   gimp_drawable_stroke_boundary (GimpDrawable      *drawable,
                                       GimpStrokeOptions *options,
                                       const BoundSeg    *bound_segs,
@@ -31,6 +38,10 @@
                                       gint               offset_y,
                                       gboolean           push_undo);
 
+void   gimp_drawable_fill_vectors    (GimpDrawable      *drawable,
+                                      GimpFillOptions   *options,
+                                      GimpVectors       *vectors,
+                                      gboolean           push_undo);
 void   gimp_drawable_stroke_vectors  (GimpDrawable      *drawable,
                                       GimpStrokeOptions *options,
                                       GimpVectors       *vectors,



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