[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(¶ms, 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, ¶ms, &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(-)