[gegl] path: handle CMYK
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] path: handle CMYK
- Date: Mon, 3 Dec 2018 23:36:34 +0000 (UTC)
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]