gimp r25595 - in trunk: . app/core app/tools



Author: simon
Date: Fri May  9 11:18:44 2008
New Revision: 25595
URL: http://svn.gnome.org/viewvc/gimp?rev=25595&view=rev

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

	* app/core/gimpscanconvert.[ch]: kind of resurrect the
	blending modes, although now implemented as compositing
	on top of the existing content of a mask.

	* app/tools/gimpforegroundselecttool.c: changed accordingly



Modified:
   trunk/ChangeLog
   trunk/app/core/gimpscanconvert.c
   trunk/app/core/gimpscanconvert.h
   trunk/app/tools/gimpforegroundselecttool.c

Modified: trunk/app/core/gimpscanconvert.c
==============================================================================
--- trunk/app/core/gimpscanconvert.c	(original)
+++ trunk/app/core/gimpscanconvert.c	Fri May  9 11:18:44 2008
@@ -56,24 +56,16 @@
 
   guint           num_nodes;
   GArray         *path_data;
-
-  /* stuff necessary for the rendering callback */
-  GimpChannelOps  op;
-  guchar         *buf;
-  gint            rowstride;
-  gint            x0, x1;
-  gboolean        antialias;
-  gboolean        value;
 };
 
 
 /* private functions */
 
 static void   gimp_scan_convert_render_internal  (GimpScanConvert *sc,
-                                                  GimpChannelOps   op,
                                                   TileManager     *tile_manager,
                                                   gint             off_x,
                                                   gint             off_y,
+                                                  gboolean         replace,
                                                   gboolean         antialias,
                                                   guchar           value);
 
@@ -352,9 +344,8 @@
   g_return_if_fail (sc != NULL);
   g_return_if_fail (tile_manager != NULL);
 
-  gimp_scan_convert_render_internal (sc, GIMP_CHANNEL_OP_REPLACE,
-                                     tile_manager, off_x, off_y,
-                                     antialias, 255);
+  gimp_scan_convert_render_internal (sc, tile_manager, off_x, off_y,
+                                     TRUE, antialias, 255);
 }
 
 /**
@@ -382,9 +373,8 @@
   g_return_if_fail (sc != NULL);
   g_return_if_fail (tile_manager != NULL);
 
-  gimp_scan_convert_render_internal (sc, GIMP_CHANNEL_OP_REPLACE,
-                                     tile_manager, off_x, off_y,
-                                     FALSE, value);
+  gimp_scan_convert_render_internal (sc, tile_manager, off_x, off_y,
+                                     TRUE, FALSE, value);
 }
 
 /**
@@ -401,7 +391,6 @@
  */
 void
 gimp_scan_convert_compose (GimpScanConvert *sc,
-                           GimpChannelOps   op,
                            TileManager     *tile_manager,
                            gint             off_x,
                            gint             off_y)
@@ -409,17 +398,43 @@
   g_return_if_fail (sc != NULL);
   g_return_if_fail (tile_manager != NULL);
 
-  gimp_scan_convert_render_internal (sc, op,
-                                     tile_manager, off_x, off_y,
-                                     FALSE, 255);
+  gimp_scan_convert_render_internal (sc, tile_manager, off_x, off_y,
+                                     FALSE, FALSE, 255);
+}
+
+/**
+ * gimp_scan_convert_compose_value:
+ * @sc:           a #GimpScanConvert context
+ * @tile_manager: the #TileManager to render to
+ * @off_x:        horizontal offset into the @tile_manager
+ * @off_y:        vertical offset into the @tile_manager
+ * @value:        value to use for covered pixels
+ *
+ * This is a variant of gimp_scan_convert_render() that composes the
+ * (aliased) scan conversion with the content of the @tile_manager.
+ *
+ * You cannot add additional polygons after this command.
+ */
+void
+gimp_scan_convert_compose_value (GimpScanConvert *sc,
+                                 TileManager     *tile_manager,
+                                 gint             off_x,
+                                 gint             off_y,
+                                 gint             value)
+{
+  g_return_if_fail (sc != NULL);
+  g_return_if_fail (tile_manager != NULL);
+
+  gimp_scan_convert_render_internal (sc, tile_manager, off_x, off_y,
+                                     FALSE, FALSE, value);
 }
 
 static void
 gimp_scan_convert_render_internal (GimpScanConvert *sc,
-                                   GimpChannelOps   op,
                                    TileManager     *tile_manager,
                                    gint             off_x,
                                    gint             off_y,
+                                   gboolean         replace,
                                    gboolean         antialias,
                                    guchar           value)
 {
@@ -448,10 +463,6 @@
 
   g_return_if_fail (maskPR.bytes == 1);
 
-  sc->antialias = antialias;
-  sc->value     = value;
-  sc->op        = op;
-
   path.status   = CAIRO_STATUS_SUCCESS;
   path.data     = (cairo_path_data_t *) sc->path_data->data;
   path.num_data = sc->path_data->len;
@@ -463,19 +474,28 @@
       guchar *tmp_buf = NULL;
       gint    stride;
 
-      sc->buf       = maskPR.data;
-      sc->rowstride = maskPR.rowstride;
-      sc->x0        = off_x + maskPR.x;
-      sc->x1        = off_x + maskPR.x + maskPR.w;
-
       stride = gimp_cairo_stride_for_width (maskPR.w);
 
       g_assert (stride > 0);
 
       if (maskPR.rowstride != stride)
         {
-          tmp_buf = g_alloca (stride * maskPR.h);
-          memset (tmp_buf, 0, stride * maskPR.h);
+          const guchar *src = maskPR.data;
+          guchar       *dest;
+          gint          i;
+
+          dest = tmp_buf = g_alloca (stride * maskPR.h);
+
+          if (!replace)
+            {
+              for (i = 0; i < maskPR.h; i++)
+                {
+                  memcpy (dest, src, maskPR.w);
+
+                  src  += maskPR.rowstride;
+                  dest += stride;
+                }
+            }
         }
 
       surface = cairo_image_surface_create_for_data (tmp_buf ?
@@ -488,10 +508,15 @@
                                        -off_x - maskPR.x,
                                        -off_y - maskPR.y);
       cr = cairo_create (surface);
-      cairo_set_source_rgb (cr, value / 255.0, value / 255.0, value / 255.0);
+      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+      if (replace)
+        {
+          cairo_set_source_rgba (cr, 0, 0, 0, 0);
+          cairo_paint (cr);
+        }
+      cairo_set_source_rgba (cr, 0, 0, 0, value / 255.0);
       cairo_append_path (cr, &path);
-      cairo_set_antialias (cr,
-                           sc->antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
+      cairo_set_antialias (cr, antialias ? CAIRO_ANTIALIAS_GRAY : CAIRO_ANTIALIAS_NONE);
       if (sc->do_stroke)
         {
           cairo_set_line_cap (cr, sc->cap == GIMP_CAP_BUTT ? CAIRO_LINE_CAP_BUTT :
@@ -513,7 +538,6 @@
           cairo_fill (cr);
         }
 
-      cairo_surface_flush (surface);
       cairo_destroy (cr);
       cairo_surface_destroy (surface);
 
@@ -551,34 +575,3 @@
   return CAIRO_STRIDE_FOR_WIDTH_BPP (width, 8);
 }
 
-static inline void
-compose (GimpChannelOps  op,
-         guchar         *buf,
-         guchar          value,
-         gint            len)
-{
-  switch (op)
-    {
-    case GIMP_CHANNEL_OP_ADD:
-      if (value)
-        memset (buf, value, len);
-      break;
-    case GIMP_CHANNEL_OP_SUBTRACT:
-      if (value)
-        memset (buf, 0, len);
-      break;
-    case GIMP_CHANNEL_OP_REPLACE:
-      memset (buf, value, len);
-      break;
-    case GIMP_CHANNEL_OP_INTERSECT:
-      do
-        {
-          if (*buf)
-            *buf = value;
-          buf++;
-        }
-      while (--len);
-      break;
-    }
-}
-

Modified: trunk/app/core/gimpscanconvert.h
==============================================================================
--- trunk/app/core/gimpscanconvert.h	(original)
+++ trunk/app/core/gimpscanconvert.h	Fri May  9 11:18:44 2008
@@ -52,10 +52,14 @@
                                                 gint             off_y,
                                                 guchar           value);
 void      gimp_scan_convert_compose            (GimpScanConvert *sc,
-                                                GimpChannelOps   op,
                                                 TileManager     *tile_manager,
                                                 gint             off_x,
                                                 gint             off_y);
+void      gimp_scan_convert_compose_value      (GimpScanConvert *sc,
+                                                TileManager     *tile_manager,
+                                                gint             off_x,
+                                                gint             off_y,
+                                                gint             value);
 
 
 #endif /* __GIMP_SCAN_CONVERT_H__ */

Modified: trunk/app/tools/gimpforegroundselecttool.c
==============================================================================
--- trunk/app/tools/gimpforegroundselecttool.c	(original)
+++ trunk/app/tools/gimpforegroundselecttool.c	Fri May  9 11:18:44 2008
@@ -782,11 +782,9 @@
                             stroke->width,
                             GIMP_JOIN_ROUND, GIMP_CAP_ROUND, 10.0,
                             0.0, NULL);
-  gimp_scan_convert_compose (scan_convert,
-                             stroke->background ?
-                             GIMP_CHANNEL_OP_SUBTRACT : GIMP_CHANNEL_OP_ADD,
+  gimp_scan_convert_compose_value (scan_convert,
                              gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
-                             0, 0);
+                             0, 0, stroke->background ? 0 : 255);
   gimp_scan_convert_free (scan_convert);
 }
 



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