Bug 783528 - PDF export ignores layer masks.

Cairo doc is pretty clear about cairo_mask_surface():
> A drawing operator that paints the current source using the alpha
> channel of @surface as a mask
Therefore when creating a mask surface, it must be in one of
CAIRO_FORMAT_* with an alpha channel and the mask data must be copied
into this alpha channel. I chose CAIRO_FORMAT_A8 (a format with alpha
only) which I map to "Y u8" babl format in GEGL so that
gegl_buffer_copy() copies the contents of Y into A.
This commit is contained in:
Jehan 2017-06-16 16:23:38 +02:00
parent 85c0373489
commit dd6dab113e
1 changed files with 22 additions and 6 deletions

View File

@ -242,7 +242,8 @@ static void remove_call (GtkTreeModel *tree_model
gpointer user_data); gpointer user_data);
static void recount_pages (void); static void recount_pages (void);
static cairo_surface_t * get_drawable_image (gint32 drawable_ID, static cairo_surface_t * get_cairo_surface (gint32 drawable_ID,
gboolean as_mask,
GError **error); GError **error);
static GimpRGB get_layer_color (gint32 layer_ID, static GimpRGB get_layer_color (gint32 layer_ID,
@ -591,7 +592,8 @@ run (const gchar *name,
mask_ID = gimp_layer_get_mask (layer_ID); mask_ID = gimp_layer_get_mask (layer_ID);
if (mask_ID != -1) if (mask_ID != -1)
{ {
mask_image = get_drawable_image (mask_ID, &error); mask_image = get_cairo_surface (mask_ID, TRUE,
&error);
if (error != NULL) if (error != NULL)
{ {
*nreturn_vals = 2; *nreturn_vals = 2;
@ -638,7 +640,8 @@ run (const gchar *name,
{ {
cairo_surface_t *layer_image; cairo_surface_t *layer_image;
layer_image = get_drawable_image (layer_ID, &error); layer_image = get_cairo_surface (layer_ID, FALSE,
&error);
if (error != NULL) if (error != NULL)
{ {
*nreturn_vals = 2; *nreturn_vals = 2;
@ -1304,8 +1307,9 @@ recount_pages (void)
/******************************************************/ /******************************************************/
static cairo_surface_t * static cairo_surface_t *
get_drawable_image (gint32 drawable_ID, get_cairo_surface (gint32 drawable_ID,
GError **error) gboolean as_mask,
GError **error)
{ {
GeglBuffer *src_buffer; GeglBuffer *src_buffer;
GeglBuffer *dest_buffer; GeglBuffer *dest_buffer;
@ -1320,7 +1324,9 @@ get_drawable_image (gint32 drawable_ID,
width = gegl_buffer_get_width (src_buffer); width = gegl_buffer_get_width (src_buffer);
height = gegl_buffer_get_height (src_buffer); height = gegl_buffer_get_height (src_buffer);
if (gimp_drawable_has_alpha (drawable_ID)) if (as_mask)
format = CAIRO_FORMAT_A8;
else if (gimp_drawable_has_alpha (drawable_ID))
format = CAIRO_FORMAT_ARGB32; format = CAIRO_FORMAT_ARGB32;
else else
format = CAIRO_FORMAT_RGB24; format = CAIRO_FORMAT_RGB24;
@ -1351,6 +1357,16 @@ get_drawable_image (gint32 drawable_ID,
} }
dest_buffer = gimp_cairo_surface_create_buffer (surface); dest_buffer = gimp_cairo_surface_create_buffer (surface);
if (as_mask)
{
/* src_buffer represents a mask in "Y u8", "Y u16", etc. formats.
* Yet cairo_mask*() functions only care about the alpha channel of
* the surface. Hence I change the format of dest_buffer so that the
* Y channel of src_buffer actually refers to the A channel of
* dest_buffer/surface in Cairo.
*/
gegl_buffer_set_format (dest_buffer, babl_format ("Y u8"));
}
gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL); gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);