Issue #1002: Fix for layer groups in PDF export
Added a recursive loop to draw layer children in layer groups. Text layers in layer groups are now exported correctly.
This commit is contained in:
@ -260,6 +260,19 @@ static void drawText (gint32 text_id,
|
||||
gdouble x_res,
|
||||
gdouble y_res);
|
||||
|
||||
static void draw_layer (gint32 *layers,
|
||||
gint n_layers,
|
||||
gint *j,
|
||||
gint *nreturn_vals,
|
||||
cairo_surface_t *pdf_file,
|
||||
cairo_t *cr,
|
||||
FILE *fp,
|
||||
GimpParam *values,
|
||||
gdouble x_res,
|
||||
gdouble y_res,
|
||||
const gchar *name,
|
||||
GError *error);
|
||||
|
||||
static gboolean dnd_remove = TRUE;
|
||||
static PdfMultiPage multi_page;
|
||||
|
||||
@ -580,122 +593,7 @@ run (const gchar *name,
|
||||
/* Now, we should loop over the layers of each image */
|
||||
for (j = 0; j < n_layers; j++)
|
||||
{
|
||||
gint32 layer_ID;
|
||||
gint32 mask_ID = -1;
|
||||
cairo_surface_t *mask_image = NULL;
|
||||
gdouble opacity;
|
||||
gboolean single_color;
|
||||
gint x, y;
|
||||
|
||||
if (optimize.reverse_order && optimize.layers_as_pages)
|
||||
layer_ID = layers [j];
|
||||
else
|
||||
layer_ID = layers [n_layers - j - 1];
|
||||
|
||||
opacity = gimp_layer_get_opacity (layer_ID) / 100.0;
|
||||
|
||||
if ((gimp_item_get_visible (layer_ID) && opacity > 0.0) ||
|
||||
! optimize.ignore_hidden)
|
||||
{
|
||||
mask_ID = gimp_layer_get_mask (layer_ID);
|
||||
if (mask_ID != -1)
|
||||
{
|
||||
mask_image = get_cairo_surface (mask_ID, TRUE,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
*nreturn_vals = 2;
|
||||
|
||||
/* free the resources */
|
||||
cairo_surface_destroy (pdf_file);
|
||||
cairo_destroy (cr);
|
||||
fclose (fp);
|
||||
|
||||
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
||||
|
||||
values[1].type = GIMP_PDB_STRING;
|
||||
values[1].data.d_string = error->message;
|
||||
return;
|
||||
}
|
||||
}
|
||||
gimp_drawable_offsets (layer_ID, &x, &y);
|
||||
|
||||
if (! gimp_item_is_text_layer (layer_ID))
|
||||
{
|
||||
/* For raster layers */
|
||||
|
||||
GimpRGB layer_color;
|
||||
|
||||
layer_color = get_layer_color (layer_ID, &single_color);
|
||||
|
||||
cairo_rectangle (cr, x, y,
|
||||
gimp_drawable_width (layer_ID),
|
||||
gimp_drawable_height (layer_ID));
|
||||
|
||||
if (optimize.vectorize && single_color)
|
||||
{
|
||||
cairo_set_source_rgba (cr,
|
||||
layer_color.r,
|
||||
layer_color.g,
|
||||
layer_color.b,
|
||||
layer_color.a * opacity);
|
||||
if (mask_ID != -1)
|
||||
cairo_mask_surface (cr, mask_image, x, y);
|
||||
else
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_surface_t *layer_image;
|
||||
|
||||
layer_image = get_cairo_surface (layer_ID, FALSE,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
*nreturn_vals = 2;
|
||||
|
||||
/* free the resources */
|
||||
cairo_surface_destroy (pdf_file);
|
||||
cairo_destroy (cr);
|
||||
fclose (fp);
|
||||
|
||||
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
||||
|
||||
values[1].type = GIMP_PDB_STRING;
|
||||
values[1].data.d_string = error->message;
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_set_source_surface (cr, layer_image, x, y);
|
||||
cairo_push_group (cr);
|
||||
cairo_paint_with_alpha (cr, opacity);
|
||||
cairo_pop_group_to_source (cr);
|
||||
|
||||
if (mask_ID != -1)
|
||||
cairo_mask_surface (cr, mask_image, x, y);
|
||||
else
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_reset_clip (cr);
|
||||
|
||||
cairo_surface_destroy (layer_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For text layers */
|
||||
drawText (layer_ID, opacity, cr, x_res, y_res);
|
||||
}
|
||||
/* draw new page if "layers as pages" option is checked */
|
||||
if (optimize.layers_as_pages &&
|
||||
g_strcmp0 (name, SAVE2_PROC) == 0)
|
||||
cairo_show_page (cr);
|
||||
}
|
||||
/* We are done with the layer - time to free some resources */
|
||||
if (mask_ID != -1)
|
||||
cairo_surface_destroy (mask_image);
|
||||
draw_layer (layers, n_layers, &j, nreturn_vals, pdf_file, cr, fp, values, x_res, y_res, name, error);
|
||||
}
|
||||
|
||||
/* We are done with this image - Show it!
|
||||
@ -1752,3 +1650,147 @@ drawText (gint32 text_id,
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void draw_layer (gint32 *layers,
|
||||
gint n_layers,
|
||||
gint *j,
|
||||
gint *nreturn_vals,
|
||||
cairo_surface_t *pdf_file,
|
||||
cairo_t *cr,
|
||||
FILE *fp,
|
||||
GimpParam *values,
|
||||
gdouble x_res,
|
||||
gdouble y_res,
|
||||
const gchar *name,
|
||||
GError *error)
|
||||
{
|
||||
gint32 layer_ID;
|
||||
gint32 mask_ID = -1;
|
||||
cairo_surface_t *mask_image = NULL;
|
||||
gdouble opacity;
|
||||
gboolean single_color;
|
||||
gint x, y, i;
|
||||
gint children_num;
|
||||
gint *children;
|
||||
|
||||
if (optimize.reverse_order && optimize.layers_as_pages)
|
||||
layer_ID = layers [*j];
|
||||
else
|
||||
layer_ID = layers [n_layers - *j - 1];
|
||||
|
||||
if (gimp_item_is_group (layer_ID))
|
||||
{
|
||||
children = gimp_item_get_children (layer_ID, &children_num);
|
||||
for (i = 0; i < children_num; i++)
|
||||
{
|
||||
draw_layer (children, children_num, &i, nreturn_vals, pdf_file, cr, fp, values, x_res, y_res, name, error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
opacity = gimp_layer_get_opacity (layer_ID) / 100.0;
|
||||
|
||||
if ((gimp_item_get_visible (layer_ID) && opacity > 0.0) ||
|
||||
! optimize.ignore_hidden)
|
||||
{
|
||||
mask_ID = gimp_layer_get_mask (layer_ID);
|
||||
if (mask_ID != -1)
|
||||
{
|
||||
mask_image = get_cairo_surface (mask_ID, TRUE,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
*nreturn_vals = 2;
|
||||
|
||||
/* free the resources */
|
||||
cairo_surface_destroy (pdf_file);
|
||||
cairo_destroy (cr);
|
||||
fclose (fp);
|
||||
|
||||
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
||||
|
||||
values[1].type = GIMP_PDB_STRING;
|
||||
values[1].data.d_string = error->message;
|
||||
return;
|
||||
}
|
||||
}
|
||||
gimp_drawable_offsets (layer_ID, &x, &y);
|
||||
|
||||
if (! gimp_item_is_text_layer (layer_ID))
|
||||
{
|
||||
/* For raster layers */
|
||||
|
||||
GimpRGB layer_color;
|
||||
|
||||
layer_color = get_layer_color (layer_ID, &single_color);
|
||||
|
||||
cairo_rectangle (cr, x, y,
|
||||
gimp_drawable_width (layer_ID),
|
||||
gimp_drawable_height (layer_ID));
|
||||
|
||||
if (optimize.vectorize && single_color)
|
||||
{
|
||||
cairo_set_source_rgba (cr,
|
||||
layer_color.r,
|
||||
layer_color.g,
|
||||
layer_color.b,
|
||||
layer_color.a * opacity);
|
||||
if (mask_ID != -1)
|
||||
cairo_mask_surface (cr, mask_image, x, y);
|
||||
else
|
||||
cairo_fill (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_surface_t *layer_image;
|
||||
|
||||
layer_image = get_cairo_surface (layer_ID, FALSE,
|
||||
&error);
|
||||
if (error != NULL)
|
||||
{
|
||||
*nreturn_vals = 2;
|
||||
|
||||
/* free the resources */
|
||||
cairo_surface_destroy (pdf_file);
|
||||
cairo_destroy (cr);
|
||||
fclose (fp);
|
||||
|
||||
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
||||
|
||||
values[1].type = GIMP_PDB_STRING;
|
||||
values[1].data.d_string = error->message;
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_clip (cr);
|
||||
|
||||
cairo_set_source_surface (cr, layer_image, x, y);
|
||||
cairo_push_group (cr);
|
||||
cairo_paint_with_alpha (cr, opacity);
|
||||
cairo_pop_group_to_source (cr);
|
||||
|
||||
if (mask_ID != -1)
|
||||
cairo_mask_surface (cr, mask_image, x, y);
|
||||
else
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_reset_clip (cr);
|
||||
|
||||
cairo_surface_destroy (layer_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For text layers */
|
||||
drawText (layer_ID, opacity, cr, x_res, y_res);
|
||||
}
|
||||
/* draw new page if "layers as pages" option is checked */
|
||||
if (optimize.layers_as_pages &&
|
||||
g_strcmp0 (name, SAVE2_PROC) == 0)
|
||||
cairo_show_page (cr);
|
||||
}
|
||||
/* We are done with the layer - time to free some resources */
|
||||
if (mask_ID != -1)
|
||||
cairo_surface_destroy (mask_image);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user