[gimp/gimp-2-10] Issue #1002: Fix for layer groups in PDF export



commit 7278663a98295664dcd42e866c0cd9a2360896e2
Author: Lionel <lionel pc-27 home>
Date:   Wed Mar 20 19:59:07 2019 +0100

    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.
    
    (cherry picked from commit bbd5ebbe8ab4e810952a2a0080a13c1d593e438c)

 plug-ins/common/file-pdf-save.c | 274 +++++++++++++++++++++++-----------------
 1 file changed, 158 insertions(+), 116 deletions(-)
---
diff --git a/plug-ins/common/file-pdf-save.c b/plug-ins/common/file-pdf-save.c
index 5faf3068a2..3eae429182 100644
--- a/plug-ins/common/file-pdf-save.c
+++ b/plug-ins/common/file-pdf-save.c
@@ -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);
+    }
+}


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