diff options
Diffstat (limited to 'gs/contrib/japanese/gdevdmpr.c')
-rw-r--r-- | gs/contrib/japanese/gdevdmpr.c | 881 |
1 files changed, 881 insertions, 0 deletions
diff --git a/gs/contrib/japanese/gdevdmpr.c b/gs/contrib/japanese/gdevdmpr.c new file mode 100644 index 000000000..7b5cc7e6d --- /dev/null +++ b/gs/contrib/japanese/gdevdmpr.c @@ -0,0 +1,881 @@ +/* COPYRIGHT (C) 1990, 1992 Aladdin Enterprises. All rights reserved. + Distributed by Free Software Foundation, Inc. + + This file is part of Ghostscript. + + Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the Ghostscript General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute + Ghostscript, but only under the conditions described in the Ghostscript + General Public License. A copy of this license is supposed to have been + given to you along with Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. */ + +/* gdevdmpr.c + * + * Dot matrix printer driver for Ghostscript + * + * The first version written by ... K.Asayama Nov 1992 + * NEC PC-H98 high resolution mode supported by ... OkI Dec 1992 + * IBM PC AT/Compatible machines supported by ... hero.h Mar 1993 + * Modified for 386BSD by ... FKR Mar 1993 + * Modified for Ghostscript version 2.5.2 by ... K.Asayama Mar 1993 + * Modified for Ghostscript version 2.6.1 by ... K.Asayama Oct 1993 + * Modified for Ghostscript version 4.03 by ... K.Asayama May 1997 + */ + +#include "gdevprn.h" +#include "gp.h" +#include "errors.h" +#include "gsparam.h" +#include "gsstate.h" +#include "math_.h" +#include "malloc_.h" + +/* include library header. */ +#include "dviprlib.h" + +extern FILE *lib_fopen(const char *); + +#define LOCAL_DEBUG 0 + +#define DEVICE_NAME "dmprt" +#define DEVICE_VERSION 201 /* 2.01 */ + +typedef struct gx_device_dmprt_local_s gx_device_dmprt_local; +struct gx_device_dmprt_local_s { + int orig_x_dpi; + int orig_y_dpi; + + int x_offset; + int y_offset; + + int spec_width; + int spec_height; + int max_width; + int max_height; + int dev_margin[4]; /* left bottom right top */ + + int prtcfg_init_f; + int verbose_f; + int debug_f; + dviprt_cfg_t prtcfg; + dviprt_print prtinfo; +}; + +/* declaration of the structure to describe `DMPRT' device driver */ +typedef struct gx_device_dmprt_s gx_device_dmprt; +struct gx_device_dmprt_s { + gx_device_common; + gx_prn_device_common; + + gx_device_dmprt_local dmprt; +}; + +/* declarations of main functions */ +private dev_proc_get_params(gdev_dmprt_get_params); +private dev_proc_put_params(gdev_dmprt_put_params); +private dev_proc_get_initial_matrix(gdev_dmprt_get_initial_matrix); +private dev_proc_open_device(gdev_dmprt_open); +private dev_proc_print_page(gdev_dmprt_print_page); +private dev_proc_close_device(gdev_dmprt_close); + +/* declarations of sub functions to get printer properties. */ +private void gdev_dmprt_init_printer_props(gx_device_dmprt *); +private int gdev_dmprt_get_printer_props(gx_device_dmprt *,char *); +private int gdev_dmprt_check_code_props(byte * ,int ); +private FILE *gdev_dmprt_dviprt_lib_fopen(const char *,char *); + +private int gdev_dmprt_error_no_dviprt_to_gs(int ); + +/* The device descriptor */ +gx_device_procs prn_dmprt_procs = { + gdev_dmprt_open, + gdev_dmprt_get_initial_matrix, + 0, /* sync_output */ + gdev_prn_output_page, + gdev_dmprt_close, + gdev_prn_map_rgb_color, + gdev_prn_map_color_rgb, + 0, /* fill_rectangle */ + 0, /* tile_rectangle */ + 0, /* copy_mono */ + 0, /* copy_color */ + 0, /* draw_line */ + 0, /* get_bits */ + gdev_dmprt_get_params, + gdev_dmprt_put_params, + gx_default_map_cmyk_color, + 0, +}; + +#define DEFAULT_DPI 180 +#define DEFAULT_WIDTH 8.3 +#define DEFAULT_HEIGHT 11.7 + +gx_device_dmprt gs_dmprt_device = { + prn_device_body(gx_device_dmprt, prn_dmprt_procs, DEVICE_NAME, + DEFAULT_WIDTH*10, /* width 10'th */ + DEFAULT_HEIGHT*10, /* height 10'th */ + DEFAULT_DPI, /* X resolution */ + DEFAULT_DPI, /* Y resolution */ + 0,0,0,0, /* margins (top,left,bottom,right) */ + 1,1,1,1,2,2, /* color info. */ + gdev_dmprt_print_page), + + { + DEFAULT_DPI, DEFAULT_DPI, + 0, 0, /* offset */ + DEFAULT_DPI*DEFAULT_WIDTH, /* specified width */ + DEFAULT_DPI*DEFAULT_HEIGHT, /* specified height */ + -1,-1, /* maximal width,height */ + { 0,0,0,0 }, /* margins */ + + /* status of the device */ + 0, /* printer configuration is not initialized */ + 0, /* verbose mode */ + 0, /* debug flag */ + }, +}; + +#define ppdev ((gx_device_printer *)pdev) +#define pddev ((gx_device_dmprt *)pdev) + + +typedef struct { + char *name; + int no; +} dmprt_encoding; +private dmprt_encoding gdev_dmprt_encode_list[] = { + {"Null",CFG_ENCODE_NULL}, + {"AsciiHex",CFG_ENCODE_HEX }, + {"CCITTFax",CFG_ENCODE_FAX }, + {"PCLMode1Compress",CFG_ENCODE_PCL1 }, + {"PCLMode2Compress",CFG_ENCODE_PCL2 }, + {0}, +}; + + +/* --- Get properties of printer device. --- */ +private int gdev_dmprt_get_dmprt_params(gx_device *pdev, gs_param_list *plist); +private int +gdev_dmprt_get_dviprt_params(gx_device *pdev, gs_param_list *plist); + +private int +gdev_dmprt_get_params(gx_device *pdev, gs_param_list *plist) +{ + int code; + gs_param_dict dict; + const char *param_name; + + if (!pddev->dmprt.prtcfg_init_f) + gdev_dmprt_init_printer_props(pddev); + + dict.size = 30; + code = param_begin_write_dict(plist, (param_name = "DmprtParams"), + &dict, false); + if (code < 0) return code; + if (code == 0) { + code = gdev_dmprt_get_dmprt_params(pdev, dict.list); + param_end_write_dict(plist, param_name, &dict); + if (code < 0) return code; + } + + dict.size = 30; + code = param_begin_write_dict(plist, (param_name = "DviprtParams"), + &dict, false); + if (code < 0) return code; + if (code == 0) { + code = gdev_dmprt_get_dviprt_params(pdev, dict.list); + param_end_write_dict(plist, param_name, &dict); + if (code < 0) return code; + } + + { + int w = pddev->width; + int h = pddev->height; + pddev->width = pddev->dmprt.spec_width; + pddev->height = pddev->dmprt.spec_height; + code = gdev_prn_get_params(pdev, plist); + pddev->width = w; + pddev->height = h; + } + + return code; +} + +/* internal routines for get_params */ +private int +gdev_dmprt_get_dmprt_params(gx_device *pdev, gs_param_list *plist) +{ + int code; + long vlong; + bool vbool; + gs_param_int_array vaint; + int int_data[4]; + + vlong = DEVICE_VERSION; + code = param_write_long(plist, "Version", &vlong); + if (code < 0) return code; + + vbool = pddev->dmprt.debug_f; + code = param_write_bool(plist, "Debug", &vbool); + if (code < 0) return code; + + vbool = pddev->dmprt.verbose_f; + code = param_write_bool(plist, "Verbose", &vbool); + if (code < 0) return code; + + vaint.size = 2; + vaint.data = int_data; + vaint.persistent = false; + int_data[0] = pddev->dmprt.max_width; + int_data[1] = pddev->dmprt.max_height; + code = param_write_int_array(plist, "MaxSize", &vaint); + if (code < 0) return code; + + vaint.size = 2; + vaint.data = int_data; + vaint.persistent = false; + int_data[0] = pddev->dmprt.x_offset; + int_data[1] = pddev->dmprt.y_offset; + code = param_write_int_array(plist, "Offsets", &vaint); + if (code < 0) return code; + + vaint.size = 4; + vaint.data = int_data; + vaint.persistent = false; + { int i; + for (i=0;i<4;i++) int_data[i] = pddev->dmprt.dev_margin[i]; + } + code = param_write_int_array(plist, "Margins", &vaint); + if (code < 0) return code; + + return code; +} + +private int +gdev_dmprt_get_dviprt_params(gx_device *pdev, gs_param_list *plist) +{ + dviprt_cfg_t *pprt = &pddev->dmprt.prtcfg; + long vlong; + bool vbool; + gs_param_string vstr; + const char *vchar; + int code; + int i; + + vlong = pprt->integer[CFG_PINS] * 8; + code = param_write_long(plist,"Pins", &vlong); + if (code < 0) return code; + code = param_write_long(plist, "MinimalUnit", + pprt->integer+CFG_MINIMAL_UNIT); + if (code < 0) return code; + code = param_write_long(plist,"MaximalUnit", + pprt->integer+CFG_MAXIMAL_UNIT); + if (code < 0) return code; + code = param_write_int(plist,"HDpi" , &pddev->dmprt.orig_x_dpi); + if (code < 0) return code; + code = param_write_int(plist,"VDpi", &pddev->dmprt.orig_y_dpi); + if (code < 0) return code; + code = param_write_long(plist,"Constant", pprt->integer+CFG_CONSTANT); + if (code < 0) return code; + + vbool = pprt->integer[CFG_UPPER_POS] & CFG_NON_TRANSPOSE_BIT ? 0 : 1; + code = param_write_bool(plist,"Transpose", &vbool); + if (code < 0) return code; + vbool = pprt->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT ? 1 : 0; + code = param_write_bool(plist,"Reverse", &vbool); + if (code < 0) return code; + vbool = (pprt->integer[CFG_UPPER_POS] & CFG_NON_MOVING) ? 1 : 0; + code = param_write_bool(plist,"NonMoving", &vbool); + if (code < 0) return code; + + vchar = pprt->strings[CFG_NAME] ? (const char*)pprt->strings[CFG_NAME] : ""; + param_string_from_string(vstr, vchar); + code = param_write_string(plist, "Name", &vstr); + if (code < 0) return code; + + for (i=0;gdev_dmprt_encode_list[i].name;i++) { + if (pprt->integer[CFG_ENCODE] == gdev_dmprt_encode_list[i].no) + break; + } + if (gdev_dmprt_encode_list[i].name == 0) i = 0; + param_string_from_string(vstr, gdev_dmprt_encode_list[i].name); + code = param_write_string(plist, "Encoding", &vstr); + if (code < 0) return code; + +#define param_string_from_prt(ps, pprt, n) \ + ((ps).data = pprt->prtcode[n] ? pprt->prtcode[n] : (const byte*)"", \ + (ps).size = pprt->prtcode[n] ? pprt->prtcode_size[n] : 0, \ + (ps).persistent = true) +#define param_write_prt(plist, name, pprt, n) \ + (param_string_from_prt(vstr, pprt, n), \ + param_write_string(plist, name, &vstr)) + + code = param_write_prt(plist, "BitImageMode", + pprt, CFG_BIT_IMAGE_MODE); + if (code < 0) return code; + code = param_write_prt(plist, "SendBitImage", + pprt, CFG_SEND_BIT_IMAGE); + if (code < 0) return code; + code = param_write_prt(plist, "BitRowHeader", + pprt, CFG_BIT_ROW_HEADER); + if (code < 0) return code; + code = param_write_prt(plist, "AfterBitImage", + pprt, CFG_AFTER_BIT_IMAGE); + if (code < 0) return code; + code = param_write_prt(plist, "LineFeed", pprt, CFG_LINE_FEED); + if (code < 0) return code; + code = param_write_prt(plist, "FormFeed", pprt, CFG_FORM_FEED); + if (code < 0) return code; + code = param_write_prt(plist, "NormalMode", pprt, CFG_NORMAL_MODE); + if (code < 0) return code; + code = param_write_prt(plist, "SkipSpaces", pprt, CFG_SKIP_SPACES); + if (code < 0) return code; + + return code; +} +/* end of internal routines for get_params */ + + +/* --- Put properties of printer device. --- */ +private int gdev_dmprt_put_dmprt_params(gx_device *pdev, gs_param_list *plist); +private int +gdev_dmprt_put_dviprt_params(gx_device *pdev, gs_param_list *plist); +private int gdev_dmprt_put_prt_code_param(gs_param_list *plist, + dviprt_cfg_t *pprt, + const char* name, int idx); +private int +gdev_dmprt_put_prt_string_param(gs_param_list *plist, + dviprt_cfg_t *pprt, const char* name, int idx); + +private int +gdev_dmprt_put_params(gx_device *pdev, gs_param_list *plist) +{ + int code = 0; + const char *param_name; + gs_param_dict dict; + + if (!pddev->dmprt.prtcfg_init_f) + gdev_dmprt_init_printer_props(pddev); + + /* dmprt parameters */ + code = param_begin_read_dict(plist, (param_name = "DmprtParams"), + &dict, false); + if (code < 0) return code; + if (code == 0) { + code = gdev_dmprt_put_dmprt_params(pdev, dict.list); + param_end_read_dict(plist, param_name, &dict); + if (code < 0) return code; + } + + /* dviprt parameters */ + code = param_begin_read_dict(plist, (param_name = "DviprtParams"), + &dict, false); + if (code < 0) return code; + if (code == 0) { + code = gdev_dmprt_put_dviprt_params(pdev, dict.list); + param_end_read_dict(plist, param_name, &dict); + if (code < 0) return code; + } + + if (pdev->is_open && code) { + int ccode = gs_closedevice(pdev); + if (ccode < 0) return ccode; + } + + pddev->width = pddev->dmprt.spec_width; + pddev->height = pddev->dmprt.spec_height; + code = gdev_prn_put_params(pdev, plist); + pddev->dmprt.spec_width = pddev->width; + pddev->dmprt.spec_height = pddev->height; + pddev->width -= (pddev->dmprt.dev_margin[0] + pddev->dmprt.dev_margin[2]); + pddev->height -= (pddev->dmprt.dev_margin[1] + pddev->dmprt.dev_margin[3]); + if (code < 0) return code; + + if (pddev->dmprt.max_width>0 && pddev->dmprt.max_width<pddev->width) + pddev->width = pddev->dmprt.max_width; + if (pddev->dmprt.max_height>0 && pddev->dmprt.max_height<pddev->height) + pddev->height = pddev->dmprt.max_height; + + dviprt_setmessagestream(pddev->dmprt.debug_f ? stderr : NULL); + + return code; +} + +/* internal routines for put_params */ + +private int +gdev_dmprt_put_dmprt_params(gx_device *pdev, gs_param_list *plist) +{ + int code; + long vlong; + bool vbool; + gs_param_int_array vaint; + + /* debug flag */ + code = param_read_bool(plist, "Debug", &vbool); + if (code < 0) return code; + if (code == 0) pddev->dmprt.debug_f = vbool; + + dviprt_setmessagestream(pddev->dmprt.debug_f ? stderr : NULL); + + code = param_read_bool(plist, "Verbose", &vbool); + if (code < 0) return code; + pddev->dmprt.verbose_f = vbool; + + /* dummy */ + code = param_read_long(plist, "Version", &vlong); + if (code < 0) return code; + + code = param_read_int_array(plist, "MaxSize", &vaint); + if (code < 0) return code; + if (code == 0) { + if (vaint.size != 2) return e_typecheck; + pddev->dmprt.max_width = vaint.data[0]; + pddev->dmprt.max_height = vaint.data[1]; + } + + code = param_read_int_array(plist, "Offsets", &vaint); + if (code < 0) return code; + if (code == 0) { + if (vaint.size != 2) return e_typecheck; + pddev->dmprt.x_offset = vaint.data[0]; + pddev->dmprt.y_offset = vaint.data[1]; + } + + code = param_read_int_array(plist, "Margins", &vaint); + if (code < 0) return code; + if (code == 0) { + int i; + if (vaint.size != 4) return e_typecheck; + for (i=0;i<4;i++) pddev->dmprt.dev_margin[i] = vaint.data[i]; + } + + return code; +} + +private int +gdev_dmprt_put_dviprt_params(gx_device *pdev, gs_param_list *plist) +{ + int code; + dviprt_cfg_t *pprt = &pddev->dmprt.prtcfg; + gs_param_string vstr; + long vlong; + bool vbool; + + /* load .cfg/.src file */ + code = param_read_string(plist, "FileName", &vstr); + if (code < 0) return code; + if (code == 0) { + char *filename = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), vstr.size + 1, 1, + "gdev_dmprt_put_props(filename)"); + int ccode; + if (filename == 0) return e_VMerror; + strncpy(filename, (const char*)vstr.data, vstr.size); + filename[vstr.size] = '\0'; + ccode = gdev_dmprt_get_printer_props(pddev,filename); + gs_free(gs_lib_ctx_get_non_gc_memory_t(), filename, vstr.size+1, 1, "gdev_dmprt_put_props(filename)"); + if (ccode < 0) return ccode; + } + + code = param_read_long(plist, "Pins", &vlong); + if (code < 0) return code; + if (code == 0) pprt->integer[CFG_PINS] = vlong / 8; + + code = param_read_long(plist, "MinimalUnit", &vlong); + if (code < 0) return code; + if (code == 0) pprt->integer[CFG_MINIMAL_UNIT] = vlong; + + code = param_read_long(plist, "MaximalUnit", &vlong); + if (code < 0) return code; + if (code == 0) pprt->integer[CFG_MAXIMAL_UNIT] = vlong; + + code = param_read_long(plist, "HDpi", &vlong); + if (code < 0) return code; + if (code == 0) pddev->dmprt.orig_x_dpi = vlong; + + code = param_read_long(plist, "VDpi", &vlong); + if (code < 0) return code; + if (code == 0) pddev->dmprt.orig_y_dpi = vlong; + + code = param_read_long(plist, "Constant", &vlong); + if (code < 0) return code; + if (code == 0) pprt->integer[CFG_CONSTANT] = vlong; + + { + long tr = pprt->integer[CFG_UPPER_POS] & CFG_NON_TRANSPOSE_BIT; + long rv = pprt->integer[CFG_UPPER_POS] & CFG_REVERSE_BIT; + long nm = pprt->integer[CFG_UPPER_POS] & CFG_NON_MOVING; + param_read_bool(plist,"Transpose", &vbool); + if (code < 0) return code; + if (code == 0) tr = vbool ? 0 : CFG_NON_TRANSPOSE_BIT; + param_read_bool(plist,"Reverse", &vbool); + if (code < 0) return code; + if (code == 0) rv = vbool ? CFG_REVERSE_BIT : 0; + param_read_bool(plist,"NonMoving", &vbool); + if (code < 0) return code; + if (code == 0) nm = vbool ? CFG_NON_MOVING : 0; + pprt->integer[CFG_UPPER_POS] = tr | rv | nm; + } + + code = gdev_dmprt_put_prt_code_param(plist, pprt, "BitImageMode", + CFG_BIT_IMAGE_MODE); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "SendBitImage", + CFG_SEND_BIT_IMAGE); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "BitRowHeader", + CFG_BIT_ROW_HEADER); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "AfterBitImage", + CFG_AFTER_BIT_IMAGE); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "LineFeed", + CFG_LINE_FEED); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "FormFeed", + CFG_FORM_FEED); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "NormalMode", + CFG_NORMAL_MODE); + if (code < 0) return code; + code = gdev_dmprt_put_prt_code_param(plist, pprt, "SkipSpaces", + CFG_SKIP_SPACES); + if (code < 0) return code; + + code = gdev_dmprt_put_prt_string_param(plist, pprt, "Name", + CFG_NAME); + if (code < 0) return code; + + code = param_read_string(plist, "Encoding", &vstr); + if (code < 0) return code; + if (code == 0) { + int i; + for (i=0; gdev_dmprt_encode_list[i].name ; i++) { + if (strlen(gdev_dmprt_encode_list[i].name) == vstr.size) { + if (strncmp(gdev_dmprt_encode_list[i].name, + vstr.data, vstr.size) == 0) { + pprt->integer[CFG_ENCODE] = gdev_dmprt_encode_list[i].no; + break; + } + } + } + if (gdev_dmprt_encode_list[i].name == 0) + return e_rangecheck; + } + + return code; +} + +private int +gdev_dmprt_put_prt_code_param(gs_param_list *plist, + dviprt_cfg_t *pprt, const char* name, int idx) +{ + gs_param_string vstr; + + int code = param_read_string(plist, name, &vstr); + if (code == 0) { + int ccode = gdev_dmprt_check_code_props(vstr.data, vstr.size); + byte *pbyte; + if (ccode < 0) return e_rangecheck; + pbyte = (byte *)malloc(vstr.size+1); + if (pbyte == 0) return e_VMerror; + memcpy(pbyte, vstr.data, vstr.size); + pbyte[vstr.size] = 0; + pprt->prtcode[idx] = pbyte; + pprt->prtcode_size[idx] = vstr.size; + if (code == 0) code = 1; + } + return code; +} + +private int +gdev_dmprt_put_prt_string_param(gs_param_list *plist, + dviprt_cfg_t *pprt, const char* name, int idx) +{ + gs_param_string vstr; + + int code = param_read_string(plist, name, &vstr); + if (code == 0) { + byte *pbyte; + pbyte = (byte *)malloc(vstr.size+1); + if (pbyte == 0) return e_VMerror; + memcpy(pbyte, vstr.data, vstr.size); + pbyte[vstr.size] = 0; + pprt->strings[idx] = pbyte; + if (code == 0) code = 1; + } + return code; +} +/* end of internal routines for put_params */ + + +/* --- Get initial matrix. --- */ +private void +gdev_dmprt_get_initial_matrix(gx_device *pdev, gs_matrix *pmat) +{ + gx_default_get_initial_matrix(pdev,pmat); + pmat->tx += (pddev->dmprt.x_offset - pddev->dmprt.dev_margin[0]); + pmat->ty += (pddev->dmprt.y_offset + pddev->dmprt.dev_margin[3]); +} + +/* --- Open printer device. --- */ +private int +gdev_dmprt_open(gx_device *pdev) +{ + int code; + dviprt_cfg_t *pcfg; + dviprt_print *pprint; + + pprint = &pddev->dmprt.prtinfo; + pcfg = &pddev->dmprt.prtcfg; + + if ((code = gdev_prn_open(pdev)) < 0) + return code; + pcfg->integer[CFG_DPI] = (int)ppdev->x_pixels_per_inch; + pcfg->integer[CFG_Y_DPI] = (int)ppdev->y_pixels_per_inch; + code = dviprt_initlibrary(pprint,pcfg,gdev_prn_raster(pdev),pdev->height); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + code = dviprt_setbuffer(pprint,NULL); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + + return 0; +} + +/* --- Close printer device. --- */ +private int +gdev_dmprt_close(gx_device *pdev) +{ + int code; + dviprt_print *pprint; + + pprint = &pddev->dmprt.prtinfo; + + if (!strchr(pddev->fname,'%')) { + code = dviprt_endbitmap(pprint); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + } + if (pddev->dmprt.verbose_f && pddev->PageCount>0) { + eprintf2("%s: Total %lu bytes output.\n", + pddev->dname,dviprt_getoutputbytes(pprint)); + } + code = dviprt_unsetbuffer(pprint); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + return gdev_prn_close(pdev); +} + +/* Output the PAGE. */ +private int +gdev_dmprt_print_page(gx_device_printer *pdev, FILE *prn_stream) +{ + int code = 0; + dviprt_print *pprint = &pddev->dmprt.prtinfo; + int line_size = gdev_prn_raster((gx_device *)pdev); + int pins = dviprt_getscanlines(pprint); + int i_buf_size = pins * line_size; + int lnum = 0; + ulong prev_bytes; + byte *in; + + /* get work buffer */ + in = (byte *)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 1, i_buf_size ,"gdev_dmprt_print_page(in)"); + if ( in == 0 ) + return e_VMerror; + + /* Initialize this printer driver */ + if (pdev->file_is_new) { + code = dviprt_setstream(pprint,NULL,prn_stream); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + } + if (pddev->dmprt.verbose_f) { + if (pddev->PageCount == 1) + eprintf2("%s: %s\n", pddev->dname, pddev->dmprt.prtcfg.strings[CFG_NAME]); + eprintf2("%s: [%ld]",pddev->dname, pddev->PageCount); + } + prev_bytes = dviprt_getoutputbytes(pprint); + code = dviprt_beginpage(pprint); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + + /* Transfer pixels to printer */ + while ( lnum < pdev->height ) { + int num_lines; + + num_lines = pdev->height-lnum; + if (num_lines > pins) + num_lines = pins; + + code = gdev_prn_copy_scan_lines(pdev,lnum,in,line_size*num_lines); + if (code < 0) goto error_ex; + + lnum += num_lines; + if (num_lines < pins) { + memset(in+line_size*num_lines,0,line_size*(pins-num_lines)); + } + + code = dviprt_outputscanlines(pprint,in); + if (code < 0) { + code = gdev_dmprt_error_no_dviprt_to_gs(code); + goto error_ex; + } + } + + /* Eject the page and set printer normal mode. */ + if (strchr(pdev->fname,'%')) { + code = dviprt_endbitmap(pprint); + if (code < 0) return gdev_dmprt_error_no_dviprt_to_gs(code); + } + fflush(pddev->file); + if (pddev->dmprt.verbose_f) { + eprintf1(" %lu bytes\n",dviprt_getoutputbytes(pprint)-prev_bytes); + } +error_ex: + gs_free(gs_lib_ctx_get_non_gc_memory_t(), (char *)in, 1, i_buf_size,"gdev_dmprt_print_page(in)"); + + return code; +} + + +/************************** Internal Routines **************************/ + +/************************ Get printer properties. ***********************/ +private int +gdev_dmprt_check_code_props(byte *str,int len) +{ + byte *end = str+len; + while (str < end) { + byte fmt = *str++; + if (fmt & CFG_FMT_BIT) { + int s = *str++; + str += s; + if (str > end) return e_rangecheck; + if ((fmt & CFG_FMT_FORMAT_BIT) == CFG_FMT_STRINGS) { + s = *str++; + str += s; + if (str > end) return e_rangecheck; + } + } + else { + str += fmt; + if (str > end) return e_rangecheck; + } + } + return str == end ? 0 : e_rangecheck; +} + +private void +gdev_dmprt_init_printer_props(gx_device_dmprt *pdev) +{ + dviprt_cfg_t *pprt; + int i; + + pprt = &pdev->dmprt.prtcfg; + + for (i=0;i<CFG_INTEGER_TYPE_COUNT;i++) + pprt->integer[i] = 0; + for (i=0;i<CFG_STRINGS_TYPE_COUNT;i++) + pprt->strings[i] = 0; + for (i=0;i<CFG_PRTCODE_TYPE_COUNT;i++) { + pprt->prtcode[i] = 0; + pprt->prtcode_size[i] = 0; + } + pdev->dmprt.prtcfg_init_f = 1; +} + +private int +gdev_dmprt_get_printer_props(gx_device_dmprt *pdev,char *fnamebase) +{ + int code; + FILE *fp; + dviprt_cfg_t cfg; + char *fname; + + fname = gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 256,1,"dviprt_lib_fname"); + if (fname == NULL) return e_VMerror; + + fp = gdev_dmprt_dviprt_lib_fopen(fnamebase,fname); + if (fp == NULL) { + return e_undefinedfilename; + } + if (fseek(fp,18,0) < 0) + return e_ioerror; + code = fgetc(fp); + fclose(fp); + + if (code == EOF) + code = e_ioerror; + else if (code == 0xff) { + code = dviprt_readcfg(fname,&cfg,NULL,0,NULL,0); + } + else { + code = dviprt_readsrc(fname,&cfg,NULL,0,NULL,0); + } + + if (code < 0) { + code = gdev_dmprt_error_no_dviprt_to_gs(code); + } + else { /* success */ + memcpy(&pdev->dmprt.prtcfg,&cfg,sizeof(dviprt_cfg_t)); + pddev->dmprt.orig_x_dpi = cfg.integer[CFG_DPI]; + pddev->dmprt.orig_y_dpi = + cfg.integer[CFG_Y_DPI] > 0 ? cfg.integer[CFG_Y_DPI] : pddev->dmprt.orig_x_dpi; + } + + gs_free(gs_lib_ctx_get_non_gc_memory_t(), fname,256,1,"dviprt_lib_fname"); + + return code; +} + +private const char * gp_file_name_concat_string(const char *, unsigned); +private FILE * +gdev_dmprt_dviprt_lib_fopen(const char *fnamebase,char *fname) +{ + FILE *fp; + char *env; + + strcpy(fname,fnamebase); + fp = lib_fopen(fname); + if (fp == NULL) { + env = getenv("TEXCFG"); + if (env) { + strcpy(fname,env); + strcat(fname, gp_file_name_concat_string(env,strlen(env))); + strcat(fname,fnamebase); + fp = fopen(fname,gp_fmode_rb); + } + } + return fp; +} + +/* Misc. */ +private int +gdev_dmprt_error_no_dviprt_to_gs(int code) +{ + switch (code) { + case CFG_ERROR_MEMORY: + return e_VMerror; + case CFG_ERROR_FILE_OPEN: + case CFG_ERROR_OUTPUT: + return e_ioerror; + default: + return -1; + } +} + +/* Answer the string to be used for combining a directory/device prefix */ +/* with a base file name. The prefix directory/device is examined to */ +/* determine if a separator is needed and may return an empty string */ +private const char * +gp_file_name_concat_string(const char *prefix, unsigned plen) +{ + if (plen > 0 && prefix[plen - 1] == '/') + return ""; + return "/"; +} |