[gimp/multi-stroke: 28/30] app: port MyBrush to symmetry core.



commit 95f80a3c5690e00c2279cd47de2a693c8b10157b
Author: Jehan <jehan girinstud io>
Date:   Wed Apr 1 01:41:18 2015 +0200

    app: port MyBrush to symmetry core.

 app/paint/gimpmybrush.c |  262 +++++++++++++++++++++++++++++++----------------
 1 files changed, 175 insertions(+), 87 deletions(-)
---
diff --git a/app/paint/gimpmybrush.c b/app/paint/gimpmybrush.c
index 23a057e..439d1f7 100644
--- a/app/paint/gimpmybrush.c
+++ b/app/paint/gimpmybrush.c
@@ -42,6 +42,7 @@
 #include "core/gimpdrawable.h"
 #include "core/gimpimage.h"
 #include "core/gimpimage-undo.h"
+#include "core/gimpsymmetry.h"
 #include "core/gimptempbuf.h"
 
 #include "gimpmybrushoptions.h"
@@ -53,23 +54,24 @@
 struct _GimpMybrushPrivate
 {
   MyPaintGeglTiledSurface *surface;
-  MyPaintBrush            *brush;
+  GList                   *brushes;
 };
 
 
 /*  local function prototypes  */
 
-static void   gimp_mybrush_paint  (GimpPaintCore    *paint_core,
-                                   GimpDrawable     *drawable,
-                                   GimpPaintOptions *paint_options,
-                                   const GimpCoords *coords,
-                                   GimpPaintState    paint_state,
-                                   guint32           time);
-static void   gimp_mybrush_motion (GimpPaintCore    *paint_core,
-                                   GimpDrawable     *drawable,
-                                   GimpPaintOptions *paint_options,
-                                   const GimpCoords *coords,
-                                   guint32           time);
+static void   gimp_mybrush_finalize (GObject          *object);
+static void   gimp_mybrush_paint    (GimpPaintCore    *paint_core,
+                                     GimpDrawable     *drawable,
+                                     GimpPaintOptions *paint_options,
+                                     GimpSymmetry     *sym,
+                                     GimpPaintState    paint_state,
+                                     guint32           time);
+static void   gimp_mybrush_motion   (GimpPaintCore    *paint_core,
+                                     GimpDrawable     *drawable,
+                                     GimpPaintOptions *paint_options,
+                                     GimpSymmetry     *sym,
+                                     guint32           time);
 
 
 G_DEFINE_TYPE (GimpMybrush, gimp_mybrush, GIMP_TYPE_PAINT_CORE)
@@ -93,8 +95,11 @@ gimp_mybrush_register (Gimp                      *gimp,
 static void
 gimp_mybrush_class_init (GimpMybrushClass *klass)
 {
+  GObjectClass       *object_class     = G_OBJECT_CLASS (klass);
   GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass);
 
+  object_class->finalize  = gimp_mybrush_finalize;
+
   paint_core_class->paint = gimp_mybrush_paint;
 
   g_type_class_add_private (klass, sizeof (GimpMybrushPrivate));
@@ -109,16 +114,33 @@ gimp_mybrush_init (GimpMybrush *mybrush)
 }
 
 static void
+gimp_mybrush_finalize (GObject *object)
+{
+  GimpMybrush *mybrush = GIMP_MYBRUSH (object);
+
+  if (mybrush->private->brushes)
+    {
+      g_list_free_full (mybrush->private->brushes,
+                        (GDestroyNotify) mypaint_brush_unref);
+      mybrush->private->brushes = NULL;
+    }
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
 gimp_mybrush_paint (GimpPaintCore    *paint_core,
                     GimpDrawable     *drawable,
                     GimpPaintOptions *paint_options,
-                    const GimpCoords *coords,
+                    GimpSymmetry     *sym,
                     GimpPaintState    paint_state,
                     guint32           time)
 {
   GimpMybrush        *mybrush = GIMP_MYBRUSH (paint_core);
   GimpMybrushOptions *options = GIMP_MYBRUSH_OPTIONS (paint_options);
   GeglBuffer         *buffer;
+  gint                n_strokes;
+  gint                i;
 
   switch (paint_state)
     {
@@ -136,37 +158,54 @@ gimp_mybrush_paint (GimpPaintCore    *paint_core,
       mypaint_gegl_tiled_surface_set_buffer (mybrush->private->surface, buffer);
       g_object_unref (buffer);
 
-      mybrush->private->brush = mypaint_brush_new ();
-      mypaint_brush_from_defaults (mybrush->private->brush);
+      if (mybrush->private->brushes)
+        {
+          g_list_free_full (mybrush->private->brushes,
+                            (GDestroyNotify) mypaint_brush_unref);
+          mybrush->private->brushes = NULL;
+        }
 
-      if (options->mybrush)
+      n_strokes = gimp_symmetry_get_size (sym);
+      for (i = 0; i < n_strokes; i++)
         {
-          gchar *string;
-          gsize  length;
+          MyPaintBrush *brush;
 
-          if (g_file_get_contents (options->mybrush,
-                                   &string, &length, NULL))
+          brush = mypaint_brush_new ();
+          mypaint_brush_from_defaults (brush);
+
+          if (options->mybrush)
             {
-              if (! mypaint_brush_from_string (mybrush->private->brush, string))
-                g_printerr ("Failed to deserialize MyPaint brush\n");
+              gchar *string;
+              gsize  length;
+
+              if (g_file_get_contents (options->mybrush,
+                                       &string, &length, NULL))
+                {
+                  if (! mypaint_brush_from_string (brush, string))
+                    g_printerr ("Failed to deserialize MyPaint brush\n");
 
-              g_free (string);
+                  g_free (string);
+                }
             }
-        }
 
-      mypaint_brush_new_stroke (mybrush->private->brush);
+          mypaint_brush_new_stroke (brush);
+
+          mybrush->private->brushes = g_list_prepend (mybrush->private->brushes, brush);
+        }
+      mybrush->private->brushes = g_list_reverse (mybrush->private->brushes);
       break;
 
     case GIMP_PAINT_STATE_MOTION:
-      gimp_mybrush_motion (paint_core, drawable, paint_options, coords, time);
+      gimp_mybrush_motion (paint_core, drawable, paint_options, sym, time);
       break;
 
     case GIMP_PAINT_STATE_FINISH:
       mypaint_surface_unref ((MyPaintSurface *) mybrush->private->surface);
       mybrush->private->surface = NULL;
 
-      mypaint_brush_unref (mybrush->private->brush);
-      mybrush->private->brush = NULL;
+      g_list_free_full (mybrush->private->brushes,
+                        (GDestroyNotify) mypaint_brush_unref);
+      mybrush->private->brushes = NULL;
       break;
     }
 }
@@ -175,82 +214,131 @@ static void
 gimp_mybrush_motion (GimpPaintCore    *paint_core,
                      GimpDrawable     *drawable,
                      GimpPaintOptions *paint_options,
-                     const GimpCoords *coords,
+                     GimpSymmetry     *sym,
                      guint32           time)
 {
   GimpMybrush        *mybrush = GIMP_MYBRUSH (paint_core);
   GimpMybrushOptions *options = GIMP_MYBRUSH_OPTIONS (paint_options);
   GimpContext        *context = GIMP_CONTEXT (paint_options);
+  GimpCoords         *coords;
   GimpComponentMask   active_mask;
   GimpRGB             fg;
   GimpHSV             hsv;
   MyPaintRectangle    rect;
+  gint                n_strokes;
+  gint                i;
+  GList              *iter;
 
   active_mask = gimp_drawable_get_active_mask (drawable);
 
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_LOCK_ALPHA,
-                                (active_mask & GIMP_COMPONENT_ALPHA) ?
-                                FALSE : TRUE);
-
-  gimp_context_get_foreground (context, &fg);
-  gimp_rgb_to_hsv (&fg, &hsv);
-
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_COLOR_H,
-                                hsv.h);
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_COLOR_S,
-                                hsv.s);
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_COLOR_V,
-                                hsv.v);
-
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_OPAQUE,
-                                gimp_context_get_opacity (context));
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC,
-                                options->radius);
-  mypaint_brush_set_base_value (mybrush->private->brush,
-                                MYPAINT_BRUSH_SETTING_HARDNESS,
-                                options->hardness);
-
-  mypaint_surface_begin_atomic ((MyPaintSurface *) mybrush->private->surface);
-
-  mypaint_brush_stroke_to (mybrush->private->brush,
-                           (MyPaintSurface *) mybrush->private->surface,
-                           coords->x,
-                           coords->y,
-                           coords->pressure,
-                           coords->xtilt,
-                           coords->ytilt,
-                           1);
-
-  mypaint_surface_end_atomic ((MyPaintSurface *) mybrush->private->surface,
-                              &rect);
-
-  g_printerr ("painted rect: %d %d %d %d\n",
-              rect.x, rect.y, rect.width, rect.height);
-
-  if (rect.width > 0 && rect.height > 0)
+  n_strokes = gimp_symmetry_get_size (sym);
+
+  /* Number of strokes may change during a motion, depending on the type
+   * of symmetry. When that happens, we reset the brushes. */
+  if (g_list_length (mybrush->private->brushes) != n_strokes)
     {
-      GeglBuffer *src;
+      g_list_free_full (mybrush->private->brushes,
+                        (GDestroyNotify) mypaint_brush_unref);
+      mybrush->private->brushes = NULL;
 
-      src = mypaint_gegl_tiled_surface_get_buffer (mybrush->private->surface);
+      for (i = 0; i < n_strokes; i++)
+        {
+          MyPaintBrush *brush;
 
-      gegl_buffer_copy (src,
-                        (GeglRectangle *) &rect,
-                        GEGL_ABYSS_NONE,
-                        gimp_drawable_get_buffer (drawable),
-                        NULL);
+          brush = mypaint_brush_new ();
+          mypaint_brush_from_defaults (brush);
 
-      paint_core->x1 = MIN (paint_core->x1, rect.x);
-      paint_core->y1 = MIN (paint_core->y1, rect.y);
-      paint_core->x2 = MAX (paint_core->x2, rect.x + rect.width);
-      paint_core->y2 = MAX (paint_core->y2, rect.y + rect.height);
+          if (options->mybrush)
+            {
+              gchar *string;
+              gsize  length;
 
-      gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);
+              if (g_file_get_contents (options->mybrush,
+                                       &string, &length, NULL))
+                {
+                  if (! mypaint_brush_from_string (brush, string))
+                    g_printerr ("Failed to deserialize MyPaint brush\n");
+
+                  g_free (string);
+                }
+            }
+
+          mypaint_brush_new_stroke (brush);
+
+          mybrush->private->brushes = g_list_prepend (mybrush->private->brushes, brush);
+        }
+    }
+
+  for (iter = mybrush->private->brushes, i = 0; iter ; iter = g_list_next (iter), i++)
+    {
+      MyPaintBrush *brush = iter->data;
+
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_LOCK_ALPHA,
+                                    (active_mask & GIMP_COMPONENT_ALPHA) ?
+                                    FALSE : TRUE);
+
+      gimp_context_get_foreground (context, &fg);
+      gimp_rgb_to_hsv (&fg, &hsv);
+
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_COLOR_H,
+                                    hsv.h);
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_COLOR_S,
+                                    hsv.s);
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_COLOR_V,
+                                    hsv.v);
+
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_OPAQUE,
+                                    gimp_context_get_opacity (context));
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_RADIUS_LOGARITHMIC,
+                                    options->radius);
+      mypaint_brush_set_base_value (brush,
+                                    MYPAINT_BRUSH_SETTING_HARDNESS,
+                                    options->hardness);
+
+      mypaint_surface_begin_atomic ((MyPaintSurface *) mybrush->private->surface);
+
+      coords = gimp_symmetry_get_coords (sym, i);
+
+      mypaint_brush_stroke_to (brush,
+                               (MyPaintSurface *) mybrush->private->surface,
+                               coords->x,
+                               coords->y,
+                               coords->pressure,
+                               coords->xtilt,
+                               coords->ytilt,
+                               1);
+
+      mypaint_surface_end_atomic ((MyPaintSurface *) mybrush->private->surface,
+                                  &rect);
+
+      g_printerr ("painted rect: %d %d %d %d\n",
+                  rect.x, rect.y, rect.width, rect.height);
+
+      if (rect.width > 0 && rect.height > 0)
+        {
+          GeglBuffer *src;
+
+          src = mypaint_gegl_tiled_surface_get_buffer (mybrush->private->surface);
+
+          gegl_buffer_copy (src,
+                            (GeglRectangle *) &rect,
+                            GEGL_ABYSS_NONE,
+                            gimp_drawable_get_buffer (drawable),
+                            NULL);
+
+          paint_core->x1 = MIN (paint_core->x1, rect.x);
+          paint_core->y1 = MIN (paint_core->y1, rect.y);
+          paint_core->x2 = MAX (paint_core->x2, rect.x + rect.width);
+          paint_core->y2 = MAX (paint_core->y2, rect.y + rect.height);
+
+          gimp_drawable_update (drawable, rect.x, rect.y, rect.width, rect.height);
+        }
     }
 }
 


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