|
|
993c09 |
From d2423464852664218310ae7c5610fb0b6da4218b Mon Sep 17 00:00:00 2001
|
|
|
993c09 |
From: Ken Sharp <ken.sharp@artifex.com>
|
|
|
993c09 |
Date: Fri, 7 Mar 2014 13:41:01 +0000
|
|
|
993c09 |
Subject: [PATCH] PS interpreter, vector devices and pdfwrite - remove setdash
|
|
|
993c09 |
limit of 11
|
|
|
993c09 |
|
|
|
993c09 |
Bug #693916 "setdash does not accept more than 11 elements in the array argument"
|
|
|
993c09 |
|
|
|
993c09 |
The PostScript interpreter was already capable of this, it simply required
|
|
|
993c09 |
the limit check to be removed. The vector device needed to allocate and
|
|
|
993c09 |
free an array of floats, rather than maintain a fixed size array.
|
|
|
993c09 |
|
|
|
993c09 |
pdfwrite was teh most complex as it maintains a stack of gstates, and these
|
|
|
993c09 |
also needed to be modified to allocate and free the dash array. However the
|
|
|
993c09 |
gstate stack wasn't already a garbage collecting structure. Rather than going
|
|
|
993c09 |
to the effort of turning it into one I've opted to allocate the dash pattern
|
|
|
993c09 |
from non-gc memory.
|
|
|
993c09 |
|
|
|
993c09 |
A few PCL files show differences with pdfwrite, because previously pdfwrite
|
|
|
993c09 |
would throw an error (more than 11 elements in the dash array) and the stroked
|
|
|
993c09 |
lines would degenerate into filled rectangles, whereas now they are drawn as
|
|
|
993c09 |
stroked lines with a correct dash pattern. This is much more efficient.
|
|
|
993c09 |
|
|
|
993c09 |
The clist remains unmodified, Ray assures me that it will be handled there
|
|
|
993c09 |
without problems.
|
|
|
993c09 |
---
|
|
|
993c09 |
Resource/Init/gs_init.ps | 1 -
|
|
|
993c09 |
base/gdevpdf.c | 6 ++++++
|
|
|
993c09 |
base/gdevpdfg.c | 32 +++++++++++++++++++++++++++-----
|
|
|
993c09 |
base/gdevpdfx.h | 3 ++-
|
|
|
993c09 |
base/gdevvec.c | 14 ++++++++++----
|
|
|
993c09 |
base/gdevvec.h | 13 ++++++-------
|
|
|
993c09 |
6 files changed, 51 insertions(+), 18 deletions(-)
|
|
|
993c09 |
|
|
|
993c09 |
diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
|
|
|
993c09 |
index 0083fa3..b4a6c48 100644
|
|
|
993c09 |
--- a/Resource/Init/gs_init.ps
|
|
|
993c09 |
+++ b/Resource/Init/gs_init.ps
|
|
|
993c09 |
@@ -518,7 +518,6 @@ userdict /.echo.mode //true put
|
|
|
993c09 |
0 .argindex type dup /integertype eq exch /realtype eq or not {
|
|
|
993c09 |
/setdash .systemvar /typecheck signalerror
|
|
|
993c09 |
} if
|
|
|
993c09 |
- 1 .argindex length 11 gt { /setdash .systemvar /limitcheck signalerror } if
|
|
|
993c09 |
//setdash
|
|
|
993c09 |
} odef
|
|
|
993c09 |
/setdevice
|
|
|
993c09 |
diff --git a/base/gdevpdf.c b/base/gdevpdf.c
|
|
|
993c09 |
index 8416b51..d740cc1 100644
|
|
|
993c09 |
--- a/base/gdevpdf.c
|
|
|
993c09 |
+++ b/base/gdevpdf.c
|
|
|
993c09 |
@@ -2873,6 +2873,12 @@ pdf_close(gx_device * dev)
|
|
|
993c09 |
gs_free_object(mem, pdev->Pages, "Free Pages dict");
|
|
|
993c09 |
pdev->Pages = 0;
|
|
|
993c09 |
|
|
|
993c09 |
+ {
|
|
|
993c09 |
+ int i;
|
|
|
993c09 |
+ for (i=0;i < pdev->vgstack_depth;i++)
|
|
|
993c09 |
+ gs_free_object(pdev->memory->non_gc_memory, pdev->vgstack[i].dash_pattern, "pdfwrite final free stored dash in gstate");
|
|
|
993c09 |
+ }
|
|
|
993c09 |
+
|
|
|
993c09 |
cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack");
|
|
|
993c09 |
gs_free_object(mem, pdev->NI_stack, "Free Name Index stack");
|
|
|
993c09 |
pdev->NI_stack = 0;
|
|
|
993c09 |
diff --git a/base/gdevpdfg.c b/base/gdevpdfg.c
|
|
|
993c09 |
index 2d4e040..56b24f7 100644
|
|
|
993c09 |
--- a/base/gdevpdfg.c
|
|
|
993c09 |
+++ b/base/gdevpdfg.c
|
|
|
993c09 |
@@ -71,8 +71,19 @@ pdf_save_viewer_state(gx_device_pdf *pdev, stream *s)
|
|
|
993c09 |
pdev->vgstack[i].saved_stroke_color = pdev->saved_stroke_color;
|
|
|
993c09 |
pdev->vgstack[i].line_params = pdev->state.line_params;
|
|
|
993c09 |
pdev->vgstack[i].line_params.dash.pattern = 0; /* Use pdev->dash_pattern instead. */
|
|
|
993c09 |
- memcpy(pdev->vgstack[i].dash_pattern, pdev->dash_pattern,
|
|
|
993c09 |
- sizeof(pdev->vgstack[i].dash_pattern));
|
|
|
993c09 |
+ if (pdev->dash_pattern) {
|
|
|
993c09 |
+ if (pdev->vgstack[i].dash_pattern)
|
|
|
993c09 |
+ gs_free_object(pdev->memory->non_gc_memory, pdev->vgstack[i].dash_pattern, "free gstate copy dash");
|
|
|
993c09 |
+ pdev->vgstack[i].dash_pattern = (float *)gs_alloc_bytes(pdev->memory->non_gc_memory, pdev->dash_pattern_size * sizeof(float), "gstate copy dash");
|
|
|
993c09 |
+ memcpy(pdev->vgstack[i].dash_pattern, pdev->dash_pattern, pdev->dash_pattern_size * sizeof(float));
|
|
|
993c09 |
+ pdev->vgstack[i].dash_pattern_size = pdev->dash_pattern_size;
|
|
|
993c09 |
+ } else {
|
|
|
993c09 |
+ if (pdev->vgstack[i].dash_pattern) {
|
|
|
993c09 |
+ gs_free_object(pdev->memory->non_gc_memory, pdev->vgstack[i].dash_pattern, "free gstate copy dash");
|
|
|
993c09 |
+ pdev->vgstack[i].dash_pattern = 0;
|
|
|
993c09 |
+ pdev->vgstack[i].dash_pattern_size = 0;
|
|
|
993c09 |
+ }
|
|
|
993c09 |
+ }
|
|
|
993c09 |
pdev->vgstack_depth++;
|
|
|
993c09 |
if (s)
|
|
|
993c09 |
stream_puts(s, "q\n");
|
|
|
993c09 |
@@ -106,8 +117,18 @@ pdf_load_viewer_state(gx_device_pdf *pdev, pdf_viewer_state *s)
|
|
|
993c09 |
pdev->saved_fill_color = s->saved_fill_color;
|
|
|
993c09 |
pdev->saved_stroke_color = s->saved_stroke_color;
|
|
|
993c09 |
pdev->state.line_params = s->line_params;
|
|
|
993c09 |
- memcpy(pdev->dash_pattern, s->dash_pattern,
|
|
|
993c09 |
- sizeof(s->dash_pattern));
|
|
|
993c09 |
+ if (s->dash_pattern) {
|
|
|
993c09 |
+ if (pdev->dash_pattern)
|
|
|
993c09 |
+ gs_free_object(pdev->memory->stable_memory, pdev->dash_pattern, "vector free dash pattern");
|
|
|
993c09 |
+ pdev->dash_pattern = (float *)gs_alloc_bytes(pdev->memory->stable_memory, s->dash_pattern_size * sizeof(float), "vector allocate dash pattern");
|
|
|
993c09 |
+ pdev->dash_pattern_size = s->dash_pattern_size;
|
|
|
993c09 |
+ } else {
|
|
|
993c09 |
+ if (pdev->dash_pattern) {
|
|
|
993c09 |
+ gs_free_object(pdev->memory->stable_memory, pdev->dash_pattern, "vector free dash pattern");
|
|
|
993c09 |
+ pdev->dash_pattern = 0;
|
|
|
993c09 |
+ pdev->dash_pattern_size = 0;
|
|
|
993c09 |
+ }
|
|
|
993c09 |
+ }
|
|
|
993c09 |
}
|
|
|
993c09 |
|
|
|
993c09 |
/* Restore the viewer's graphic state. */
|
|
|
993c09 |
@@ -178,7 +199,8 @@ pdf_viewer_state_from_imager_state_aux(pdf_viewer_state *pvs, const gs_imager_st
|
|
|
993c09 |
pvs->line_params.dot_length_absolute = pis->line_params.dot_length_absolute;
|
|
|
993c09 |
pvs->line_params.dot_orientation = pis->line_params.dot_orientation;
|
|
|
993c09 |
memset(&pvs->line_params.dash, 0 , sizeof(pvs->line_params.dash));
|
|
|
993c09 |
- memset(pvs->dash_pattern, 0, sizeof(pvs->dash_pattern));
|
|
|
993c09 |
+ pvs->dash_pattern = 0;
|
|
|
993c09 |
+ pvs->dash_pattern_size = 0;
|
|
|
993c09 |
}
|
|
|
993c09 |
|
|
|
993c09 |
/* Copy viewer state from images state. */
|
|
|
993c09 |
diff --git a/base/gdevpdfx.h b/base/gdevpdfx.h
|
|
|
993c09 |
index bc0545d..69a8257 100644
|
|
|
993c09 |
--- a/base/gdevpdfx.h
|
|
|
993c09 |
+++ b/base/gdevpdfx.h
|
|
|
993c09 |
@@ -500,7 +500,8 @@ typedef struct pdf_viewer_state_s {
|
|
|
993c09 |
gx_hl_saved_color saved_fill_color;
|
|
|
993c09 |
gx_hl_saved_color saved_stroke_color;
|
|
|
993c09 |
gx_line_params line_params;
|
|
|
993c09 |
- float dash_pattern[max_dash];
|
|
|
993c09 |
+ float *dash_pattern;
|
|
|
993c09 |
+ uint dash_pattern_size;
|
|
|
993c09 |
gs_id soft_mask_id;
|
|
|
993c09 |
} pdf_viewer_state;
|
|
|
993c09 |
|
|
|
993c09 |
diff --git a/base/gdevvec.c b/base/gdevvec.c
|
|
|
993c09 |
index ddf787e..ac006f5 100644
|
|
|
993c09 |
--- a/base/gdevvec.c
|
|
|
993c09 |
+++ b/base/gdevvec.c
|
|
|
993c09 |
@@ -457,24 +457,26 @@ gdev_vector_prepare_stroke(gx_device_vector * vdev,
|
|
|
993c09 |
float dash_offset = pis->line_params.dash.offset * scale;
|
|
|
993c09 |
float half_width = pis->line_params.half_width * scale;
|
|
|
993c09 |
|
|
|
993c09 |
- if (pattern_size > max_dash)
|
|
|
993c09 |
- return_error(gs_error_limitcheck);
|
|
|
993c09 |
if (dash_offset != vdev->state.line_params.dash.offset ||
|
|
|
993c09 |
pattern_size != vdev->state.line_params.dash.pattern_size ||
|
|
|
993c09 |
(pattern_size != 0 &&
|
|
|
993c09 |
!dash_pattern_eq(vdev->dash_pattern, &pis->line_params.dash,
|
|
|
993c09 |
scale))
|
|
|
993c09 |
) {
|
|
|
993c09 |
- float pattern[max_dash];
|
|
|
993c09 |
+ float *pattern;
|
|
|
993c09 |
int i, code;
|
|
|
993c09 |
|
|
|
993c09 |
+ pattern = gs_alloc_bytes(vdev->memory->stable_memory, pattern_size * sizeof(float), "vector allocate dash pattern");
|
|
|
993c09 |
for (i = 0; i < pattern_size; ++i)
|
|
|
993c09 |
pattern[i] = pis->line_params.dash.pattern[i] * scale;
|
|
|
993c09 |
code = (*vdev_proc(vdev, setdash))
|
|
|
993c09 |
(vdev, pattern, pattern_size, dash_offset);
|
|
|
993c09 |
if (code < 0)
|
|
|
993c09 |
return code;
|
|
|
993c09 |
- memcpy(vdev->dash_pattern, pattern, pattern_size * sizeof(float));
|
|
|
993c09 |
+ if (vdev->dash_pattern)
|
|
|
993c09 |
+ gs_free_object(vdev->memory->stable_memory, vdev->dash_pattern, "vector free old dash pattern");
|
|
|
993c09 |
+ vdev->dash_pattern = pattern;
|
|
|
993c09 |
+ vdev->dash_pattern_size = pattern_size;
|
|
|
993c09 |
|
|
|
993c09 |
vdev->state.line_params.dash.pattern_size = pattern_size;
|
|
|
993c09 |
vdev->state.line_params.dash.offset = dash_offset;
|
|
|
993c09 |
@@ -816,6 +818,10 @@ gdev_vector_close_file(gx_device_vector * vdev)
|
|
|
993c09 |
FILE *f = vdev->file;
|
|
|
993c09 |
int err;
|
|
|
993c09 |
|
|
|
993c09 |
+ if (vdev->dash_pattern) {
|
|
|
993c09 |
+ gs_free_object(vdev->memory->stable_memory, vdev->dash_pattern, "vector free dash pattern");
|
|
|
993c09 |
+ vdev->dash_pattern = 0;
|
|
|
993c09 |
+ }
|
|
|
993c09 |
if (vdev->bbox_device) {
|
|
|
993c09 |
rc_decrement(vdev->bbox_device->icc_struct, "vector_close(bbox_device->icc_struct");
|
|
|
993c09 |
vdev->bbox_device->icc_struct = NULL;
|
|
|
993c09 |
diff --git a/base/gdevvec.h b/base/gdevvec.h
|
|
|
993c09 |
index 1a3eece..385e126 100644
|
|
|
993c09 |
--- a/base/gdevvec.h
|
|
|
993c09 |
+++ b/base/gdevvec.h
|
|
|
993c09 |
@@ -66,9 +66,6 @@ typedef struct gx_device_vector_s gx_device_vector;
|
|
|
993c09 |
/* Define the maximum size of the output file name. */
|
|
|
993c09 |
#define fname_size (gp_file_name_sizeof - 1)
|
|
|
993c09 |
|
|
|
993c09 |
-/* Define the longest dash pattern we can remember. */
|
|
|
993c09 |
-#define max_dash 11
|
|
|
993c09 |
-
|
|
|
993c09 |
/*
|
|
|
993c09 |
* Define procedures for writing common output elements. Not all devices
|
|
|
993c09 |
* will support all of these elements. Note that these procedures normally
|
|
|
993c09 |
@@ -168,7 +165,8 @@ int gdev_vector_dorect(gx_device_vector * vdev, fixed x0, fixed y0,
|
|
|
993c09 |
int open_options; /* see below */\
|
|
|
993c09 |
/* Graphics state */\
|
|
|
993c09 |
gs_imager_state state;\
|
|
|
993c09 |
- float dash_pattern[max_dash];\
|
|
|
993c09 |
+ float *dash_pattern;\
|
|
|
993c09 |
+ uint dash_pattern_size;\
|
|
|
993c09 |
bool fill_used_process_color;\
|
|
|
993c09 |
bool stroke_used_process_color;\
|
|
|
993c09 |
gx_hl_saved_color saved_fill_color;\
|
|
|
993c09 |
@@ -194,7 +192,8 @@ int gdev_vector_dorect(gx_device_vector * vdev, fixed x0, fixed y0,
|
|
|
993c09 |
0, /* strmbuf_size */\
|
|
|
993c09 |
0, /* open_options */\
|
|
|
993c09 |
{ 0 }, /* state */\
|
|
|
993c09 |
- { 0 }, /* dash_pattern */\
|
|
|
993c09 |
+ 0, /* dash_pattern */\
|
|
|
993c09 |
+ 0, /* dash pattern size */\
|
|
|
993c09 |
true, /* fill_used_process_color */\
|
|
|
993c09 |
true, /* stroke_used_process_color */\
|
|
|
993c09 |
{ 0 }, /* fill_color ****** WRONG ****** */\
|
|
|
993c09 |
@@ -216,10 +215,10 @@ struct gx_device_vector_s {
|
|
|
993c09 |
/* extern its descriptor for the sake of subclasses. */
|
|
|
993c09 |
extern_st(st_device_vector);
|
|
|
993c09 |
#define public_st_device_vector() /* in gdevvec.c */\
|
|
|
993c09 |
- gs_public_st_suffix_add3_final(st_device_vector, gx_device_vector,\
|
|
|
993c09 |
+ gs_public_st_suffix_add4_final(st_device_vector, gx_device_vector,\
|
|
|
993c09 |
"gx_device_vector", device_vector_enum_ptrs,\
|
|
|
993c09 |
device_vector_reloc_ptrs, gx_device_finalize, st_device, strm, strmbuf,\
|
|
|
993c09 |
- bbox_device)
|
|
|
993c09 |
+ dash_pattern, bbox_device)
|
|
|
993c09 |
#define st_device_vector_max_ptrs (st_device_max_ptrs + 3)
|
|
|
993c09 |
|
|
|
993c09 |
/* ================ Utility procedures ================ */
|
|
|
993c09 |
--
|
|
|
993c09 |
2.14.3
|
|
|
993c09 |
|