[gs-cvs] rev 8623 - trunk/gs/contrib/opvp

till at ghostscript.com till at ghostscript.com
Fri Apr 4 04:28:27 PDT 2008


Author: till
Date: 2008-04-04 04:28:22 -0700 (Fri, 04 Apr 2008)
New Revision: 8623

Modified:
   trunk/gs/contrib/opvp/gdevopvp.c
   trunk/gs/contrib/opvp/opvp_common.h
   trunk/gs/contrib/opvp/opvp_media.def
Log:
Updated the OpenPrinting Vector driver interface ("opvp", "oprp") to version 1.0.


Modified: trunk/gs/contrib/opvp/gdevopvp.c
===================================================================
--- trunk/gs/contrib/opvp/gdevopvp.c	2008-04-04 08:53:57 UTC (rev 8622)
+++ trunk/gs/contrib/opvp/gdevopvp.c	2008-04-04 11:28:22 UTC (rev 8623)
@@ -16,69 +16,69 @@
 
 */
 
-/* $Id: gdevopvp.c,v 1.13 2006/01/18 15:11:59 gishi Exp $ */
+/* $Id: gdevopvp.c 728 2008-03-03 02:56:05Z sho-otani $ */
 /* gdevopvp.c  ver.1.00 rel.1.0     26 Nov 2004 */
 /* OpenPrinting Vector Printer Driver Glue Code */
 
-#include        "std.h"
-#include	<stdio.h>
-#include	<stdlib.h>
-#include	<unistd.h>
-#include	<string.h>
-#include	<locale.h>
-#include	<iconv.h>
-#include	<langinfo.h>
-#include	<dlfcn.h>
-#include	<sys/types.h>
-#include	<sys/stat.h>
-#include	<fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <locale.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
-#include	"string_.h"
-#include	"math_.h"
-#include	"gx.h"
-#include	"ghost.h"
-#include	"gscdefs.h"
-#include	"gsexit.h"
-#include	"gsstruct.h"
-#include	"gserrors.h"
-#include	"gsmatrix.h"
-#include	"gsparam.h"
-#include	"gxdevice.h"
-#include	"gscspace.h"
-#include	"gsutil.h"
-#include	"gdevprn.h"
-#include	"gdevvec.h"
-#include	"spprint.h"
-#include	"ghost.h"
-#include	"gzstate.h"
-#include	"ialloc.h"
-#include	"iddict.h"
-#include	"dstack.h"
-#include	"ilevel.h"
-#include	"iinit.h"
-#include	"iname.h"
-#include	"imemory.h"
-#include	"igstate.h"
-#include	"interp.h"
-#include	"ipacked.h"
-#include	"iparray.h"
-#include	"iutil.h"
-#include	"ivmspace.h"
-#include	"opdef.h"
-#include	"store.h"
-#include	"gspath.h"
-#include	"gzpath.h"
-#include	"gsropt.h"
-#include	"gsiparam.h"
-#include	"gxxfont.h"
+#include "string_.h"
+#include "math_.h"
+#include "gx.h"
+#include "ghost.h"
+#include "gscdefs.h"
+#include "gsexit.h"
+#include "gsstruct.h"
+#include "gserrors.h"
+#include "gsmatrix.h"
+#include "gsparam.h"
+#include "gxdevice.h"
+#include "gxdcconv.h"
+#include "gscspace.h"
+#include "gsutil.h"
+#include "gdevprn.h"
+#include "gdevvec.h"
+#include "spprint.h"
+#include "ghost.h"
+#include "gzstate.h"
+#include "ialloc.h"
+#include "iddict.h"
+#include "dstack.h"
+#include "ilevel.h"
+#include "iinit.h"
+#include "iname.h"
+#include "imemory.h"
+#include "igstate.h"
+#include "interp.h"
+#include "ipacked.h"
+#include "iparray.h"
+#include "iutil.h"
+#include "ivmspace.h"
+#include "opdef.h"
+#include "store.h"
+#include "gspath.h"
+#include "gzpath.h"
+#include "gsropt.h"
+#include "gsiparam.h"
+#include "gxxfont.h"
 
 /* added for image gamma correction */
-#include	"gximage.h"
-#include	"gxfmap.h"
-#include	"gxfrac.h"
-#include	"gxcvalue.h"
+#include "gximage.h"
+#include "gxfmap.h"
+#include "gxfrac.h"
+#include "gxcvalue.h"
 
-#include	"opvp_common.h"
+#include "opvp_common.h"
 
 #define	ENABLE_SIMPLE_MODE	1
 #define	ENABLE_SKIP_RASTER	1
@@ -97,49 +97,40 @@
 /* buffer */
 #define	OPVP_BUFF_SIZE	1024
 
+/* ROP */
+#define OPVP_0_2_ROP_S	0xCC
+#define OPVP_0_2_ROP_P	0xF0
+#define OPVP_0_2_ROP_OR	0xB8
+
 /* paper */
 #define	PS_DPI		72
 #define	MMPI		25.4
 #define	TOLERANCE	3.0
 
 typedef	struct {
-const	char		*region;
-const	char		*name;
-	float		width;
-	float		height;
+    const char *region;
+    const char *name;
+    float width;
+    float height;
 } OPVP_Paper;
 
 #define	X_DPI		300
 #define	Y_DPI		300
 
 /* driver */
-#define	gx_device_opvp_common\
-	char		*vectorDriver;\
-	char		*printerModel;\
-	void		*handle;\
-	int		(*OpenPrinter)(int,char*,int*,OPVP_api_procs**);\
-	int		*errorno;\
-	int		outputFD;\
-	int		nApiEntry;\
-	OPVP_api_procs	*apiEntry;\
-	int		printerContext;\
-	char		*jobInfo;\
-	char		*docInfo;\
-	char		*pageInfo
-
 typedef	struct	gx_device_opvp_s {
-	gx_device_vector_common;
+    gx_device_vector_common;
 } gx_device_opvp;
 
 typedef	struct	gx_device_oprp_s {
-	gx_device_common;
-	gx_prn_device_common;
+    gx_device_common;
+    gx_prn_device_common;
 } gx_device_oprp;
 
 /* point (internal) */
 typedef	struct {
-	floatp		x;
-	floatp		y;
+    floatp x;
+    floatp y;
 } _fPoint;
 
 /* ----- private function prototypes ----- */
@@ -166,9 +157,9 @@
 static	char *opvp_gen_doc_info(gx_device *);
 static	char *opvp_gen_job_info(gx_device *);
 static	int opvp_set_brush_color(gx_device_opvp *, gx_color_index,
-                                 OPVP_Brush *);
+                                 opvp_brush_t *);
 static	int opvp_draw_image(gx_device_opvp *, int,
-                            int, int, int, int, int, /*const*/ byte *);
+                            int, int, int, int, int, int, const byte *);
 
 /* load/unload vector driver */
 static	int opvp_load_vector_driver(void);
@@ -182,16 +173,16 @@
 static	int opvp_output_page(gx_device *, int, int);
 static	int opvp_close(gx_device *);
 #if GS_VERSION_MAJOR >= 8
-static	gx_color_index opvp_map_rgb_color(gx_device *, gx_color_value *);	/* modified for gs 8.15 */
+static	gx_color_index opvp_map_rgb_color(gx_device *, const gx_color_value *);	/* modified for gs 8.15 */
 #else
 static	gx_color_index opvp_map_rgb_color(gx_device *, gx_color_value,
 	               gx_color_value, gx_color_value);
 #endif
 static	int opvp_map_color_rgb(gx_device *, gx_color_index, gx_color_value *);
-static	int opvp_copy_mono(gx_device *, /*const*/ byte *, int, int,
+static	int opvp_copy_mono(gx_device *, const byte *, int, int,
                            gx_bitmap_id, int, int, int, int,
                            gx_color_index, gx_color_index);
-static	int opvp_copy_color(gx_device *, /*const*/ byte *, int, int,
+static	int opvp_copy_color(gx_device *, const byte *, int, int,
                             gx_bitmap_id, int, int, int, int);
 static	int _get_params(gs_param_list *);
 static	int opvp_get_params(gx_device *, gs_param_list *);
@@ -209,6 +200,19 @@
 	                   int, int, int, int, const gx_drawing_color *,
 	                   int, gs_logical_operation_t, const gx_clip_path *);
 
+/* available color spaces */
+
+static char cspace_available[] = {
+        0, /* OPVP_CSPACE_BW */
+        0, /* OPVP_CSPACE_DEVICEGRAY */
+        0, /* OPVP_CSPACE_DEVICECMY */
+        0, /* OPVP_CSPACE_DEVICECMYK */
+        0, /* OPVP_CSPACE_DEVICERGB */
+        0, /* OPVP_CSPACE_DEVICEKRGB */
+        1, /* OPVP_CSPACE_STANDARDRGB */
+        0 /* OPVP_CSPACE_STANDARDRGB64 */
+};
+
 /* vector driver procs */
 static	int opvp_beginpage(gx_device_vector *);
 static	int opvp_setlinewidth(gx_device_vector *, floatp);
@@ -281,218 +285,906 @@
 static	image_enum_proc_end_image(opvp_image_end_image);
 
 gs_public_st_suffix_add0_final(
-	st_device_opvp,
-	gx_device_opvp,
-	"gx_device_opvp",
-	device_opvp_enum_ptrs,
-	device_opvp_reloc_ptrs,
-	gx_device_finalize,
-	st_device_vector
+    st_device_opvp,
+    gx_device_opvp,
+    "gx_device_opvp",
+    device_opvp_enum_ptrs,
+    device_opvp_reloc_ptrs,
+    gx_device_finalize,
+    st_device_vector
 );
 
 #define	opvp_initial_values	\
-	NULL,	/* *vectorDriver */\
-	NULL,	/* *printerModel */\
-	NULL,	/* *handle */\
-	NULL,	/* (*OpenPrinter)() */\
-	NULL,	/* *errorno */\
-	-1,	/* outputFD */\
-	0,	/* nApiEntry */\
-	NULL,	/* *apiEntry */\
-	-1,	/* printerContext */\
-	NULL,	/* *jobInfo */\
-	NULL	/* *docInfo */
+    NULL, /* *vectorDriver */\
+    NULL, /* *printerModel */\
+    NULL, /* *handle */\
+    NULL, /* (*OpenPrinter)() */\
+    NULL, /* *ErrorNo */\
+    -1,	/* outputFD */\
+    0,	/* nApiEntry */\
+    NULL, /* *apiEntry */\
+    -1,	/* printerContext */\
+    NULL, /* *jobInfo */\
+    NULL /* *docInfo */
 
 /* device procs */
 #define	opvp_procs \
 {\
-	opvp_open,\
-	opvp_get_initial_matrix,\
-	NULL,	/* sync_output */\
-	opvp_output_page,\
-	opvp_close,\
-	opvp_map_rgb_color,\
-	opvp_map_color_rgb,\
-	opvp_fill_rectangle, /*gdev_vector_fill_rectangle,*/\
-	NULL,	/* tile_rectangle OBSOLETE */\
-	opvp_copy_mono,\
-	opvp_copy_color,\
-	NULL,	/* draw_line OBSOLETE */\
-	NULL,	/* get_bits */\
-	opvp_get_params,\
-	opvp_put_params,\
-	NULL,	/* map_cmyk_color */\
-	NULL,	/* get_xfont_procs */\
-	NULL,	/* get_xfont_device */\
-	NULL,	/* map_rgb_alpha_color */\
-	gx_page_device_get_page_device,\
-	NULL,	/* get_alpha_bits OBSOLETE */\
-	NULL,	/* copy_alpha */\
-	NULL,	/* get_band */\
-	NULL,	/* copy_rop */\
-	opvp_fill_path,\
-	opvp_stroke_path,\
-	opvp_fill_mask,\
-	gdev_vector_fill_trapezoid,\
-	gdev_vector_fill_parallelogram,\
-	gdev_vector_fill_triangle,\
-	NULL,	/* draw_thin_line */\
-	opvp_begin_image,\
-	NULL,	/* image_data */\
-	NULL,	/* end_image */\
-	NULL,	/* strip_tile_rectangle */\
-	NULL,	/* strip_copy_rop */\
-	NULL,	/* get_clipping_box */\
-	NULL,	/* begin_typed_image */\
-        NULL,   /* get_bits_rectangle */\
-        NULL,   /* map_color_rgb_alpha */\
-        NULL,   /* create_compositor */\
-        NULL,   /* get_hardware_params */\
-        NULL,   /* text_begin */\
-        NULL,   /* finish_copydevice */\
-        NULL,   /* begin_transparency_group */\
-        NULL,   /* end_transparency_group */\
-        NULL,   /* begin_transparency_mask */\
-        NULL,   /* end_transparency_mask */\
-        NULL    /* discard_transparency_layer */\
+    opvp_open,\
+    opvp_get_initial_matrix,\
+    NULL, /* sync_output */\
+    opvp_output_page,\
+    opvp_close,\
+    opvp_map_rgb_color,\
+    opvp_map_color_rgb,\
+    opvp_fill_rectangle, /*gdev_vector_fill_rectangle,*/\
+    NULL, /* tile_rectangle OBSOLETE */\
+    opvp_copy_mono,\
+    opvp_copy_color,\
+    NULL, /* draw_line OBSOLETE */\
+    NULL, /* get_bits */\
+    opvp_get_params,\
+    opvp_put_params,\
+    NULL, /* map_cmyk_color */\
+    NULL, /* get_xfont_procs */\
+    NULL, /* get_xfont_device */\
+    NULL, /* map_rgb_alpha_color */\
+    gx_page_device_get_page_device,\
+    NULL, /* get_alpha_bits OBSOLETE */\
+    NULL, /* copy_alpha */\
+    NULL, /* get_band */\
+    NULL, /* copy_rop */\
+    opvp_fill_path,\
+    opvp_stroke_path,\
+    opvp_fill_mask,\
+    gdev_vector_fill_trapezoid,\
+    gdev_vector_fill_parallelogram,\
+    gdev_vector_fill_triangle,\
+    NULL, /* draw_thin_line */\
+    opvp_begin_image,\
+    NULL, /* image_data */\
+    NULL, /* end_image */\
+    NULL, /* strip_tile_rectangle */\
+    NULL, /* strip_copy_rop */\
+    NULL, /* get_clipping_box */\
+    NULL, /* begin_typed_image */\
+    NULL, /* get_bits_rectangle */\
+    NULL, /* map_color_rgb_alpha */\
+    NULL, /* create_compositor */\
+    NULL, /* get_hardware_params */\
+    NULL, /* text_begin */\
+    NULL, /* finish_copydevice */\
+    NULL, /* begin_transparency_group */\
+    NULL, /* end_transparency_group */\
+    NULL, /* begin_transparency_mask */\
+    NULL, /* end_transparency_mask */\
+    NULL  /* discard_transparency_layer */\
 }
 
+
 /* vector procs */
 static	gx_device_vector_procs	opvp_vector_procs =
 {
-	/* Page management */
-	opvp_beginpage,
-	/* Imager state */
-	opvp_setlinewidth,
-	opvp_setlinecap,
-	opvp_setlinejoin,
-	opvp_setmiterlimit,
-	opvp_setdash,
-	opvp_setflat,
-	opvp_setlogop,
-	/* Other state */
+    /* Page management */
+    opvp_beginpage,
+    /* Imager state */
+    opvp_setlinewidth,
+    opvp_setlinecap,
+    opvp_setlinejoin,
+    opvp_setmiterlimit,
+    opvp_setdash,
+    opvp_setflat,
+    opvp_setlogop,
+    /* Other state */
 #if GS_VERSION_MAJOR >= 8
-	opvp_can_handle_hl_color,		/* added for gs 8.15 */
+    opvp_can_handle_hl_color,		/* added for gs 8.15 */
 #endif
-	opvp_setfillcolor,
-	opvp_setstrokecolor,
-	/* Paths */
-	opvp_vector_dopath,
-	opvp_vector_dorect,
-	opvp_beginpath,
-	opvp_moveto,
-	opvp_lineto,
-	opvp_curveto,
-	opvp_closepath,
-	opvp_endpath
+    opvp_setfillcolor,
+    opvp_setstrokecolor,
+    /* Paths */
+    opvp_vector_dopath,
+    opvp_vector_dorect,
+    opvp_beginpath,
+    opvp_moveto,
+    opvp_lineto,
+    opvp_curveto,
+    opvp_closepath,
+    opvp_endpath
 };
 
 const	gx_device_opvp		gs_opvp_device =
 {
-	std_device_dci_type_body(
-		gx_device_opvp,
-		0,
-		"opvp",
-		&st_device_opvp,
-		DEFAULT_WIDTH_10THS_A4  * X_DPI / 10,
-		DEFAULT_HEIGHT_10THS_A4 * Y_DPI / 10,
-		X_DPI,
-		Y_DPI,
-		3,
-		24,
-		255,
-		255,
-		256,
-		256
-	),
-	opvp_procs
+    std_device_dci_type_body(
+	gx_device_opvp,
+	0,
+	"opvp",
+	&st_device_opvp,
+	DEFAULT_WIDTH_10THS_A4  * X_DPI / 10,
+	DEFAULT_HEIGHT_10THS_A4 * Y_DPI / 10,
+	X_DPI,
+	Y_DPI,
+	3,
+	24,
+	255,
+	255,
+	256,
+	256
+    ),
+    opvp_procs
 };
 
 /* for inkjet */
-static	gx_device_procs		prn_oprp_procs =
-	prn_color_params_procs(
-		oprp_open,
-		opvp_output_page,
-		opvp_close,
-		opvp_map_rgb_color,
-		opvp_map_color_rgb,
-		oprp_get_params,
-		oprp_put_params
-	);
+static	gx_device_procs prn_oprp_procs =
+    prn_color_params_procs(
+	oprp_open,
+	opvp_output_page,
+	opvp_close,
+	opvp_map_rgb_color,
+	opvp_map_color_rgb,
+	oprp_get_params,
+	oprp_put_params
+    );
 
-const	gx_device_oprp		gs_oprp_device =
+const gx_device_oprp gs_oprp_device =
 {
-	prn_device_std_margins_body(
-		gx_device_oprp,
-		prn_oprp_procs,
-		"oprp",
-		DEFAULT_WIDTH_10THS_A4,
-		DEFAULT_HEIGHT_10THS_A4,
-		X_DPI,
-		Y_DPI,
-		0, 0, 0, 0, 0, 0,
-		24,
-		oprp_print_page
-	)
+    prn_device_std_margins_body(
+	gx_device_oprp,
+	prn_oprp_procs,
+	"oprp",
+	DEFAULT_WIDTH_10THS_A4,
+	DEFAULT_HEIGHT_10THS_A4,
+	X_DPI,
+	Y_DPI,
+	0, 0, 0, 0, 0, 0,
+	24,
+	oprp_print_page
+    )
 };
 
 /* driver mode */
-static	bool			vector = true;
-static	bool			inkjet = false;
-static	char			*vectorDriver = NULL;
-static	char			*printerModel = NULL;
-static	void			*handle = NULL;
-static	int			(*OpenPrinter)(int,char*,int*,OPVP_api_procs**)
-				    = NULL;
-static	int			*errorno = NULL;
-static	int			outputFD = -1;
-static	int			nApiEntry = 0;
-static	OPVP_api_procs		*apiEntry = NULL;
-static	int			printerContext = -1;
-static	char			*jobInfo = NULL;
-static	char			*docInfo = NULL;
-static	OPVP_ColorSpace		colorSpace = OPVP_cspaceStandardRGB;
-static	OPVP_Brush		*vectorFillColor = NULL;
-static	float			margins[4] = {0, 0, 0, 0};
-static	float			zoom[2] = {1, 1};
-static	float			shift[2] = {0, 0};
-static	bool			zoomAuto = false;
-static	bool			zooming = false;
-static  bool			beginPage = false;
+static bool vector = true;
+static bool inkjet = false;
+static char *vectorDriver = NULL;
+static char *printerModel = NULL;
+static void *handle = NULL;
+static opvp_dc_t (*OpenPrinter)(opvp_int_t,const opvp_char_t*,
+                                  const opvp_int_t[2],
+				  opvp_api_procs_t**) = NULL;
+static int (*OpenPrinter_0_2)(int,char*,int*,
+				  OPVP_api_procs**) = NULL;
+static opvp_int_t *ErrorNo = NULL;
+static opvp_int_t outputFD = -1;
+static opvp_int_t nApiEntry = 0;
+static opvp_api_procs_t *apiEntry = NULL;
+static OPVP_api_procs *apiEntry_0_2 = NULL;
+static opvp_dc_t printerContext = -1;
+static char *jobInfo = NULL;
+static char *docInfo = NULL;
+static opvp_cspace_t colorSpace = OPVP_CSPACE_STANDARDRGB;
+static opvp_cspace_t savedColorSpace;
+static opvp_brush_t *vectorFillColor = NULL;
+static float margins[4] = {0, 0, 0, 0};
+static float zoom[2] = {1, 1};
+static float shift[2] = {0, 0};
+static bool zoomAuto = false;
+static bool zooming = false;
+static bool beginPage = false;
 
+static int
+GetLastError_1_0(void)
+{
+    return *ErrorNo;
+}
+
+static int (*GetLastError)(void) = GetLastError_1_0;
+
+/* Wrapper functions that keep compatible with 0.2 */
+
+/* color space mapping 0.2 to 1.0 */
+static opvp_cspace_t cspace_0_2_to_1_0[] = {
+    OPVP_CSPACE_BW,
+    OPVP_CSPACE_DEVICEGRAY,
+    OPVP_CSPACE_DEVICECMY,
+    OPVP_CSPACE_DEVICECMYK,
+    OPVP_CSPACE_DEVICERGB,
+    OPVP_CSPACE_STANDARDRGB,
+    OPVP_CSPACE_STANDARDRGB64
+};
+
+/* color space mapping 1.0 to 0.2 */
+static opvp_cspace_t cspace_1_0_to_0_2[] = {
+    OPVP_cspaceBW,
+    OPVP_cspaceDeviceGray,
+    OPVP_cspaceDeviceCMY,
+    OPVP_cspaceDeviceCMYK,
+    OPVP_cspaceDeviceRGB,
+    0, /* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+    OPVP_cspaceStandardRGB,
+    OPVP_cspaceStandardRGB64,
+};
+
+/* image format mapping 1.0 to 0.2 */
+static opvp_imageformat_t iformat_1_0_to_0_2[] = {
+    OPVP_iformatRaw,
+    OPVP_iformatRaw, /* OPVP_IFORMAT_MASK use iformat raw in 0.2 */
+    OPVP_iformatRLE,
+    OPVP_iformatJPEG,
+    OPVP_iformatPNG,
+};
+/* image colorDepth needed in 0.2 */
+static int colorDepth_0_2[] = {
+    1, /* OPVP_CSPACE_BW */
+    8, /* OPVP_CSPACE_DEVICEGRAY */
+    24, /* OPVP_CSPACE_DEVICECMY */
+    32, /* OPVP_CSPACE_DEVICECMYK */
+    24, /* OPVP_CSPACE_DEVICERGB */
+    32, /* OPVP_CSPACE_DEVICEKRGB */
+    24, /* OPVP_CSPACE_STANDARDRGB */
+    64, /* OPVP_CSPACE_STANDARDRGB64 */
+};
+
+/* translate error code */
+static int
+GetLastError_0_2(void)
+{
+    switch(*ErrorNo) {
+    case OPVP_FATALERROR_0_2:
+	return OPVP_FATALERROR; 
+	break;
+    case OPVP_BADREQUEST_0_2:
+	return OPVP_BADREQUEST; 
+	break;
+    case OPVP_BADCONTEXT_0_2:
+	return OPVP_BADCONTEXT; 
+	break;
+    case OPVP_NOTSUPPORTED_0_2:
+	return OPVP_NOTSUPPORTED; 
+	break;
+    case OPVP_JOBCANCELED_0_2:
+	return OPVP_JOBCANCELED; 
+	break;
+    case OPVP_PARAMERROR_0_2:
+	return OPVP_PARAMERROR; 
+	break;
+    default:
+	break;
+    }
+    /* unknown error no */
+    /* return FATALERROR instead */
+    return OPVP_FATALERROR;
+}
+
+static opvp_result_t
+StartPageWrapper(opvp_dc_t printerContext, const opvp_char_t *pageInfo)
+{
+    int r;
+
+    if ((r = apiEntry_0_2->StartPage(printerContext,
+           /* discard const */(char *)pageInfo)) != OPVP_OK) {
+	  /* error */
+	return r;
+    }
+    /* initialize ROP */
+    if (apiEntry_0_2->SetROP != NULL) {
+	apiEntry_0_2->SetROP(printerContext,
+	  OPVP_0_2_ROP_P);
+    }
+    return OPVP_OK;
+}
+
+static opvp_result_t
+InitGSWrapper(opvp_dc_t printerContext)
+{
+    int r;
+
+    if ((r = apiEntry_0_2->InitGS(printerContext)) != OPVP_OK) {
+	  /* error */
+	return r;
+    }
+    /* initialize ROP */
+    if (apiEntry_0_2->SetROP != NULL) {
+	apiEntry_0_2->SetROP(printerContext,
+	  OPVP_0_2_ROP_P);
+    }
+    return OPVP_OK;
+}
+
+static opvp_result_t
+QueryColorSpaceWrapper( opvp_dc_t printerContext, opvp_int_t *pnum,
+    opvp_cspace_t *pcspace)
+{
+    int r;
+    int i;
+
+    if ((r = apiEntry_0_2->QueryColorSpace(printerContext,
+	 (OPVP_ColorSpace *)pcspace,pnum)) != OPVP_OK) {
+	/* error */
+	return r;
+    }
+    /* translate cspaces */
+    for (i = 0;i < *pnum;i++) {
+	if (pcspace[i] 
+	     > sizeof(cspace_0_2_to_1_0)/sizeof(opvp_cspace_t)) {
+	    /* unknown color space */
+	    /* set DEVICERGB instead */
+	    pcspace[i] = OPVP_CSPACE_DEVICERGB;
+	} else {
+	    pcspace[i] = cspace_0_2_to_1_0[pcspace[i]];
+	}
+    }
+    return OPVP_OK;
+}
+
+static opvp_result_t
+SetColorSpaceWrapper(opvp_dc_t printerContext, opvp_cspace_t cspace)
+{
+    if (cspace == OPVP_CSPACE_DEVICEKRGB) {
+	/* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+	*ErrorNo = OPVP_NOTSUPPORTED_0_2;
+	return -1;
+    }
+    if (cspace
+	 > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+	/* unknown color space */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    return  apiEntry_0_2->SetColorSpace(printerContext,
+      cspace_1_0_to_0_2[cspace]);
+}
+
+static opvp_result_t
+GetColorSpaceWrapper(opvp_dc_t printerContext, opvp_cspace_t *pcspace)
+{
+    int r;
+
+    if ((r = apiEntry_0_2->GetColorSpace(printerContext,
+      (OPVP_ColorSpace *)pcspace)) != OPVP_OK) {
+	/* error */
+	return r;
+    }
+    if (*pcspace
+	 > sizeof(cspace_0_2_to_1_0)/sizeof(opvp_cspace_t)) {
+	/* unknown color space */
+	/* set DEVICERGB instead */
+	*pcspace = OPVP_CSPACE_DEVICERGB;
+    } else {
+	*pcspace = cspace_0_2_to_1_0[*pcspace];
+    }
+    return r;
+}
+
+static opvp_result_t
+SetStrokeColorWrapper(opvp_dc_t printerContext, const opvp_brush_t *brush)
+{
+    OPVP_Brush brush_0_2;
+
+    if (brush == NULL) {
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+	/* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+	return OPVP_NOTSUPPORTED;
+    }
+    if (brush->colorSpace
+	 > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+	/* unknown color space */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+    brush_0_2.xorg = brush->xorg;
+    brush_0_2.yorg = brush->yorg;
+    brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+    memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+    return apiEntry_0_2->SetStrokeColor(printerContext,&brush_0_2);
+}
+
+static opvp_result_t
+SetFillColorWrapper(opvp_dc_t printerContext, const opvp_brush_t *brush)
+{
+    OPVP_Brush brush_0_2;
+
+    if (brush == NULL) {
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+	/* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+	return OPVP_NOTSUPPORTED;
+    }
+    if (brush->colorSpace
+	 > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+	/* unknown color space */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+    brush_0_2.xorg = brush->xorg;
+    brush_0_2.yorg = brush->yorg;
+    brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+    memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+    return apiEntry_0_2->SetFillColor(printerContext,&brush_0_2);
+}
+
+static opvp_result_t
+SetBgColorWrapper(opvp_dc_t printerContext, const opvp_brush_t *brush)
+{
+    OPVP_Brush brush_0_2;
+
+    if (brush == NULL) {
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    if (brush->colorSpace == OPVP_CSPACE_DEVICEKRGB) {
+	/* 0.2 doesn't have OPVP_CSPACE_DEVICEKRGB */
+	*ErrorNo = OPVP_NOTSUPPORTED_0_2;
+	return -1;
+    }
+    if (brush->colorSpace
+	 > sizeof(cspace_1_0_to_0_2)/sizeof(OPVP_ColorSpace)) {
+	/* unknown color space */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    brush_0_2.colorSpace = cspace_1_0_to_0_2[brush->colorSpace];
+    brush_0_2.xorg = brush->xorg;
+    brush_0_2.yorg = brush->yorg;
+    brush_0_2.pbrush = (OPVP_BrushData *)brush->pbrush;
+    memcpy(brush_0_2.color,brush->color,sizeof(brush_0_2.color));
+    return apiEntry_0_2->SetBgColor(printerContext,&brush_0_2);
+}
+
+static opvp_result_t
+DrawImageWrapper(
+    opvp_dc_t printerContext,
+    opvp_int_t sourceWidth,
+    opvp_int_t sourceHeight,
+    opvp_int_t sourcePitch,
+    opvp_imageformat_t imageFormat,
+    opvp_int_t destinationWidth,
+    opvp_int_t destinationHeight,
+    const void *imagedata)
+{
+    int r;
+    OPVP_Rectangle rect;
+    OPVP_ImageFormat iformat_0_2;
+    OPVP_PaintMode paintmode_0_2 = OPVP_paintModeTransparent;
+    int depth;
+
+    if (imageFormat == OPVP_IFORMAT_MASK) {
+	if (apiEntry_0_2->GetPaintMode != NULL) {
+	    apiEntry_0_2->GetPaintMode(printerContext,
+	      &paintmode_0_2);
+	}
+	if (paintmode_0_2 != OPVP_paintModeTransparent) {
+	    if (apiEntry_0_2->SetROP != NULL) {
+		apiEntry_0_2->SetROP(printerContext,
+		    OPVP_0_2_ROP_S);
+	    }
+	}
+	else {
+	    if (apiEntry_0_2->SetROP != NULL) {
+		apiEntry_0_2->SetROP(printerContext,
+		    OPVP_0_2_ROP_OR);
+	    }
+	}
+	depth = 1;
+    } else {
+	if (apiEntry_0_2->SetROP != NULL) {
+	    apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_S);
+	}
+	depth = colorDepth_0_2[colorSpace];
+    }
+
+    OPVP_I2FIX(0,rect.p0.x);
+    OPVP_I2FIX(0,rect.p0.y);
+    OPVP_I2FIX(destinationWidth,rect.p1.x);
+    OPVP_I2FIX(destinationHeight,rect.p1.y);
+    if (imageFormat > sizeof(iformat_1_0_to_0_2)/sizeof(OPVP_ImageFormat)) {
+	/* illegal image format */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    iformat_0_2 = iformat_1_0_to_0_2[imageFormat];
+    r = apiEntry_0_2->DrawImage(printerContext,sourceWidth,sourceHeight,
+	    depth,iformat_0_2,rect,
+	    sourcePitch*sourceHeight,
+	    /* remove const */ (void *)imagedata);
+
+    if (apiEntry_0_2->SetROP != NULL) {
+        apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_P);
+    }
+
+    return r;
+}
+
+static opvp_result_t
+StartDrawImageWrapper(
+    opvp_dc_t printerContext,
+    opvp_int_t sourceWidth,
+    opvp_int_t sourceHeight,
+    opvp_int_t sourcePitch,
+    opvp_imageformat_t imageFormat,
+    opvp_int_t destinationWidth,
+    opvp_int_t destinationHeight)
+{
+    int r;
+    OPVP_Rectangle rect;
+    OPVP_ImageFormat iformat_0_2;
+    OPVP_PaintMode paintmode_0_2 = OPVP_paintModeTransparent;
+    int depth;
+
+    if (imageFormat == OPVP_IFORMAT_MASK) {
+	if (apiEntry_0_2->GetPaintMode != NULL) {
+	    apiEntry_0_2->GetPaintMode(printerContext,
+	      &paintmode_0_2);
+	}
+	if (paintmode_0_2 != OPVP_paintModeTransparent) {
+	    if (apiEntry_0_2->SetROP != NULL) {
+		apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_S);
+	    }
+	}
+	else {
+	    if (apiEntry_0_2->SetROP != NULL) {
+		apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_OR);
+	    }
+	}
+	depth = 1;
+    } else {
+	if (apiEntry_0_2->SetROP != NULL) {
+	    apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_S);
+	}
+	depth = colorDepth_0_2[colorSpace];
+    }
+
+    OPVP_I2FIX(0,rect.p0.x);
+    OPVP_I2FIX(0,rect.p0.y);
+    OPVP_I2FIX(destinationWidth,rect.p1.x);
+    OPVP_I2FIX(destinationHeight,rect.p1.y);
+    if (imageFormat > sizeof(iformat_1_0_to_0_2)/sizeof(OPVP_ImageFormat)) {
+	/* illegal image format */
+	*ErrorNo = OPVP_PARAMERROR_0_2;
+	return -1;
+    }
+    iformat_0_2 = iformat_1_0_to_0_2[imageFormat];
+    r = apiEntry_0_2->StartDrawImage(printerContext,
+	    sourceWidth,sourceHeight,
+	    depth,iformat_0_2,rect);
+
+    return r;
+}
+
+static opvp_result_t
+EndDrawImageWrapper(opvp_dc_t printerContext)
+{
+    int r;
+
+    r = apiEntry_0_2->EndDrawImage(printerContext);
+
+    /* make sure rop is pattern copy */
+    if (apiEntry_0_2->SetROP != NULL) {
+	apiEntry_0_2->SetROP(printerContext,OPVP_0_2_ROP_P);
+    }
+
+    return r;
+}
+
+static opvp_result_t
+QueryDeviceCapabilityWrapper(
+    opvp_dc_t printerContext,
+    opvp_queryinfoflags_t queryflag,
+    opvp_int_t *buflen,
+    opvp_char_t *infoBuf)
+{
+    return apiEntry_0_2->QueryDeviceCapability(printerContext,queryflag,
+      *buflen,(char *)infoBuf);
+}
+
+static opvp_result_t
+QueryDeviceInfoWrapper(
+    opvp_dc_t printerContext,
+    opvp_queryinfoflags_t queryflag,
+    opvp_int_t *buflen,
+    opvp_char_t *infoBuf)
+{
+    if (queryflag & OPVP_QF_MEDIACOPY) {
+	*ErrorNo = OPVP_NOTSUPPORTED;
+	return -1;
+    }
+    if (queryflag & OPVP_QF_PRINTREGION) {
+	queryflag &= ~OPVP_QF_PRINTREGION;
+	queryflag |= 0x0020000;
+    }
+    return apiEntry_0_2->QueryDeviceInfo(printerContext,queryflag,
+      *buflen,(char *)infoBuf);
+}
+
+static opvp_result_t
+SetLineDashWrapper(opvp_dc_t printerContext, opvp_int_t num,
+    const opvp_fix_t *pdash)
+{
+    return apiEntry_0_2->SetLineDash(printerContext,
+      /* remove const */ (OPVP_Fix *)pdash,num);
+}
+
+static opvp_result_t
+GetLineDashWrapper(opvp_dc_t printerContext, opvp_int_t *pnum,
+    opvp_fix_t *pdash)
+{
+    return apiEntry_0_2->GetLineDash(printerContext,
+      pdash,pnum);
+}
+
+static opvp_dc_t
+OpenPrinterWrapper(
+    opvp_int_t outputFD,
+    const opvp_char_t *printerModel,
+    const opvp_int_t apiVersion[2],
+    opvp_api_procs_t **apiProcs)
+{
+    opvp_dc_t dc = -1;
+
+    if (OpenPrinter != NULL) {
+	dc = (*OpenPrinter)(outputFD,printerModel,apiVersion,apiProcs);
+    } else {
+	/* try version 0.2 */
+
+	if (OpenPrinter_0_2 != NULL) {
+	    static opvp_api_procs_t tEntry;
+	    int nApiEntry;
+
+	    dc = (*OpenPrinter_0_2)(outputFD,
+		    /* remove const */
+		    (char *)printerModel,
+		    &nApiEntry,&apiEntry_0_2);
+	    /* setting functions */
+	    tEntry.opvpClosePrinter
+		    = apiEntry_0_2->ClosePrinter;
+	    tEntry.opvpStartJob
+		    = (opvp_result_t (*)(opvp_int_t,
+		       const opvp_char_t*))
+		       apiEntry_0_2->StartJob;
+	    tEntry.opvpEndJob = apiEntry_0_2->EndJob;
+	    tEntry.opvpAbortJob = NULL;
+	    tEntry.opvpStartDoc
+		    = (opvp_result_t (*)(opvp_dc_t,
+		       const opvp_char_t*))
+		       apiEntry_0_2->StartDoc;
+	    tEntry.opvpEndDoc = apiEntry_0_2->EndDoc;
+	    if (apiEntry_0_2->StartPage != NULL) {
+		tEntry.opvpStartPage = StartPageWrapper;
+	    } else {
+		tEntry.opvpStartPage = NULL;
+	    }
+	    tEntry.opvpEndPage = apiEntry_0_2->EndPage;
+
+	    if (apiEntry_0_2->QueryDeviceCapability != NULL) {
+		tEntry.opvpQueryDeviceCapability
+		  = QueryDeviceCapabilityWrapper;
+	    } else {
+		tEntry.opvpQueryDeviceCapability = NULL;
+	    }
+
+	    if (apiEntry_0_2->QueryDeviceInfo != NULL) {
+		tEntry.opvpQueryDeviceInfo = QueryDeviceInfoWrapper;
+	    } else {
+		tEntry.opvpQueryDeviceInfo = NULL;
+	    }
+
+	    tEntry.opvpResetCTM = apiEntry_0_2->ResetCTM;
+	    tEntry.opvpSetCTM = (opvp_result_t (*)(opvp_dc_t,
+		       const opvp_ctm_t*))
+		       apiEntry_0_2->SetCTM;
+	    tEntry.opvpGetCTM = (opvp_result_t (*)(opvp_dc_t,opvp_ctm_t*))
+		       apiEntry_0_2->GetCTM;
+	    if (apiEntry_0_2->InitGS != NULL) {
+		tEntry.opvpInitGS = InitGSWrapper;
+	    } else {
+		tEntry.opvpInitGS = NULL;
+	    }
+	    tEntry.opvpSaveGS = apiEntry_0_2->SaveGS;
+	    tEntry.opvpRestoreGS = apiEntry_0_2->RestoreGS;
+	    if (apiEntry_0_2->QueryColorSpace != NULL) {
+		tEntry.opvpQueryColorSpace = QueryColorSpaceWrapper;
+	    } else {
+		tEntry.opvpQueryColorSpace = NULL;
+	    }
+	    if (apiEntry_0_2->SetColorSpace != NULL) {
+		tEntry.opvpSetColorSpace = SetColorSpaceWrapper;
+	    } else {
+		tEntry.opvpSetColorSpace = NULL;
+	    }
+	    if (apiEntry_0_2->GetColorSpace != NULL) {
+		tEntry.opvpGetColorSpace = GetColorSpaceWrapper;
+	    } else {
+		tEntry.opvpGetColorSpace = NULL;
+	    }
+	    tEntry.opvpSetFillMode
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_fillmode_t))
+		       apiEntry_0_2->SetFillMode;
+	    tEntry.opvpGetFillMode
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_fillmode_t*))
+		       apiEntry_0_2->GetFillMode;
+	    tEntry.opvpSetAlphaConstant = apiEntry_0_2->SetAlphaConstant;
+	    tEntry.opvpGetAlphaConstant = apiEntry_0_2->GetAlphaConstant;
+	    tEntry.opvpSetLineWidth = apiEntry_0_2->SetLineWidth;
+	    tEntry.opvpGetLineWidth = apiEntry_0_2->GetLineWidth;
+	    if (apiEntry_0_2->SetLineDash != NULL) {
+		tEntry.opvpSetLineDash = SetLineDashWrapper;
+	    } else {
+		tEntry.opvpSetLineDash = NULL;
+	    }
+	    if (apiEntry_0_2->GetLineDash != NULL) {
+		tEntry.opvpGetLineDash = GetLineDashWrapper;
+	    } else {
+		tEntry.opvpGetLineDash = NULL;
+	    }
+	    tEntry.opvpSetLineDashOffset
+		    = apiEntry_0_2->SetLineDashOffset;
+	    tEntry.opvpGetLineDashOffset
+		    = apiEntry_0_2->GetLineDashOffset;
+	    tEntry.opvpSetLineStyle
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linestyle_t))
+		       apiEntry_0_2->SetLineStyle;
+	    tEntry.opvpGetLineStyle
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linestyle_t*))
+		       apiEntry_0_2->GetLineStyle;
+	    tEntry.opvpSetLineCap
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linecap_t))
+		       apiEntry_0_2->SetLineCap;
+	    tEntry.opvpGetLineCap
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linecap_t*))
+		       apiEntry_0_2->GetLineCap;
+	    tEntry.opvpSetLineJoin
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linejoin_t))
+		       apiEntry_0_2->SetLineJoin;
+	    tEntry.opvpGetLineJoin
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_linejoin_t*))
+		       apiEntry_0_2->GetLineJoin;
+	    tEntry.opvpSetMiterLimit = apiEntry_0_2->SetMiterLimit;
+	    tEntry.opvpGetMiterLimit = apiEntry_0_2->GetMiterLimit;
+	    tEntry.opvpSetPaintMode
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_paintmode_t))
+		       apiEntry_0_2->SetPaintMode;
+	    tEntry.opvpGetPaintMode
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_paintmode_t*))
+		       apiEntry_0_2->GetPaintMode;
+	    if (apiEntry_0_2->SetStrokeColor != NULL) {
+		tEntry.opvpSetStrokeColor = SetStrokeColorWrapper;
+	    } else {
+		tEntry.opvpSetStrokeColor = NULL;
+	    }
+	    if (apiEntry_0_2->SetFillColor != NULL) {
+		tEntry.opvpSetFillColor = SetFillColorWrapper;
+	    } else {
+		tEntry.opvpSetFillColor = NULL;
+	    }
+	    if (apiEntry_0_2->SetBgColor != NULL) {
+		tEntry.opvpSetBgColor = SetBgColorWrapper;
+	    } else {
+		tEntry.opvpSetBgColor = NULL;
+	    }
+	    tEntry.opvpNewPath = apiEntry_0_2->NewPath;
+	    tEntry.opvpEndPath = apiEntry_0_2->EndPath;
+	    tEntry.opvpStrokePath = apiEntry_0_2->StrokePath;
+	    tEntry.opvpFillPath = apiEntry_0_2->FillPath;
+	    tEntry.opvpStrokeFillPath = apiEntry_0_2->StrokeFillPath;
+	    tEntry.opvpSetClipPath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_cliprule_t))
+		       apiEntry_0_2->SetClipPath;
+	    tEntry.opvpResetClipPath = apiEntry_0_2->ResetClipPath;
+	    tEntry.opvpSetCurrentPoint = apiEntry_0_2->SetCurrentPoint;
+	    tEntry.opvpLinePath
+		    = (opvp_result_t (*)(opvp_dc_t,
+		       opvp_pathmode_t,opvp_int_t,
+		       const opvp_point_t*))
+		       apiEntry_0_2->LinePath;
+	    tEntry.opvpPolygonPath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_int_t*,
+		       const opvp_point_t*))
+		       apiEntry_0_2->PolygonPath;
+	    tEntry.opvpRectanglePath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_rectangle_t*))
+		       apiEntry_0_2->RectanglePath;
+	    tEntry.opvpRoundRectanglePath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_roundrectangle_t*))
+		       apiEntry_0_2->RoundRectanglePath;
+	    tEntry.opvpBezierPath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_point_t*))
+		       apiEntry_0_2->BezierPath;
+	    tEntry.opvpArcPath
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_arcmode_t,
+		       opvp_arcdir_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,
+		       opvp_fix_t,opvp_fix_t,opvp_fix_t,opvp_fix_t,
+		       opvp_fix_t))apiEntry_0_2->ArcPath;
+	    if (apiEntry_0_2->DrawImage != NULL) {
+		tEntry.opvpDrawImage = DrawImageWrapper;
+	    } else {
+		tEntry.opvpDrawImage = NULL;
+	    }
+	    if (apiEntry_0_2->StartDrawImage != NULL) {
+		tEntry.opvpStartDrawImage = StartDrawImageWrapper;
+	    } else {
+		tEntry.opvpStartDrawImage = NULL;
+	    }
+	    tEntry.opvpTransferDrawImage = 
+	       (opvp_result_t (*)(opvp_dc_t,opvp_int_t,const void*))
+	       apiEntry_0_2->TransferDrawImage;
+	    if (apiEntry_0_2->EndDrawImage != NULL) {
+		tEntry.opvpEndDrawImage = EndDrawImageWrapper;
+	    } else {
+		tEntry.opvpEndDrawImage = NULL;
+	    }
+	    tEntry.opvpStartScanline = apiEntry_0_2->StartScanline;
+	    tEntry.opvpScanline
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_int_t*))
+		       apiEntry_0_2->Scanline;
+	    tEntry.opvpEndScanline = apiEntry_0_2->EndScanline;
+	    tEntry.opvpStartRaster = apiEntry_0_2->StartRaster;
+	    tEntry.opvpTransferRasterData
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const opvp_byte_t*))
+		       apiEntry_0_2->TransferRasterData;
+	    tEntry.opvpSkipRaster = apiEntry_0_2->SkipRaster;
+	    tEntry.opvpEndRaster = apiEntry_0_2->EndRaster;
+	    tEntry.opvpStartStream = apiEntry_0_2->StartStream;
+	    tEntry.opvpTransferStreamData
+		    = (opvp_result_t (*)(opvp_dc_t,opvp_int_t,
+		       const void *))
+		       apiEntry_0_2->TransferStreamData;
+	    tEntry.opvpEndStream = apiEntry_0_2->EndStream;
+
+	    *apiProcs = &tEntry;
+
+	    GetLastError = GetLastError_0_2;
+	}
+    }
+    return dc;
+}
+
 /* for image */
 static	const
-gx_image_enum_procs_t	opvp_image_enum_procs =
+gx_image_enum_procs_t opvp_image_enum_procs =
 {
-	opvp_image_plane_data,
-	opvp_image_end_image
+    opvp_image_plane_data,
+    opvp_image_end_image
 };
-typedef	enum	_FastImageSupportMode {
-	FastImageDisable,
-	FastImageNoCTM,
-	FastImageNoRotate,
-	FastImageRightAngle,
-	FastImageReverseAngle,
-	FastImageAll
+typedef	enum _FastImageSupportMode {
+    FastImageDisable,
+    FastImageNoCTM,
+    FastImageNoRotate,
+    FastImageRightAngle,
+    FastImageReverseAngle,
+    FastImageAll
 } FastImageSupportMode;
-static	char			*fastImage = NULL;
-static	FastImageSupportMode	FastImageMode = FastImageDisable;
-static	bool			begin_image = false;
-static	gs_color_space_index	color_index = 0;
-static	byte			palette[3*256];
-static  float                   imageDecode[GS_IMAGE_MAX_COMPONENTS * 2];
-static	bool			reverse_image = false;
+static char *fastImage = NULL;
+static FastImageSupportMode FastImageMode = FastImageDisable;
+static bool begin_image = false;
+static bool change_paint_mode = false;
+static bool change_cspace = false;
+static gs_color_space_index color_index = 0;
+static gs_color_space_index base_color_index = 0;
+static byte palette[3*256];
+static float imageDecode[GS_IMAGE_MAX_COMPONENTS * 2];
+static bool reverse_image = false;
 
 /* added for image gamma correction */
 typedef struct bbox_image_enum_s {
-							gx_image_enum_common;
-	gs_memory_t				*memory;
-	gs_matrix				matrix;		/* map from image space to device dpace */
-	const	gx_clip_path	*pcpath;
-	gx_image_enum_common_t	*target_info;
-	bool					params_are_const;
-	int						x0, x1;
-	int						y, height;
+    gx_image_enum_common;
+    gs_memory_t	*memory;
+    gs_matrix matrix; /* map from image space to device dpace */
+    const gx_clip_path *pcpath;
+    gx_image_enum_common_t *target_info;
+    bool params_are_const;
+    int	x0, x1;
+    int	y, height;
 } bbox_image_enum;
 
 /* The following is already defined in stdpre.h */
@@ -500,637 +1192,570 @@
 
 
 /* ----- Utilities ----- */
+
+/* initialize Graphic State */
+/* No defaults in OPVP 1.0 */
+static int
+InitGS(void)
+{
+    if (apiEntry->opvpInitGS != NULL) {
+	if (apiEntry->opvpInitGS(printerContext) != OPVP_OK) {
+	    return -1;
+	}
+    }
+    if (apiEntry->opvpSetColorSpace != NULL) {
+	if (apiEntry->opvpSetColorSpace(printerContext,colorSpace)
+	   != OPVP_OK) {
+	    return -1;
+	}
+    }
+    if (apiEntry->opvpSetPaintMode != NULL) {
+	if (apiEntry->opvpSetPaintMode(printerContext,
+	    OPVP_PAINTMODE_TRANSPARENT) != OPVP_OK) {
+	    return -1;
+	}
+    }
+    if (apiEntry->opvpSetAlphaConstant != NULL) {
+	if (apiEntry->opvpSetAlphaConstant(printerContext,1.0)
+	   != OPVP_OK) {
+	    return -1;
+	}
+    }
+
+    /* other properties are set by GhostScript */
+    return 0;
+}
+
 static	int
-opvp_startpage(
-	gx_device		*dev
-	)
+opvp_startpage(gx_device *dev)
 {
-	int			ecode = 0;
-	int			code = -1;
-static	char			*page_info = NULL;
+    int	ecode = 0;
+    opvp_result_t r = -1;
+    static char	*page_info = NULL;
 
-	/* page info */
-	page_info = opvp_alloc_string(&page_info, OPVP_INFO_PREFIX);
-	page_info = opvp_cat_string(&page_info, opvp_gen_page_info(dev));
+    /* page info */
+    page_info = opvp_alloc_string(&page_info, OPVP_INFO_PREFIX);
+    page_info = opvp_cat_string(&page_info, opvp_gen_page_info(dev));
 
-	/* call StartPage */
-	if (printerContext != -1) {
-		if (apiEntry->StartPage)
-		code = apiEntry->StartPage(printerContext,
-		                           opvp_to_utf8(page_info));
-		if (code != OPVP_OK) {
-			ecode = -1;
-		}
+    /* call StartPage */
+    if (printerContext != -1) {
+	if (apiEntry->opvpStartPage)
+	    r = apiEntry->opvpStartPage(printerContext,
+		       (opvp_char_t *)opvp_to_utf8(page_info));
+	if (r != OPVP_OK) {
+	    ecode = -1;
+	} else {
+	    ecode = InitGS();
 	}
+    }
 
-	return ecode;
+    return ecode;
 }
 
 static	int
-opvp_endpage(
-	void
-	)
+opvp_endpage(void)
 {
-	int			ecode = 0;
-	int			code = -1;
+    int	ecode = 0;
+    opvp_result_t r = -1;
 
-	/* call EndPage */
-	if (printerContext != -1) {
-		if (apiEntry->EndPage)
-		code = apiEntry->EndPage(printerContext);
-		if (code != OPVP_OK) {
-			ecode = -1;
-		}
+    /* call EndPage */
+    if (printerContext != -1) {
+	if (apiEntry->opvpEndPage)
+	    r = apiEntry->opvpEndPage(printerContext);
+	if (r != OPVP_OK) {
+	    ecode = -1;
 	}
+    }
 
-	return ecode;
+    return ecode;
 }
 
 static	char *
-opvp_alloc_string(
-	char			**destin,
-const	char			*source
-	)
+opvp_alloc_string(char **destin, const char *source)
 {
-	if (!destin) return NULL;
+    if (!destin) return NULL;
 
-	if (*destin) {
-		if (source) {
-			*destin = realloc(*destin, strlen(source)+1);
-		} else {
-			free(*destin);
-			*destin = NULL;
-		}
+    if (*destin) {
+	if (source) {
+	    *destin = realloc(*destin, strlen(source)+1);
 	} else {
-		if (source) {
-			*destin = malloc(strlen(source)+1);
-		}
+	    free(*destin);
+	    *destin = NULL;
 	}
-	if (*destin && source) {
-		if (*destin != source) {
-			strcpy(*destin, source);
-		}
+    } else {
+	if (source) {
+	    *destin = malloc(strlen(source)+1);
 	}
+    }
+    if (*destin && source) {
+	if (*destin != source) {
+	    strcpy(*destin, source);
+	}
+    }
 
-	return *destin;
+    return *destin;
 }
 
 static	char *
-opvp_cat_string(
-	char			**destin,
-const	char			*string
-	)
+opvp_cat_string(char **destin, const char *string)
 {
-	if (!destin) return NULL;
-	if (!(*destin)) return opvp_alloc_string(destin, string);
+    if (!destin) return NULL;
+    if (!(*destin)) return opvp_alloc_string(destin, string);
 
-	if (string) {
-		*destin = realloc(*destin, strlen(*destin)+strlen(string)+1);
-		strcat(*destin, string);
-	}
+    if (string) {
+	*destin = realloc(*destin, strlen(*destin) +strlen(string)+1);
+	strcat(*destin, string);
+    }
 
-	return *destin;
+    return *destin;
 }
 
 static	char *
-opvp_adjust_num_string(
-	char			*num_string
-	)
+opvp_adjust_num_string(char *num_string)
 {
-	char			*pp;
-	char			*lp;
+    char *pp;
+    char *lp;
 
-	if (!num_string) return NULL;
+    if (!num_string) return NULL;
 
-	if ((pp = strrchr(num_string, '.'))) {
-		for (lp = &(num_string[strlen(num_string)-1]); lp > pp; lp--) {
-			if (*lp == '0') {
-				*lp = '\0';
-			} else {
-				break;
-			}
-		}
-		if (lp == pp) *lp = '\0';
+    if ((pp = strrchr(num_string, '.'))) {
+	for (lp = &(num_string[strlen(num_string)-1]); lp > pp; lp--) {
+	    if (*lp == '0') {
+		*lp = '\0';
+	    } else {
+		break;
+	    }
 	}
+	if (lp == pp) *lp = '\0';
+    }
 
-	return num_string;
+    return num_string;
 }
 
 static	char **
-opvp_gen_dynamic_lib_name(
-	void
-	)
+opvp_gen_dynamic_lib_name(void)
 {
-static	char			*buff[5] = {NULL,NULL,NULL,NULL,NULL};
-	char			tbuff[OPVP_BUFF_SIZE];
+    static char	*buff[5] = {NULL,NULL,NULL,NULL,NULL};
+    char tbuff[OPVP_BUFF_SIZE];
 
-	if (!vectorDriver) {
-		return NULL;
-	}
+    if (!vectorDriver) {
+	return NULL;
+    }
 
-	memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
-	strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 1);
-	opvp_alloc_string(&(buff[0]), tbuff);
+    memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
+    strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 1);
+    opvp_alloc_string(&(buff[0]), tbuff);
 
-	memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
-	strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 4);
-	strcat(tbuff, ".so");
-	opvp_alloc_string(&(buff[1]), tbuff);
+    memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
+    strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 4);
+    strcat(tbuff, ".so");
+    opvp_alloc_string(&(buff[1]), tbuff);
 
-	memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
-	strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 5);
-	strcat(tbuff, ".dll");
-	opvp_alloc_string(&(buff[2]), tbuff);
+    memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
+    strncpy(tbuff, vectorDriver, OPVP_BUFF_SIZE - 5);
+    strcat(tbuff, ".dll");
+    opvp_alloc_string(&(buff[2]), tbuff);
 
-	memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
-	strcpy(tbuff, "lib");
-	strncat(tbuff, vectorDriver, OPVP_BUFF_SIZE - 7);
-	strcat(tbuff, ".so");
-	opvp_alloc_string(&(buff[3]), tbuff);
+    memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
+    strcpy(tbuff, "lib");
+    strncat(tbuff, vectorDriver, OPVP_BUFF_SIZE - 7);
+    strcat(tbuff, ".so");
+    opvp_alloc_string(&(buff[3]), tbuff);
 
-	buff[4] = NULL;
+    buff[4] = NULL;
 
-	return buff;
+    return buff;
 }
 
 static	char *
-opvp_to_utf8(
-	char			*string
-	)
+opvp_to_utf8(char *string)
 {
-	char			*locale;
-	iconv_t			cd;
-	char			*buff = NULL;
-	size_t			ib, ob;
-	int			complete = false;
-	char			*ibuff, *obuff;
-	char			*ostring = NULL;
+    char *locale;
+    iconv_t cd;
+    char *buff = NULL;
+    size_t ib, ob;
+    int	 complete = false;
+    char *ibuff, *obuff;
+    char *ostring = NULL;
 
-	if (string) {
-		ib = strlen(string);
-		if (ib > 0) {
-			ob = ib * 4;
-			buff = malloc(ob+1);
-			setlocale(LC_CTYPE, "");
+    if (string) {
+	ib = strlen(string);
+	if (ib > 0) {
+	    ob = ib * 4;
+	    buff = malloc(ob+1);
+	    setlocale(LC_CTYPE, "");
 #ifdef CODESET
-			locale = nl_langinfo(CODESET);
+	    locale = nl_langinfo(CODESET);
 #else
-			locale = "UTF-8";
+	    locale = "UTF-8";
 #endif /* CODESET */
-			if (locale) {
-				if (strcmp(locale, "C") && buff) {
-					if ((cd = iconv_open("UTF-8", locale))
-					     != (iconv_t)-1) {
-						ibuff = string;
-						obuff = buff;
-						if (iconv(cd, &ibuff, &ib,
-						          &obuff, &ob)
-						    != -1) {
-							*obuff = 0;
-							complete = true;
-						}
-						iconv_close(cd);
-					}
-				}
+	    if (locale) {
+		if (strcmp(locale, "C") && buff) {
+		    if ((cd = iconv_open("UTF-8", locale)) != (iconv_t)-1) {
+			ibuff = string;
+			obuff = buff;
+			if (iconv(cd, &ibuff, &ib, &obuff, &ob) != -1) {
+			    *obuff = 0;
+			    complete = true;
 			}
+			iconv_close(cd);
+		    }
 		}
+	    }
 	}
+    }
 
-	if (complete) {
-		ostring = opvp_alloc_string(&ostring, buff);
-	} else {
-		ostring = string;
-	}
+    if (complete) {
+	ostring = opvp_alloc_string(&ostring, buff);
+    } else {
+	ostring = string;
+    }
 
-	if (buff) free(buff);
-	return ostring;
+    if (buff) free(buff);
+    return ostring;
 }
 
 static float
 opvp_fabsf(float f)
 {
-	return (float)fabs((double)f);
+    return (float)fabs((double)f);
 }
 
 static	int
-opvp_get_papertable_index(
-	gx_device		*pdev
-	)
+opvp_get_papertable_index(gx_device *pdev)
 {
-	int			i;
-	float			width, height;
-	bool			landscape;
-	float			paper_w, paper_h;
-	float			prev = -1;
-	int			paper = -1;
-	int			candidate = -1;
-	int			smaller = -1;
-	int			larger  = -1;
-	int			s_candi = -1;
-	int			l_candi = -1;
-	float			h_delta = TOLERANCE;
-	float			sw_delta = TOLERANCE;
-	float			sh_delta = TOLERANCE;
-	float			lw_delta = TOLERANCE;
-	float			lh_delta = TOLERANCE;
-	bool			match = false;
-	float			f;
+    int	i;
+    float width, height;
+    bool landscape;
+    float paper_w, paper_h;
+    float prev = -1;
+    int	paper = -1;
+    int	candidate = -1;
+    int	smaller = -1;
+    int	larger  = -1;
+    int	s_candi = -1;
+    int	l_candi = -1;
+    float h_delta = TOLERANCE;
+    float sw_delta = TOLERANCE;
+    float sh_delta = TOLERANCE;
+    float lw_delta = TOLERANCE;
+    float lh_delta = TOLERANCE;
+    bool match = false;
+    float f;
 
-	/* portrait or landscape */
-	landscape = (pdev->MediaSize[0] < pdev->MediaSize[1] ? false : true);
+    /* portrait or landscape */
+    landscape = (pdev->MediaSize[0] < pdev->MediaSize[1] ? false : true);
 
-	/* paper size */
-	width  = (landscape ? pdev->MediaSize[1] : pdev->MediaSize[0]);
-	height = (landscape ? pdev->MediaSize[0] : pdev->MediaSize[1]);
+    /* paper size */
+    width  = (landscape ? pdev->MediaSize[1] : pdev->MediaSize[0]);
+    height = (landscape ? pdev->MediaSize[0] : pdev->MediaSize[1]);
 
-#if 0
-	for (i=0; paperTable[i].name != NULL; i++) {
-		if ((width  <= ceilf(paperTable[i].width)) &&
-		    (height <= ceilf(paperTable[i].height))) {
-			break;
+    for (i=0; paperTable[i].name != NULL; i++) {
+	paper_w = paperTable[i].width;
+	paper_h = paperTable[i].height;
+	if (width == paper_w) {
+	    if (height == paper_h) {
+		paper = i;
+		match = true;
+		break;
+	    } else if ((f = opvp_fabsf(height - paper_h)) < TOLERANCE) {
+		if (f < h_delta) {
+		    h_delta = f;
+		    candidate = i;
 		}
+	    }
+	} else if (candidate != -1) {
+	    paper = candidate;
+	    match = true;
+	    break;
+	} else if (prev != paper_w) {
+	    prev = paper_w;
+	    if (paper_w < width) {
+		if ((f = opvp_fabsf(width - paper_w)) < TOLERANCE) {
+		    if (f < sw_delta) {
+			sw_delta = f;
+			smaller  = i;
+		    }
+		}
+	    } else {
+		if ((f = opvp_fabsf(width - paper_w)) < TOLERANCE) {
+		    if (f < lw_delta) {
+			lw_delta = f;
+			larger   = i;
+		    }
+		}
+	    }
 	}
-	return i;
-#endif
-
-	for (i=0; paperTable[i].name != NULL; i++) {
-		paper_w = paperTable[i].width;
+    }
+    if (!match) {
+	paper = i;
+	if (smaller != -1) {
+	    paper_w = paperTable[smaller].width;
+	    for (i = smaller; paperTable[i].width == paper_w; i++) {
 		paper_h = paperTable[i].height;
-		if (width == paper_w) {
-			if (height == paper_h) {
-				paper = i;
-				match = true;
-				break;
-			} else if ((f = opvp_fabsf(height - paper_h)) < TOLERANCE) {
-				if (f < h_delta) {
-					h_delta = f;
-					candidate = i;
-				}
-			}
-		} else if (candidate != -1) {
-			paper = candidate;
-			match = true;
-			break;
-		} else if (prev != paper_w) {
-			prev = paper_w;
-			if (paper_w < width) {
-				if ((f = opvp_fabsf(width - paper_w)) < TOLERANCE) {
-					if (f < sw_delta) {
-						sw_delta = f;
-						smaller  = i;
-					}
-				}
-			} else {
-				if ((f = opvp_fabsf(width - paper_w)) < TOLERANCE) {
-					if (f < lw_delta) {
-						lw_delta = f;
-						larger   = i;
-					}
-				}
-			}
+		if (height == paper_h) {
+		    sh_delta = 0;
+		    s_candi  = i;
+		    break;
+		} else if ((f = opvp_fabsf(height - paper_h)) < TOLERANCE) {
+		    if (f < sh_delta) {
+			sh_delta = f;
+			s_candi  = i;
+		    }
 		}
+	    }
 	}
-	if (!match) {
-		paper = i;
-		if (smaller != -1) {
-			paper_w = paperTable[smaller].width;
-			for (i = smaller; paperTable[i].width == paper_w; i++) {
-				paper_h = paperTable[i].height;
-				if (height == paper_h) {
-					sh_delta = 0;
-					s_candi  = i;
-					break;
-				} else if ((f = opvp_fabsf(height - paper_h))
-				           < TOLERANCE) {
-					if (f < sh_delta) {
-						sh_delta = f;
-						s_candi  = i;
-					}
-				}
-			}
+	if (larger != -1) {
+	    paper_w = paperTable[larger].width;
+	    for (i = larger; paperTable[i].width == paper_w; i++) {
+		paper_h = paperTable[i].height;
+		if (height == paper_h) {
+		    lh_delta = 0;
+		    l_candi  = i;
+		    break;
+		} else if ((f = opvp_fabsf(height - paper_h)) < TOLERANCE) {
+		    if (f < lh_delta) {
+			lh_delta = f;
+			l_candi  = i;
+		    }
 		}
-		if (larger != -1) {
-			paper_w = paperTable[larger].width;
-			for (i = larger; paperTable[i].width == paper_w; i++) {
-				paper_h = paperTable[i].height;
-				if (height == paper_h) {
-					lh_delta = 0;
-					l_candi  = i;
-					break;
-				} else if ((f = opvp_fabsf(height - paper_h))
-				           < TOLERANCE) {
-					if (f < lh_delta) {
-						lh_delta = f;
-						l_candi  = i;
-					}
-				}
-			}
-		}
-		if (s_candi != -1) {
-			if (l_candi != -1) {
-				if ((sw_delta + sh_delta)
-				  < (lw_delta + lh_delta)) {
-					paper = s_candi;
-				} else {
-					paper = l_candi;
-				}
-			} else {
-				paper = s_candi;
-			}
+	    }
+	}
+	if (s_candi != -1) {
+	    if (l_candi != -1) {
+		if ((sw_delta + sh_delta)
+		  < (lw_delta + lh_delta)) {
+			paper = s_candi;
 		} else {
-			if (l_candi != -1) {
-				paper = l_candi;
-			}
+			paper = l_candi;
 		}
+	    } else {
+		paper = s_candi;
+	    }
+	} else {
+	    if (l_candi != -1) {
+		paper = l_candi;
+	    }
 	}
+    }
 
-	return paper;
+    return paper;
 }
 
 static	char *
-opvp_get_sizestring(
-	float			width,
-	float			height
-	)
+opvp_get_sizestring(float width, float height)
 {
-	char nbuff[OPVP_BUFF_SIZE];
-	char nbuff1[OPVP_BUFF_SIZE / 2];
-	char nbuff2[OPVP_BUFF_SIZE / 2];
-static	char			*buff = NULL;
+    char nbuff[OPVP_BUFF_SIZE];
+    char nbuff1[OPVP_BUFF_SIZE / 2];
+    char nbuff2[OPVP_BUFF_SIZE / 2];
+    static char *buff = NULL;
 
-	memset((void*)nbuff, 0, OPVP_BUFF_SIZE);
-	memset((void*)nbuff1, 0, OPVP_BUFF_SIZE / 2);
-	memset((void*)nbuff2, 0, OPVP_BUFF_SIZE / 2);
+    memset((void*)nbuff, 0, OPVP_BUFF_SIZE);
+    memset((void*)nbuff1, 0, OPVP_BUFF_SIZE / 2);
+    memset((void*)nbuff2, 0, OPVP_BUFF_SIZE / 2);
 
-	snprintf(nbuff1, OPVP_BUFF_SIZE / 2 - 1, "%.3f", width);
-	snprintf(nbuff2, OPVP_BUFF_SIZE / 2 - 1, "%.3f", height);
-	snprintf(nbuff, OPVP_BUFF_SIZE - 1, "%sx%s",
-	                        opvp_adjust_num_string(nbuff1),
-	                        opvp_adjust_num_string(nbuff2));
+    snprintf(nbuff1, OPVP_BUFF_SIZE / 2 - 1, "%.3f", width);
+    snprintf(nbuff2, OPVP_BUFF_SIZE / 2 - 1, "%.3f", height);
+    snprintf(nbuff, OPVP_BUFF_SIZE - 1, "%sx%s",
+		opvp_adjust_num_string(nbuff1),
+		opvp_adjust_num_string(nbuff2));
 
-	return opvp_alloc_string(&buff, nbuff);
+    return opvp_alloc_string(&buff, nbuff);
 }
 
-/* not used
-static	const	char *
-opvp_get_papersize_region(
-	gx_device		*pdev
-	)
-{
-	return paperTable[opvp_get_papertable_index(pdev)].region;
-}
-*/
-
-/* not used
-static	const	char *
-opvp_get_papersize_name(
-	gx_device		*pdev
-	)
-{
-	return paperTable[opvp_get_papertable_index(pdev)].name;
-}
-*/
-
-/* not used
 static	char *
-opvp_get_papersize_inch(
-	gx_device		*pdev
-	)
+opvp_get_mediasize(gx_device *pdev)
 {
-	bool			landscape;
-	float			width, height;
+    int	i;
+    char wbuff[OPVP_BUFF_SIZE];
+    static char	*buff = NULL;
+    const char *region;
+    const char *name;
+    float width;
+    float height;
+    const char *unit;
+    bool landscape;
 
-	landscape = (pdev->MediaSize[0] < pdev->MediaSize[1] ? false : true);
-	width  = (landscape ? pdev->MediaSize[1] : pdev->MediaSize[0]) / PS_DPI;
-	height = (landscape ? pdev->MediaSize[0] : pdev->MediaSize[1]) / PS_DPI;
+    i = opvp_get_papertable_index(pdev);
 
-	return opvp_get_sizestring(width, height);
-}
-*/
-
-/* not used
-static	const	char *
-opvp_get_papersize(
-	gx_device		*pdev
-	)
-{
-const	char			*paper;
-
-	paper = opvp_get_papersize_name(pdev);
-	if (!paper) paper = opvp_get_papersize_inch(pdev);
-
-	return paper;
-}
-*/
-
-static	char *
-opvp_get_mediasize(
-	gx_device		*pdev
-	)
-{
-	int			i;
-	char			wbuff[OPVP_BUFF_SIZE];
-static	char			*buff = NULL;
-const	char			*region;
-const	char			*name;
-	float			width;
-	float			height;
-const	char			*unit;
-	bool			landscape;
-
-	i = opvp_get_papertable_index(pdev);
-
-	if (paperTable[i].name) {
-		region = paperTable[i].region;
-		name   = paperTable[i].name;
-		width  = paperTable[i].width  / PS_DPI;
-		height = paperTable[i].height / PS_DPI;
-		if((strcmp(region, "na"  ) == 0) ||
-		   (strcmp(region, "asme") == 0) ||
-		   (strcmp(region, "roc" ) == 0) ||
-		   (strcmp(region, "oe"  ) == 0)) {
-			unit    = "in";
-		} else {
-			width  *= MMPI;
-			height *= MMPI;
-			unit    = "mm";
-		}
+    if (paperTable[i].name) {
+	region = paperTable[i].region;
+	name   = paperTable[i].name;
+	width  = paperTable[i].width  / PS_DPI;
+	height = paperTable[i].height / PS_DPI;
+	if((strcmp(region, "na"  ) == 0) ||
+	   (strcmp(region, "asme") == 0) ||
+	   (strcmp(region, "roc" ) == 0) ||
+	   (strcmp(region, "oe"  ) == 0)) {
+	    unit    = "in";
 	} else {
-		landscape = (pdev->MediaSize[0] < pdev->MediaSize[1] ?
-		             false : true);
-		region = "custom";
-		name   = "opvp";
-		width  = (landscape ? pdev->MediaSize[1] : pdev->MediaSize[0])
-		       / PS_DPI;
-		height = (landscape ? pdev->MediaSize[0] : pdev->MediaSize[1])
-		       / PS_DPI;
-		unit   = "in";
+	    width  *= MMPI;
+	    height *= MMPI;
+	    unit    = "mm";
 	}
-	memset((void*)wbuff, 0, OPVP_BUFF_SIZE);
-	snprintf(wbuff, OPVP_BUFF_SIZE - 1, "%s_%s_%s%s", region, name,
-				     opvp_get_sizestring(width, height),
-				     unit);
-	buff = opvp_alloc_string(&buff, wbuff);
+    } else {
+	landscape = (pdev->MediaSize[0] < pdev->MediaSize[1] ?
+		     false : true);
+	region = "custom";
+	name   = "opvp";
+	width  = (landscape ? pdev->MediaSize[1] : pdev->MediaSize[0])
+	       / PS_DPI;
+	height = (landscape ? pdev->MediaSize[0] : pdev->MediaSize[1])
+	       / PS_DPI;
+	unit   = "in";
+    }
+    memset((void*)wbuff, 0, OPVP_BUFF_SIZE);
+    snprintf(wbuff, OPVP_BUFF_SIZE - 1, "%s_%s_%s%s", region, name,
+				 opvp_get_sizestring(width, height),
+				 unit);
+    buff = opvp_alloc_string(&buff, wbuff);
 
-	return buff;
+    return buff;
 }
 
 static	char *
-opvp_gen_page_info(
-	gx_device		*dev
-	)
+opvp_gen_page_info(gx_device *dev)
 {
-static	char			*buff = NULL;
-	int num_copies = 1;
-	bool landscape;
-	char tbuff[OPVP_BUFF_SIZE];
+    static char	*buff = NULL;
+    int num_copies = 1;
+    bool landscape;
+    char tbuff[OPVP_BUFF_SIZE];
 
-	/* copies */
-	if (!inkjet) {
-		if (dev->IgnoreNumCopies) {
-			num_copies = 1;
-		} else if (dev->NumCopies_set > 0) {
-			num_copies = dev->NumCopies;
-		}
+    /* copies */
+    if (!inkjet) {
+	if (dev->IgnoreNumCopies) {
+	    num_copies = 1;
+	} else if (dev->NumCopies_set > 0) {
+	    num_copies = dev->NumCopies;
 	}
+    }
 
-	landscape = (dev->MediaSize[0] < dev->MediaSize[1] ? false
-	                                                   : true);
-	memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
-	snprintf(tbuff, OPVP_BUFF_SIZE - 1,
-	"MediaCopy=%d;DeviceResolution=deviceResolution_%s;MediaPageRotation=%s;MediaSize=%s",
-	num_copies,
-	opvp_get_sizestring(dev->x_pixels_per_inch, dev->y_pixels_per_inch),
-	(landscape ? "landscape" : "portrait"),
-	opvp_get_mediasize(dev));
+    landscape = (dev->MediaSize[0] < dev->MediaSize[1] ? false
+						       : true);
+    memset((void*)tbuff, 0, OPVP_BUFF_SIZE);
+    snprintf(tbuff, OPVP_BUFF_SIZE - 1,
+       "MediaCopy=%d;DeviceResolution=deviceResolution_%s;"
+       "MediaPageRotation=%s;MediaSize=%s",
+       num_copies,
+       opvp_get_sizestring(dev->x_pixels_per_inch, dev->y_pixels_per_inch),
+       (landscape ? "landscape" : "portrait"),
+       opvp_get_mediasize(dev));
 
-	opvp_alloc_string(&buff, tbuff);
+    opvp_alloc_string(&buff, tbuff);
 
-	return buff;
+    return buff;
 }
 
 static	char *
-opvp_gen_doc_info(
-	gx_device		*dev
-	)
+opvp_gen_doc_info(gx_device *dev)
 {
-	return opvp_gen_page_info(dev);
+    return opvp_gen_page_info(dev);
 }
 
 static	char *
-opvp_gen_job_info(
-	gx_device		*dev
-	)
+opvp_gen_job_info(gx_device *dev)
 {
-	return opvp_gen_doc_info(dev);
+    return opvp_gen_doc_info(dev);
 }
 
 static	int
-opvp_set_brush_color(
-	gx_device_opvp		*pdev,
-	gx_color_index		color,
-	OPVP_Brush		*brush
-	)
+opvp_set_brush_color(gx_device_opvp *pdev, gx_color_index color,
+    opvp_brush_t *brush)
 {
-	int			code;
-	int			ecode = 0;
-	gx_color_value		rgb[3];
+    int code;
+    int ecode = 0;
+    gx_color_value rgb[3];
 
-	code = opvp_map_color_rgb((gx_device *)pdev, color, rgb);
-	if (code) {
-		ecode = -1;
-	} else {
+    code = opvp_map_color_rgb((gx_device *)pdev, color, rgb);
+    if (code) {
+	ecode = -1;
+    } else {
 #if ENABLE_SIMPLE_MODE
-		brush->colorSpace = colorSpace;
+	brush->colorSpace = colorSpace;
 #else
-		/* call GetColorSpace */
-		if (apiEntry->GetColorSpace)
-		code = apiEntry->GetColorSpace(printerContext,
-		                               &(brush->colorSpace));
-		if (code != OPVP_OK) {
-			brush->colorSpace = OPVP_cspaceDeviceRGB;
-		}
+	opvp_result_t		r = -1;
+	/* call GetColorSpace */
+	if (apiEntry->opvpGetColorSpace) {
+	    r = apiEntry->opvpGetColorSpace(printerContext,
+				   &(brush->colorSpace));
+	}
+	if (r != OPVP_OK) {
+	    brush->colorSpace = OPVP_CSPACE_DEVICEKRGB;
+	}
 #endif
-		brush->pbrush = NULL;
-		brush->xorg = brush->yorg = 0;
-		brush->color[3] = (color == gx_no_color_index ? -1 : 0);
-		brush->color[2] = rgb[0];
-		brush->color[1] = rgb[1];
-		brush->color[0] = rgb[2];
-	}
+	brush->pbrush = NULL;
+	brush->xorg = brush->yorg = 0;
+	brush->color[3] = (color == gx_no_color_index ? -1 : 0);
+	brush->color[2] = rgb[0];
+	brush->color[1] = rgb[1];
+	brush->color[0] = rgb[2];
+    }
 
-	return ecode;
+    return ecode;
 }
 
 static	int
 opvp_draw_image(
-	gx_device_opvp		*pdev,
-	int			depth,
-	int			sw,
-	int			sh,
-	int			dw,
-	int			dh,
-	int			raster,
-/*const*/
-	byte			*data
-	)
+    gx_device_opvp *pdev,
+    int	depth,
+    int	sw,
+    int	sh,
+    int	dw,
+    int	dh,
+    int	raster,
+    int	mask,
+    const byte *data)
 {
-	int			code = -1;
-	int			ecode = 0;
-	int			count;
-	OPVP_Rectangle		rect;
+    opvp_result_t		r = -1;
+    int			ecode = 0;
+    int			count;
 
-	/* check page-in */
-	if (opvp_check_in_page(pdev)) return -1;
+    /* check page-in */
+    if (opvp_check_in_page(pdev)) return -1;
 
-	/* image size */
-/*	count = (((((sw * depth + 7) >> 3) + 3) >> 2) << 2) * sh; */
-	count = raster * sh;
-	OPVP_i2Fix(0, rect.p0.x);
-	OPVP_i2Fix(0, rect.p0.y);
-	OPVP_i2Fix(dw, rect.p1.x);
-	OPVP_i2Fix(dh, rect.p1.y);
+    /* image size */
+    count = raster * sh;
 
-	/* call DrawImage */
-	if (apiEntry->DrawImage)
-	code = apiEntry->DrawImage(printerContext,
-	                           sw,
-	                           sh,
-	                           depth,
-	                           OPVP_iformatRaw,
-	                           rect,
-	                           count,
-	                           (void *)data);
-	if (code != OPVP_OK) {
+    /* call DrawImage */
+    if (apiEntry->opvpDrawImage) {
+	r = apiEntry->opvpDrawImage(printerContext,
+	       sw,sh,
+	       raster,
+	       mask ? OPVP_IFORMAT_MASK : OPVP_IFORMAT_RAW,
+	       dw,dh,
+	       /* discard 'const' qualifier */
+	       (void *)data);
+    }
+    if (r != OPVP_OK) {
+	/* call StartDrawImage */
+	if (apiEntry->opvpStartDrawImage) {
+	    r = apiEntry->opvpStartDrawImage(printerContext,
+		    sw,sh,
+		    raster,
+		    mask ? OPVP_IFORMAT_MASK : OPVP_IFORMAT_RAW,
+		    dw,dh);
+	}
+	if (r == OPVP_OK) {
+	    /* call TansferDrawImage */
+	    if (apiEntry->opvpTransferDrawImage) {
+		r = apiEntry->opvpTransferDrawImage(
+		       printerContext,
+		       count,
+			/* discard 'const' qualifier */
+		       (void *)data);
+	    }
+	    if (r != OPVP_OK) ecode = -1;
 
-		/* call StartDrawImage */
-		if (apiEntry->StartDrawImage)
-		code = apiEntry->StartDrawImage(printerContext,
-		                                sw,
-		                                sh,
-		                                depth,
-		                                OPVP_iformatRaw,
-		                                rect);
-		if (code == OPVP_OK) {
-
-			/* call TansferDrawImage */
-			if (apiEntry->TransferDrawImage)
-			code = apiEntry->TransferDrawImage(printerContext,
-			                                   count,
-			                                   (void *)data);
-			if (code != OPVP_OK) ecode = -1;
-
-			/* call EndDrawImage */
-			if (apiEntry->EndDrawImage)
-			apiEntry->EndDrawImage(printerContext);
-
-		} else {
-			/* ecode = -1;*/
-			ecode = 0;	/* continue... */
-		}
+	    /* call EndDrawImage */
+	    if (apiEntry->opvpEndDrawImage) {
+		apiEntry->opvpEndDrawImage(printerContext);
+	    }
+	} else {
+	    ecode = 0;	/* continue... */
 	}
+    }
 
-	return ecode;
+    return ecode;
 }
 
 /* ----- load/unload vector driver ----- */
@@ -1139,189 +1764,202 @@
  * load vector-driver
  */
 static	int
-opvp_load_vector_driver(
-	void
-	)
+opvp_load_vector_driver(void)
 {
-	char			**list = NULL;
-	int			i;
-	void			*h;
+    char **list = NULL;
+    int	i;
+    void *h;
 
-	if (handle) {
-		opvp_unload_vector_driver();
-	}
+    if (handle) {
+	opvp_unload_vector_driver();
+    }
 
-	if (vectorDriver) {
-		list = opvp_gen_dynamic_lib_name();
-	}
+    if (vectorDriver) {
+	list = opvp_gen_dynamic_lib_name();
+    }
 
-	if (list) {
-		i = 0;
-		while (list[i]) {
-			if ((h = dlopen(list[i],RTLD_NOW))) {
-				OpenPrinter = dlsym(h,"OpenPrinter");
-				errorno = dlsym(h,"errorno");
-				if (OpenPrinter && errorno) {
-					handle = h;
-					break;
-				}
-				OpenPrinter = NULL;
-				errorno = NULL;
-			}
-			i++;
+    if (list) {
+	i = 0;
+	while (list[i]) {
+	    if ((h = dlopen(list[i],RTLD_NOW))) {
+		OpenPrinter = dlsym(h,"opvpOpenPrinter");
+		ErrorNo = dlsym(h,"opvpErrorNo");
+		if (OpenPrinter && ErrorNo) {
+		    handle = h;
+		    break;
 		}
+		OpenPrinter = NULL;
+		ErrorNo = NULL;
+		/* try version 0.2 driver */
+		OpenPrinter_0_2 = dlsym(h,"OpenPrinter");
+		ErrorNo = dlsym(h,"errorno");
+		if (OpenPrinter_0_2 && ErrorNo) {
+		    handle = h;
+		    break;
+		}
+		OpenPrinter_0_2 = NULL;
+		ErrorNo = NULL;
+	    }
+	    i++;
 	}
+    }
 
-	if (handle) {
-		return 0;
-	} else {
-		return -1;
-	}
+    if (handle) {
+	return 0;
+    } else {
+	return -1;
+    }
 }
 
 /*
  * unload vector-driver
  */
 static	int
-opvp_unload_vector_driver(
-	void
-	)
+opvp_unload_vector_driver(void)
 {
-	if (handle) {
-		dlclose(handle);
-		handle = NULL;
-		OpenPrinter = NULL;
-		errorno = NULL;
-	}
-	return 0;
+    if (handle) {
+	dlclose(handle);
+	handle = NULL;
+	OpenPrinter = NULL;
+	ErrorNo = NULL;
+    }
+    return 0;
 }
 
 /*
  * prepare open
  */
 static	int
-prepare_open(
-	gx_device		*dev
-	)
+prepare_open(gx_device *dev)
 {
-	int			ecode = 0;
-	int			code = -1;
-	OPVP_api_procs		*api_entry;
-	int			dumFD = -1;
-	int			dumContext = -1;
-	OPVP_ColorSpace		cspace = OPVP_cspaceStandardRGB;
+    int ecode = 0;
+    int code;
+    opvp_result_t r = -1;
+    opvp_api_procs_t *api_entry;
+    int dumFD = -1;
+    opvp_dc_t dumContext = -1;
+    opvp_cspace_t cspace = OPVP_CSPACE_STANDARDRGB;
 
-	/* open dummy device */
-	code = open("/dev/null", O_RDWR);
-	if (code < 0) ecode = code;
-	else dumFD = code;
+    /* open dummy device */
+    code = open("/dev/null", O_RDWR);
+    if (code < 0) ecode = code;
+    else dumFD = code;
 
-	/* load vector driver */
-	if (!ecode) {
-		if ((code = opvp_load_vector_driver())) {
-			ecode = code;
-		}
+    /* load vector driver */
+    if (!ecode) {
+	if ((code = opvp_load_vector_driver())) {
+	    ecode = code;
 	}
+    }
 
-	/* prepare array of function pointer for PDAPI */
-	if (!ecode) {
-		if (!apiEntry) {
-			if (!(apiEntry = calloc(sizeof(OPVP_api_procs), 1))) {
-				ecode = -1;
-			}
-		} else {
-			memset(apiEntry, 0, sizeof(OPVP_api_procs));
-		}
+    /* prepare array of function pointer for PDAPI */
+    if (!ecode) {
+	if (!apiEntry) {
+	    if (!(apiEntry = calloc(sizeof(opvp_api_procs_t), 1))) {
+		ecode = -1;
+	    }
+	} else {
+	    memset(apiEntry, 0, sizeof(opvp_api_procs_t));
 	}
+    }
 
-	/* call OpenPrinter as dummy */
-	if (!ecode) {
-		code = OpenPrinter(dumFD, printerModel,
-				   &nApiEntry, &api_entry);
-		if (code == -1) ecode = code;
-		else dumContext = code;
+    /* call opvpOpenPrinter as dummy */
+    if (!ecode) {
+	opvp_dc_t dc;
+	opvp_int_t apiVersion[2];
+
+	/* require version 1.0 */
+	apiVersion[0] = 1;
+	apiVersion[1] = 0;
+	dc = OpenPrinterWrapper(dumFD, (opvp_char_t *)printerModel,
+	  apiVersion,&api_entry);
+	if (dc == -1) {
+	    ecode = -1;
+	} else {
+	    dumContext = dc;
 	}
+    }
 
-	/* set apiEntry */
-	if (!ecode) {
-		if (nApiEntry > sizeof(OPVP_api_procs)/sizeof(void *)) {
-			nApiEntry = sizeof(OPVP_api_procs)/sizeof(void *);
-		}
-		memcpy(apiEntry, api_entry, nApiEntry*sizeof(void *));
+    /* set apiEntry */
+    if (!ecode) {
+	nApiEntry = sizeof(opvp_api_procs_t)/sizeof(void *);
+	memcpy(apiEntry, api_entry, nApiEntry*sizeof(void *));
+    } else {
+	if (apiEntry) free(apiEntry);
+	apiEntry = NULL;
+    }
+
+    /* check vector fucntion */
+    if (apiEntry) {
+	if (!inkjet) {
+	    if (!(apiEntry->opvpNewPath) ||
+		!(apiEntry->opvpEndPath) ||
+		!(apiEntry->opvpStrokePath) ||
+		!(apiEntry->opvpSetCurrentPoint) ||
+		!(apiEntry->opvpLinePath) ||
+		!(apiEntry->opvpBezierPath)) {
+		/* NOT avail vector drawing mode */
+		vector = false;
+	    }
+	}
+	/* call GetColorSpace */
+	if (apiEntry->opvpGetColorSpace) {
+	    r = apiEntry->opvpGetColorSpace(dumContext, &cspace);
+	}
+	if (cspace == OPVP_CSPACE_BW) {
+	    /* mono-color */
+	    colorSpace = cspace;
+	    dev->color_info.num_components = 1;
+	    dev->color_info.depth = 1;
+	    dev->color_info.max_gray = 0;
+	    dev->color_info.max_color = 0;
+	    dev->color_info.dither_grays = 1;
+	    dev->color_info.dither_colors = 1;
+	} else if (cspace == OPVP_CSPACE_DEVICEGRAY) {
+	    /* gray-scale */
+	    colorSpace = cspace;
+	    dev->color_info.num_components = 1;
+	    dev->color_info.depth = 8;
+	    dev->color_info.max_gray = 255;
+	    dev->color_info.max_color = 255;
+	    dev->color_info.dither_grays = 256;
+	    dev->color_info.dither_colors = 256;
 	} else {
-		if (apiEntry) free(apiEntry);
-		apiEntry = NULL;
+	    /* rgb color */
+	    colorSpace = OPVP_CSPACE_STANDARDRGB;
+	    dev->color_info.num_components = 3;
+	    dev->color_info.depth = 24;
+	    dev->color_info.max_gray = 255;
+	    dev->color_info.max_color = 255;
+	    dev->color_info.dither_grays = 256;
+	    dev->color_info.dither_colors = 256;
 	}
-
-	/* check vector fucntion */
-	if (apiEntry) {
-		if (!inkjet) {
-			if (!(apiEntry->NewPath) ||
-			    !(apiEntry->EndPath) ||
-			    !(apiEntry->StrokePath) ||
-			    !(apiEntry->SetCurrentPoint) ||
-			    !(apiEntry->LinePath) ||
-			    !(apiEntry->BezierPath)) {
-				/* NOT avail vector drawing mode */
-				vector = false;
-			}
-		}
-		/* call GetColorSpace */
-		if (apiEntry->GetColorSpace)
-		code = apiEntry->GetColorSpace(dumContext, &cspace);
-		if (cspace == OPVP_cspaceBW) {
-			/* mono-color */
-			colorSpace = cspace;
-			dev->color_info.num_components = 1;
-			dev->color_info.depth = 1;
-			dev->color_info.max_gray = 0;
-			dev->color_info.max_color = 0;
-			dev->color_info.dither_grays = 1;
-			dev->color_info.dither_colors = 1;
-		} else if (cspace == OPVP_cspaceDeviceGray) {
-			/* gray-scale */
-			colorSpace = cspace;
-			dev->color_info.num_components = 1;
-			dev->color_info.depth = 8;
-			dev->color_info.max_gray = 255;
-			dev->color_info.max_color = 255;
-			dev->color_info.dither_grays = 256;
-			dev->color_info.dither_colors = 256;
-		} else {
-			/* rgb color */
-			colorSpace = OPVP_cspaceStandardRGB;
-			dev->color_info.num_components = 3;
-			dev->color_info.depth = 24;
-			dev->color_info.max_gray = 255;
-			dev->color_info.max_color = 255;
-			dev->color_info.dither_grays = 256;
-			dev->color_info.dither_colors = 256;
-		}
 #if GS_VERSION_MAJOR >= 8
-		dev->procs.get_color_mapping_procs = NULL;
-		dev->procs.get_color_comp_index = NULL;
-		gx_device_fill_in_procs(dev);
+	dev->procs.get_color_mapping_procs = NULL;
+	dev->procs.get_color_comp_index = NULL;
+	gx_device_fill_in_procs(dev);
 #endif
-	}
+    }
 
-	/* call Closerinter as dummy */
-	if (dumContext != -1) {
-		/* call ClosePrinter */
-		if (apiEntry->ClosePrinter)
-		apiEntry->ClosePrinter(dumContext);
-		dumContext = -1;
+    /* call Closerinter as dummy */
+    if (dumContext != -1) {
+	/* call ClosePrinter */
+	if (apiEntry->opvpClosePrinter) {
+	    apiEntry->opvpClosePrinter(dumContext);
 	}
+	dumContext = -1;
+    }
 
-	/* close device for dummy */
-	if (dumFD != -1) {
-		close(dumFD);
-		dumFD = -1;
-	}
+    /* close device for dummy */
+    if (dumFD != -1) {
+	close(dumFD);
+	dumFD = -1;
+    }
 
-	/* un-load vector driver */
-	opvp_unload_vector_driver();
+    /* un-load vector driver */
+    opvp_unload_vector_driver();
 
-	return ecode;
+    return ecode;
 }
 
 /* ----- driver procs ----- */
@@ -1329,497 +1967,507 @@
  * open device
  */
 static	int
-opvp_open(
-	gx_device		*dev
-	)
+opvp_open(gx_device *dev)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	gx_device_oprp		*rdev = (gx_device_oprp *)dev;
-	int			ecode = 0;
-	int			code;
-	OPVP_api_procs		*api_entry;
-	char			*job_info = NULL;
-	char			*doc_info = NULL;
-	char			*tmp_info = NULL;
-	float			margin_width = 0;
-	float			margin_height = 0;
-	float			adj_margins[4];
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    gx_device_oprp *rdev = (gx_device_oprp *)dev;
+    int ecode = 0;
+    int code;
+    opvp_result_t r = -1;
+    opvp_dc_t dc;
+    opvp_api_procs_t *api_entry;
+    char *job_info = NULL;
+    char *doc_info = NULL;
+    char *tmp_info = NULL;
+    float margin_width = 0;
+    float margin_height = 0;
+    float adj_margins[4];
+    opvp_int_t apiVersion[2];
 
-	/* prepare open : load and open as dummy */
-	code = prepare_open(dev);
-	if (code) {
-		ecode = code;
-		return ecode;
-	}
+    /* prepare open : load and open as dummy */
+    code = prepare_open(dev);
+    if (code) {
+	ecode = code;
+	return ecode;
+    }
 
-	/* set margins */
-	if (zoomAuto) {
-		margin_width = (margins[0] + margins[2])
-		             * dev->HWResolution[0];
-		margin_height = (margins[1] + margins[3])
-		              * dev->HWResolution[1];
-		zoom[0] = (dev->width - margin_width) / dev->width;
-		zoom[1] = (dev->height - margin_height) / dev->height;
-		if (zoom[0] < zoom[1]) zoom[1] = zoom[0];
-		else zoom[0] = zoom[1];
-	}
-	if (inkjet) {
-		if ((margins[0] != 0) ||
-		    (margins[1] != 0) || (margins[3] != 0)) {
-			shift[0] = margins[0] * dev->HWResolution[0];
-			shift[1] = (margins[1] + margins[3])
-				 * dev->HWResolution[1];
-			zooming = true;
-		}
-		dev->width -= margins[2] * dev->HWResolution[0];
-		dev->height -= margins[1] * dev->HWResolution[1];
+    /* set margins */
+    if (zoomAuto) {
+	margin_width = (margins[0] + margins[2])
+		     * dev->HWResolution[0];
+	margin_height = (margins[1] + margins[3])
+		      * dev->HWResolution[1];
+	zoom[0] = (dev->width - margin_width) / dev->width;
+	zoom[1] = (dev->height - margin_height) / dev->height;
+	if (zoom[0] < zoom[1]) {
+	    zoom[1] = zoom[0];
 	} else {
-		if ((margins[0] != 0) || (margins[1] != 0)) {
-			shift[0] = margins[0] * dev->HWResolution[0];
-			shift[1] = margins[3] * dev->HWResolution[1];
-			zooming = true;
-		}
-		adj_margins[0] = 0;
-		adj_margins[3] = 0;
-		adj_margins[1] = dev->height * zoom[1] / dev->HWResolution[1]
-		                - (dev->MediaSize[1] / PS_DPI
-		                 - (margins[1] + margins[3]));
-		if (adj_margins[1] < 0) adj_margins[0] = 0;
-		adj_margins[2] = dev->width * zoom[0] / dev->HWResolution[0]
-		                - (dev->MediaSize[0] / PS_DPI
-		                 - (margins[0] + margins[2]));
-		if (adj_margins[2] < 0) adj_margins[2] = 0;
-		gx_device_set_margins(dev, adj_margins, true);
+	    zoom[0] = zoom[1];
 	}
-	if ((zoom[0] != 1) || (zoom[1] != 1)) zooming = true;
+    }
+    if (inkjet) {
+	if ((margins[0] != 0) ||
+	    (margins[1] != 0) || (margins[3] != 0)) {
+	    shift[0] = margins[0] * dev->HWResolution[0];
+	    shift[1] = (margins[1] + margins[3])
+		     * dev->HWResolution[1];
+	    zooming = true;
+	}
+	dev->width -= margins[2] * dev->HWResolution[0];
+	dev->height -= margins[1] * dev->HWResolution[1];
+    } else {
+	    if ((margins[0] != 0) || (margins[1] != 0)) {
+		shift[0] = margins[0] * dev->HWResolution[0];
+		shift[1] = margins[3] * dev->HWResolution[1];
+		zooming = true;
+	    }
+	    adj_margins[0] = 0;
+	    adj_margins[3] = 0;
+	    adj_margins[1] = dev->height * zoom[1] / dev->HWResolution[1]
+			    - (dev->MediaSize[1] / PS_DPI
+			     - (margins[1] + margins[3]));
+	    if (adj_margins[1] < 0) adj_margins[0] = 0;
+	    adj_margins[2] = dev->width * zoom[0] / dev->HWResolution[0]
+			    - (dev->MediaSize[0] / PS_DPI
+			     - (margins[0] + margins[2]));
+	    if (adj_margins[2] < 0) adj_margins[2] = 0;
+	    gx_device_set_margins(dev, adj_margins, true);
+    }
+    if ((zoom[0] != 1) || (zoom[1] != 1)) zooming = true;
 
-	/* open file for output device */
-	if (!inkjet) {
-		pdev->v_memory = gs_memory_stable(pdev->memory);
-		/* open output stream */
-		code = gdev_vector_open_file_options((gx_device_vector*)dev,
-		           512,
-		           (VECTOR_OPEN_FILE_SEQUENTIAL
-		           |VECTOR_OPEN_FILE_BBOX
-		           ));
-		if (code < 0) {
-			ecode = code;
-			return ecode;
-		}
+    /* open file for output device */
+    if (!inkjet) {
+	pdev->v_memory = gs_memory_stable(pdev->memory);
+	/* open output stream */
+	code = gdev_vector_open_file_options((gx_device_vector*)dev,
+		   512,
+		   (VECTOR_OPEN_FILE_SEQUENTIAL
+		   |VECTOR_OPEN_FILE_BBOX
+		   ));
+	if (code < 0) {
+	    ecode = code;
+	    return ecode;
+	}
 #if GS_VERSION_MAJOR >= 8
-		if (pdev->bbox_device != NULL) {
-			if (pdev->bbox_device->memory == NULL)
-				pdev->bbox_device->memory = gs_memory_stable(dev->memory);
-		}
+	if (pdev->bbox_device != NULL) {
+	    if (pdev->bbox_device->memory == NULL) {
+		pdev->bbox_device->memory = gs_memory_stable(dev->memory);
+	    }
+	}
 #endif
-		outputFD = fileno(pdev->file);
-	} else {
-		/* open printer device */
-		code = gdev_prn_open(dev);
-		if (code < 0) {
-			ecode = ecode;
-			return ecode;
-		}
-		/* open output stream */
-		code = gdev_prn_open_printer_seekable(dev, true, false);
-		if (code < 0) {
-			ecode = code;
-			return ecode;
-		}
-		outputFD = fileno(rdev->file);
+	outputFD = fileno(pdev->file);
+    } else {
+	/* open printer device */
+	code = gdev_prn_open(dev);
+	if (code < 0) {
+	    ecode = ecode;
+	    return ecode;
 	}
+	/* open output stream */
+	code = gdev_prn_open_printer_seekable(dev, true, false);
+	if (code < 0) {
+	    ecode = code;
+	    return ecode;
+	}
+	outputFD = fileno(rdev->file);
+    }
 
-	/* RE-load vector driver */
-	if ((code = opvp_load_vector_driver())) {
-		ecode = code;
-		return ecode;
+    /* RE-load vector driver */
+    if ((code = opvp_load_vector_driver())) {
+	ecode = code;
+	return ecode;
+    }
+
+    /* call opvpOpenPrinter */
+    /* require version 1.0 */
+    apiVersion[0] = 1;
+    apiVersion[1] = 0;
+    dc = OpenPrinterWrapper(outputFD,(opvp_char_t *)printerModel,
+      apiVersion,&api_entry);
+    if (!apiEntry) {
+	if (!(apiEntry = calloc(sizeof(opvp_api_procs_t), 1))) {
+	    ecode = -1;
 	}
+    } else {
+	memset(apiEntry, 0, sizeof(opvp_api_procs_t));
+    }
+    if (dc == -1) {
+	ecode =  -1;
+	if (apiEntry) free(apiEntry);
+	apiEntry = NULL;
+	opvp_unload_vector_driver();
+	if (inkjet) gdev_prn_close(dev);
+	else gdev_vector_close_file((gx_device_vector *)pdev);
+	return ecode;
+    }
+    printerContext = dc;
+    nApiEntry = sizeof(opvp_api_procs_t)/sizeof(void *);
+    memcpy(apiEntry, api_entry, nApiEntry*sizeof(void *));
 
-	/* call OpenPrinter */
-	code = OpenPrinter(outputFD, printerModel,
-	                   &nApiEntry, &api_entry);
-	if (!apiEntry) {
-		if (!(apiEntry = calloc(sizeof(OPVP_api_procs), 1))) {
-			ecode = -1;
+    /* initialize */
+    if ((!ecode) && (!inkjet)) {
+	pdev->vec_procs = &opvp_vector_procs;
+	if (vector) gdev_vector_init((gx_device_vector *)pdev);
+    }
+
+    if (apiEntry->opvpQueryColorSpace) {
+	int n = sizeof(cspace_available);
+	int nn = n;
+	opvp_cspace_t *p = malloc(n*sizeof(opvp_cspace_t));
+
+	if ((r = apiEntry->opvpQueryColorSpace(printerContext,&nn,p))
+	     == OPVP_PARAMERROR && nn > n) {
+	    /* realloc buffer and retry */
+	    p = realloc(p,nn*sizeof(opvp_cspace_t));
+	    r = apiEntry->opvpQueryColorSpace(printerContext,&nn,p);
+	}
+	if (r == OPVP_OK) {
+	    int i;
+
+	    for (i = 0;i < nn;i++) {
+		if (p[i] < sizeof(cspace_available)) {
+		    cspace_available[p[i]] = 1;
 		}
-	} else {
-		memset(apiEntry, 0, sizeof(OPVP_api_procs));
+	    }
 	}
-	if (code == -1) {
-		ecode =  code;
-		if (apiEntry) free(apiEntry);
-		apiEntry = NULL;
-		opvp_unload_vector_driver();
-		if (inkjet) gdev_prn_close(dev);
-		else gdev_vector_close_file((gx_device_vector *)pdev);
-		return ecode;
+	free(p);
+    }
+    /* start job */
+    if (!ecode) {
+	/* job info */
+	if (jobInfo) {
+	    if (strlen(jobInfo) > 0) {
+		job_info = opvp_alloc_string(&job_info,jobInfo);
+	    }
 	}
-	printerContext = code;
-	if (nApiEntry > sizeof(OPVP_api_procs)/sizeof(void *)) {
-		nApiEntry = sizeof(OPVP_api_procs)/sizeof(void *);
+	tmp_info = opvp_alloc_string(&tmp_info,opvp_gen_job_info(dev));
+	if (tmp_info) {
+	    if (strlen(tmp_info) > 0) {
+		if (job_info) {
+		    if (strlen(job_info) > 0) {
+			opvp_cat_string(&job_info, ";");
+		    }
+		}
+		job_info = opvp_cat_string(&job_info,OPVP_INFO_PREFIX);
+		job_info = opvp_cat_string(&job_info,tmp_info);
+	    }
 	}
-	memcpy(apiEntry, api_entry, nApiEntry*sizeof(void *));
 
-	/* call SetColorSpace */
-	if (!ecode) {
-		if (apiEntry->SetColorSpace)
-		apiEntry->SetColorSpace(printerContext, colorSpace);
+	/* call StartJob */
+	if (apiEntry->opvpStartJob) {
+	    r = apiEntry->opvpStartJob(printerContext,
+	      (opvp_char_t *)opvp_to_utf8(job_info));
 	}
+	if (r != OPVP_OK) {
+	    ecode = -1;
+	}
+    }
 
-	/* initialize */
-	if ((!ecode) && (!inkjet)) {
-		pdev->vec_procs = &opvp_vector_procs;
-		if (vector) gdev_vector_init((gx_device_vector *)pdev);
+    /* start doc */
+    if (!ecode) {
+	/* doc info */
+	if (docInfo) {
+	    if (strlen(docInfo) > 0) {
+		doc_info = opvp_alloc_string(&doc_info,docInfo);
+	    }
 	}
-
-	/* start job */
-	if (!ecode) {
-		/* job info */
-		if (jobInfo) {
-			if (strlen(jobInfo) > 0) {
-				job_info = opvp_alloc_string(&job_info,
-				                             jobInfo);
-			}
+	tmp_info = opvp_alloc_string(&tmp_info, opvp_gen_doc_info(dev));
+	if (tmp_info) {
+	    if (strlen(tmp_info) > 0) {
+		if (doc_info) {
+		    if (strlen(doc_info) > 0) {
+			opvp_cat_string(&doc_info, ";");
+		    }
 		}
-		tmp_info = opvp_alloc_string(&tmp_info,
-		                             opvp_gen_job_info(dev));
-		if (tmp_info) {
-			if (strlen(tmp_info) > 0) {
-				if (job_info) {
-					if (strlen(job_info) > 0) {
-						opvp_cat_string(&job_info, ";");
-					}
-				}
-				job_info = opvp_cat_string(&job_info,
-				                           OPVP_INFO_PREFIX);
-				job_info = opvp_cat_string(&job_info, tmp_info);
-			}
-		}
-
-		/* call StartJob */
-		if (apiEntry->StartJob)
-		code = apiEntry->StartJob(printerContext,
-		                          opvp_to_utf8(job_info));
-		if (code != OPVP_OK) {
-			ecode = -1;
-		}
+		doc_info = opvp_cat_string(&doc_info,OPVP_INFO_PREFIX);
+		doc_info = opvp_cat_string(&doc_info,tmp_info);
+	    }
 	}
 
-	/* start doc */
-	if (!ecode) {
-		/* doc info */
-		if (docInfo) {
-			if (strlen(docInfo) > 0) {
-				doc_info = opvp_alloc_string(&doc_info,
-					                     docInfo);
-			}
-		}
-		tmp_info = opvp_alloc_string(&tmp_info,
-		                             opvp_gen_doc_info(dev));
-		if (tmp_info) {
-			if (strlen(tmp_info) > 0) {
-				if (doc_info) {
-					if (strlen(doc_info) > 0) {
-						opvp_cat_string(&doc_info, ";");
-					}
-				}
-				doc_info = opvp_cat_string(&doc_info,
-				                           OPVP_INFO_PREFIX);
-				doc_info = opvp_cat_string(&doc_info, tmp_info);
-			}
-		}
-
-		/* call StartDoc */
-		if (apiEntry->StartDoc)
-		code = apiEntry->StartDoc(printerContext,
-		                          opvp_to_utf8(doc_info));
-		if (code != OPVP_OK) {
-			ecode = -1;
-		}
+	/* call StartDoc */
+	if (apiEntry->opvpStartDoc) {
+	    r = apiEntry->opvpStartDoc(printerContext,
+	      (opvp_char_t *)opvp_to_utf8(doc_info));
 	}
+	if (r != OPVP_OK) {
+	    ecode = -1;
+	}
+    }
 
-	if (tmp_info) opvp_alloc_string(&tmp_info, NULL);
-	if (doc_info) opvp_alloc_string(&doc_info, NULL);
-	if (job_info) opvp_alloc_string(&job_info, NULL);
+    if (tmp_info) opvp_alloc_string(&tmp_info, NULL);
+    if (doc_info) opvp_alloc_string(&doc_info, NULL);
+    if (job_info) opvp_alloc_string(&job_info, NULL);
 
-	return ecode;
+    return ecode;
 }
 
 /*
  * open device for inkjet
  */
 static	int
-oprp_open(
-	gx_device		*dev
-	)
+oprp_open(gx_device *dev)
 {
-	/* set inkjet mode */
-	vector = false;
-	inkjet = true;
+    /* set inkjet mode */
+    vector = false;
+    inkjet = true;
 
-	/* matrix */
-	dev->procs.get_initial_matrix = opvp_get_initial_matrix;
-	return opvp_open(dev);
+    /* matrix */
+    dev->procs.get_initial_matrix = opvp_get_initial_matrix;
+    return opvp_open(dev);
 }
 
 /*
  * get initial matrix
  */
 static	void
-opvp_get_initial_matrix(
-	gx_device		*dev,
-	gs_matrix		*pmat
-	)
+opvp_get_initial_matrix(gx_device *dev, gs_matrix *pmat)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	OPVP_CTM		omat;
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    opvp_ctm_t omat;
 
-	gx_default_get_initial_matrix(dev,pmat);
-	if (zooming) {
-		/* gs matrix */
-		pmat->xx *= zoom[0];
-		pmat->xy *= zoom[1];
-		pmat->yx *= zoom[0];
-		pmat->yy *= zoom[1];
-		pmat->tx = pmat->tx * zoom[0] + shift[0];
-		pmat->ty = pmat->ty * zoom[1] + shift[1];
-	}
+    gx_default_get_initial_matrix(dev,pmat);
+    if (zooming) {
+	/* gs matrix */
+	pmat->xx *= zoom[0];
+	pmat->xy *= zoom[1];
+	pmat->yx *= zoom[0];
+	pmat->yy *= zoom[1];
+	pmat->tx = pmat->tx * zoom[0] + shift[0];
+	pmat->ty = pmat->ty * zoom[1] + shift[1];
+    }
 
-	if (pdev->is_open) {
-
-		/* call ResetCTM */
-		if (apiEntry->ResetCTM)
-		apiEntry->ResetCTM(printerContext);
-		else {
-			/* call SetCTM */
-			omat.a = 1;
-			omat.b = 0;
-			omat.c = 0;
-			omat.d = 1;
-			omat.e = 0;
-			omat.f = 0;
-			if (apiEntry->SetCTM)
-			apiEntry->SetCTM(printerContext, &omat);
-		}
+    if (pdev->is_open) {
+	/* call ResetCTM */
+	if (apiEntry->opvpResetCTM) {
+	    apiEntry->opvpResetCTM(printerContext);
+	} else {
+	    /* call SetCTM */
+	    omat.a = 1;
+	    omat.b = 0;
+	    omat.c = 0;
+	    omat.d = 1;
+	    omat.e = 0;
+	    omat.f = 0;
+	    if (apiEntry->opvpSetCTM) {
+		apiEntry->opvpSetCTM(printerContext, &omat);
+	    }
 	}
+    }
 
-	return;
+    return;
 }
 
 /*
  * output page
  */
 static	int
-opvp_output_page(
-	gx_device		*dev,
-	int			num_copies,
-	int			flush
-	)
+opvp_output_page(gx_device *dev, int num_copies, int flush)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	int			ecode = 0;
-	int			code = OPVP_OK;
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    int ecode = 0;
+    int code = -1;
 
-	if (inkjet) return gdev_prn_output_page(dev, num_copies, flush);
+    if (inkjet) return gdev_prn_output_page(dev, num_copies, flush);
 
 #ifdef OPVP_IGNORE_BLANK_PAGE
-	if (pdev->in_page) {
+    if (pdev->in_page) {
 #else
-	/* check page-in */
-	if (opvp_check_in_page(pdev)) return -1;
+    /* check page-in */
+    if (opvp_check_in_page(pdev)) return -1;
 #endif
-		/* end page */
-		code = opvp_endpage();
-		if (code) ecode = code;
+	/* end page */
+	code = opvp_endpage();
+	if (code) ecode = code;
 
-		pdev->in_page = false;
-		beginPage = false;
+	pdev->in_page = false;
+	beginPage = false;
 #ifdef OPVP_IGNORE_BLANK_PAGE
-	}
+    }
 #endif
 
-	if (vector) {
-		gdev_vector_reset((gx_device_vector *)pdev);
-	}
+    if (vector) {
+	gdev_vector_reset((gx_device_vector *)pdev);
+    }
 
-	code = gx_finish_output_page(dev, num_copies, flush);
-	if (code) ecode = code;
+    code = gx_finish_output_page(dev, num_copies, flush);
+    if (code) ecode = code;
 
-	return ecode;
+    return ecode;
 }
 
 /*
  * print page
  */
 static	int
-oprp_print_page(
-	gx_device_printer	*pdev,
-	FILE			*prn_stream
-	)
+oprp_print_page(gx_device_printer *pdev, FILE *prn_stream)
 {
-	int			ecode = 0;
-	int			code = -1;
-	int			raster_size;
-	int			buff_size;
-	byte			*buff = NULL;
-	int			line;
-	int			scan_lines;
-	byte			*data;
-	int			rasterWidth;
-	bool			start_page = false;
-	bool			start_raster = false;
+    int ecode = 0;
+    int code = -1;
+    opvp_result_t r = -1;
+    int raster_size;
+    int buff_size;
+    byte *buff = NULL;
+    int line;
+    int scan_lines;
+    byte *data;
+    int rasterWidth;
+    bool start_page = false;
+    bool start_raster = false;
 #if ENABLE_SKIP_RASTER
-	int			i;
-	byte			check;
+    int i;
+    byte check;
 #endif
 
-	/* get raster/pixel size */
-	raster_size = gx_device_raster((gx_device *)pdev, 0);
-	buff_size = ((raster_size + 3) >> 2) << 2;
-	scan_lines = dev_print_scan_lines(pdev);
-	rasterWidth = pdev->width;
+    /* get raster/pixel size */
+    raster_size = gx_device_raster((gx_device *)pdev, 0);
+    buff_size = ((raster_size + 3) >> 2) << 2;
+    scan_lines = dev_print_scan_lines(pdev);
+    rasterWidth = pdev->width;
 
-	/* allocate buffer */
-	buff = (byte*)gs_malloc(gs_lib_ctx_get_non_gc_memory_t(), 1, buff_size, "oprp_print_page(buff)");
-	if (!buff) return ecode = -1;
+    /* allocate buffer */
+    buff = (byte*)calloc(1, buff_size);
+    if (!buff) return ecode = -1;
 
-	/* start page */
-	if (!ecode) {
-		code = opvp_startpage((gx_device *)pdev);
-		if (code) ecode = code;
-		else start_page = true;
+    /* start page */
+    if (!ecode) {
+	code = opvp_startpage((gx_device *)pdev);
+	if (code) ecode = code;
+	else start_page = true;
+    }
+
+    /* moveto origin */
+    if (!ecode)
+    opvp_moveto((gx_device_vector*)pdev, 0, 0, 0, 0, 0);
+
+    /* call StartRaster */
+    if (!ecode) {
+	if (apiEntry->opvpStartRaster) {
+	    r = apiEntry->opvpStartRaster(printerContext,rasterWidth);
 	}
+	if (r != OPVP_OK) {
+	    ecode = r;
+	} else {
+	    start_raster = true;
+	}
+    }
 
-	/* moveto origin */
-	if (!ecode)
-	opvp_moveto((gx_device_vector*)pdev, 0, 0, 0, 0, 0);
-
-	/* call StartRaster */
+    /* line */
+    for (line = 0; (line < scan_lines) && (!ecode); line++) {
+	/* get raster data */
 	if (!ecode) {
-		if (apiEntry->StartRaster)
-		code = apiEntry->StartRaster(printerContext, rasterWidth);
-		if (code != OPVP_OK) ecode = code;
-		else start_raster = true;
+	    code = gdev_prn_get_bits(pdev, line, buff, &data);
+	    if (code) {
+		ecode = code;
+		break;
+	    }
 	}
-
-	/* line */
-	for (line = 0; (line < scan_lines) && (!ecode); line++) {
-		/* get raster data */
-		if (!ecode) {
-			code = gdev_prn_get_bits(pdev, line, buff, &data);
-			if (code) {
-				ecode = code;
-				break;
-			}
-		}
 #if ENABLE_SKIP_RASTER
-		/* check support SkipRaster */
-		if (apiEntry->SkipRaster) {
-			/* check all white */
-			if (pdev->color_info.depth > 8) {
-				for (check = 0xff, i = 0; i < raster_size; i++)
-				{
-					check &= data[i];
-					if (check != 0xff) break;
-				}
-				/* if all white call SkipRaster */
-				if (check == 0xff) {
-					code = apiEntry->SkipRaster(
-					           printerContext, 1);
-					if (code == OPVP_OK) continue;
-				}
-			} else {
-				for (check = 0, i = 0; i < raster_size; i++)
-				{
-					check |= data[i];
-					if (check) break;
-				}
-				/* if all zero call SkipRaster */
-				if (check) {
-					code = apiEntry->SkipRaster(
-					           printerContext, 1);
-					if (code == OPVP_OK) continue;
-				}
-			}
+	/* check support SkipRaster */
+	if (apiEntry->opvpSkipRaster) {
+	    /* check all white */
+	    if (pdev->color_info.depth > 8) {
+		for (check = 0xff, i = 0; i < raster_size; i++)
+		{
+		    check &= data[i];
+		    if (check != 0xff) break;
 		}
-#endif
-		/* call TransferRasterData */
-		if (!ecode) {
-			if (apiEntry->TransferRasterData)
-			code = apiEntry->TransferRasterData(printerContext,
-			                                    raster_size,
-			                                    data);
-			if (code != OPVP_OK) ecode = code;
+		/* if all white call SkipRaster */
+		if (check == 0xff) {
+		    r = apiEntry->opvpSkipRaster(printerContext, 1);
+		    if (r == OPVP_OK) continue;
 		}
+	    } else {
+		for (check = 0, i = 0; i < raster_size; i++) {
+		    check |= data[i];
+		    if (check) break;
+		}
+		/* if all zero call SkipRaster */
+		if (check) {
+		    r = apiEntry->opvpSkipRaster(printerContext, 1);
+		    if (r == OPVP_OK) continue;
+		}
+	    }
 	}
-
-	/* call StartRaster */
-	if (start_raster) {
-		if (apiEntry->EndRaster)
-		code = apiEntry->EndRaster(printerContext);
-		if (code != OPVP_OK) ecode = code;
-		start_raster = false;
+#endif
+	/* call TransferRasterData */
+	if (!ecode) {
+	    if (apiEntry->opvpTransferRasterData) {
+		r = apiEntry->opvpTransferRasterData(printerContext,
+						raster_size,
+						data);
+	    }
+	    if (r != OPVP_OK) ecode = r;
 	}
+    }
 
-	/* end page */
-	if (start_page) {
-		code = opvp_endpage();
-		if (code) ecode = code;
-		start_page = false;
+    /* call EndRaster */
+    if (start_raster) {
+	if (apiEntry->opvpEndRaster) {
+	    r = apiEntry->opvpEndRaster(printerContext);
 	}
+	if (r != OPVP_OK) ecode = r;
+	start_raster = false;
+    }
 
-	/* free buffer */
-	if (buff) {
-		gs_free(gs_lib_ctx_get_non_gc_memory_t(), (char*)buff, 1, buff_size, "oprp_print_page(buff)");
-		buff = NULL;
-	}
+    /* end page */
+    if (start_page) {
+	code = opvp_endpage();
+	if (code) ecode = code;
+	start_page = false;
+    }
 
-	return ecode;
+    /* free buffer */
+    if (buff) {
+	free(buff);
+	buff = NULL;
+    }
+
+    return ecode;
 }
 
 /*
  * close device
  */
 static	int
-opvp_close(
-	gx_device		*dev
-	)
+opvp_close(gx_device *dev)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	int			ecode = 0;
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    int ecode = 0;
 
-	/* finalize */
-	if (printerContext != -1) {
+    /* finalize */
+    if (printerContext != -1) {
+	/* call EndDoc */
+	if (apiEntry->opvpEndDoc) {
+	    apiEntry->opvpEndDoc(printerContext);
+	}
 
-		/* call EndDoc */
-		if (apiEntry->EndDoc)
-		apiEntry->EndDoc(printerContext);
+	/* call EndJob */
+	if (apiEntry->opvpEndJob) {
+	    apiEntry->opvpEndJob(printerContext);
+	}
 
-		/* call EndJob */
-		if (apiEntry->EndJob)
-		apiEntry->EndJob(printerContext);
-
-		/* call ClosePrinter */
-		if (apiEntry->ClosePrinter)
-		apiEntry->ClosePrinter(printerContext);
-		printerContext = -1;
+	/* call ClosePrinter */
+	if (apiEntry->opvpClosePrinter) {
+	    apiEntry->opvpClosePrinter(printerContext);
 	}
+	printerContext = -1;
+    }
 
-	/* unload vector driver */
-	if (apiEntry) free(apiEntry);
-	apiEntry = NULL;
-	opvp_unload_vector_driver();
+    /* unload vector driver */
+    if (apiEntry) free(apiEntry);
+    apiEntry = NULL;
+    opvp_unload_vector_driver();
 
-	if (inkjet) {
-		/* close printer */
-		gdev_prn_close(dev);
-	} else {
-		/* close output stream */
-		gdev_vector_close_file((gx_device_vector *)pdev);
-	}
-	outputFD = -1;
+    if (inkjet) {
+	/* close printer */
+	gdev_prn_close(dev);
+    } else {
+	/* close output stream */
+	gdev_vector_close_file((gx_device_vector *)pdev);
+    }
+    outputFD = -1;
 
-	return ecode;
+    return ecode;
 }
 
 /*
@@ -1827,205 +2475,197 @@
  */
 #if GS_VERSION_MAJOR >= 8
 static	gx_color_index
-opvp_map_rgb_color(
-	gx_device		*dev,
-	gx_color_value	*prgb		/* modified for gs 8.15 */
-	)
+opvp_map_rgb_color(gx_device *dev,
+	const gx_color_value *prgb /* modified for gs 8.15 */)
 #else
 static	gx_color_index
-opvp_map_rgb_color(
-	gx_device		*dev,
-	gx_color_value		r,
-	gx_color_value		g,
-	gx_color_value		b
-	)
+opvp_map_rgb_color(gx_device *dev,
+	gx_color_value r,
+	gx_color_value g,
+	gx_color_value b)
 #endif
 {
-	OPVP_ColorSpace		cs;
-	uint				c, m, y, k;
+    opvp_cspace_t cs;
+    uint c, m, y, k;
 
 #if !(ENABLE_SIMPLE_MODE)
-	gx_device_opvp		*pdev;
-	int				code;
+    gx_device_opvp *pdev;
+    opvp_result_t r;
 #endif
 
 #if GS_VERSION_MAJOR >= 8
-	gx_color_value	r, g, b;	/* added for gs 8.15 */
-	r = prgb[0];
-	g = prgb[1];
-	b = prgb[2];
+    gx_color_value r, g, b; /* added for gs 8.15 */
+    r = prgb[0];
+    g = prgb[1];
+    b = prgb[2];
 #endif
 
 #if !(ENABLE_SIMPLE_MODE)
-	pdev = (gx_device_opvp *)dev;
-	code = -1;
+    pdev = (gx_device_opvp *)dev;
+    r = -1;
 #endif
-	cs = OPVP_cspaceStandardRGB;
+    cs = OPVP_CSPACE_STANDARDRGB;
 
 #if ENABLE_SIMPLE_MODE
-	cs = colorSpace;
+    cs = colorSpace;
 #else
-	if (pdev->is_open) {
-		/* call GetColorSpace */
-		if (apiEntry->GetColorSpace)
-		code = apiEntry->GetColorSpace(printerContext, &cs);
-		if (code != OPVP_OK) {
-			if (pdev->color_info.depth > 32) {
-				cs = OPVP_cspaceStandardRGB64;
-			} else if (pdev->color_info.depth > 8 ) {
-				cs = OPVP_cspaceStandardRGB;
-			} else if (pdev->color_info.depth > 1 ) {
-				cs = OPVP_cspaceDeviceGray;
-			} else {
-				cs = OPVP_cspaceBW;
-			}
-		}
+    if (pdev->is_open) {
+	/* call GetColorSpace */
+	if (apiEntry->opvpGetColorSpace) {
+	    r = apiEntry->opvpGetColorSpace(printerContext, &cs);
 	}
+	if (r != OPVP_OK) {
+	    if (pdev->color_info.depth > 32) {
+		    cs = OPVP_CSPACE_STANDARDRGB64;
+	    } else if (pdev->color_info.depth > 8 ) {
+		    cs = OPVP_CSPACE_STANDARDRGB;
+	    } else if (pdev->color_info.depth > 1 ) {
+		    cs = OPVP_CSPACE_DEVICEGRAY;
+	    } else {
+		    cs = OPVP_CSPACE_BW;
+	    }
+	}
+    }
 #endif
 
-	switch (cs) {
-		case	OPVP_cspaceStandardRGB64 :
-			/* unsupported */
-			if (sizeof(gx_color_index) >= 6) {
-				return (long long)b
-				     + ((long long)g << 16)
-				     + ((long long)b << 32);
-			} else {
-				return gx_color_value_to_byte(b)
-				     + ((uint)gx_color_value_to_byte(g) << 8)
-				     + ((ulong)gx_color_value_to_byte(r) << 16);
-			}
-			break;
-		case	OPVP_cspaceDeviceCMYK :
-		case	OPVP_cspaceDeviceCMY :
-			/* unsupported */
-			c = gx_color_value_to_byte(~r);
-			m = gx_color_value_to_byte(~g);
-			y = gx_color_value_to_byte(~b);
-			if (cs == OPVP_cspaceDeviceCMYK) {
-				k = (c<m ? (c<y ? c : y) : (m<y ? m : y));
-				c -= k;
-				m -= k;
-				y -= k;
-			} else {
-				k = 0;
-			}
-			return (k + (y << 8) + (m << 16) + (c << 24));
-			break;
-		case	OPVP_cspaceDeviceGray :
+    switch (cs) {
+    case OPVP_CSPACE_STANDARDRGB64:
+	/* unsupported */
+	if (sizeof(gx_color_index) >= 6) {
+	    return (long long)b
+		 + ((long long)g << 16)
+		 + ((long long)b << 32);
+	} else {
+	    return gx_color_value_to_byte(b)
+		 + ((uint)gx_color_value_to_byte(g) << 8)
+		 + ((ulong)gx_color_value_to_byte(r) << 16);
+	}
+	break;
+    case OPVP_CSPACE_DEVICECMYK:
+    case OPVP_CSPACE_DEVICECMY:
+	/* unsupported */
+	c = gx_color_value_to_byte(~r);
+	m = gx_color_value_to_byte(~g);
+	y = gx_color_value_to_byte(~b);
+	if (cs == OPVP_CSPACE_DEVICECMYK) {
+	    k = (c<m ? (c<y ? c : y) : (m<y ? m : y));
+	    c -= k;
+	    m -= k;
+	    y -= k;
+	} else {
+	    k = 0;
+	}
+	return (k + (y << 8) + (m << 16) + (c << 24));
+	break;
+    case OPVP_CSPACE_DEVICEGRAY:
 #if GS_VERSION_MAJOR >= 8
-			{
-				gx_color_value rgb[3];
-				rgb[0] = rgb[1] = rgb[2] = r;
-				return gx_default_gray_map_rgb_color(dev, rgb);
-			}
+	{
+	    gx_color_value rgb[3];
+	    rgb[0] = rgb[1] = rgb[2] = r;
+	    return gx_default_gray_map_rgb_color(dev, rgb);
+	}
 #else
-			return gx_default_gray_map_rgb_color(dev, r, g, b);
+	return gx_default_gray_map_rgb_color(dev, r, g, b);
 #endif
-			break;
-		case	OPVP_cspaceBW :
+	break;
+    case OPVP_CSPACE_BW :
 #if GS_VERSION_MAJOR >= 8
-			return gx_default_b_w_map_rgb_color(dev, prgb);
+	return gx_default_b_w_map_rgb_color(dev, prgb);
 #else
-			return gx_default_b_w_map_rgb_color(dev, r, g, b);
+	return gx_default_b_w_map_rgb_color(dev, r, g, b);
 #endif
-			break;
-		case	OPVP_cspaceStandardRGB :
-		case	OPVP_cspaceDeviceRGB :
-		default :
+	break;
+    case OPVP_CSPACE_STANDARDRGB:
+    case OPVP_CSPACE_DEVICEKRGB:
+    default:
 #if GS_VERSION_MAJOR >= 8
-			return gx_default_rgb_map_rgb_color(dev, prgb);
+	return gx_default_rgb_map_rgb_color(dev, prgb);
 #else
-			return gx_default_rgb_map_rgb_color(dev, r, g, b);
+	return gx_default_rgb_map_rgb_color(dev, r, g, b);
 #endif
-			break;
-	}
+	break;
+    }
 }
 
 /*
  * map color rgb
  */
 static	int
-opvp_map_color_rgb(
-	gx_device		*dev,
-	gx_color_index		color,
-	gx_color_value		prgb[3]
-	)
+opvp_map_color_rgb(gx_device *dev, gx_color_index color,
+    gx_color_value prgb[3])
 {
 #if !(ENABLE_SIMPLE_MODE)
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	int			code = -1;
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    opvp_result_t r = -1;
 #endif
-	OPVP_ColorSpace		cs = OPVP_cspaceStandardRGB;
-	uint			c, m, y, k;
+    opvp_cspace_t cs = OPVP_CSPACE_STANDARDRGB;
+    uint c, m, y, k;
 
 #if ENABLE_SIMPLE_MODE
-	cs = colorSpace;
+    cs = colorSpace;
 #else
-	/* call GetColorSpace */
-	if (pdev->is_open) {
-		if (apiEntry->GetColorSpace)
-		code = apiEntry->GetColorSpace(printerContext, &cs);
-		if (code != OPVP_OK) {
-			if (pdev->color_info.depth > 32) {
-				cs = OPVP_cspaceStandardRGB64;
-			} else if (pdev->color_info.depth > 8 ) {
-				cs = OPVP_cspaceStandardRGB;
-			} else if (pdev->color_info.depth > 1 ) {
-				cs = OPVP_cspaceDeviceGray;
-			} else {
-				cs = OPVP_cspaceBW;
-			}
-		}
+    /* call GetColorSpace */
+    if (pdev->is_open) {
+	if (apiEntry->opvpGetColorSpace) {
+	    r = apiEntry->opvpGetColorSpace(printerContext, &cs);
 	}
+	if (r != OPVP_OK) {
+	    if (pdev->color_info.depth > 32) {
+		cs = OPVP_CSPACE_STANDARDRGB64;
+	    } else if (pdev->color_info.depth > 8 ) {
+		cs = OPVP_CSPACE_STANDARDRGB;
+	    } else if (pdev->color_info.depth > 1 ) {
+		cs = OPVP_CSPACE_DEVICEGRAY;
+	    } else {
+		cs = OPVP_CSPACE_BW;
+	    }
+	}
+    }
 #endif
 
-	switch (cs) {
-		case	OPVP_cspaceStandardRGB64 :
-			/* unsupported */
-			if (sizeof(gx_color_index) >= 6) {
-				prgb[0] = ((long long)color >> 32) & 0xffff;
-				prgb[1] = ((long long)color >> 16) & 0xffff;
-				prgb[2] = color & 0xffff;
-			} else {
-				prgb[0] = gx_color_value_from_byte(
-				              (color >> 16) & 0xff);
-				prgb[1] = gx_color_value_from_byte(
-				              (color >> 8) & 0xff);
-				prgb[2] = gx_color_value_from_byte(
-				              color & 0xff);
-			}
-			break;
-		case	OPVP_cspaceDeviceCMYK :
-		case	OPVP_cspaceDeviceCMY :
-			/* unsupported */
-			c = gx_color_value_from_byte((color >> 24) & 0xff);
-			m = gx_color_value_from_byte((color >> 16) & 0xff);
-			y = gx_color_value_from_byte((color >> 8) & 0xff);
-			if (cs == OPVP_cspaceDeviceCMYK) {
-				k = gx_color_value_from_byte(color & 0xff);
-				c += k; if (c > 255) c = 255;
-				m += k; if (m > 255) m = 255;
-				y += k; if (y > 255) y = 255;
-			}
-			prgb[0] = gx_color_value_from_byte(~c & 0xff);
-			prgb[1] = gx_color_value_from_byte(~m & 0xff);
-			prgb[2] = gx_color_value_from_byte(~y & 0xff);
-			break;
-		case	OPVP_cspaceDeviceGray :
-			return gx_default_gray_map_color_rgb(dev, color, prgb);
-			break;
-		case	OPVP_cspaceBW :
-			return gx_default_b_w_map_color_rgb(dev, color, prgb);
-			break;
-		case	OPVP_cspaceStandardRGB :
-		case	OPVP_cspaceDeviceRGB :
-		default :
-			return gx_default_rgb_map_color_rgb(dev, color, prgb);
-			break;
+    switch (cs) {
+    case OPVP_CSPACE_STANDARDRGB64:
+	/* unsupported */
+	if (sizeof(gx_color_index) >= 6) {
+	    prgb[0] = ((long long)color >> 32) & 0xffff;
+	    prgb[1] = ((long long)color >> 16) & 0xffff;
+	    prgb[2] = color & 0xffff;
+	} else {
+	    prgb[0] = gx_color_value_from_byte((color >> 16) & 0xff);
+	    prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
+	    prgb[2] = gx_color_value_from_byte(color & 0xff);
 	}
+	break;
+    case OPVP_CSPACE_DEVICECMYK:
+    case OPVP_CSPACE_DEVICECMY:
+	/* unsupported */
+	c = gx_color_value_from_byte((color >> 24) & 0xff);
+	m = gx_color_value_from_byte((color >> 16) & 0xff);
+	y = gx_color_value_from_byte((color >> 8) & 0xff);
+	if (cs == OPVP_CSPACE_DEVICECMYK) {
+	    k = gx_color_value_from_byte(color & 0xff);
+	    c += k; if (c > 255) c = 255;
+	    m += k; if (m > 255) m = 255;
+	    y += k; if (y > 255) y = 255;
+	}
+	prgb[0] = gx_color_value_from_byte(~c & 0xff);
+	prgb[1] = gx_color_value_from_byte(~m & 0xff);
+	prgb[2] = gx_color_value_from_byte(~y & 0xff);
+	break;
+    case OPVP_CSPACE_DEVICEGRAY:
+	return gx_default_gray_map_color_rgb(dev, color, prgb);
+	break;
+    case OPVP_CSPACE_BW:
+	return gx_default_b_w_map_color_rgb(dev, color, prgb);
+	break;
+    case OPVP_CSPACE_STANDARDRGB:
+    case OPVP_CSPACE_DEVICEKRGB:
+    default:
+	return gx_default_rgb_map_color_rgb(dev, color, prgb);
+	break;
+    }
 
-	return 0;
+    return 0;
 }
 
 /*
@@ -2033,100 +2673,77 @@
  */
 static	int
 opvp_fill_rectangle(
-	gx_device		*dev,
-	int			x,
-	int			y,
-	int			w,
-	int			h,
-	gx_color_index		color
-	)
+    gx_device *dev,
+    int x,
+    int y,
+    int w,
+    int h,
+    gx_color_index color)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	byte			data[8] = {0xC0, 0, 0, 0, 0xC0, 0, 0, 0};
-	int			code = -1;
-	int			ecode = 0;
-	OPVP_Brush		brush;
-	OPVP_Point		point;
-#if !(ENABLE_SIMPLE_MODE)
-	int			rop = 0;
-#endif
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    byte data[8] = {0xC0, 0, 0, 0, 0xC0, 0, 0, 0};
+    int code = -1;
+    int ecode = 0;
+    opvp_brush_t brush;
+    opvp_point_t point;
 
-	if (vector) {
-		return gdev_vector_fill_rectangle( dev, x, y, w, h, color);
-	}
+    if (vector) {
+	return gdev_vector_fill_rectangle( dev, x, y, w, h, color);
+    }
 
-	/* check page-in */
-	if (opvp_check_in_page(pdev)) return -1;
+    /* check page-in */
+    if (opvp_check_in_page(pdev)) return -1;
 
 #if !(ENABLE_SIMPLE_MODE)
-	/* call SaveGS */
-	if (apiEntry->SaveGS)
-	apiEntry->SaveGS(printerContext);
+    /* call SaveGS */
+    if (apiEntry->opvpSaveGS) {
+	apiEntry->opvpSaveGS(printerContext);
+    }
 #endif
 
-	/* zero-color */
-	opvp_set_brush_color(pdev, gx_no_color_index, &brush);
+    /* one-color */
+    opvp_set_brush_color(pdev, color, &brush);
 
-	/* call SetBgColor */
-	if (apiEntry->SetBgColor)
-	apiEntry->SetBgColor(printerContext, &brush);
+    /* call SetFillColor */
+    if (apiEntry->opvpSetFillColor) {
+	apiEntry->opvpSetFillColor(printerContext, &brush);
+    }
 
-	/* one-color */
-	opvp_set_brush_color(pdev, color, &brush);
+    /* call SetCurrentPoint */
+    OPVP_I2FIX(x, point.x);
+    OPVP_I2FIX(y, point.y);
+    if (apiEntry->opvpSetCurrentPoint) {
+	apiEntry->opvpSetCurrentPoint(printerContext,point.x, point.y);
+    }
 
+    /* draw image */
+    code = opvp_draw_image(pdev,
+			   1,
+			   2, 2,
+			   w, h,
+			   4,
+			   0,
+			   data);
+    if (code) {
+	ecode = code;
+    }
+
+    /* restore fill color */
+    if (vectorFillColor) {
 	/* call SetFillColor */
-	if (apiEntry->SetFillColor)
-	apiEntry->SetFillColor(printerContext, &brush);
-
-#if !(ENABLE_SIMPLE_MODE)
-	/* save ROP */
-	if (apiEntry->GetROP)
-	apiEntry->GetROP(printerContext, &rop);
-#endif
-	/* call SetROP */
-	if (apiEntry->SetROP)
-	apiEntry->SetROP(printerContext, 0xB8);
-
-	/* call SetCurrentPoint */
-	OPVP_i2Fix(x, point.x);
-	OPVP_i2Fix(y, point.y);
-	if (apiEntry->SetCurrentPoint)
-	apiEntry->SetCurrentPoint(printerContext, point.x, point.y);
-
-	/* draw image */
-	code = opvp_draw_image(pdev,
-	                       1,
-	                       2, 2,
-	                       w, h,
-	                       4,
-	                       data);
-	if (code) {
-		ecode = code;
+	if (apiEntry->opvpSetFillColor) {
+	    apiEntry->opvpSetFillColor(printerContext,vectorFillColor);
 	}
+    }
 
 #if !(ENABLE_SIMPLE_MODE)
-	/* restore ROP */
-	if (rop) {
-		/* call SetROP */
-		if (apiEntry->SetROP)
-		apiEntry->SetROP(printerContext, rop);
-	}
+    /* call RestoreGS */
+    if (apiEntry->opvpRestoreGS) {
+	apiEntry->opvpRestoreGS(printerContext);
+    }
 #endif
 
-	/* restore fill color */
-	if (vectorFillColor) {
-		/* call SetFillColor */
-		if (apiEntry->SetFillColor)
-		apiEntry->SetFillColor(printerContext, vectorFillColor);
-	}
-
-#if !(ENABLE_SIMPLE_MODE)
-	/* call RestoreGS */
-	if (apiEntry->RestoreGS)
-	apiEntry->RestoreGS(printerContext);
-#endif
-
-	return ecode;
+    return ecode;
 }
 
 /*
@@ -2134,192 +2751,170 @@
  */
 static	int
 opvp_copy_mono(
-	gx_device		*dev,
-/*const*/
-	byte			*data,
-	int			data_x,
-	int			raster,
-	gx_bitmap_id		id,
-	int			x,
-	int			y,
-	int			w,
-	int			h,
-	gx_color_index		zero,
-	gx_color_index		one
-	)
+    gx_device *dev,
+    const byte *data,
+    int data_x,
+    int raster,
+    gx_bitmap_id id,
+    int x,
+    int y,
+    int w,
+    int h,
+    gx_color_index zero,
+    gx_color_index one)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	int			code = -1;
-	int			ecode = 0;
-	OPVP_Brush		brush;
-	OPVP_Point		point;
-	byte			*buff = data;
-	int			i, j;
-	byte			*d;
-	byte			*s;
-	int			byte_offset = 0;
-	int			bit_offset = 0;
-	int			byte_length = raster;
-	int			bit_shift = 0;
-	int			trans_color = -1;
-	int			adj_raster = raster;
-	int			adj_height = h;
-	char			bit_mask = 0xff;
-	int			loop = 1;
-#if !(ENABLE_SIMPLE_MODE)
-	int			rop = 0;
-#endif
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    int code = -1;
+    int ecode = 0;
+    opvp_brush_t brush;
+    opvp_point_t point;
+    const byte *buff = data;
+    byte *mybuf = NULL;
+    int i, j;
+    byte *d;
+    const byte *s;
+    int byte_offset = 0;
+    int byte_length = raster;
+    int bit_shift = 0;
+    int adj_raster = raster;
+    char bit_mask = 0xff;
+    bool reverse = false;
 
-	/* check page-in */
-	if (opvp_check_in_page(pdev)) return -1;
+    /* check page-in */
+    if (opvp_check_in_page(pdev)) return -1;
 
-	/* data offset */
-	if (data_x) {
-		byte_offset = data_x >> 3;
-		bit_offset = data_x & 0x07;
-		if (bit_offset) bit_mask <<= (8 - bit_offset);
+    /* data offset */
+    if (data_x) {
+	byte_offset = data_x >> 3;
+	bit_shift = data_x & 0x07;
+	if (bit_shift) bit_mask <<= (8 - bit_shift);
 
-		if (zero == gx_no_color_index) {
-			trans_color = 0;
-		} else if (one == gx_no_color_index) {
-			trans_color = 1;
-		} else {
-			trans_color = -1;
-			bit_shift = bit_offset;
-			bit_offset = 0;
-		}
-		byte_length = (((w + (bit_offset - bit_shift)) + 7) >> 3);
-		adj_raster = ((byte_length + 3) >> 2) << 2;
+	byte_length = ((w + 7) >> 3);
+	adj_raster = ((byte_length + 3) >> 2) << 2;
 
-		if (trans_color != -1) {
-			loop = 1;
-			adj_height = h;
+	buff = mybuf = calloc(adj_raster, h);
+	if (!mybuf) {
+	    /* memory error */
+	    return -1;
+	}
+	s = &(data[byte_offset]);
+	d = mybuf;
+	if (bit_shift) {
+	    for (i = 0;i < h; i++, d += adj_raster, s+= raster) {
+		for (j = 0; j < byte_length; j++) {
+		    d[j] = ((s[j] & ~bit_mask) << bit_shift)
+			 | ((s[j + 1] & bit_mask) >> (8 - bit_shift));
 		}
-
-		buff = calloc(adj_raster, h);
-		if (buff) {
-			s = &(data[byte_offset]);
-			d = buff;
-			if (bit_shift) {
-				for (i = 0;i < h; i++, d += adj_raster,
-				                  s+= raster) {
-					for (j = 0; j < byte_length; j++) {
-					d[j] = ((s[j] & ~bit_mask)
-					        << bit_shift)
-					     | ((s[j + 1] & bit_mask)
-					        >> (8 - bit_shift));
-					}
-				}
-			} else {
-				for (i = 0;i < h; i++, d += adj_raster,
-				                  s += raster) {
-					memcpy(d, s, byte_length);
-					if (bit_offset) {
-						if (trans_color == 0) {
-							*d &= ~bit_mask;
-						} else {
-							*d |= bit_mask;
-						}
-					}
-				}
-			}
-			byte_offset = 0;
-		} else {
-			buff = data;
-			loop = y;
-			adj_raster = raster;
-			adj_height = 1;
-			if (bit_shift) bit_offset = bit_shift;
+	    }
+	} else {
+	    for (i = 0;i < h; i++, d += adj_raster, s+= raster) {
+		for (j = 0; j < byte_length; j++) {
+		    d[j] = s[j];
 		}
+	    }
 	}
+	byte_offset = 0;
+    }
 
 #if !(ENABLE_SIMPLE_MODE)
-	/* call SaveGS */
-	if (apiEntry->SaveGS)
-	apiEntry->SaveGS(printerContext);
+    /* call SaveGS */
+    if (apiEntry->opvpSaveGS) {
+	apiEntry->opvpSaveGS(printerContext);
+    }
 #endif
+    if (one == gx_no_color_index) {
+	gx_color_index tc;
 
+	reverse = (!reverse);
+	tc = zero;
+	zero = one;
+	one = tc;
+    }
+
+    if (zero != gx_no_color_index) {
+	/* not mask */
+	/* Set PaintMode */
+	if (apiEntry->opvpSetPaintMode) {
+	    apiEntry->opvpSetPaintMode(printerContext,OPVP_PAINTMODE_OPAQUE);
+	}
 	/* zero-color */
 	opvp_set_brush_color(pdev, zero, &brush);
 
 	/* call SetBgColor */
-	if (apiEntry->SetBgColor)
-	apiEntry->SetBgColor(printerContext, &brush);
+	if (apiEntry->opvpSetBgColor) {
+	    apiEntry->opvpSetBgColor(printerContext, &brush);
+	}
+    }
 
-	/* one-color */
-	opvp_set_brush_color(pdev, one, &brush);
+    /* one-color */
+    opvp_set_brush_color(pdev, one, &brush);
 
-	/* call SetFillColor */
-	if (apiEntry->SetFillColor)
-	apiEntry->SetFillColor(printerContext, &brush);
+    /* call SetFillColor */
+    if (apiEntry->opvpSetFillColor) {
+	apiEntry->opvpSetFillColor(printerContext, &brush);
+    }
 
-#if !(ENABLE_SIMPLE_MODE)
-	/* save ROP */
-	if (apiEntry->GetROP)
-	apiEntry->GetROP(printerContext, &rop);
-#endif
-	/* call SetROP */
-	if (zero == gx_no_color_index) {
-		if (apiEntry->SetROP)
-		apiEntry->SetROP(printerContext, 0xB8);
-	} else {
-		if (apiEntry->SetROP)
-		apiEntry->SetROP(printerContext, 0xCC);
+    if (reverse) {
+	/* 0/1 reverse image */
+	int n = adj_raster*h;
+
+	if (buff == data) {
+	    /* buff was not allocated from this function yet */
+	    /* allocate here */
+	    if ((mybuf = malloc(n)) == 0) return -1;
 	}
+	for (i = 0;i < n;i++) {
+	    mybuf[i] = ~buff[i];
+	}
+	buff = mybuf;
+    }
+    /* call SetCurrentPoint */
+    OPVP_I2FIX(x, point.x);
+    OPVP_I2FIX(y, point.y);
+    if (apiEntry->opvpSetCurrentPoint) {
+	apiEntry->opvpSetCurrentPoint(printerContext,point.x, point.y);
+    }
 
-	/* adjust */
-	x -= bit_offset;
-	w += bit_offset;
-	h = adj_height;
+    /* draw image */
+    code = opvp_draw_image(pdev,
+			   1,
+			   w, h,
+			   w, h,
+			   adj_raster,
+			   1,
+			   &(buff[byte_offset]));
+    if (code) {
+	ecode = code;
+    }
 
-	/* loop */
-	for (i = 0; i < loop; i++, y += h) {
-		/* call SetCurrentPoint */
-		OPVP_i2Fix(x, point.x);
-		OPVP_i2Fix(y, point.y);
-		if (apiEntry->SetCurrentPoint)
-		apiEntry->SetCurrentPoint(printerContext, point.x, point.y);
-
-		/* draw image */
-		code = opvp_draw_image(pdev,
-				       1,
-				       w, h,
-				       w, h,
-				       adj_raster,
-				       &(buff[byte_offset + (adj_raster * i)]));
-		if (code) {
-			ecode = code;
-			break;
-		}
+    if (zero != gx_no_color_index) {
+	/* restore PaintMode */
+	if (apiEntry->opvpSetPaintMode) {
+	    apiEntry->opvpSetPaintMode(printerContext,
+	      OPVP_PAINTMODE_TRANSPARENT);
 	}
-
-#if !(ENABLE_SIMPLE_MODE)
-	/* restore ROP */
-	if (rop) {
-		/* call SetROP */
-		if (apiEntry->SetROP)
-		apiEntry->SetROP(printerContext, rop);
+    }
+    /* restore fill color */
+    if (vectorFillColor) {
+	/* call SetFillColor */
+	if (apiEntry->opvpSetFillColor) {
+	    apiEntry->opvpSetFillColor(printerContext,vectorFillColor);
 	}
-#endif
+    }
 
-	/* restore fill color */
-	if (vectorFillColor) {
-		/* call SetFillColor */
-		if (apiEntry->SetFillColor)
-		apiEntry->SetFillColor(printerContext, vectorFillColor);
-	}
-
 #if !(ENABLE_SIMPLE_MODE)
-	/* call RestoreGS */
-	if (apiEntry->RestoreGS)
-	apiEntry->RestoreGS(printerContext);
+    /* call RestoreGS */
+    if (apiEntry->opvpRestoreGS) {
+	apiEntry->opvpRestoreGS(printerContext);
+    }
 #endif
 
-	if (buff != data) {
-		if (buff) free(buff);
-	}
+    if (buff != data) {
+	/* buff was allocated from this function */
+	if (mybuf) free(mybuf);
+    }
 
-	return ecode;
+    return ecode;
 }
 
 /*
@@ -2327,546 +2922,502 @@
  */
 static	int
 opvp_copy_color(
-	gx_device		*dev,
-/*const*/
-	byte			*data,
-	int			data_x,
-	int			raster,
-	gx_bitmap_id		id,
-	int			x,
-	int			y,
-	int			w,
-	int			h
-	)
+    gx_device *dev,
+    const byte *data,
+    int data_x,
+    int raster,
+    gx_bitmap_id id,
+    int x,
+    int y,
+    int w,
+    int h)
 {
-	gx_device_opvp		*pdev = (gx_device_opvp *)dev;
-	int			code = -1;
-	int			ecode = 0;
-	OPVP_Point		point;
-	byte			*buff = data;
-	int			i;
-	byte			*d;
-	byte			*s;
-	int			byte_length = raster;
-	int			depth;
-	int			pixel;
-	int			adj_raster = raster;
-	int			adj_height = h;
-	int			loop = 1;
-#if !(ENABLE_SIMPLE_MODE)
-	int			j;
-	int			rop = 0;
-#endif
+    gx_device_opvp *pdev = (gx_device_opvp *)dev;
+    int code = -1;
+    int ecode = 0;
+    opvp_point_t point;
+    const byte *buff = data;
+    byte *mybuf = NULL;
+    int i;
+    byte *d;
+    const byte *s;
+    int byte_length = raster;
+    int depth;
+    int pixel;
+    int adj_raster = raster;
 
-	/* check page-in */
-	if (opvp_check_in_page(pdev)) return -1;
+    /* check page-in */
+    if (opvp_check_in_page(pdev)) return -1;
 
-	/* data offset */
-	if (data_x) {
-		depth = pdev->color_info.depth;
-		pixel = (depth + 7) >> 3;
-		byte_length = pixel * w;
-		adj_raster = ((byte_length + 3) >> 2) << 2;
+    /* data offset */
+    if (data_x) {
+	depth = pdev->color_info.depth;
+	pixel = (depth + 7) >> 3;
+	byte_length = pixel * w;
+	adj_raster = ((byte_length + 3) >> 2) << 2;
 
-		buff = malloc(adj_raster * h);
-		if (buff) {
-			s = &(data[data_x]);
-			d = buff;
-			for (i = 0;i < h; i++, d += adj_raster, s += raster) {
-				memcpy(d, s, byte_length);
-			}
-		} else {
-			buff = data;
-			loop = y;
-			adj_height = 1;
-			adj_raster = raster;
-		}
+	buff = mybuf = malloc(adj_raster * h);
+	if (!mybuf) {
+	    /* memory error */
+	    return -1;
 	}
+	s = &(data[data_x*pixel]);
+	d = mybuf;
+	for (i = 0;i < h; i++, d += adj_raster, s += raster) {
+	    memcpy(d, s, byte_length);
+	}
+	data_x = 0;
+    }
 
 #if !(ENABLE_SIMPLE_MODE)
-	/* call SaveGS */
-	if (apiEntry->SaveGS)
-	apiEntry->SaveGS(printerContext);
+    /* call SaveGS */
+    if (apiEntry->opvpSaveGS) {
+	apiEntry->opvpSaveGS(printerContext);
+    }
 #endif
 
-#if !(ENABLE_SIMPLE_MODE)
-	/* save ROP */
-	if (apiEntry->GetROP)
-	apiEntry->GetROP(printerContext, &rop);
-#endif
-	/* call SetROP */
-	if (apiEntry->SetROP)
-	apiEntry->SetROP(printerContext, 0xCC); /* SRCCOPY */
+    /* call SetCurrentPoint */
+    OPVP_I2FIX(x, point.x);
+    OPVP_I2FIX(y, point.y);
+    if (apiEntry->opvpSetCurrentPoint) {
+	apiEntry->opvpSetCurrentPoint(printerContext, point.x, point.y);
+    }
 
-	/* adjust */
-	h = adj_height;
+    /* draw image */
+    code = opvp_draw_image(pdev,
+			   pdev->color_info.depth,
+			   w, h,
+			   w, h,
+			   adj_raster,
+			   0,
+			   &(buff[data_x]));
+    if (code) {
+	ecode = code;
+    }
 
-	/* loop */
-	for (i = 0; i < loop; i++, y += h) {
-		/* call SetCurrentPoint */
-		OPVP_i2Fix(x, point.x);
-		OPVP_i2Fix(y, point.y);
-		if (apiEntry->SetCurrentPoint)
-		apiEntry->SetCurrentPoint(printerContext, point.x, point.y);
 
-		/* draw image */
-		code = opvp_draw_image(pdev,
-				       pdev->color_info.depth,
-				       w, h,
-				       w, h,
-					   adj_raster,
-				       &(buff[data_x + (adj_raster * i)]));
-		if (code) {
-			ecode = code;
-			break;
-		}
-	}
-
 #if !(ENABLE_SIMPLE_MODE)
-	/* restore ROP */
-	if (rop) {
-		/* call SetROP */
-		if (apiEntry->SetROP)
-		apiEntry->SetROP(printerContext, rop);
-	}
+    /* call RestoreGS */
+    if (apiEntry->opvpRestoreGS) {
+	apiEntry->opvpRestoreGS(printerContext);
+    }
 #endif
 
-#if !(ENABLE_SIMPLE_MODE)
-	/* call RestoreGS */
-	if (apiEntry->RestoreGS)
-	apiEntry->RestoreGS(printerContext);
-#endif
+    if (buff != data) {
+	/* buff was allocated from this function */
+	if (mybuf) free(mybuf);
+    }
 
-	if (buff != data) {
-		if (buff) free(buff);
-	}
-
-	return ecode;
+    return ecode;
 }
 
 /*
  * get params
  */
 static	int
-_get_params(
-	gs_param_list		*plist
-	)
+_get_params(gs_param_list *plist)
 {
-	int			code;
-	int			ecode = 0;
-	gs_param_name		pname;
-	gs_param_string		vdps;
-	gs_param_string		pmps;
-	gs_param_string		jips;
-	gs_param_string		dips;
-	gs_param_string		fips;
-	gs_param_string		mlps;
-	gs_param_string		mtps;
-	gs_param_string		mrps;
-	gs_param_string		mbps;
-	gs_param_string		zmps;
-	char			buff[OPVP_BUFF_SIZE];
+    int code;
+    int ecode = 0;
+    gs_param_name pname;
+    gs_param_string vdps;
+    gs_param_string pmps;
+    gs_param_string jips;
+    gs_param_string dips;
+    gs_param_string fips;
+    gs_param_string mlps;
+    gs_param_string mtps;
+    gs_param_string mrps;
+    gs_param_string mbps;
+    gs_param_string zmps;
+    char buff[OPVP_BUFF_SIZE];
 
-	/* get params */
+    /* get params */
 
-	/* vector driver name */
-	pname = "Driver";
-	vdps.data = vectorDriver;
-	vdps.size = (vectorDriver ? strlen(vectorDriver) + 1 : 0);
-	vdps.persistent = false;
-	code = param_write_string(plist, pname, &vdps);
-	if (code) ecode = code;
+    /* vector driver name */
+    pname = "Driver";
+    vdps.data = (byte *)vectorDriver;
+    vdps.size = (vectorDriver ? strlen(vectorDriver) + 1 : 0);
+    vdps.persistent = false;
+    code = param_write_string(plist, pname, &vdps);
+    if (code) ecode = code;
 
-	/* printer model name */
-	pname = "Model";
-	pmps.data = printerModel;
-	pmps.size = (printerModel ? strlen(printerModel) + 1 : 0);
-	pmps.persistent = false;
-	code = param_write_string(plist, pname, &pmps);
-	if (code) ecode = code;
+    /* printer model name */
+    pname = "Model";
+    pmps.data = (byte *)printerModel;
+    pmps.size = (printerModel ? strlen(printerModel) + 1 : 0);
+    pmps.persistent = false;
+    code = param_write_string(plist, pname, &pmps);
+    if (code) ecode = code;
 
-	/* job info */
-	pname = "JobInfo";
-	jips.data = jobInfo;
-	jips.size = (jobInfo ? strlen(jobInfo) + 1 : 0);
-	jips.persistent = false;
-	code = param_write_string(plist, pname, &jips);
-	if (code) ecode = code;
+    /* job info */
+    pname = "JobInfo";
+    jips.data = (byte *)jobInfo;
+    jips.size = (jobInfo ? strlen(jobInfo) + 1 : 0);
+    jips.persistent = false;
+    code = param_write_string(plist, pname, &jips);
+    if (code) ecode = code;
 
-	/* doc info */
-	pname = "DocInfo";
-	dips.data = docInfo;
-	dips.size = (docInfo ? strlen(docInfo) + 1 : 0);
-	dips.persistent = false;
-	code = param_write_string(plist, pname, &dips);
-	if (code) ecode = code;
+    /* doc info */
+    pname = "DocInfo";
+    dips.data = (byte *)docInfo;
+    dips.size = (docInfo ? strlen(docInfo) + 1 : 0);
+    dips.persistent = false;
+    code = param_write_string(plist, pname, &dips);
+    if (code) ecode = code;
 
-	/* fast image support */
-	switch (FastImageMode) {
-		case	FastImageNoCTM :
-			opvp_alloc_string(&fastImage, "NoCTM");
-			break;
-		case	FastImageNoRotate :
-			opvp_alloc_string(&fastImage, "NoRotateCTM");
-			break;
-		case	FastImageRightAngle :
-			opvp_alloc_string(&fastImage, "RightAngleCTM");
-			break;
-		case	FastImageReverseAngle :
-			opvp_alloc_string(&fastImage, "ReverseAngleCTM");
-			break;
-		case	FastImageAll :
-			opvp_alloc_string(&fastImage, "All");
-			break;
-		case	FastImageDisable :
-		default :
-			opvp_alloc_string(&fastImage, NULL);
-			break;
-	}
-	pname = "FastImage";
-	fips.data = fastImage;
-	fips.size = (fastImage ? strlen(fastImage) + 1 : 0);
-	fips.persistent = false;
-	code = param_write_string(plist, pname, &fips);
-	if (code) ecode = code;
-	
-	/* margins */
-	memset((void*)buff, 0, OPVP_BUFF_SIZE);
-	pname = "MarginLeft";
-	snprintf(buff, OPVP_BUFF_SIZE - 1, "%f",margins[0]);
-	mlps.data = buff;
-	mlps.size = strlen(buff) + 1;
-	mlps.persistent = false;
-	code = param_write_string(plist, pname, &mlps);
-	if (code) ecode = code;
-	pname = "MarginTop";
-	snprintf(buff, OPVP_BUFF_SIZE - 1, "%f",margins[3]);
-	mtps.data = buff;
-	mtps.size = strlen(buff) + 1;
-	mtps.persistent = false;
-	code = param_write_string(plist, pname, &mtps);
-	if (code) ecode = code;
-	pname = "MarginRight";
-	snprintf(buff, OPVP_BUFF_SIZE - 1, "%f",margins[2]);
-	mrps.data = buff;
-	mrps.size = strlen(buff) + 1;
-	mrps.persistent = false;
-	code = param_write_string(plist, pname, &mrps);
-	if (code) ecode = code;
-	pname = "MarginBottom";
-	snprintf(buff, OPVP_BUFF_SIZE - 1, "%f",margins[1]);
-	mbps.data = buff;
-	mbps.size = strlen(buff) + 1;
-	mbps.persistent = false;
-	code = param_write_string(plist, pname, &mbps);
-	if (code) ecode = code;
+    /* fast image support */
+    switch (FastImageMode) {
+    case FastImageNoCTM:
+	opvp_alloc_string(&fastImage, "NoCTM");
+	break;
+    case FastImageNoRotate:
+	opvp_alloc_string(&fastImage, "NoRotateCTM");
+	break;
+    case FastImageRightAngle:
+	opvp_alloc_string(&fastImage, "RightAngleCTM");
+	break;
+    case FastImageReverseAngle:
+	opvp_alloc_string(&fastImage, "ReverseAngleCTM");
+	break;
+    case FastImageAll:
+	opvp_alloc_string(&fastImage, "All");
+	break;
+    case FastImageDisable:
+    default:
+	opvp_alloc_string(&fastImage, NULL);
+	break;
+    }
+    pname = "FastImage";
+    fips.data = (byte *)fastImage;
+    fips.size = (fastImage ? strlen(fastImage) + 1 : 0);
+    fips.persistent = false;
+    code = param_write_string(plist, pname, &fips);
+    if (code) ecode = code;
+    
+    /* margins */
+    memset((