[gegl] path: handle CMYK



commit 6557b5efdcfe28173cbbc121a98a4c6177d45d0f
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Dec 4 00:34:47 2018 +0100

    path: handle CMYK

 operations/external/path.c | 89 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 71 insertions(+), 18 deletions(-)
---
diff --git a/operations/external/path.c b/operations/external/path.c
index 2cf3e9b21..c01b2f0f0 100644
--- a/operations/external/path.c
+++ b/operations/external/path.c
@@ -13,7 +13,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
  *
- * Copyright 2006 Øyvind Kolås <pippin gimp org>
+ * Copyright 2006, 2018 Øyvind Kolås <pippin gimp org>
  */
 
 
@@ -216,20 +216,22 @@ gegl_path_stamp (GeglBuffer *buffer,
                  GeglColor  *color,
                  gdouble     opacity)
 {
-  gfloat col[4];
+  gfloat col[5];
   StampStatic s = {FALSE,}; /* there should be a cache of stamps,
                                note that stamps are accessed in multiple threads
                              */
-
   GeglRectangle temp;
   GeglRectangle roi;
+  const Babl *format = gegl_color_get_format (color);
+  BablModelFlag model_flags = babl_get_model_flags (format);
+  int is_cmyk = model_flags & BABL_MODEL_FLAG_CMYK ? 1 : 0;
 
   roi.x = floor(x-radius);
   roi.y = floor(y-radius);
   roi.width = ceil (x+radius) - floor (x-radius);
   roi.height = ceil (y+radius) - floor (y-radius);
 
-  gegl_color_get_pixel (color, babl_format ("RGBA float"), col);
+  gegl_color_get_pixel (color, babl_format (is_cmyk?"cmykA float":"RGBA float"), col);
 
   /* bail out if we wouldn't leave a mark on the buffer */
   if (!gegl_rectangle_intersect (&temp, &roi, clip_rect))
@@ -238,7 +240,7 @@ gegl_path_stamp (GeglBuffer *buffer,
     }
 
   if (s.format == NULL)
-    s.format = babl_format ("RaGaBaA float");
+    s.format = babl_format (is_cmyk?"camayakaA float":"RaGaBaA float");
 
   if (s.buf == NULL ||
       s.radius != radius)
@@ -246,7 +248,7 @@ gegl_path_stamp (GeglBuffer *buffer,
       g_free (s.buf);
       /* allocate a little bit more, just in case due to rounding errors and
        * such */
-      s.buf = g_malloc (4*4* (roi.width + 2 ) * (roi.height + 2));
+      s.buf = g_malloc (4*5* (roi.width + 2 ) * (roi.height + 2));
       s.radius = radius;
       s.valid = TRUE;
     }
@@ -257,6 +259,7 @@ gegl_path_stamp (GeglBuffer *buffer,
   {
     gint u, v;
     gint i=0;
+    gint components = is_cmyk ? 5 : 4;
 
     gfloat radius_squared = radius * radius;
     gfloat inner_radius_squared = (radius * hardness)*(radius * hardness);
@@ -270,10 +273,10 @@ gegl_path_stamp (GeglBuffer *buffer,
           gfloat o = (u-x) * (u-x) + vy2;
 
           if (o < inner_radius_squared)
-             o = col[3];
+             o = col[components-1];
           else if (o < radius_squared)
             {
-              o = (1.0 - (o-inner_radius_squared) / (soft_range)) * col[3];
+              o = (1.0 - (o-inner_radius_squared) / (soft_range)) * col[components-1];
             }
           else
             {
@@ -283,8 +286,8 @@ gegl_path_stamp (GeglBuffer *buffer,
            {
              gint c;
              o = o*opacity;
-             for (c=0;c<4;c++)
-               s.buf[i*4+c] = (s.buf[i*4+c] * (1.0-o) + col[c] * o);
+             for (c=0;c<components;c++)
+               s.buf[i*components+c] = (s.buf[i*components+c] * (1.0-o) + col[c] * o);
            }
          i++;
         }
@@ -314,7 +317,20 @@ static void
 prepare (GeglOperation *operation)
 {
   GeglProperties *o = GEGL_PROPERTIES (operation);
-  gegl_operation_set_format (operation, "output", babl_format ("R'aG'aB'aA float"));
+
+  const Babl *fill_format = gegl_color_get_format (o->fill);
+  const Babl *stroke_format = gegl_color_get_format (o->stroke);
+  BablModelFlag model_flags = babl_get_model_flags (fill_format) |
+                              babl_get_model_flags (stroke_format);
+
+  if (model_flags & BABL_MODEL_FLAG_CMYK)
+  {
+    gegl_operation_set_format (operation, "output", babl_format ("camayakaA float"));
+  }
+  else
+  {
+    gegl_operation_set_format (operation, "output", babl_format ("R'aG'aB'aA float"));
+  }
   if (o->transform && o->transform[0] != '\0')
     {
       GeglMatrix3 matrix;
@@ -358,6 +374,11 @@ process (GeglOperation       *operation,
          gint                 level)
 {
   GeglProperties *o = GEGL_PROPERTIES (operation);
+  const Babl *format =  gegl_operation_get_format (operation, "output");
+
+  int is_cmyk = babl_get_model_flags (format) & BABL_MODEL_FLAG_CMYK?1:0;
+
+  const Babl *formats[4]={NULL, NULL, NULL};
 
   if (input)
     {
@@ -369,13 +390,28 @@ process (GeglOperation       *operation,
       gegl_buffer_clear (output, result);
     }
 
+  if (is_cmyk)
+  {
+    formats[0]=babl_format ("cairo-ACYK32");
+    formats[1]=babl_format ("cairo-ACMK32");
+  }
+  else
+  {
+    formats[0]=babl_format ("cairo-ARGB32");
+  }
+
   if (o->fill_opacity > 0.0001 && o->fill)
     {
-      gdouble color[4] = {0, 0, 0, 0};
-      gegl_color_get_pixel (o->fill, babl_format ("R'G'B'A double"), color);
-      color[3] *= o->fill_opacity;
+      int alpha_no = is_cmyk ? 4 : 3;
+      gdouble color[5] = {0, 0, 0, 0, 0};
+
+      if (is_cmyk)
+        gegl_color_get_pixel (o->fill, babl_format ("cmykA double"), color);
+      else
+        gegl_color_get_pixel (o->fill, babl_format ("R'G'B'A double"), color);
+      color[alpha_no] *= o->fill_opacity;
 
-      if (color[3] > 0.001)
+      if (color[alpha_no] > 0.001)
         {
           static GMutex mutex = { 0, };
           cairo_t *cr;
@@ -383,7 +419,10 @@ process (GeglOperation       *operation,
           guchar *data;
 
           g_mutex_lock (&mutex);
-          data = gegl_buffer_linear_open (output, result, NULL, babl_format ("cairo-ARGB32"));
+
+          for (int i = 0; formats[i]; i++)
+          {
+          data = gegl_buffer_linear_open (output, result, NULL, formats[i]);
           surface = cairo_image_surface_create_for_data (data,
                                                          CAIRO_FORMAT_ARGB32,
                                                          result->width,
@@ -398,11 +437,25 @@ process (GeglOperation       *operation,
             }
 
           gegl_path_cairo_play (o->d, cr);
-          cairo_set_source_rgba (cr, color[0], color[1], color[2], color[3]);
+
+          switch (i + is_cmyk)
+          {
+            case 0:
+              cairo_set_source_rgba (cr, color[0], color[1], color[2], color[3]);
+              break;
+            case 1:
+              cairo_set_source_rgba (cr, color[0], color[2], color[3], color[4]);
+              break;
+            case 2:
+              cairo_set_source_rgba (cr, color[0], color[1], color[3], color[4]);
+              break;
+          }
           cairo_fill (cr);
 
-          g_mutex_unlock (&mutex);
           gegl_buffer_linear_close (output, data);
+          }
+
+          g_mutex_unlock (&mutex);
         }
     }
 


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