[gimp/wip/alxsa/mypaint-brush-v2] Combining Surface2 code back to GimpMybrushSurface



commit ddf7d3e6250872804aba62fc6089d0375ba96ff3
Author: Alx Sa <cmyk student gmail com>
Date:   Mon Oct 10 03:31:56 2022 +0000

    Combining Surface2 code back to GimpMybrushSurface

 app/paint/gimpmybrushsurface.c | 369 +++--------------------------------------
 app/paint/gimpmybrushsurface.h |  23 +--
 2 files changed, 27 insertions(+), 365 deletions(-)
---
diff --git a/app/paint/gimpmybrushsurface.c b/app/paint/gimpmybrushsurface.c
index b7145b9421..2a6c070a31 100644
--- a/app/paint/gimpmybrushsurface.c
+++ b/app/paint/gimpmybrushsurface.c
@@ -40,18 +40,6 @@
 #define WGM_EPSILON 0.001
 
 struct _GimpMybrushSurface
-{
-  MyPaintSurface surface;
-  GeglBuffer *buffer;
-  GeglBuffer *paint_mask;
-  gint        paint_mask_x;
-  gint        paint_mask_y;
-  GeglRectangle dirty;
-  GimpComponentMask component_mask;
-  GimpMybrushOptions *options;
-};
-
-struct _GimpMybrushSurface2
 {
   MyPaintSurface2     surface;
   GeglBuffer         *buffer;
@@ -422,297 +410,12 @@ calculate_dab_roi (float x,
   return *GEGL_RECTANGLE (x0, y0, x1 - x0, y1 - y0);
 }
 
-static void
-gimp_mypaint_surface_get_color (MyPaintSurface *base_surface,
-                                float           x,
-                                float           y,
-                                float           radius,
-                                float          *color_r,
-                                float          *color_g,
-                                float          *color_b,
-                                float          *color_a)
-{
-  GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
-  GeglRectangle dabRect;
-
-  if (radius < 1.0f)
-    radius = 1.0f;
-
-  dabRect = calculate_dab_roi (x, y, radius);
-
-  *color_r = 0.0f;
-  *color_g = 0.0f;
-  *color_b = 0.0f;
-  *color_a = 0.0f;
-
-  if (dabRect.width > 0 || dabRect.height > 0)
-  {
-    const float one_over_radius2 = 1.0f / (radius * radius);
-    float sum_weight = 0.0f;
-    float sum_r = 0.0f;
-    float sum_g = 0.0f;
-    float sum_b = 0.0f;
-    float sum_a = 0.0f;
-
-     /* Read in clamp mode to avoid transparency bleeding in at the edges */
-    GeglBufferIterator *iter = gegl_buffer_iterator_new (surface->buffer, &dabRect, 0,
-                                                         babl_format ("R'aG'aB'aA float"),
-                                                         GEGL_BUFFER_READ,
-                                                         GEGL_ABYSS_CLAMP, 2);
-    if (surface->paint_mask)
-      {
-        GeglRectangle mask_roi = dabRect;
-        mask_roi.x -= surface->paint_mask_x;
-        mask_roi.y -= surface->paint_mask_y;
-        gegl_buffer_iterator_add (iter, surface->paint_mask, &mask_roi, 0,
-                                  babl_format ("Y float"),
-                                  GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
-      }
-
-    while (gegl_buffer_iterator_next (iter))
-      {
-        float *pixel = (float *)iter->items[0].data;
-        float *mask;
-        int iy, ix;
-
-        if (surface->paint_mask)
-          mask = iter->items[1].data;
-        else
-          mask = NULL;
-
-        for (iy = iter->items[0].roi.y; iy < iter->items[0].roi.y + iter->items[0].roi.height; iy++)
-          {
-            float yy = (iy + 0.5f - y);
-            for (ix = iter->items[0].roi.x; ix < iter->items[0].roi.x +  iter->items[0].roi.width; ix++)
-              {
-                /* pixel_weight == a standard dab with hardness = 0.5, aspect_ratio = 1.0, and angle = 0.0 */
-                float xx = (ix + 0.5f - x);
-                float rr = (yy * yy + xx * xx) * one_over_radius2;
-                float pixel_weight = 0.0f;
-                if (rr <= 1.0f)
-                  pixel_weight = 1.0f - rr;
-                if (mask)
-                  pixel_weight *= *mask;
-
-                sum_r += pixel_weight * pixel[RED];
-                sum_g += pixel_weight * pixel[GREEN];
-                sum_b += pixel_weight * pixel[BLUE];
-                sum_a += pixel_weight * pixel[ALPHA];
-                sum_weight += pixel_weight;
-
-                pixel += 4;
-                if (mask)
-                  mask += 1;
-              }
-          }
-      }
-
-    if (sum_a > 0.0f && sum_weight > 0.0f)
-      {
-        sum_r /= sum_weight;
-        sum_g /= sum_weight;
-        sum_b /= sum_weight;
-        sum_a /= sum_weight;
-
-        sum_r /= sum_a;
-        sum_g /= sum_a;
-        sum_b /= sum_a;
-
-        /* FIXME: Clamping is wrong because GEGL allows alpha > 1, this should probably re-multipy things */
-        *color_r = CLAMP(sum_r, 0.0f, 1.0f);
-        *color_g = CLAMP(sum_g, 0.0f, 1.0f);
-        *color_b = CLAMP(sum_b, 0.0f, 1.0f);
-        *color_a = CLAMP(sum_a, 0.0f, 1.0f);
-      }
-  }
-
-}
-
-static int
-gimp_mypaint_surface_draw_dab (MyPaintSurface *base_surface,
-                               float           x,
-                               float           y,
-                               float           radius,
-                               float           color_r,
-                               float           color_g,
-                               float           color_b,
-                               float           opaque,
-                               float           hardness,
-                               float           color_a,
-                               float           aspect_ratio,
-                               float           angle,
-                               float           lock_alpha,
-                               float           colorize)
-{
-  GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
-  GeglBufferIterator *iter;
-  GeglRectangle       dabRect;
-  GimpComponentMask   component_mask = surface->component_mask;
-
-  const float one_over_radius2 = 1.0f / (radius * radius);
-  const double angle_rad = angle / 360 * 2 * M_PI;
-  const float cs = cos(angle_rad);
-  const float sn = sin(angle_rad);
-  float normal_mode;
-  float segment1_slope;
-  float segment2_slope;
-  float r_aa_start;
-
-  hardness = CLAMP (hardness, 0.0f, 1.0f);
-  segment1_slope = -(1.0f / hardness - 1.0f);
-  segment2_slope = -hardness / (1.0f - hardness);
-  aspect_ratio = MAX (1.0f, aspect_ratio);
-
-  r_aa_start = radius - 1.0f;
-  r_aa_start = MAX (r_aa_start, 0);
-  r_aa_start = (r_aa_start * r_aa_start) / aspect_ratio;
-
-  normal_mode = opaque * (1.0f - colorize);
-  colorize = opaque * colorize;
-
-  /* FIXME: This should use the real matrix values to trim aspect_ratio dabs */
-  dabRect = calculate_dab_roi (x, y, radius);
-  gegl_rectangle_intersect (&dabRect, &dabRect, gegl_buffer_get_extent (surface->buffer));
-
-  if (dabRect.width <= 0 || dabRect.height <= 0)
-    return 0;
-
-  gegl_rectangle_bounding_box (&surface->dirty, &surface->dirty, &dabRect);
-
-  iter = gegl_buffer_iterator_new (surface->buffer, &dabRect, 0,
-                                   babl_format ("R'G'B'A float"),
-                                   GEGL_BUFFER_READWRITE,
-                                   GEGL_ABYSS_NONE, 2);
-  if (surface->paint_mask)
-    {
-      GeglRectangle mask_roi = dabRect;
-      mask_roi.x -= surface->paint_mask_x;
-      mask_roi.y -= surface->paint_mask_y;
-      gegl_buffer_iterator_add (iter, surface->paint_mask, &mask_roi, 0,
-                                babl_format ("Y float"),
-                                GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
-    }
-
-  while (gegl_buffer_iterator_next (iter))
-    {
-      float *pixel = (float *)iter->items[0].data;
-      float *mask;
-      int iy, ix;
-
-      if (surface->paint_mask)
-        mask = iter->items[1].data;
-      else
-        mask = NULL;
-
-      for (iy = iter->items[0].roi.y; iy < iter->items[0].roi.y + iter->items[0].roi.height; iy++)
-        {
-          for (ix = iter->items[0].roi.x; ix < iter->items[0].roi.x +  iter->items[0].roi.width; ix++)
-            {
-              float rr, base_alpha, alpha, dst_alpha, r, g, b, a;
-              if (radius < 3.0f)
-                rr = calculate_rr_antialiased (ix, iy, x, y, aspect_ratio, sn, cs, one_over_radius2, 
r_aa_start);
-              else
-                rr = calculate_rr (ix, iy, x, y, aspect_ratio, sn, cs, one_over_radius2);
-              base_alpha = calculate_alpha_for_rr (rr, hardness, segment1_slope, segment2_slope);
-              alpha = base_alpha * normal_mode;
-              if (mask)
-                alpha *= *mask;
-              dst_alpha = pixel[ALPHA];
-              /* a = alpha * color_a + dst_alpha * (1.0f - alpha);
-               * which converts to: */
-              a = alpha * (color_a - dst_alpha) + dst_alpha;
-              r = pixel[RED];
-              g = pixel[GREEN];
-              b = pixel[BLUE];
-
-              if (a > 0.0f)
-                {
-                  /* By definition the ratio between each color[] and pixel[] component in a 
non-pre-multipled blend always sums to 1.0f.
-                   * Originally this would have been "(color[n] * alpha * color_a + pixel[n] * dst_alpha * 
(1.0f - alpha)) / a",
-                   * instead we only calculate the cheaper term. */
-                  float src_term = (alpha * color_a) / a;
-                  float dst_term = 1.0f - src_term;
-                  r = color_r * src_term + r * dst_term;
-                  g = color_g * src_term + g * dst_term;
-                  b = color_b * src_term + b * dst_term;
-                }
-
-              if (colorize > 0.0f && base_alpha > 0.0f)
-                {
-                  alpha = base_alpha * colorize;
-                  a = alpha + dst_alpha - alpha * dst_alpha;
-                  if (a > 0.0f)
-                    {
-                      GimpHSL pixel_hsl, out_hsl;
-                      GimpRGB pixel_rgb = {color_r, color_g, color_b};
-                      GimpRGB out_rgb   = {r, g, b};
-                      float src_term = alpha / a;
-                      float dst_term = 1.0f - src_term;
-
-                      gimp_rgb_to_hsl (&pixel_rgb, &pixel_hsl);
-                      gimp_rgb_to_hsl (&out_rgb, &out_hsl);
-
-                      out_hsl.h = pixel_hsl.h;
-                      out_hsl.s = pixel_hsl.s;
-                      gimp_hsl_to_rgb (&out_hsl, &out_rgb);
-
-                      r = (float)out_rgb.r * src_term + r * dst_term;
-                      g = (float)out_rgb.g * src_term + g * dst_term;
-                      b = (float)out_rgb.b * src_term + b * dst_term;
-                    }
-                }
-
-              if (surface->options->no_erasing)
-                a = MAX (a, pixel[ALPHA]);
-
-              if (component_mask != GIMP_COMPONENT_MASK_ALL)
-                {
-                  if (component_mask & GIMP_COMPONENT_MASK_RED)
-                    pixel[RED]   = r;
-                  if (component_mask & GIMP_COMPONENT_MASK_GREEN)
-                    pixel[GREEN] = g;
-                  if (component_mask & GIMP_COMPONENT_MASK_BLUE)
-                    pixel[BLUE]  = b;
-                  if (component_mask & GIMP_COMPONENT_MASK_ALPHA)
-                    pixel[ALPHA] = a;
-                }
-              else
-                {
-                  pixel[RED]   = r;
-                  pixel[GREEN] = g;
-                  pixel[BLUE]  = b;
-                  pixel[ALPHA] = a;
-                }
-
-              pixel += 4;
-              if (mask)
-                mask += 1;
-            }
-        }
-    }
-
-  return 1;
-}
-
 static void
 gimp_mypaint_surface_begin_atomic (MyPaintSurface *base_surface)
 {
 
 }
 
-static void
-gimp_mypaint_surface_end_atomic (MyPaintSurface   *base_surface,
-                                 MyPaintRectangle *roi)
-{
-  GimpMybrushSurface *surface = (GimpMybrushSurface *)base_surface;
-
-  roi->x         = surface->dirty.x;
-  roi->y         = surface->dirty.y;
-  roi->width     = surface->dirty.width;
-  roi->height    = surface->dirty.height;
-  surface->dirty = *GEGL_RECTANGLE (0, 0, 0, 0);
-}
-
 static void
 gimp_mypaint_surface_destroy (MyPaintSurface *base_surface)
 {
@@ -723,36 +426,6 @@ gimp_mypaint_surface_destroy (MyPaintSurface *base_surface)
   g_free (surface);
 }
 
-GimpMybrushSurface *
-gimp_mypaint_surface_new (GeglBuffer         *buffer,
-                          GimpComponentMask   component_mask,
-                          GeglBuffer         *paint_mask,
-                          gint                paint_mask_x,
-                          gint                paint_mask_y,
-                          GimpMybrushOptions *options)
-{
-  GimpMybrushSurface *surface = g_malloc0 (sizeof (GimpMybrushSurface));
-
-  mypaint_surface_init ((MyPaintSurface *)surface);
-
-  surface->surface.get_color    = gimp_mypaint_surface_get_color;
-  surface->surface.draw_dab     = gimp_mypaint_surface_draw_dab;
-  surface->surface.begin_atomic = gimp_mypaint_surface_begin_atomic;
-  surface->surface.end_atomic   = gimp_mypaint_surface_end_atomic;
-  surface->surface.destroy      = gimp_mypaint_surface_destroy;
-  surface->component_mask       = component_mask;
-  surface->options              = options;
-  surface->buffer               = g_object_ref (buffer);
-  if (paint_mask)
-    surface->paint_mask         = g_object_ref (paint_mask);
-
-  surface->paint_mask_x         = paint_mask_x;
-  surface->paint_mask_y         = paint_mask_y;
-  surface->dirty                = *GEGL_RECTANGLE (0, 0, 0, 0);
-
-  return surface;
-}
-
 /* MyPaintSurface2 implementation */
 static int
 gimp_mypaint_surface_draw_dab_2 (MyPaintSurface2 *base_surface,
@@ -773,8 +446,7 @@ gimp_mypaint_surface_draw_dab_2 (MyPaintSurface2 *base_surface,
                                 float             posterize_num,
                                 float             paint)
 {
-  /* Placeholder - eventually implement here */
-  GimpMybrushSurface2 *surface = (GimpMybrushSurface2 *) base_surface;
+  GimpMybrushSurface *surface = (GimpMybrushSurface *) base_surface;
   GeglBufferIterator *iter;
   GeglRectangle       dabRect;
   GimpComponentMask   component_mask = surface->component_mask;
@@ -1001,7 +673,6 @@ gimp_mypaint_surface_draw_dab_2 (MyPaintSurface2 *base_surface,
   return 1;
 }
 
-
 static int
 gimp_mypaint_surface_draw_dab_wrapper (MyPaintSurface *surface,
                                        float           x,
@@ -1040,8 +711,8 @@ gimp_mypaint_surface_get_color_2 (MyPaintSurface2 *base_surface,
                                   float           *color_a,
                                   float            paint)
 {
-  GimpMybrushSurface2 *surface = (GimpMybrushSurface2 *) base_surface;
-  GeglRectangle dabRect;
+  GimpMybrushSurface *surface = (GimpMybrushSurface *) base_surface;
+  GeglRectangle       dabRect;
 
   if (radius < 1.0f)
     radius = 1.0f;
@@ -1180,7 +851,7 @@ static void
 gimp_mypaint_surface_end_atomic_2 (MyPaintSurface2    *base_surface,
                                    MyPaintRectangles  *roi)
 {
-  GimpMybrushSurface2 *surface = (GimpMybrushSurface2 *) base_surface;
+  GimpMybrushSurface *surface = (GimpMybrushSurface *) base_surface;
 
   if (roi)
     {
@@ -1205,16 +876,16 @@ gimp_mypaint_surface_end_atomic_wrapper (MyPaintSurface   *surface,
   gimp_mypaint_surface_end_atomic_2 ((MyPaintSurface2 *) surface, &rois);
 }
 
-GimpMybrushSurface2 *
-gimp_mypaint_surface2_new (GeglBuffer         *buffer,
-                           GimpComponentMask   component_mask,
-                           GeglBuffer         *paint_mask,
-                           gint                paint_mask_x,
-                           gint                paint_mask_y,
-                           GimpMybrushOptions *options)
+GimpMybrushSurface *
+gimp_mypaint_surface_new (GeglBuffer         *buffer,
+                          GimpComponentMask   component_mask,
+                          GeglBuffer         *paint_mask,
+                          gint                paint_mask_x,
+                          gint                paint_mask_y,
+                          GimpMybrushOptions *options)
 {
-  GimpMybrushSurface2 *surface = g_malloc0 (sizeof (GimpMybrushSurface2));
-  MyPaintSurface2 *s;
+  GimpMybrushSurface *surface = g_malloc0 (sizeof (GimpMybrushSurface));
+  MyPaintSurface2    *s;
 
   mypaint_surface_init (&surface->surface.parent);
   s = &surface->surface;
@@ -1228,15 +899,15 @@ gimp_mypaint_surface2_new (GeglBuffer         *buffer,
   s->parent.get_color     = gimp_mypaint_surface_get_color_wrapper;
   s->parent.end_atomic    = gimp_mypaint_surface_end_atomic_wrapper;
 
-  surface->component_mask               = component_mask;
-  surface->options                      = options;
-  surface->buffer                       = g_object_ref (buffer);
+  surface->component_mask = component_mask;
+  surface->options        = options;
+  surface->buffer         = g_object_ref (buffer);
   if (paint_mask)
-    surface->paint_mask                 = g_object_ref (paint_mask);
+    surface->paint_mask   = g_object_ref (paint_mask);
 
-  surface->paint_mask_x                 = paint_mask_x;
-  surface->paint_mask_y                 = paint_mask_y;
-  surface->dirty                        = *GEGL_RECTANGLE (0, 0, 0, 0);
+  surface->paint_mask_x   = paint_mask_x;
+  surface->paint_mask_y   = paint_mask_y;
+  surface->dirty          = *GEGL_RECTANGLE (0, 0, 0, 0);
 
   return surface;
 }
diff --git a/app/paint/gimpmybrushsurface.h b/app/paint/gimpmybrushsurface.h
index 287df2c20f..71bc0baa22 100644
--- a/app/paint/gimpmybrushsurface.h
+++ b/app/paint/gimpmybrushsurface.h
@@ -19,24 +19,15 @@
 #define  __GIMP_MYBRUSH_SURFACE_H__
 
 
-typedef struct _GimpMybrushSurface  GimpMybrushSurface;
-typedef struct _GimpMybrushSurface2 GimpMybrushSurface2;
+typedef struct _GimpMybrushSurface GimpMybrushSurface;
 
 GimpMybrushSurface *
-gimp_mypaint_surface_new  (GeglBuffer         *buffer,
-                           GimpComponentMask   component_mask,
-                           GeglBuffer         *paint_mask,
-                           gint                paint_mask_x,
-                           gint                paint_mask_y,
-                           GimpMybrushOptions *options);
-
-GimpMybrushSurface2 *
-gimp_mypaint_surface2_new (GeglBuffer         *buffer,
-                           GimpComponentMask   component_mask,
-                           GeglBuffer         *paint_mask,
-                           gint                paint_mask_x,
-                           gint                paint_mask_y,
-                           GimpMybrushOptions *options);
+gimp_mypaint_surface_new (GeglBuffer         *buffer,
+                          GimpComponentMask   component_mask,
+                          GeglBuffer         *paint_mask,
+                          gint                paint_mask_x,
+                          gint                paint_mask_y,
+                          GimpMybrushOptions *options);
 
 
 #endif  /*  __GIMP_MYBRUSH_SURFACE_H__  */


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