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)
>
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.