Re: outputFile support in bbox device
Ray Johnston <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Alex,
This change to the bbox device should NOT be committed until after we
get the 8.11 release out (refer to the email from Ralph Giles). This
change is too risky and is not a fix for a high priority bug.
We expect to be able to get 8.11 release out by Friday (there have
been delays getting the regressions clean, with a bug we decided was
a "show stopper" and with vacations by Raph and Ralph).
In the meantime, I'll take a look at this change to see if I have
any comments as I'm sure Igor will as well.
Regards,
Ray
____________________________________________________________________
Ralph Giles wrote (on 8/4/2003):
> Everybody,
>
> Just a heads up about the AFPL Ghostscript 8.11 release. We're now
> significantly overdue with this, so I'd like to request that we get
> the recent regression issues cleared up in the next two days. I'm
> acting as release manager for this one, and I need to be able to
> release on wednesday before I go on vacation in California.
>
> Consider this a freeze notice then. We've been relatively
> regression free recently, so this short period should be fine.
> Just no new features or non-regression-tested bugfixes please.
>
> It's better at this point to let it go out with bugs than to delay
> the release further.
_____________________________________________________________________
Alex Cherepanov wrote:
> Add OutputFile support to bbox device.
>
> The new feature will be used to re-implement ps2epsi
> bbox device as following:
> (1) calculate bbox
> (2) render epsi preview (or tiff preview) using normal
> GS devices.
>
> Current bbox device is broken because the fix for
> the bug 686892 "bbox device returns empty box" is still
> not committed.
>
>
> ------------------------------------------------------------------------
>
> Index: gs/src/gdevbbox.c
> ===================================================================
> RCS file: /cvs/ghostscript/gs/src/gdevbbox.c,v
> retrieving revision 1.12
> diff -b -u -r1.12 gdevbbox.c
> --- gs/src/gdevbbox.c 21 Apr 2003 15:39:46 -0000 1.12
> +++ gs/src/gdevbbox.c 10 Aug 2003 13:49:41 -0000
> @@ -19,6 +19,7 @@
> #include "math_.h"
> #include "memory_.h"
> #include "gx.h"
> +#include "gp.h" /* for gp_file_name_sizeof */
> #include "gserrors.h"
> #include "gsparam.h"
> #include "gxdevice.h"
> @@ -236,9 +237,16 @@
> private int
> bbox_close_device(gx_device * dev)
> {
> + int code;
> gx_device_bbox *const bdev = (gx_device_bbox *) dev;
> gx_device *tdev = bdev->target;
>
> + if (bdev->file) {
> + code = gx_device_close_output_file(dev, bdev->fname, bdev->file);
> + if(code < 0)
> + return code;
> + }
> +
> if (bdev->box_procs.init_box != box_procs_default.init_box) {
> /*
> * This device was created as a wrapper for a compositor.
> @@ -332,6 +340,7 @@
> private int
> bbox_open_device(gx_device * dev)
> {
> + int code;
> gx_device_bbox *const bdev = (gx_device_bbox *) dev;
>
> if (bdev->free_standing) {
> @@ -341,12 +350,12 @@
> }
> if (bdev->box_procs.init_box == box_procs_default.init_box)
> BBOX_INIT_BOX(bdev);
> +
> /* gx_forward_open_device doesn't exist */
> {
> gx_device *tdev = bdev->target;
> - int code =
> - (tdev && bdev->forward_open_close ? gs_opendevice(tdev) : 0);
>
> + code = (tdev && bdev->forward_open_close ? gs_opendevice(tdev) : 0);
> bbox_copy_params(bdev, true);
> return code;
> }
> @@ -361,14 +370,40 @@
> /*
> * This is a free-standing device. Print the page bounding box.
> */
> + int code;
> gs_rect bbox;
>
> gx_device_bbox_bbox(bdev, &bbox);
> - dlprintf4("%%%%BoundingBox: %d %d %d %d\n",
> + if ( bdev->file && (bdev->has_format || bdev->new_fname)) {
> + code = gx_device_close_output_file(dev, bdev->fname, bdev->file);
> + if(code < 0)
> + return code;
> + bdev->file = 0;
> + }
> + bdev->new_fname = false;
> +
> + if (bdev->fname[0] && bdev->file == 0) {
> + code = gx_device_open_output_file(dev, bdev->fname,
> + false, false, &bdev->file);
> + if (code < 0)
> + return code;
> + }
> +
> + if (bdev->file) {
> + code = fprintf(bdev->file, "%%%%BoundingBox: %d %d %d %d\n"
> + "%%%%HiResBoundingBox: %f %f %f %f\n",
> (int)floor(bbox.p.x), (int)floor(bbox.p.y),
> - (int)ceil(bbox.q.x), (int)ceil(bbox.q.y));
> - dlprintf4("%%%%HiResBoundingBox: %f %f %f %f\n",
> + (int)ceil(bbox.q.x), (int)ceil(bbox.q.y),
> bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
> + } else {
> + code = dlprintf8("%%%%BoundingBox: %d %d %d %d\n"
> + "%%%%HiResBoundingBox: %f %f %f %f\n",
> + (int)floor(bbox.p.x), (int)floor(bbox.p.y),
> + (int)ceil(bbox.q.x), (int)ceil(bbox.q.y),
> + bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
> + }
> + if (code < 0)
> + return_error(gs_error_ioerror);
> }
> return gx_forward_output_page(dev, num_copies, flush);
> }
> @@ -495,6 +530,9 @@
>
> /* ---------------- Parameters ---------------- */
>
> +private const char * const iamPageBoundingBox = "PageBoundingBox";
> +private const char * const iamOutputFile = "OutputFile";
> +
> /* We implement get_params to provide a way to read out the bounding box. */
> private int
> bbox_get_params(gx_device * dev, gs_param_list * plist)
> @@ -520,7 +558,20 @@
> bbox[2] = fixed2float(fbox.q.x);
> bbox[3] = fixed2float(fbox.q.y);
> bba.data = bbox, bba.size = 4, bba.persistent = false;
> - return param_write_float_array(plist, "PageBoundingBox", &bba);
> + code = param_write_float_array(plist, iamPageBoundingBox, &bba);
> + if (code < 0)
> + return code;
> +
> + if(bdev->fname[0]) {
> + gs_param_string ofns;
> + ofns.data = (const byte *)bdev->fname;
> + ofns.size = strlen(bdev->fname);
> + ofns.persistent = false;
> + code = param_write_string(plist, iamOutputFile, &ofns);
> + } else {
> + code = param_write_null(plist, iamOutputFile);
> + }
> + return code;
> }
>
> /* We implement put_params to ensure that we keep the important */
> @@ -530,37 +581,80 @@
> bbox_put_params(gx_device * dev, gs_param_list * plist)
> {
> gx_device_bbox *const bdev = (gx_device_bbox *) dev;
> - int code;
> - int ecode = 0;
> - gs_param_name param_name;
> + int ecode=0, code;
> gs_param_float_array bba;
> + gs_param_string ofs;
> + enum tag_fname_status {
> + k_not_set=0, k_null=1, k_name=2, k_format=3
> + } fname_status = k_not_set;
>
> - code = param_read_float_array(plist, (param_name = "PageBoundingBox"),
> - &bba);
> + code = param_read_float_array(plist, iamPageBoundingBox, &bba);
> switch (code) {
> case 0:
> - if (bba.size != 4) {
> - ecode = gs_note_error(gs_error_rangecheck);
> - goto e;
> - }
> + if (bba.size == 4)
> break;
> + code = gs_note_error(gs_error_rangecheck);
> default:
> + param_signal_error(plist, iamPageBoundingBox, code);
> ecode = code;
> - e:param_signal_error(plist, param_name, ecode);
> case 1:
> bba.data = 0;
> }
>
> + code = param_read_string(plist, iamOutputFile, &ofs);
> + switch (code) {
> + case 0:
> + if (bdev->LockSafetyParams &&
> + bytes_compare(ofs.data, ofs.size,
> + (const byte *)bdev->fname, strlen(bdev->fname))) {
> + code = gs_note_error(gs_error_invalidaccess);
> + } else if (ofs.size >= gp_file_name_sizeof) {
> + code = gs_note_error(gs_error_limitcheck);
> + } else {
> + gs_parsed_file_name_t parsed;
> + const char *fmt;
> + code = gx_parse_output_file_name(&parsed, &fmt, (const char *)ofs.data, ofs.size);
> + if (code >= 0)
> + { fname_status = fmt ? k_format : k_name;
> + break;
> + }
> + }
> + default:
> + if (param_read_null(plist, iamOutputFile) == 0) {
> + fname_status = k_null;
> + break;
> + }
> + param_signal_error(plist, iamOutputFile, code);
> + ecode = code;
> + case 1:
> + break;
> + }
> +
> code = gx_forward_put_params(dev, plist);
> - if (ecode < 0)
> - code = ecode;
> - if (code >= 0 && bba.data != 0) {
> + if (code < 0)
> + ecode = code;
> +
> + if (ecode >= 0) {
> + if( bba.data != 0) {
> BBOX_INIT_BOX(bdev);
> BBOX_ADD_RECT(bdev, float2fixed(bba.data[0]), float2fixed(bba.data[1]),
> float2fixed(bba.data[2]), float2fixed(bba.data[3]));
> }
> +
> + if (fname_status) {
> + bdev->has_format = fname_status == k_format;
> + if (fname_status >= k_name) {
> + bdev->new_fname |= bdev->fname[ofs.size] || memcmp(bdev->fname, ofs.data, ofs.size);
> + memcpy(bdev->fname, ofs.data, ofs.size);
> + bdev->fname[ofs.size] = 0;
> + } else {
> + bdev->new_fname |= bdev->fname[0] != 0;
> + bdev->fname[0] = 0;
> + }
> + }
> + }
> bbox_copy_params(bdev, true);
> - return code;
> + return ecode;
> }
>
> /* ---------------- Polygon drawing ---------------- */
> Index: gs/src/gdevbbox.h
> ===================================================================
> RCS file: /cvs/ghostscript/gs/src/gdevbbox.h,v
> retrieving revision 1.5
> diff -b -u -r1.5 gdevbbox.h
> --- gs/src/gdevbbox.h 16 Jun 2002 07:25:26 -0000 1.5
> +++ gs/src/gdevbbox.h 10 Aug 2003 13:49:41 -0000
> @@ -108,12 +108,17 @@
> /* The following are updated dynamically. */\
> gs_fixed_rect bbox;\
> gx_color_index black, white;\
> - gx_color_index transparent /* white or gx_no_color_index */
> + gx_color_index transparent; /* white or gx_no_color_index */\
> + char fname[gp_file_name_sizeof];\
> + FILE *file;\
> + bool has_format;\
> + bool new_fname
> typedef struct gx_device_bbox_s gx_device_bbox;
> #define gx_device_bbox_common_initial(fs, foc, wio)\
> 0 /* target */,\
> fs, foc, {0}, 0, wio,\
> - {{0, 0}, {0, 0}}, gx_no_color_index, gx_no_color_index, gx_no_color_index
> + {{0, 0}, {0, 0}}, gx_no_color_index, gx_no_color_index, gx_no_color_index,\
> + "", 0, false, false
> struct gx_device_bbox_s {
> gx_device_bbox_common;
> };
> Index: gs/src/gximag3x.c
> ===================================================================
> RCS file: /cvs/ghostscript/gs/src/gximag3x.c,v
> retrieving revision 1.14
> diff -b -u -r1.14 gximag3x.c
> --- gs/src/gximag3x.c 28 Mar 2003 20:15:36 -0000 1.14
> +++ gs/src/gximag3x.c 10 Aug 2003 13:49:41 -0000
> @@ -20,6 +20,7 @@
> #include "math_.h" /* for ceil, floor */
> #include "memory_.h"
> #include "gx.h"
> +#include "gp.h" /* for gp_file_name_sizeof */
> #include "gserrors.h"
> #include "gsbitops.h"
> #include "gscspace.h"
> Index: gs/src/lib.mak
> ===================================================================
> RCS file: /cvs/ghostscript/gs/src/lib.mak,v
> retrieving revision 1.130
> diff -b -u -r1.130 lib.mak
> --- gs/src/lib.mak 1 Aug 2003 15:53:37 -0000 1.130
> +++ gs/src/lib.mak 10 Aug 2003 13:49:43 -0000
> @@ -949,6 +949,7 @@
> $(SETDEV2) $(GLD)bbox $(GLOBJ)gdevbbox.$(OBJ)
>
> $(GLOBJ)gdevbbox.$(OBJ) : $(GLSRC)gdevbbox.c $(GXERR) $(math__h) $(memory__h)\
> + $(gp_h)\
> $(gdevbbox_h) $(gsdevice_h) $(gsparam_h)\
> $(gxcpath_h) $(gxdcolor_h) $(gxdevice_h) $(gxiparam_h) $(gxistate_h)\
> $(gxpaint_h) $(gxpath_h)
> @@ -2354,7 +2355,7 @@
> $(GLCC) $(GLO_)gstrans.$(OBJ) $(C_) $(GLSRC)gstrans.c
>
> $(GLOBJ)gximag3x.$(OBJ) : $(GLSRC)gximag3x.c $(GXERR) $(math__h) $(memory__h)\
> - $(gdevbbox_h)\
> + $(gdevbbox_h) $(gp_h)\
> $(gsbitops_h) $(gscpixel_h) $(gscspace_h) $(gsstruct_h)\
> $(gxdevice_h) $(gxdevmem_h) $(gximag3x_h) $(gxistate_h)
> $(GLCC) $(GLO_)gximag3x.$(OBJ) $(C_) $(GLSRC)gximag3x.c
> Index: gs/doc/Devices.htm
> ===================================================================
> RCS file: /cvs/ghostscript/gs/doc/Devices.htm,v
> retrieving revision 1.67
> diff -b -u -r1.67 Devices.htm
> --- gs/doc/Devices.htm 9 Jun 2003 21:55:07 -0000 1.67
> +++ gs/doc/Devices.htm 10 Aug 2003 13:49:43 -0000
> @@ -1138,8 +1138,9 @@
> <p></p>
>
> <p>
> -Currently, it always prints the bounding box on <b><tt>stderr</tt></b>;
> -eventually, it should also recognize <b><tt>-sOutputFile=</tt></b>.
> +Old versions always print the bounding box on <b><tt>stderr</tt></b>.
> +Since v. 8.11 <b><tt>-sOutputFile=</tt></b> is supported with
> +default <b><tt>null</tt></b> value corresponding to <b><tt>stderr</tt></b>.
>
> <p>
> Note that this device, like other devices, has a resolution and a (maximum)