Re: outputFile support in bbox device
"Igor V. Melichev" <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
IMO this to be delayed until 8.11 release. (I don't review this patch now. Please remind later). Igor. ----- Original Message ----- From: "Alex Cherepanov" <[email protected]> To: "gs-code-review" <[email protected]>; "Igor V. Melichev" <[email protected]> Sent: Sunday, August 10, 2003 7:23 PM Subject: outputFile support in bbox device > 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) >