[gs-commits] ghostpdl branch, pdfi, updated. jbig2dec-0.14-2111-g4e8997d

[email protected] (Nancy Durgin)
Newsgroups gmane.comp.printing.ghostscript.cvs
Message-ID <[email protected]>
The ghostpdl branch, pdfi has been updated
       via  4e8997d4784d586220229b859e078f9c4ca17f21 (commit)
      from  86f47207b9e2a97fd8cb2880539ba70367140b8d (commit)

----------------------------------------------------------------------
commit 4e8997d4784d586220229b859e078f9c4ca17f21
Author: Nancy Durgin <[email protected]>
Date:   Thu Aug 15 14:36:01 2019 -0700

    Supporting "GroupGState" and "GroupMat" for SMask
    
    Need to save the gstate at the time that the GS_SMask is set, so
    it needs to go into the client_data in the gstate.
    
    What a mess!  I think I have this correct, but it's ugly.  Need to make
    sure the gstate that we are saving doesn't have a client_data reference or
    havoc ensues.  I think this is fine because in the context where it's
    needed, the SMask should be nulled out.  If we ever put additional things
    in client_data, may need to revisit this.
    
    This commit has some visual progressions, some visual regressions, and
    fixes some segfaults... I have made note of some of the visual regressions
    and will look into them.

diff --git a/pdf/pdf_gstate.c b/pdf/pdf_gstate.c
index 5bd2b77..140345a 100644
--- a/pdf/pdf_gstate.c
+++ b/pdf/pdf_gstate.c
@@ -32,9 +32,34 @@
 #include "gslparam.h"
 #include "gstparam.h"
 
+void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate)
+{
+    void *client_data_save;
+
+    if (!SMask)
+        return;
+    igs->memory = memory;
+    igs->SMask = SMask;
+    pdfi_countup(SMask);
+    client_data_save = gstate->client_data;
+    gstate->client_data = NULL;
+    igs->GroupGState = gs_gstate_copy(gstate, memory);
+    gstate->client_data = client_data_save;
+}
+
+void pdfi_gstate_smask_free(pdfi_int_gstate *igs)
+{
+    pdfi_countdown(igs->SMask);
+    igs->SMask = NULL;
+    if (igs->GroupGState)
+        gs_gstate_free(igs->GroupGState);
+    igs->GroupGState = NULL;
+}
+
+
 /* Allocate the interpreter's part of a graphics state. */
 static void *
-pdfi_gstate_alloc(gs_memory_t * mem)
+pdfi_gstate_alloc_cb(gs_memory_t * mem)
 {
     pdfi_int_gstate *igs;
 
@@ -47,32 +72,31 @@ pdfi_gstate_alloc(gs_memory_t * mem)
 
 /* Copy the interpreter's part of a graphics state. */
 static int
-pdfi_gstate_copy(void *to, const void *from)
+pdfi_gstate_copy_cb(void *to, const void *from)
 {
     const pdfi_int_gstate *igs_from = (const pdfi_int_gstate *)from;
     pdfi_int_gstate *igs_to = (pdfi_int_gstate *)to;
 
     *(pdfi_int_gstate *) igs_to = *igs_from;
-    if (igs_from->SMask)
-        pdfi_countup(igs_from->SMask);
+    pdfi_gstate_smask_install(igs_to, igs_from->memory, igs_from->SMask, igs_from->GroupGState);
     return 0;
 }
 
 /* Free the interpreter's part of a graphics state. */
 static void
-pdfi_gstate_free(void *old, gs_memory_t * mem)
+pdfi_gstate_free_cb(void *old, gs_memory_t * mem)
 {
     pdfi_int_gstate *igs = (pdfi_int_gstate *)old;
     if (old == NULL)
         return;
-    pdfi_countdown(igs->SMask);
+    pdfi_gstate_smask_free(igs);
     gs_free_object(mem, igs, "pdfi_gstate_free");
 }
 
 static const gs_gstate_client_procs pdfi_gstate_procs = {
-    pdfi_gstate_alloc,
-    pdfi_gstate_copy,
-    pdfi_gstate_free,
+    pdfi_gstate_alloc_cb,
+    pdfi_gstate_copy_cb,
+    pdfi_gstate_free_cb,
     NULL,			/* copy_for */
 };
 
@@ -81,7 +105,7 @@ pdfi_gstate_set_client(pdf_context *ctx)
 {
     pdfi_int_gstate *igs;
 
-    igs = pdfi_gstate_alloc(ctx->memory);
+    igs = pdfi_gstate_alloc_cb(ctx->memory);
     gs_gstate_set_client(ctx->pgs, igs, &pdfi_gstate_procs, true /* TODO: client_has_pattern_streams ? */);
     return 0;
 }
@@ -137,6 +161,7 @@ int pdfi_op_q(pdf_context *ctx)
 {
     int code;
 
+    dbgmprintf(ctx->memory, "(doing q)\n"); /* TODO: Spammy, delete me at some point */
     code = pdfi_gsave(ctx);
 
     if (code < 0 && ctx->pdfstoponerror)
@@ -152,6 +177,7 @@ int pdfi_op_Q(pdf_context *ctx)
 {
     int code;
 
+    dbgmprintf(ctx->memory, "(doing Q)\n"); /* TODO: Spammy, delete me at some point */
     if (ctx->page_has_transparency)
         code = gs_pop_transparency_state(ctx->pgs, false);
 
@@ -757,9 +783,8 @@ static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_d
         pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
 
         if (igs->SMask)
-            pdfi_countdown(igs->SMask);
-        igs->SMask = (pdf_dict *)o;
-        pdfi_countup(o);
+            pdfi_gstate_smask_free(igs);
+        pdfi_gstate_smask_install(igs, ctx->memory, (pdf_dict *)o, ctx->pgs);
     }
 
     pdfi_countdown(o);
diff --git a/pdf/pdf_gstate.h b/pdf/pdf_gstate.h
index b78e464..d5c9947 100644
--- a/pdf/pdf_gstate.h
+++ b/pdf/pdf_gstate.h
@@ -21,9 +21,13 @@
 /* Interpreter graphics state things (see igstate.h/int_gstate) */
 typedef struct int_gstate_s {
     pdf_dict *SMask; /* PDF only, null | dictionary | true */
+    gs_gstate *GroupGState; /* gstate associated with the SMask */
+    gs_memory_t *memory;
 } pdfi_int_gstate;
 
 int pdfi_gstate_set_client(pdf_context *ctx);
+void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate);
+void pdfi_gstate_smask_free(pdfi_int_gstate *igs);
 
 int pdfi_concat(pdf_context *ctx);
 int pdfi_gsave(pdf_context *ctx);
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 44a8191..9469dea 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -895,8 +895,7 @@ pdfi_do_image_smask(pdf_context *ctx, pdf_stream *source, pdfi_image_info_t *ima
     code = pdfi_gsave(ctx);
 
     /* Disable SMask for inner image */
-    pdfi_countdown(igs->SMask);
-    igs->SMask = NULL;
+    pdfi_gstate_smask_free(igs);
 
     gs_setopacityalpha(ctx->pgs, 1.0);
     gs_setshapealpha(ctx->pgs, 1.0);
@@ -1297,7 +1296,7 @@ int pdfi_EI(pdf_context *ctx)
 }
 
 /* see .execgroup */
-int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *xobject_dict)
+int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *xobject_dict, gs_gstate *GroupGState)
 {
     int code;
     pdf_array *FormMatrix = NULL;
@@ -1315,8 +1314,14 @@ int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *xobject
     if (code < 0)
         goto exit;
 
-    pdfi_countdown(igs->SMask);
-    igs->SMask = NULL;
+    if (GroupGState) {
+        code = gs_setgstate(ctx->pgs, GroupGState);
+        if (code < 0)
+            goto exit;
+    }
+
+    /* Disable the SMask */
+    pdfi_gstate_smask_free(igs);
 
     gs_setopacityalpha(ctx->pgs, 1.0);
     gs_setshapealpha(ctx->pgs, 1.0);
@@ -1388,7 +1393,7 @@ static int pdfi_do_form(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *form_di
     }
 
     if (do_group) {
-        code = pdfi_form_execgroup(ctx, page_dict, form_dict);
+        code = pdfi_form_execgroup(ctx, page_dict, form_dict, NULL);
         if (code < 0)
             (void)pdfi_trans_end_group(ctx);
         else
diff --git a/pdf/pdf_image.h b/pdf/pdf_image.h
index 559cb6e..5c5f0fa 100644
--- a/pdf/pdf_image.h
+++ b/pdf/pdf_image.h
@@ -23,6 +23,6 @@ int pdfi_EI(pdf_context *ctx);
 int pdfi_ID(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_stream *source);
 int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict);
 int pdfi_do_image_or_form(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_dict *xobject_dict);
-int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *xobject_dict);
+int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *xobject_dict, gs_gstate *GroupGState);
 
 #endif
diff --git a/pdf/pdf_trans.c b/pdf/pdf_trans.c
index f7dd276..f6de93f 100644
--- a/pdf/pdf_trans.c
+++ b/pdf/pdf_trans.c
@@ -26,9 +26,10 @@
 
 #include "gstparam.h"
 
-static int pdfi_trans_set_mask(pdf_context *ctx, pdf_dict *SMask)
+static int pdfi_trans_set_mask(pdf_context *ctx, pdfi_int_gstate *igs)
 {
     int code;
+    pdf_dict *SMask = igs->SMask;
     //    gs_color_space *gray_cs = gs_cspace_new_DeviceGray(ctx->memory);
     gs_color_space *pcs = NULL;
     gs_rect bbox = { { 0, 0} , { 1, 1} };
@@ -73,7 +74,11 @@ static int pdfi_trans_set_mask(pdf_context *ctx, pdf_dict *SMask)
             gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
             params.replacing = true;
 
-            /* TODO: GroupGState, GMatrix ? */
+            /* Need to set just the ctm (GroupMat) from the saved GroupGState, to
+               have gs_begin_transparency_mask work correctly.  Or at least that's
+               what the PS code comments claim (see pdf_draw.ps/.execmaskgroup)
+            */
+            gs_setmatrix(ctx->pgs, &igs->GroupGState->ctm);
 
             /* CS is in the dict "Group" inside the dict "G" */
             /* TODO: Not sure if this is a required thing or just one possibility */
@@ -105,7 +110,7 @@ static int pdfi_trans_set_mask(pdf_context *ctx, pdf_dict *SMask)
             code = gs_begin_transparency_mask(ctx->pgs, &params, &bbox, true);
             if (code < 0)
                 goto exit;
-            code = pdfi_form_execgroup(ctx, ctx->CurrentPageDict, G_dict);
+            code = pdfi_form_execgroup(ctx, ctx->CurrentPageDict, G_dict, igs->GroupGState);
             code = gs_end_transparency_mask(ctx->pgs, 0);
         }
     } else {
@@ -311,7 +316,7 @@ int pdfi_trans_set_params(pdf_context *ctx, double alpha)
             gs_setopacityalpha(ctx->pgs, alpha);
         }
         if (igs->SMask) {
-            pdfi_trans_set_mask(ctx, igs->SMask);
+            pdfi_trans_set_mask(ctx, igs);
         }
     }
 


Summary of changes:
 pdf/pdf_gstate.c | 51 ++++++++++++++++++++++++++++++++++++++-------------
 pdf/pdf_gstate.h |  4 ++++
 pdf/pdf_image.c  | 17 +++++++++++------
 pdf/pdf_image.h  |  2 +-
 pdf/pdf_trans.c  | 13 +++++++++----
 5 files changed, 63 insertions(+), 24 deletions(-)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.