1 /* Copyright (C) 1998, 1999 Norihito Ohmori.
2 
3    Ghostscript printer driver
4    for Canon LBP (LIPS IV)
5 
6    This software is distributed in the hope that it will be useful, but
7    WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
8    to anyone for the consequences of using it or for whether it serves any
9    particular purpose or works at all, unless he says so in writing.  Refer
10    to the GNU General Public License for full details.
11 
12    Everyone is granted permission to copy, modify and redistribute
13    this software, but only under the conditions described in the GNU
14    General Public License.  A copy of this license is supposed to have been
15    given to you along with this software so you can know your rights and
16    responsibilities.  It should be in a file named COPYING.  Among other
17    things, the copyright notice and this notice must be preserved on all
18    copies.
19  */
20 
21 /*$Id: gdevl4v.c $ */
22 /* Vector Version of LIPS driver */
23 
24 /*
25 
26    Vector driver �� Ghostscript 5.0 ���鿷���˲ä�ä��ɥ饤�ФǤ���
27    ��äƻ��ͤ����ꤷ�Ƥ��ޤ���Ghostscript 5.10 �� Ghostscript 5.50 �Ǥ�
28    Hi-level bitmap imaging �λ��ͤ��Ѥ�äƤ��ޤ���
29    Ghostscript 6.0 �ǤϹ��� text_begin �Ȥ��� API ���ɲä����褦�Ǥ���
30 
31 
32    ��Ghostscript 5.10/5.50 �ΥХ��ˤĤ���
33 
34    Ghostscript 5.10/5.50 �� Vector driver �� setlinewidth �ؿ��ˤ�
35    �Х�������ޤ������襹�����뤬�ѹ������ˤ������ä������������ѹ�����
36    �ʤ���Фʤ�ޤ�����Ghostscript 5.10/5.50 �Ǥϥ���������θ����Τ�
37    ˺��Ƥ��ޤ���(�Х�����2��ۤ����ä��Τ������...)
38    ���Υɥ饤�ФϤ��ΥХ�������뤿��˥��������ʬ�ǽ������Ƥ��ޤ���
39 
40    Ghostscript 5.10 ����������ѥ��� Ghostscript 5.50 ����������ѥ�����
41    ���˸�Ψ�ΰ�����Τˤʤ뤳�Ȥ�����ޤ���LIPS IV �ν����Ǥ���³���Ķ����
42    ���Ȥ⤢��ޤ�������Ψ�ΰ����ѥ���®�٤��㲼�ˤ�Ĥʤ���Τ� Ghostscript
43    5.50 ��Ȥä��������Υɥ饤�ФǤϽ���®�٤�®���ʤ�ޤ���
44 
45    �ޤ� Ghostscript 5.10 �Ǥ�
46    fill_trapezoid��fill_parallelogram��fill_triangle
47    �δؿ��ε�ư���Ѥˤʤ뤳�Ȥ����ä��ΤǤ����ϻȤäƤ��ޤ���
48 
49 
50    �� LIPS IV �ΥХ��ˤĤ���
51 
52    ���Υɥ饤�Фϳ�ȯ���ȯ���������� LIPS IV �ΥХ�������Ƥ��ޤ���
53    1. 1 dot �Υ��᡼�����ѷ������Ȥ��˺�ɸ�η׻�������
54    2. �����ʥ��᡼�������褹��������������ʤ�
55    3. ����åԥ�̿��ȥѥ�������åԥ�̿�᤬���줾����Ω��Ư���Ƥ��ޤ���
56 
57    1. �� 1 dot �Υ��᡼�������ˤ��Ʋ����ޤ�����
58    2. �ϥ��᡼���ΰ����̿���ʬ�����ꤹ�뤳�Ȥˤ������ޤ�����
59    3. �ϥ���åԥ�̿���Ȥ�ʤ����Ȥˤ��Ʋ����ޤ�����
60 
61 
62    �� LIPS IV �λ��ͤˤĤ���
63 
64    1. ñ�����᡼�������顼����̿��ϥ��졼�������륤�᡼�����Ф��Ƥ�
65    Ư���Ƥ��ޤ��ޤ���
66    2. LIPS IV �Ǥϥ��졼��������ο�ɽ���� PostScript �ȵդǤ���
67    3. LIPS IV �ˤϥ��᡼���ΥӥåȤ�ȿž�����륳�ޥ�ɤϤ���ޤ���
68    4. LIPS IV �ˤ� CMYK �Υ��顼���ڡ����Ϥ���ޤ���
69 
70  */
71 
72 #include "string.h"
73 #include "math_.h"
74 #include "gx.h"
75 #include "gserrors.h"
76 #include "gsmatrix.h"
77 #include "gsparam.h"
78 #include "gxdevice.h"
79 #include "gscspace.h"
80 #include "gsutil.h"
81 #include "gdevvec.h"
82 #if 0
83 #include "gdevpstr.h"
84 #endif
85 #include "ghost.h"
86 #include "gzstate.h"
87 #include "imemory.h"
88 #include "igstate.h"
89 #include "gdevlips.h"
90 
91 /* ---------------- Device definition ---------------- */
92 
93 /* Device procedures */
94 private dev_proc_open_device(lips4v_open);
95 private dev_proc_output_page(lips4v_output_page);
96 private dev_proc_close_device(lips4v_close);
97 private dev_proc_copy_mono(lips4v_copy_mono);
98 private dev_proc_copy_color(lips4v_copy_color);
99 private dev_proc_put_params(lips4v_put_params);
100 private dev_proc_get_params(lips4v_get_params);
101 private dev_proc_fill_mask(lips4v_fill_mask);
102 private dev_proc_begin_image(lips4v_begin_image);
103 
104 
105 #define X_DPI 600
106 #define Y_DPI 600
107 
108 typedef struct gx_device_lips4v_s
109 {
110     gx_device_vector_common;
111     lips_params_common;
112     lips4_params_common;
113     bool first_page;
114     bool ManualFeed;
115     bool Duplex;
116     int Duplex_set;
117     bool Tumble;
118     bool OneBitMask;		/* for LIPS Bug */
119     int ncomp;
120     int MaskReverse;
121     int MaskState;
122     bool TextMode;
123     int prev_x;
124     int prev_y;
125     gx_color_index prev_color;
126     gx_color_index current_color;
127     int linecap;
128     /* for Font Downloading */
129 #define max_cached_chars 256	/* 128 * n */
130     bool FontDL;
131     int current_font;
132     int count;
133     gx_bitmap_id id_table[max_cached_chars + 1];
134     gx_bitmap_id id_cache[max_cached_chars + 1];
135 }
136 gx_device_lips4v;
137 
138 gs_public_st_suffix_add0_final(st_device_lips4v, gx_device_lips4v,
139 			       "gx_device_lips4v", device_lips4v_enum_ptrs,
140 			       device_lips4v_reloc_ptrs, gx_device_finalize,
141 			       st_device_vector);
142 
143 #define lips_device_full_body(dtype, pprocs, dname, stype, w, h, xdpi, ydpi, ncomp, depth, mg, mc, dg, dc, lm, bm, rm, tm)\
144         std_device_part1_(dtype, pprocs, dname, stype, open_init_closed),\
145         dci_values(ncomp, depth, mg, mc, dg, dc),\
146         std_device_part2_(w, h, xdpi, ydpi),\
147         offset_margin_values(-lm * xdpi, -tm * ydpi, lm * 72.0, bm * 72.0, rm * 72.0, tm * 72.0),\
148         std_device_part3_()
149 
150 #define lips4v_device_body\
151   lips_device_full_body(gx_device_lips4v, 0, "lips4v",\
152 			&st_device_lips4v,\
153 			DEFAULT_WIDTH_10THS * X_DPI / 10,\
154 			DEFAULT_HEIGHT_10THS * Y_DPI / 10,\
155 			X_DPI, Y_DPI,\
156 			1, 8, 1000, 1000, 5, 2,\
157 			LIPS4_LEFT_MARGIN_DEFAULT,\
158 			LIPS4_BOTTOM_MARGIN_DEFAULT,\
159 			LIPS4_RIGHT_MARGIN_DEFAULT,\
160 			LIPS4_TOP_MARGIN_DEFAULT)
161 
162 
163 #define lips4v_procs\
164 	{	lips4v_open,\
165 		gx_upright_get_initial_matrix,\
166 		NULL,			/* sync_output */\
167 		lips4v_output_page,\
168 		lips4v_close,\
169 		gx_default_gray_map_rgb_color,\
170 		gx_default_gray_map_color_rgb,\
171 		gdev_vector_fill_rectangle,\
172 		NULL,			/* tile_rectangle */\
173 		lips4v_copy_mono,\
174 		lips4v_copy_color,\
175 		NULL,			/* draw_line */\
176 		NULL,			/* get_bits */\
177 		lips4v_get_params,\
178 		lips4v_put_params,\
179 		NULL,			/* map_cmyk_color */\
180 		NULL,			/* get_xfont_procs */\
181 		NULL,			/* get_xfont_device */\
182 		NULL,			/* map_rgb_alpha_color */\
183 		gx_page_device_get_page_device,\
184 		NULL,			/* get_alpha_bits */\
185 		NULL,			/* copy_alpha */\
186 		NULL,			/* get_band */\
187 		NULL,			/* copy_rop */\
188 		gdev_vector_fill_path,\
189 		gdev_vector_stroke_path,\
190 		lips4v_fill_mask,\
191 		gdev_vector_fill_trapezoid,\
192 		gdev_vector_fill_parallelogram,\
193 		gdev_vector_fill_triangle,\
194 		NULL /****** WRONG ******/,	/* draw_thin_line */\
195 		lips4v_begin_image,\
196 		NULL,\
197 		NULL,\
198 		NULL,			/* strip_tile_rectangle */\
199 		NULL/******strip_copy_rop******/\
200 	}
201 
202 gx_device_lips4v far_data gs_lips4v_device = {
203     lips4v_device_body,
204     lips4v_procs,
205     vector_initial_values,
206     LIPS_CASSETFEED_DEFAULT,
207     LIPS_USERNAME_DEFAULT,
208     FALSE /* PJL */ ,
209     0 /* toner_density */ ,
210     FALSE /* toner_saving */ ,
211     0 /* toner_saving_set */ ,
212     0, 0, 0, 0, -1,
213     0 /* prev_duplex_mode */ ,
214     LIPS_NUP_DEFAULT,
215     LIPS_FACEUP_DEFAULT,
216     LIPS_MEDIATYPE_DEFAULT,
217     0 /* first_page */ ,
218     LIPS_MANUALFEED_DEFAULT,
219     0 /* Duplex */ , 0 /* Duplex_set */ , LIPS_TUMBLE_DEFAULT,
220     0 /* OneBitMask */ ,
221     0 /* ncomp */ , -1 /* MaskReverse */ , 0 /* MaskState */ ,
222     0 /* TextMode */ , 0 /* prev_x */ , 0 /* prev_y */ ,
223     0 /* prev_color */ , 0 /* current_color */ ,
224     0 /* linecap */ ,
225     0 /* FontDL */ ,
226     -1 /* current_font */ ,
227     0 /* count */ ,
228     {},
229     {}
230 };
231 
232 /* Vector device implementation */
233 #if GS_VERSION_MAJOR >= 8
234 private int lips4v_beginpage(gx_device_vector * vdev);
235 private int lips4v_setfillcolor(gx_device_vector * vdev,
236 				   const gx_drawing_color * pdc);
237 private int lips4v_setstrokecolor(gx_device_vector * vdev,
238 				     const gx_drawing_color * pdc);
239 private int lips4v_setdash(gx_device_vector * vdev, const float *pattern,
240 			      uint count, floatp offset);
241 private int lips4v_setflat(gx_device_vector * vdev, floatp flatness);
242 private int
243 lips4v_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
244 		 gs_logical_operation_t diff);
245 private int
246 
247 lips4v_beginpath(gx_device_vector * vdev, gx_path_type_t type);
248 private int
249 lips4v_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
250 	       floatp y, gx_path_type_t type);
251 private int
252 lips4v_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
253 	       floatp y, gx_path_type_t type);
254 private int
255 lips4v_curveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x1,
256 		floatp y1, floatp x2, floatp y2, floatp x3, floatp y3,
257 		gx_path_type_t type);
258 lips4v_closepath(gx_device_vector * vdev, floatp x, floatp y, floatp x_start,
259 		  floatp y_start, gx_path_type_t type);
260 
261 private int lips4v_endpath(gx_device_vector * vdev, gx_path_type_t type);
262 #else
263 private int lips4v_beginpage(P1(gx_device_vector * vdev));
264 private int lips4v_setfillcolor(gx_device_vector * vdev,
265 				   const gx_drawing_color * pdc);
266 private int lips4v_setstrokecolor(gx_device_vector * vdev,
267 				     const gx_drawing_color * pdc);
268 private int lips4v_setdash(gx_device_vector * vdev, const float *pattern,
269 			      uint count, floatp offset);
270 private int lips4v_setflat(gx_device_vector * vdev, floatp flatness);
271 private int
272 lips4v_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
273 		 gs_logical_operation_t diff);
274 private int
275 
276 lips4v_beginpath(gx_device_vector * vdev, gx_path_type_t type);
277 private int
278 lips4v_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
279 	       floatp y, gx_path_type_t type);
280 private int
281 lips4v_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
282 	       floatp y, gx_path_type_t type);
283 private int
284 lips4v_curveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x1,
285 		floatp y1, floatp x2, floatp y2, floatp x3, floatp y3,
286 		gx_path_type_t type);
287 private int
288 lips4v_closepath(gx_device_vector * vdev, floatp x, floatp y, floatp x_start,
289 		  floatp y_start, gx_path_type_t type);
290 
291 private int lips4v_endpath(gx_device_vector * vdev, gx_path_type_t type);
292 #endif
293 private int lips4v_setlinewidth(gx_device_vector * vdev, floatp width);
294 private int lips4v_setlinecap(gx_device_vector * vdev, gs_line_cap cap);
295 private int lips4v_setlinejoin(gx_device_vector * vdev, gs_line_join join);
296 private int lips4v_setmiterlimit(gx_device_vector * vdev, floatp limit);
297 private const gx_device_vector_procs lips4v_vector_procs = {
298     /* Page management */
299     lips4v_beginpage,
300     /* Imager state */
301     lips4v_setlinewidth,
302     lips4v_setlinecap,
303     lips4v_setlinejoin,
304     lips4v_setmiterlimit,
305     lips4v_setdash,
306     lips4v_setflat,
307     lips4v_setlogop,
308     /* Other state */
309     lips4v_setfillcolor,	/* fill & stroke colors are the same */
310     lips4v_setstrokecolor,
311     /* Paths */
312     gdev_vector_dopath,
313     gdev_vector_dorect,
314     lips4v_beginpath,
315     lips4v_moveto,
316     lips4v_lineto,
317     lips4v_curveto,
318     lips4v_closepath,
319     lips4v_endpath
320 };
321 
322 /* ---------------- File header ---------------- */
323 
324 private const char *l4v_file_header1 =
325 
326     "\033%-12345X@PJL CJLMODE\n@PJL JOB\n\033%-12345X@PJL CJLMODE\n";
327 private const char *l4v_file_header2 = "@PJL SET LPARM : LIPS SW2 = ON\n";
328 private const char *l4v_file_header3 = "@PJL ENTER LANGUAGE = LIPS\n";
329 private const char *l4v_file_header4 = "\033%@\033P41;";
330 
331 
332 private const char *l4vmono_file_header =
333 
334     ";1J" L4VMONO_STRING LIPS_VERSION "\033\\\033[0\"p\033<";
335 
336 private const char *l4vcolor_file_header =
337 
338     ";1J" L4VCOLOR_STRING LIPS_VERSION "\033\\\033[1\"p\033<";
339 
340 /* ---------------- Utilities ---------------- */
341 
342 private void
lips_param(int param,char * c)343 lips_param(int param, char *c)
344 {
345     int i, j;
346     bool bSign;
347 
348     bSign = TRUE;
349     if (param < 0) {
350 	bSign = FALSE;
351 	param = -param;
352     }
353     if (param < 16)
354 	i = 1;
355     else if (param < 1024)
356 	i = 2;
357     else if (param < 65536)
358 	i = 3;
359     else
360 	i = 4;
361 
362     c[i] = '\0';
363     c[i - 1] = (param & 0x0f) | 0x20 | (bSign ? 0x10 : 0x00);
364     param >>= 4;
365     for (j = i - 2; j >= 0; j--) {
366 	c[j] = (param & 0x3f) | 0x40;
367 	param >>= 6;
368     }
369 }
370 
371 private void
sput_lips_int(stream * s,int param)372 sput_lips_int(stream * s, int param)
373 {
374     int i;
375     char c[5];
376 
377     lips_param(param, c);
378     for (i = 0; i < strlen(c); i++)
379 	sputc(s, c[i]);
380 }
381 
382 /* Put a string on a stream.
383    This function is copy of `pputs' in gdevpstr.c */
384 private int
lputs(stream * s,const char * str)385 lputs(stream * s, const char *str)
386 {
387     uint len = strlen(str);
388     uint used;
389     int status = sputs(s, (const byte *)str, len, &used);
390 
391     return (status >= 0 && used == len ? 0 : EOF);
392 }
393 
394 /* Write a string on a stream. */
395 private void
put_bytes(stream * s,const byte * data,uint count)396 put_bytes(stream * s, const byte * data, uint count)
397 {
398     uint used;
399 
400     sputs(s, data, count, &used);
401 }
402 
403 /* for Font Downloading */
404 private void
put_int(stream * s,uint number)405 put_int(stream * s, uint number)
406 {
407     sputc(s, number >> 8);
408     sputc(s, number & 0xff);
409 }
410 
411 private int
lips4v_range_check(gx_device * dev)412 lips4v_range_check(gx_device * dev)
413 {
414     int width = dev->MediaSize[0];
415     int height = dev->MediaSize[1];
416     int xdpi = dev->x_pixels_per_inch;
417     int ydpi = dev->y_pixels_per_inch;
418 
419     /* Paper Size Check */
420     if (width <= height) {	/* portrait */
421 	if ((width < LIPS_WIDTH_MIN || width > LIPS_WIDTH_MAX ||
422 	     height < LIPS_HEIGHT_MIN || height > LIPS_HEIGHT_MAX) &&
423 	    !(width == LIPS_LEDGER_WIDTH && height == LIPS_LEDGER_HEIGHT))
424 	    return_error(gs_error_rangecheck);
425     } else {			/* landscape */
426 	if ((width < LIPS_HEIGHT_MIN || width > LIPS_HEIGHT_MAX ||
427 	     height < LIPS_WIDTH_MIN || height > LIPS_WIDTH_MAX) &&
428 	    !(width == LIPS_LEDGER_HEIGHT && height == LIPS_LEDGER_WIDTH))
429 	    return_error(gs_error_rangecheck);
430     }
431 
432     /* Resolution Check */
433     if (xdpi != ydpi)
434 	return_error(gs_error_rangecheck);
435     else {
436 	if ((xdpi < LIPS_DPI_MIN || xdpi > LIPS4_DPI_MAX)
437 	    && xdpi != LIPS4_DPI_SUPERFINE) return_error(gs_error_rangecheck);
438     }
439 
440     return 0;
441 }
442 
443 
444 private void
lips4v_set_cap(gx_device * dev,int x,int y)445 lips4v_set_cap(gx_device * dev, int x, int y)
446 {
447 
448     char cap[15];
449     stream *s = gdev_vector_stream((gx_device_vector *) dev);
450     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
451     int dx = x - pdev->prev_x;
452     int dy = y - pdev->prev_y;
453 
454 
455     if (dx > 0) {
456 	sprintf(cap, "%c%da", LIPS_CSI, dx);
457 	lputs(s, cap);
458     } else if (dx < 0) {
459 	sprintf(cap, "%c%dj", LIPS_CSI, -dx);
460 	lputs(s, cap);
461     }
462     if (dy > 0) {
463 	sprintf(cap, "%c%dk", LIPS_CSI, dy);
464 	lputs(s, cap);
465     } else if (dy < 0) {
466 	sprintf(cap, "%c%de", LIPS_CSI, -dy);
467 	lputs(s, cap);
468     }
469     pdev->prev_x = x;
470     pdev->prev_y = y;
471 }
472 
473 #define POINT 18
474 
475 /* Font Downloading Routine */
476 private int
lips4v_copy_text_char(gx_device * dev,const byte * data,int raster,gx_bitmap_id id,int x,int y,int w,int h)477 lips4v_copy_text_char(gx_device * dev, const byte * data,
478 		      int raster, gx_bitmap_id id, int x, int y, int w, int h)
479 {
480     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
481     stream *s = gdev_vector_stream((gx_device_vector *) dev);
482     uint width_bytes = (w + 7) >> 3;
483     uint size = width_bytes * h;
484     int i, j;
485     uint ccode;
486     char cset_sub[9], cset[64], cset_number[8], text_color[15];
487     int cell_length = (POINT * (int)dev->x_pixels_per_inch) / 72;
488     bool download = TRUE;
489 
490     if (w > cell_length || h > cell_length || !pdev->FontDL)
491 	return -1;
492 
493     for (j = pdev->count - 1; j >= 0; j--) {
494 	if (pdev->id_table[j] == id)
495 	    /* font is found */
496 	{
497 	    download = FALSE;
498 	    ccode = j;
499 	    for (i = j; i < pdev->count - 1; i++) {
500 		pdev->id_cache[i] = pdev->id_cache[i + 1];
501 	    }
502 	    pdev->id_cache[pdev->count - 1] = id;
503 	    break;
504 	}
505     }
506 
507     if (download) {
508 	if (pdev->count > max_cached_chars - 1) {
509 	    gx_bitmap_id tmpid = pdev->id_cache[0];
510 
511 	    for (j = pdev->count - 1; j >= 0; j--) {
512 		if (pdev->id_table[j] == tmpid) {
513 		    ccode = j;
514 		    break;
515 		}
516 	    }
517 	    for (i = j; i < pdev->count - 1; i++) {
518 		pdev->id_cache[i] = pdev->id_cache[i + 1];
519 	    }
520 	    pdev->id_cache[pdev->count - 1] = tmpid;
521 	} else {
522 	    ccode = pdev->count;
523 	    pdev->id_cache[pdev->count] = id;
524 	}
525     }
526     if (pdev->TextMode == FALSE) {
527 	/* Text mode */
528 	lputs(s, "}p");
529 	sput_lips_int(s, x);
530 	sput_lips_int(s, y);
531 	sputc(s, LIPS_IS2);
532 	pdev->TextMode = TRUE;
533 	pdev->prev_x = x;
534 	pdev->prev_y = y;
535     } else
536 	lips4v_set_cap(dev, x, y);
537 
538     if (download) {
539 	if (ccode % 128 == 0 && ccode == pdev->count) {
540 	    /* ʸ�����å���Ͽ���̿�� */
541 	    sprintf(cset_sub, "%c%dx%c", LIPS_DCS, ccode / 128, LIPS_ST);
542 	    lputs(s, cset_sub);
543 	    /* ʸ�����å���Ͽ̿�� */
544 	    sprintf(cset,
545 		    "%c%d;1;0;0;3840;8;400;100;0;0;200;%d;%d;0;0;;;;;%d.p",
546 		    LIPS_CSI,
547 		    size + 9, cell_length,	/* Cell Width */
548 		    cell_length,	/* Cell Height */
549 		    (int)dev->x_pixels_per_inch);
550 	    lputs(s, cset);
551 	} else {
552 	    /* 1ʸ����Ͽ̿�� */
553 	    sprintf(cset,
554 		    "%c%d;%d;8;%d.q", LIPS_CSI,
555 		    size + 9, ccode / 128, (int)dev->x_pixels_per_inch);
556 	    lputs(s, cset);
557 	}
558 
559 	/* �桼��ʸ����Ͽ�ǡ��� �Υإå� */
560 	sputc(s, ccode % 128);	/* charcter code */
561 	put_int(s, w);
562 	put_int(s, 0);
563 	put_int(s, h);
564 	put_int(s, 0);
565 	for (i = h - 1; i >= 0; --i) {
566 	    put_bytes(s, data + i * raster, width_bytes);
567 	}
568     }
569     /* ʸ�����åȡ����������ֹ�����̿��2 */
570     if (download) {
571 	if (pdev->current_font != ccode / 128) {
572 	    sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128);
573 	    lputs(s, cset_number);
574 	    pdev->current_font = ccode / 128;
575 	}
576     } else {
577 	if (pdev->current_font != ccode / 128) {
578 	    sprintf(cset_number, "%c%d%%v", LIPS_CSI, ccode / 128);
579 	    lputs(s, cset_number);
580 	    pdev->current_font = ccode / 128;
581 	}
582     }
583 
584     /* ���顼 */
585     if (pdev->current_color != pdev->prev_color) {
586 	if (pdev->color_info.depth == 8) {
587 	    sputc(s, LIPS_CSI);
588 	    lputs(s, "?10;2;");
589 	    sprintf(text_color, "%d",
590 		    (int)(pdev->color_info.max_gray - pdev->current_color));
591 	} else {
592 	    int r = (pdev->current_color >> 16) * 1000.0 / 255.0;
593 	    int g = ((pdev->current_color >> 8) & 0xff) * 1000.0 / 255.0;
594 	    int b = (pdev->current_color & 0xff) * 1000.0 / 255.0;
595 
596 	    sputc(s, LIPS_CSI);
597 	    lputs(s, "?10;;");
598 	    sprintf(text_color, "%d;%d;%d", r, g, b);
599 	}
600 	lputs(s, text_color);
601 	lputs(s, "%p");
602 	pdev->prev_color = pdev->current_color;
603     }
604     /* ����ʸ������̿�� */
605     if (ccode % 128 == 0x00 ||
606 	(ccode % 128 >= 0x07 && ccode % 128 <= 0x0F) ||
607 	ccode % 128 == 0x1B) {
608 	sputc(s, LIPS_CSI);
609 	lputs(s, "1.v");
610     }
611     sputc(s, ccode % 128);
612 
613     if (download) {
614 	pdev->id_table[ccode] = id;
615 	if (pdev->count < max_cached_chars - 1)
616 	    pdev->count++;
617     }
618     return 0;
619 }
620 
621 private void
reverse_buffer(byte * buf,int Len)622 reverse_buffer(byte * buf, int Len)
623 {
624     int i;
625 
626     for (i = 0; i < Len; i++)
627 	*(buf + i) = ~*(buf + i);
628 }
629 
630 private void
lips4v_write_image_data(gx_device_vector * vdev,byte * buf,int tbyte,int reverse)631 lips4v_write_image_data(gx_device_vector * vdev, byte * buf, int tbyte,
632 			int reverse)
633 {
634     stream *s = gdev_vector_stream(vdev);
635     byte *cbuf = gs_alloc_bytes(vdev->memory, tbyte * 3 / 2,
636 				"lips4v_write_image_data(cbuf)");
637     byte *cbuf_rle = gs_alloc_bytes(vdev->memory, tbyte * 3,
638 				    "lips4v_write_image_data(cbuf_rle)");
639     int Len, Len_rle;
640 
641     if (reverse)
642 	reverse_buffer(buf, tbyte);
643 
644 
645     Len = lips_packbits_encode(buf, cbuf, tbyte);
646     Len_rle = lips_rle_encode(buf, cbuf_rle, tbyte);
647 
648     if (Len > tbyte && Len_rle > tbyte) {
649 	/* Not compress */
650 	lputs(s, "0");
651 	sput_lips_int(s, tbyte);
652 	sputc(s, LIPS_IS2);
653 
654 	put_bytes(s, buf, tbyte);
655     } else if (Len > Len_rle) {
656 	/* Use RunLength encode */
657 	lputs(s, ":");
658 	sput_lips_int(s, Len_rle);
659 	sputc(s, LIPS_IS2);
660 
661 	put_bytes(s, cbuf_rle, Len_rle);
662     } else {
663 	/* Use PackBits encode */
664 	lputs(s, ";");
665 	sput_lips_int(s, Len);
666 	sputc(s, LIPS_IS2);
667 
668 	put_bytes(s, cbuf, Len);
669     }
670 
671     gs_free_object(vdev->memory, cbuf, "lips4v_write_image_data(cbuf)");
672     gs_free_object(vdev->memory, cbuf_rle,
673 		   "lips4v_write_image_data(cbuf_rle)");
674 }
675 
676 
677 /* ---------------- Vector device implementation ---------------- */
678 
679 private int
lips4v_beginpage(gx_device_vector * vdev)680 lips4v_beginpage(gx_device_vector * vdev)
681 {				/*
682 				 * We can't use gdev_vector_stream here, because this may be called
683 				 * from there before in_page is set.
684 				 */
685     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
686     stream *s = vdev->strm;
687     int dpi = vdev->x_pixels_per_inch;
688     int width = pdev->MediaSize[0];
689     int height = pdev->MediaSize[1];
690     int paper_size, x0, y0;
691     char dpi_char[3], unit[12];
692     char page_header[8], l4vmono_page_header[7], l4vcolor_page_header[7];
693     char duplex_char[6], tumble_char[6], toner_d[26], toner_s[5],
694 
695 	nup_char[10];
696     char username[6 + LIPS_USERNAME_MAX], feedmode[5], paper[16],
697 
698 	faceup_char[256];
699     bool dup = pdev->Duplex;
700     int dupset = pdev->Duplex_set;
701     bool tum = pdev->Tumble;
702 
703     /* �٥������⡼�ɰܹ�̿�� CSI &} ���Ǥ��Ȥ�ȯ�Ԥ��� */
704 
705     if (pdev->first_page) {
706 	if (pdev->pjl) {
707 	    lputs(s, l4v_file_header1);
708 	    if ((int)pdev->x_pixels_per_inch == 1200)
709 		lputs(s, "@PJL SET RESOLUTION = SUPERFINE\n");
710 	    else if ((int)pdev->x_pixels_per_inch == 600)
711 		lputs(s, "@PJL SET RESOLUTION = FINE\n");
712 	    else if ((int)pdev->x_pixels_per_inch == 300)
713 		lputs(s, "@PJL SET RESOLUTION = QUICK\n");
714 	    lputs(s, l4v_file_header2);
715 	    if (pdev->toner_density) {
716 		sprintf(toner_d, "@PJL SET TONER-DENSITY=%d\n",
717 			pdev->toner_density);
718 		lputs(s, toner_d);
719 	    }
720 	    if (pdev->toner_saving_set) {
721 		lputs(s, "@PJL SET TONER-SAVING=");
722 		if (pdev->toner_saving)
723 		    sprintf(toner_s, "ON\n");
724 		else
725 		    sprintf(toner_s, "OFF\n");
726 		lputs(s, toner_s);
727 	    }
728 	    lputs(s, l4v_file_header3);
729 	}
730 	lputs(s, l4v_file_header4);
731 
732 	/* set reaolution (dpi) */
733 	sprintf(dpi_char, "%d", dpi);
734 	lputs(s, dpi_char);
735 
736 	if (pdev->color_info.depth == 8)
737 	    lputs(s, l4vmono_file_header);
738 	else
739 	    lputs(s, l4vcolor_file_header);
740 
741 	/* username */
742 	sprintf(username, "%c2y%s%c", LIPS_DCS, pdev->Username, LIPS_ST);
743 	lputs(s, username);
744     }
745     if (strcmp(pdev->mediaType, "PlainPaper") == 0) {
746 	sputc(s, LIPS_CSI);
747 	lputs(s, "20\'t");
748     }
749     else if (strcmp(pdev->mediaType, "OHP") == 0 ||
750 	     strcmp(pdev->mediaType, "TransparencyFilm") == 0) {
751 	sputc(s, LIPS_CSI);
752 	lputs(s, "40\'t");	/* OHP mode (for LBP-2160) */
753     }
754     else if (strcmp(pdev->mediaType, "CardBoard") == 0) {
755         sputc(s, LIPS_CSI);
756 	lputs(s, "30\'t");	/* CardBoard mode (for LBP-2160) */
757     }
758     else if (strcmp(pdev->mediaType, "GlossyFilm") == 0) {
759         sputc(s, LIPS_CSI);
760 	lputs(s, "41\'t");	/* GlossyFilm mode (for LBP-2160) */
761     }
762 
763     /* ���⡼�� */
764     if (pdev->ManualFeed ||
765 	(strcmp(pdev->mediaType, "PlainPaper") != 0
766 	 && strcmp(pdev->mediaType, LIPS_MEDIATYPE_DEFAULT) != 0)) {
767 	/* Use ManualFeed */
768 	if (pdev->prev_feed_mode != 10) {
769 	    sprintf(feedmode, "%c10q", LIPS_CSI);
770 	    lputs(s, feedmode);
771 	    pdev->prev_feed_mode = 10;
772 	}
773     } else {
774 	if (pdev->prev_feed_mode != pdev->cassetFeed) {
775 	    sprintf(feedmode, "%c%dq", LIPS_CSI, pdev->cassetFeed);
776 	    lputs(s, feedmode);
777 	    pdev->prev_feed_mode = pdev->cassetFeed;
778 	}
779     }
780 
781     paper_size = lips_media_selection(width, height);
782 
783     /* �ѻ極���� */
784     if (pdev->prev_paper_size != paper_size) {
785 	if (paper_size == USER_SIZE) {
786 	    /* modified by shige 06/27 2003
787 	    sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */
788 	    /* modified by shige 11/09 2003
789 	    sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */
790 	    sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
791 		    (height * 10 > LIPS_HEIGHT_MAX_720)?
792 		    LIPS_HEIGHT_MAX_720 : (height * 10),
793 		    (width * 10 > LIPS_WIDTH_MAX_720)?
794 		    LIPS_WIDTH_MAX_720 : (width * 10));
795 	    lputs(s, paper);
796 	} else if (paper_size == USER_SIZE + LANDSCAPE) {
797 	    /* modified by shige 06/27 2003
798 	    sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */
799 	    /* modified by shige 11/09 2003
800 	    sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */
801 	    sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
802 		    (width * 10 > LIPS_HEIGHT_MAX_720)?
803 		    LIPS_HEIGHT_MAX_720 : (width * 10),
804 		    (height * 10 > LIPS_WIDTH_MAX_720)?
805 		    LIPS_WIDTH_MAX_720 : (height * 10));
806 	    lputs(s, paper);
807 	} else {
808 	    sprintf(paper, "%c%dp", LIPS_CSI, paper_size);
809 	    lputs(s, paper);
810 	}
811     } else if (paper_size == USER_SIZE) {
812 	if (pdev->prev_paper_width != width ||
813 	    pdev->prev_paper_height != height)
814 	  	/* modified by shige 06/27 2003
815 		sprintf(paper, "%c80;%d;%dp", LIPS_CSI, width * 10, height * 10); */
816 		/* modified by shige 11/09 2003
817 		sprintf(paper, "%c80;%d;%dp", LIPS_CSI, height * 10, width * 10); */
818 		sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
819 		    (height * 10 > LIPS_HEIGHT_MAX_720)?
820 		    LIPS_HEIGHT_MAX_720 : (height * 10),
821 		    (width * 10 > LIPS_WIDTH_MAX_720)?
822 		    LIPS_WIDTH_MAX_720 : (width * 10));
823 	lputs(s, paper);
824     } else if (paper_size == USER_SIZE + LANDSCAPE) {
825 	if (pdev->prev_paper_width != width ||
826 	    pdev->prev_paper_height != height)
827 		/* modified by shige 06/27 2003
828 		sprintf(paper, "%c81;%d;%dp", LIPS_CSI, height * 10, width * 10); */
829 	  	/* modified by shige 11/09 2003
830 		sprintf(paper, "%c81;%d;%dp", LIPS_CSI, width * 10, height * 10); */
831 		sprintf(paper, "%c80;%d;%dp", LIPS_CSI,
832 		    (width * 10 > LIPS_HEIGHT_MAX_720)?
833 		    LIPS_HEIGHT_MAX_720 : (width * 10),
834 		    (height * 10 > LIPS_WIDTH_MAX_720)?
835 		    LIPS_WIDTH_MAX_720 : (height * 10));
836 	lputs(s, paper);
837     }
838     pdev->prev_paper_size = paper_size;
839     pdev->prev_paper_width = width;
840     pdev->prev_paper_height = height;
841 
842     if (pdev->faceup) {
843 	sprintf(faceup_char, "%c11;12;12~", LIPS_CSI);
844 	lputs(s, faceup_char);
845     }
846     /* N-up Printing Setting */
847     if (pdev->first_page) {
848 	if (pdev->nup != 1) {
849 	    sprintf(nup_char, "%c%d1;;%do", LIPS_CSI, pdev->nup, paper_size);
850 	    lputs(s, nup_char);
851 	}
852     }
853     /* Duplex Setting */
854     if (dupset && dup) {
855 	if (pdev->prev_duplex_mode == 0 || pdev->prev_duplex_mode == 1) {
856 	    sprintf(duplex_char, "%c2;#x", LIPS_CSI);	/* duplex */
857 	    lputs(s, duplex_char);
858 	    if (!tum) {
859 		/* long edge binding */
860 		if (pdev->prev_duplex_mode != 2) {
861 		    sprintf(tumble_char, "%c0;#w", LIPS_CSI);
862 		    lputs(s, tumble_char);
863 		}
864 		pdev->prev_duplex_mode = 2;
865 	    } else {
866 		/* short edge binding */
867 		if (pdev->prev_duplex_mode != 3) {
868 		    sprintf(tumble_char, "%c2;#w", LIPS_CSI);
869 		    lputs(s, tumble_char);
870 		}
871 		pdev->prev_duplex_mode = 3;
872 	    }
873 	}
874     } else if (dupset && !dup) {
875 	if (pdev->prev_duplex_mode != 1) {
876 	    sprintf(duplex_char, "%c0;#x", LIPS_CSI);	/* simplex */
877 	    lputs(s, duplex_char);
878 	}
879 	pdev->prev_duplex_mode = 1;
880     }
881     sputc(s, LIPS_CSI);
882     lputs(s, "?1;4;5;6;14l");
883     sputc(s, LIPS_CSI);
884     lputs(s, "?2;3;h");
885 
886     /* size unit (dpi) */
887     sputc(s, LIPS_CSI);
888     lputs(s, "11h");
889     sprintf(unit, "%c?7;%d I", LIPS_CSI, (int)pdev->x_pixels_per_inch);
890     lputs(s, unit);
891     sprintf(page_header, "%c[0&}#%c", LIPS_ESC, LIPS_IS2);
892     lputs(s, page_header);	/* vector mode */
893 
894     lputs(s, "!0");		/* size unit (dpi) */
895     sput_lips_int(s, dpi);
896     lputs(s, "1");
897     sputc(s, LIPS_IS2);
898 
899     if (pdev->color_info.depth == 8) {
900 	sprintf(l4vmono_page_header, "!13%c$%c", LIPS_IS2, LIPS_IS2);
901 	lputs(s, l4vmono_page_header);
902     } else {
903 	sprintf(l4vcolor_page_header, "!11%c$%c", LIPS_IS2, LIPS_IS2);
904 	lputs(s, l4vcolor_page_header);
905     }
906 
907     lputs(s, "(00");
908     sput_lips_int(s,
909 		  ((width - dev_l_margin(vdev) - dev_r_margin(vdev)) * dpi) /
910 		  72);
911     sput_lips_int(s,
912 		  ((height - dev_b_margin(vdev) - dev_t_margin(vdev)) * dpi) /
913 		  72);
914     sputc(s, LIPS_IS2);
915 
916     /* ������ư̿�� */
917     x0 = (dev_l_margin(vdev) - 5. / MMETER_PER_INCH) * dpi;
918     y0 = (dev_b_margin(vdev) - 5. / MMETER_PER_INCH) * dpi;
919 
920     if (x0 != 0 && y0 != 0) {
921 	lputs(s, "}\"");
922 	sput_lips_int(s, x0);
923 	sput_lips_int(s, y0);
924 	sputc(s, LIPS_IS2);
925     }
926     lputs(s, "I00");
927     sputc(s, LIPS_IS2);
928     lputs(s, "}F2");
929     sputc(s, LIPS_IS2);
930     lputs(s, "}H1");
931     sputc(s, LIPS_IS2);
932     lputs(s, "*0");
933     sputc(s, LIPS_IS2);
934 
935     pdev->MaskState = 1;	/* �����: Ʃ�� */
936     pdev->linecap = 0;
937     lputs(s, "}M");
938     sput_lips_int(s, 3277);	/* 11 degree : 16383 * 2 / 10 */
939     sputc(s, LIPS_IS2);
940     lputs(s, "}I1");		/* non-zero winding rule is default */
941     sputc(s,  LIPS_IS2);
942 
943     return 0;
944 }
945 
946 
947 private int
lips4v_setlinewidth(gx_device_vector * vdev,floatp width)948 lips4v_setlinewidth(gx_device_vector * vdev, floatp width)
949 {
950     stream *s = gdev_vector_stream(vdev);
951     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
952 
953 
954 #if 0
955     /* Scale ��ݤ��Ƥ���Τ�, Ghostscript 5.10/5.50 �ΥХ��Τ��� */
956     floatp xscale, yscale;
957 
958     xscale = fabs(igs->ctm.xx);
959     yscale = fabs(igs->ctm.xy);
960 
961     if (xscale == 0 || yscale > xscale)	/* if portrait */
962 	width = ceil(width * yscale);
963     else
964 	width = ceil(width * xscale);
965 #endif
966 
967     if (pdev->TextMode) {
968         sputc(s, LIPS_CSI);
969 	lputs(s, "&}");
970 	pdev->TextMode = FALSE;
971     }
972     if (width < 1)
973 	width = 1;
974 
975     lputs(s, "F1");
976     sput_lips_int(s, width);
977     sputc(s, LIPS_IS2);
978 
979     return 0;
980 }
981 
982 private int
lips4v_setlinecap(gx_device_vector * vdev,gs_line_cap cap)983 lips4v_setlinecap(gx_device_vector * vdev, gs_line_cap cap)
984 {
985     stream *s = gdev_vector_stream(vdev);
986     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
987     char c[6];
988     int line_cap = 0;
989 
990     if (pdev->TextMode) {
991 	sputc(s, LIPS_CSI);
992 	lputs(s, "&}");
993 	pdev->TextMode = FALSE;
994     }
995     switch (cap) {
996 	case 0:
997 	case 3:
998 	line_cap = 0;		/* butt */
999 	break;
1000 	case 1:
1001 	line_cap = 1;		/* round */
1002 	break;
1003 	case 2:
1004 	line_cap = 2;		/* square */
1005 	break;
1006     }
1007     /* ��ü��������̿�� */
1008     sprintf(c, "}E%d%c", line_cap, LIPS_IS2);
1009     lputs(s, c);
1010 
1011     pdev->linecap = cap;
1012 
1013     return 0;
1014 }
1015 
1016 private int
lips4v_setlinejoin(gx_device_vector * vdev,gs_line_join join)1017 lips4v_setlinejoin(gx_device_vector * vdev, gs_line_join join)
1018 {
1019     stream *s = gdev_vector_stream(vdev);
1020     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1021 
1022 /* ����³����̿�� */
1023     char c[5];
1024     int lips_join = 0;
1025 
1026     if (pdev->TextMode) {
1027 	sputc(s, LIPS_CSI);
1028 	lputs(s, "&}");
1029 	pdev->TextMode = FALSE;
1030     }
1031 
1032     switch (join) {
1033 	case 0:
1034 	lips_join = 2;		/* miter */
1035 	break;
1036 	case 1:
1037 	lips_join = 1;		/* round */
1038 	break;
1039 	case 2:
1040 	lips_join = 3;		/* bevel */
1041 	break;
1042 	case 3:
1043 	case 4:
1044 	lips_join = 0;		/* none */
1045 	break;
1046     }
1047 
1048     sprintf(c, "}F%d%c", lips_join, LIPS_IS2);
1049     lputs(s, c);
1050 
1051     return 0;
1052 }
1053 
1054 private int
lips4v_setmiterlimit(gx_device_vector * vdev,floatp limit)1055 lips4v_setmiterlimit(gx_device_vector * vdev, floatp limit)
1056 {
1057     stream *s = gdev_vector_stream(vdev);
1058     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1059     floatp lips_miterlimit;
1060 
1061     if (pdev->TextMode) {
1062 	sputc(s, LIPS_CSI);
1063 	lputs(s, "&}");
1064 	pdev->TextMode = FALSE;
1065     }
1066     lips_miterlimit = (16383.0 * 2.0) / limit;
1067 
1068     lputs(s, "}M");
1069     sput_lips_int(s, lips_miterlimit);
1070     sputc(s, LIPS_IS2);
1071 
1072     return 0;
1073 }
1074 
1075 private int
lips4v_setfillcolor(gx_device_vector * vdev,const gx_drawing_color * pdc)1076 lips4v_setfillcolor(gx_device_vector * vdev, const gx_drawing_color * pdc)
1077 {
1078 
1079     if (!gx_dc_is_pure(pdc))
1080 	return_error(gs_error_rangecheck);
1081     {
1082 	stream *s = gdev_vector_stream(vdev);
1083 	gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1084 	gx_color_index color = gx_dc_pure_color(pdc);
1085 	int drawing_color;
1086 	float r, g, b;
1087 
1088 	if (vdev->color_info.depth == 8) {
1089 	    drawing_color = vdev->color_info.max_gray - color;
1090 	} else {
1091 	    r = (color >> 16) * 1000.0 / 255.0;
1092 	    g = ((color >> 8) & 0xff) * 1000.0 / 255.0;
1093 	    b = (color & 0xff) * 1000.0 / 255.0;
1094 	}
1095 
1096 	if (pdev->TextMode) {
1097 	    sputc(s, LIPS_CSI);
1098 	    lputs(s, "&}");
1099 	    pdev->TextMode = FALSE;
1100 	}
1101 	pdev->current_color = color;
1102 
1103 	if (color == gx_no_color_index) {
1104 	    lputs(s, "I0");
1105 	    sputc(s, LIPS_IS2);
1106 	} else {
1107 	    lputs(s, "I1");
1108 	    sputc(s, LIPS_IS2);
1109 	}
1110 
1111 	/* �ɤ�Ĥ֤����顼����̿�� */
1112 	/* J {color} IS2 */
1113 	lputs(s, "J");
1114 	if (vdev->color_info.depth == 8) {
1115 	    sput_lips_int(s, drawing_color);
1116 	} else {
1117 	    sput_lips_int(s, r);
1118 	    sput_lips_int(s, g);
1119 	    sput_lips_int(s, b);
1120 	}
1121 	sputc(s, LIPS_IS2);
1122 
1123 	/* ñ�����᡼�������顼����̿�� */
1124 	/* }T {color} IS2 */
1125 	lputs(s, "}T");
1126 	if (vdev->color_info.depth == 8) {
1127 	    sput_lips_int(s, drawing_color);
1128 	} else {
1129 	    sput_lips_int(s, r);
1130 	    sput_lips_int(s, g);
1131 	    sput_lips_int(s, b);
1132 	}
1133 	sputc(s, LIPS_IS2);
1134     }
1135     return 0;
1136 }
1137 
1138 private int
lips4v_setstrokecolor(gx_device_vector * vdev,const gx_drawing_color * pdc)1139 lips4v_setstrokecolor(gx_device_vector * vdev, const gx_drawing_color * pdc)
1140 {
1141     if (!gx_dc_is_pure(pdc))
1142 	return_error(gs_error_rangecheck);
1143     {
1144 	stream *s = gdev_vector_stream(vdev);
1145 	gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1146 	gx_color_index color = gx_dc_pure_color(pdc);
1147 	float r, g, b;
1148 
1149 	if (vdev->color_info.depth == 24) {
1150 	    r = (color >> 16) * 1000 / 255.0;
1151 	    g = ((color >> 8) & 0xff) * 1000 / 255.0;
1152 	    b = (color & 0xff) * 1000 / 255.0;
1153 	}
1154 
1155 	if (pdev->TextMode) {
1156 	    sputc(s, LIPS_CSI);
1157 	    lputs(s, "&}");
1158 	    pdev->TextMode = FALSE;
1159 	}
1160 	/* �饤���顼����̿�� */
1161 	/* G {color} IS2 */
1162 	lputs(s, "G");
1163 	if (vdev->color_info.depth == 8) {
1164 	    sput_lips_int(s, vdev->color_info.max_gray - color);
1165 	} else {
1166 	    sput_lips_int(s, r);
1167 	    sput_lips_int(s, g);
1168 	    sput_lips_int(s, b);
1169 	}
1170 	sputc(s, LIPS_IS2);
1171     }
1172     return 0;
1173 }
1174 
1175 /* �������̿�� */
1176 private int
lips4v_setdash(gx_device_vector * vdev,const float * pattern,uint count,floatp offset)1177 lips4v_setdash(gx_device_vector * vdev, const float *pattern, uint count,
1178 	       floatp offset)
1179 {
1180     stream *s = gdev_vector_stream(vdev);
1181     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1182     int i;
1183     float scale, xscale, yscale;
1184 
1185     if (pdev->TextMode) {
1186 	sputc(s, LIPS_CSI);
1187 	lputs(s, "&}");
1188 	pdev->TextMode = FALSE;
1189     }
1190 #if 0
1191     /* Scale ��ݤ��Ƥ���Τ�, Ghostscript 5.10/5.50 �ΥХ��Τ��� */
1192     xscale = fabs(igs->ctm.xx);
1193     yscale = fabs(igs->ctm.xy);
1194 
1195     if (xscale == 0)		/* if portrait */
1196 	scale = yscale;
1197     else
1198 	scale = xscale;
1199 #endif
1200 
1201     if (count == 0) {
1202 	lputs(s, "E10");
1203 	sputc(s, LIPS_IS2);
1204     } else {
1205 	lputs(s, "}d");
1206 	sputc(s, 0x2c);
1207 	lputs(s, "1");
1208 #if 0
1209 	sput_lips_int(s, offset * scale / vdev->x_pixels_per_inch + 0.5);
1210 #else
1211 	sput_lips_int(s, offset);
1212 #endif
1213 	for (i = 0; i < count; ++i) {
1214 	    if (pdev->linecap == 1 && count == 2 && pattern[0] == 0) {
1215 		if (i == 0) {
1216 		    sput_lips_int(s, 1);
1217 		} else {
1218 #if 0
1219 		    sput_lips_int(s,
1220 				  pattern[i] * scale /
1221 				  vdev->x_pixels_per_inch - 0.5);
1222 #else
1223 		    sput_lips_int(s, pattern[i] - 1);
1224 #endif
1225 		}
1226 	    } else {
1227 #if 0
1228 		sput_lips_int(s,
1229 			      pattern[i] * scale / vdev->x_pixels_per_inch +
1230 			      0.5);
1231 #else
1232 		sput_lips_int(s, pattern[i]);
1233 #endif
1234 	    }
1235 	}
1236 	sputc(s, LIPS_IS2);
1237 	lputs(s, "E1");
1238 	sputc(s, 0x2c);
1239 	lputs(s, "0");
1240 	sputc(s, LIPS_IS2);
1241     }
1242 
1243     return 0;
1244 }
1245 
1246 /* �ѥ�ʿ���ٻ��� */
1247 private int
lips4v_setflat(gx_device_vector * vdev,floatp flatness)1248 lips4v_setflat(gx_device_vector * vdev, floatp flatness)
1249 {
1250     stream *s = gdev_vector_stream(vdev);
1251     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1252 
1253     if (pdev->TextMode) {
1254 	sputc(s, LIPS_CSI);
1255 	lputs(s, "&}");
1256 	pdev->TextMode = FALSE;
1257     }
1258     lputs(s, "Pf");
1259     sput_lips_int(s, flatness);
1260     sputc(s, LIPS_IS2);
1261 
1262     return 0;
1263 }
1264 
1265 private int
lips4v_setlogop(gx_device_vector * vdev,gs_logical_operation_t lop,gs_logical_operation_t diff)1266 lips4v_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
1267 		gs_logical_operation_t diff)
1268 {
1269 /****** SHOULD AT LEAST DETECT SET-0 & SET-1 ******/
1270     return 0;
1271 }
1272 
1273 private int
lips4v_beginpath(gx_device_vector * vdev,gx_path_type_t type)1274 lips4v_beginpath(gx_device_vector * vdev, gx_path_type_t type)
1275 {
1276     stream *s = gdev_vector_stream(vdev);
1277     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1278 
1279     if (pdev->TextMode) {
1280 	sputc(s, LIPS_CSI);
1281 	lputs(s, "&}");
1282 	pdev->TextMode = FALSE;
1283     }
1284     /* �ѥ����۳���̿�� */
1285     if (type & gx_path_type_clip) {
1286 	lputs(s, "P(10");
1287 	sputc(s, LIPS_IS2);
1288     } else
1289 	lputs(s, "P(00");
1290 	sputc(s, LIPS_IS2);
1291 
1292     return 0;
1293 }
1294 
1295 private int
lips4v_moveto(gx_device_vector * vdev,floatp x0,floatp y0,floatp x,floatp y,gx_path_type_t type)1296 lips4v_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
1297 	      floatp y, gx_path_type_t type)
1298 {
1299     stream *s = gdev_vector_stream(vdev);
1300 
1301     /* ���֥ѥ�����̿�� p1 */
1302     lputs(s, "p10");
1303     sput_lips_int(s, x);
1304     sput_lips_int(s, y);
1305     sputc(s, LIPS_IS2);
1306 
1307     return 0;
1308 }
1309 
1310 private int
lips4v_lineto(gx_device_vector * vdev,floatp x0,floatp y0,floatp x,floatp y,gx_path_type_t type)1311 lips4v_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x,
1312 	      floatp y, gx_path_type_t type)
1313 {
1314     stream *s = gdev_vector_stream(vdev);
1315     gx_device_lips4v *const pdev = (gx_device_lips4v *) vdev;
1316 
1317     /* if round cap */
1318     if (pdev->linecap == 1) {
1319 	if ((x0 == x) && (y0 == y))
1320 	    x += 1;
1321     }
1322 
1323     /* �ѥ����ݥ�饤��̿�� */
1324     lputs(s, "p402");
1325     sput_lips_int(s, x);
1326     sput_lips_int(s, y);
1327     sputc(s, LIPS_IS2);
1328 
1329     return 0;
1330 }
1331 
1332 private int
lips4v_curveto(gx_device_vector * vdev,floatp x0,floatp y0,floatp x1,floatp y1,floatp x2,floatp y2,floatp x3,floatp y3,gx_path_type_t type)1333 lips4v_curveto(gx_device_vector * vdev, floatp x0, floatp y0,
1334 	       floatp x1, floatp y1, floatp x2, floatp y2, floatp x3,
1335 	       floatp y3, gx_path_type_t type)
1336 {
1337     stream *s = gdev_vector_stream(vdev);
1338 
1339     /* �ѥ����ݥ�饤��̿�� */
1340     lputs(s, "p404");
1341     sput_lips_int(s, x1);
1342     sput_lips_int(s, y1);
1343     sput_lips_int(s, x2);
1344     sput_lips_int(s, y2);
1345     sput_lips_int(s, x3);
1346     sput_lips_int(s, y3);
1347     sputc(s, LIPS_IS2);
1348 
1349     return 0;
1350 }
1351 
1352 private int
lips4v_closepath(gx_device_vector * vdev,floatp x,floatp y,floatp x_start,floatp y_start,gx_path_type_t type)1353 lips4v_closepath(gx_device_vector * vdev, floatp x, floatp y,
1354 		 floatp x_start, floatp y_start, gx_path_type_t type)
1355 {
1356     stream *s = gdev_vector_stream(vdev);
1357 
1358     lputs(s, "p0");
1359     sputc(s, LIPS_IS2);
1360     return 0;
1361 }
1362 
1363 private int
lips4v_endpath(gx_device_vector * vdev,gx_path_type_t type)1364 lips4v_endpath(gx_device_vector * vdev, gx_path_type_t type)
1365 {
1366     stream *s = gdev_vector_stream(vdev);
1367 
1368     lputs(s, "P)");
1369     sputc(s, LIPS_IS2);
1370     if (type & gx_path_type_rule) {
1371 	if (type & gx_path_type_winding_number) {
1372 	    lputs(s, "}I1");
1373 	    sputc(s, LIPS_IS2);
1374 	} else {
1375 	    lputs(s, "}I0");
1376 	    sputc(s, LIPS_IS2);
1377 	}
1378     }
1379     if (type & gx_path_type_fill) {
1380 	if (type & gx_path_type_stroke) {
1381 	    lputs(s, "P&00");
1382 	    sputc(s, LIPS_IS2);
1383 	} else {
1384 	    lputs(s, "PF00");
1385 	    sputc(s, LIPS_IS2);
1386 	}
1387     }
1388     if (type & gx_path_type_stroke) {
1389 	lputs(s, "PS00");
1390 	sputc(s, LIPS_IS2);
1391     }
1392     if (type & gx_path_type_clip) {
1393 	lputs(s, "PC10");
1394 	sputc(s, LIPS_IS2);
1395     }
1396     return 0;
1397 }
1398 
1399 /* ---------------- Driver procedures ---------------- */
1400 
1401 /* ------ Open/close/page ------ */
1402 
1403 /* Open the device. */
1404 private int
lips4v_open(gx_device * dev)1405 lips4v_open(gx_device * dev)
1406 {
1407     gx_device_vector *const vdev = (gx_device_vector *) dev;
1408     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1409 
1410     int code;
1411 
1412     code = lips4v_range_check(dev);
1413     if (code < 0)
1414 	return code;
1415 
1416     vdev->v_memory = dev->memory;
1417 /****** WRONG ******/
1418     vdev->vec_procs = &lips4v_vector_procs;
1419 
1420 
1421     code = gdev_vector_open_file_bbox(vdev, 512, true);
1422     if (code < 0)
1423 	return code;
1424 
1425     gdev_vector_init(vdev);
1426     pdev->first_page = true;
1427 
1428     return 0;
1429 }
1430 
1431 /* Wrap up ("output") a page. */
1432 private int
lips4v_output_page(gx_device * dev,int num_copies,int flush)1433 lips4v_output_page(gx_device * dev, int num_copies, int flush)
1434 {
1435     gx_device_vector *const vdev = (gx_device_vector *) dev;
1436     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1437     stream *s = gdev_vector_stream(vdev);
1438     char str[6];
1439 
1440     if (pdev->TextMode) {
1441 	sputc(s, LIPS_CSI);
1442 	lputs(s, "&}");
1443 	pdev->TextMode = FALSE;
1444     }
1445     lputs(s, "%");
1446     sputc(s, LIPS_IS2);
1447     lputs(s, "}p");
1448     sputc(s, LIPS_IS2);
1449 
1450     if (num_copies > 255)
1451 	num_copies = 255;
1452     if (pdev->prev_num_copies != num_copies) {
1453 	sprintf(str, "%c%dv", LIPS_CSI, num_copies);
1454 	lputs(s, str);
1455 	pdev->prev_num_copies = num_copies;
1456     }
1457     sputc(s, LIPS_FF);
1458     sflush(s);
1459     vdev->in_page = false;
1460     pdev->first_page = false;
1461     gdev_vector_reset(vdev);
1462     return 0;
1463 }
1464 
1465 private int
lips4v_close(gx_device * dev)1466 lips4v_close(gx_device * dev)
1467 {
1468     gx_device_vector *const vdev = (gx_device_vector *) dev;
1469     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1470     FILE *f = vdev->file;
1471 
1472     fprintf(f, "%c0J%c", LIPS_DCS, LIPS_ST);
1473     if (pdev->pjl) {
1474 	fprintf(f, "%c%%-12345X@PJL SET LPARM : LIPS SW2 = OFF\n", LIPS_ESC);
1475 	fprintf(f,
1476 		"%c%%-12345X%c%%-12345X@PJL EOJ\n"
1477 		"%c%%-12345X", LIPS_ESC, LIPS_ESC, LIPS_ESC);
1478     }
1479     gdev_vector_close_file(vdev);
1480 
1481     return 0;
1482 }
1483 
1484 /* Close the device. */
1485 /* Note that if this is being called as a result of finalization, */
1486 /* the stream may no longer exist; but the file will still be open. */
1487 
1488 /* ---------------- Get/put parameters ---------------- */
1489 
1490 /* Get parameters. */
1491 private int
lips4v_get_params(gx_device * dev,gs_param_list * plist)1492 lips4v_get_params(gx_device * dev, gs_param_list * plist)
1493 {
1494     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1495     int code = gdev_vector_get_params(dev, plist);
1496     int ncode;
1497     gs_param_string usern;
1498     gs_param_string pmedia;
1499 
1500     if (code < 0)
1501 	return code;
1502 
1503     if ((ncode = param_write_bool(plist, LIPS_OPTION_MANUALFEED,
1504 				  &pdev->ManualFeed)) < 0)
1505 	code = ncode;
1506 
1507     if ((ncode = param_write_int(plist, LIPS_OPTION_CASSETFEED,
1508 				 &pdev->cassetFeed)) < 0)
1509 	code = ncode;
1510 
1511     if ((ncode = param_write_bool(plist, LIPS_OPTION_DUPLEX_TUMBLE,
1512 				  &pdev->Tumble)) < 0)
1513 	code = ncode;
1514 
1515     if ((ncode = param_write_int(plist, LIPS_OPTION_NUP, &pdev->nup)) < 0)
1516 	code = ncode;
1517 
1518     if ((ncode = param_write_bool(plist, LIPS_OPTION_PJL, &pdev->pjl)) < 0)
1519 	code = ncode;
1520 
1521     if ((ncode = param_write_int(plist, LIPS_OPTION_TONERDENSITY,
1522 				 &pdev->toner_density)) < 0)
1523 	code = ncode;
1524 
1525     if (pdev->toner_saving_set >= 0 &&
1526 	(code = (pdev->toner_saving_set ?
1527 		 param_write_bool(plist, LIPS_OPTION_TONERSAVING,
1528 				  &pdev->
1529 				  toner_saving) : param_write_null(plist,
1530 								   LIPS_OPTION_TONERSAVING)))
1531 	< 0)
1532 	code = ncode;
1533 
1534     if (pdev->Duplex_set >= 0 &&
1535 	(ncode = (pdev->Duplex_set ?
1536 		  param_write_bool(plist, "Duplex", &pdev->Duplex) :
1537 		  param_write_null(plist, "Duplex"))) < 0)
1538 	code = ncode;
1539 
1540     if ((ncode = param_write_bool(plist, LIPS_OPTION_FONTDOWNLOAD,
1541 				  &pdev->FontDL)) < 0)
1542 	code = ncode;
1543 
1544     if ((ncode = param_write_bool(plist, LIPS_OPTION_FACEUP,
1545 				  &pdev->faceup)) < 0) code = ncode;
1546 
1547     pmedia.data = (const byte *)pdev->mediaType,
1548 	pmedia.size = strlen(pdev->mediaType), pmedia.persistent = false;
1549 
1550     if ((ncode = param_write_string(plist, LIPS_OPTION_MEDIATYPE,
1551 				    &pmedia)) < 0) code = ncode;
1552 
1553     if (code < 0)
1554 	return code;
1555 
1556     usern.data = (const byte *)pdev->Username,
1557 	usern.size = strlen(pdev->Username), usern.persistent = false;
1558 
1559     return param_write_string(plist, LIPS_OPTION_USER_NAME, &usern);
1560 }
1561 
1562 /* Put parameters. */
1563 private int
lips4v_put_params(gx_device * dev,gs_param_list * plist)1564 lips4v_put_params(gx_device * dev, gs_param_list * plist)
1565 {
1566     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1567     int ecode = 0;
1568     int code;
1569     gs_param_name param_name;
1570     gs_param_string pmedia;
1571     bool mf = pdev->ManualFeed;
1572     int cass = pdev->cassetFeed;
1573     gs_param_string usern;
1574     bool tum = pdev->Tumble;
1575     int nup = pdev->nup;
1576     bool pjl = pdev->pjl;
1577     int toner_density = pdev->toner_density;
1578     bool toner_saving = pdev->toner_saving;
1579     bool toner_saving_set = pdev->toner_saving_set;
1580     bool fontdl = pdev->FontDL;
1581     bool faceup = pdev->faceup;
1582     bool duplex;
1583     int duplex_set = -1;
1584     int old_bpp = dev->color_info.depth;
1585     int bpp = 0;
1586 
1587     if ((code = param_read_bool(plist,
1588 				(param_name = LIPS_OPTION_MANUALFEED),
1589 				&mf)) < 0) {
1590 	param_signal_error(plist, param_name, ecode = code);
1591     }
1592     switch (code = param_read_int(plist,
1593 				  (param_name = LIPS_OPTION_CASSETFEED),
1594 				  &cass)) {
1595 	case 0:
1596 	if (cass < -1 || cass > 17 || (cass > 3 && cass < 10))
1597 	    ecode = gs_error_limitcheck;
1598 	else
1599 	    break;
1600 	goto casse;
1601 	default:
1602 	ecode = code;
1603       casse:param_signal_error(plist, param_name, ecode);
1604 	case 1:
1605 	break;
1606     }
1607 
1608     switch (code = param_read_string(plist,
1609 				     (param_name = LIPS_OPTION_MEDIATYPE),
1610 				     &pmedia)) {
1611 	case 0:
1612 	if (pmedia.size > LIPS_MEDIACHAR_MAX)
1613 	    ecode = gs_error_limitcheck;
1614 	else {			/* Check the validity of ``MediaType'' characters */
1615 	    if (strcmp(pmedia.data, "PlainPaper") != 0 &&
1616 		strcmp(pmedia.data, "OHP") != 0 &&
1617 		strcmp(pmedia.data, "TransparencyFilm") != 0 &&	/* same as OHP */
1618 		strcmp(pmedia.data, "GlossyFilm") != 0 &&
1619 		strcmp(pmedia.data, "CardBoard") != 0) {
1620 		ecode = gs_error_rangecheck;
1621 		goto pmediae;
1622 	    }
1623 	}
1624 	break;
1625 	goto pmediae;
1626 	default:
1627 	ecode = code;
1628       pmediae:param_signal_error(plist, param_name, ecode);
1629 	case 1:
1630 	pmedia.data = 0;
1631 	break;
1632     }
1633 
1634     switch (code = param_read_string(plist,
1635 				     (param_name = LIPS_OPTION_USER_NAME),
1636 				     &usern)) {
1637 	case 0:
1638 	if (usern.size > LIPS_USERNAME_MAX)
1639 	    ecode = gs_error_limitcheck;
1640 	else {			/* Check the validity of ``User Name'' characters */
1641 	    int i;
1642 
1643 	    for (i = 0; i < usern.size; i++)
1644 		if (usern.data[i] < 0x20 || usern.data[i] > 0x7e
1645 		    /*
1646 		       && usern.data[i] < 0xa0) ||
1647 		       usern.data[i] > 0xfe
1648 		     */
1649 		    ) {
1650 		    ecode = gs_error_rangecheck;
1651 		    goto userne;
1652 		}
1653 	}
1654 	break;
1655 	goto userne;
1656 	default:
1657 	ecode = code;
1658       userne:param_signal_error(plist, param_name, ecode);
1659 	case 1:
1660 	usern.data = 0;
1661 	break;
1662     }
1663 
1664 
1665     if ((code = param_read_bool(plist,
1666 				(param_name = LIPS_OPTION_DUPLEX_TUMBLE),
1667 				&tum)) < 0)
1668 	param_signal_error(plist, param_name, ecode = code);
1669 
1670 
1671     switch (code = param_read_int(plist,
1672 				  (param_name = LIPS_OPTION_NUP), &nup)) {
1673 	case 0:
1674 	if (nup != 1 && nup != 2 && nup != 4)
1675 	    ecode = gs_error_rangecheck;
1676 	else
1677 	    break;
1678 	goto nupe;
1679 	default:
1680 	ecode = code;
1681       nupe:param_signal_error(plist, param_name, ecode);
1682 	case 1:
1683 	break;
1684     }
1685 
1686     if ((code = param_read_bool(plist,
1687 				(param_name = LIPS_OPTION_PJL), &pjl)) < 0)
1688 	param_signal_error(plist, param_name, ecode = code);
1689 
1690     switch (code = param_read_int(plist,
1691 				  (param_name = LIPS_OPTION_TONERDENSITY),
1692 				  &toner_density)) {
1693 	case 0:
1694 	if (toner_density < 0 || toner_density > 8)
1695 	    ecode = gs_error_rangecheck;
1696 	else
1697 	    break;
1698 	goto tden;
1699 	default:
1700 	ecode = code;
1701       tden:param_signal_error(plist, param_name, ecode);
1702 	case 1:
1703 	break;
1704     }
1705 
1706     if (pdev->toner_saving_set >= 0)
1707 	switch (code =
1708 		param_read_bool(plist, (param_name = LIPS_OPTION_TONERSAVING),
1709 				&toner_saving)) {
1710 	    case 0:
1711 	    toner_saving_set = 1;
1712 	    break;
1713 	    default:
1714 	    if ((code = param_read_null(plist, param_name)) == 0) {
1715 		toner_saving_set = 0;
1716 		break;
1717 	    }
1718 	    ecode = code;
1719 	    param_signal_error(plist, param_name, ecode);
1720 	    case 1:
1721 	    break;
1722 	}
1723 
1724     if (pdev->Duplex_set >= 0)	/* i.e., Duplex is supported */
1725 	switch (code = param_read_bool(plist, (param_name = "Duplex"),
1726 				       &duplex)) {
1727 	    case 0:
1728 	    duplex_set = 1;
1729 	    break;
1730 	    default:
1731 	    if ((code = param_read_null(plist, param_name)) == 0) {
1732 		duplex_set = 0;
1733 		break;
1734 	    }
1735 	    ecode = code;
1736 	    param_signal_error(plist, param_name, ecode);
1737 	    case 1:
1738 	    break;
1739 	}
1740     if ((code = param_read_bool(plist,
1741 				(param_name = LIPS_OPTION_FONTDOWNLOAD),
1742 				&fontdl)) < 0)
1743 	param_signal_error(plist, param_name, ecode = code);
1744 
1745     if ((code = param_read_bool(plist,
1746 				(param_name = LIPS_OPTION_FACEUP),
1747 				&faceup)) < 0) {
1748 	param_signal_error(plist, param_name, ecode = code);
1749     }
1750 
1751 
1752     switch (code = param_read_int(plist, (param_name = "BitsPerPixel"), &bpp)) {
1753 	case 0:
1754 	if (bpp != 8 && bpp != 24)
1755 	    ecode = gs_error_rangecheck;
1756 	else
1757 	    break;
1758 	goto bppe;
1759 	default:
1760 	ecode = code;
1761       bppe:param_signal_error(plist, param_name, ecode);
1762 	case 1:
1763 	break;
1764     }
1765 
1766     if (bpp != 0) {
1767 	dev->color_info.depth = bpp;
1768 	dev->color_info.num_components = ((bpp == 8) ? 1 : 3);
1769 	dev->color_info.max_gray = (bpp > 8 ? 255 : 1000);
1770 	dev->color_info.max_color = (bpp > 8 ? 255 : 1000);
1771 	dev->color_info.dither_grays = (bpp > 8 ? 256 : 5);
1772 	dev->color_info.dither_colors = (bpp > 8 ? 256 : 2);
1773 	dev_proc(pdev, map_rgb_color) =
1774 	    ((bpp == 8) ? gx_default_gray_map_rgb_color :
1775 	     gx_default_rgb_map_rgb_color);
1776 	dev_proc(pdev, map_color_rgb) =
1777 	    ((bpp == 8) ? gx_default_gray_map_color_rgb :
1778 	     gx_default_rgb_map_color_rgb);
1779     }
1780 
1781     if (ecode < 0)
1782 	return ecode;
1783     code = gdev_vector_put_params(dev, plist);
1784     if (code < 0)
1785 	return code;
1786 
1787     pdev->ManualFeed = mf;
1788     pdev->cassetFeed = cass;
1789     pdev->Tumble = tum;
1790     pdev->nup = nup;
1791     pdev->pjl = pjl;
1792     pdev->toner_density = toner_density;
1793     pdev->toner_saving = toner_saving;
1794     pdev->toner_saving_set = toner_saving_set;
1795     pdev->FontDL = fontdl;
1796     pdev->faceup = faceup;
1797 
1798     if (duplex_set >= 0) {
1799 	pdev->Duplex = duplex;
1800 	pdev->Duplex_set = duplex_set;
1801     }
1802     if (pmedia.data != 0 &&
1803 	bytes_compare(pmedia.data, pmedia.size,
1804 		      (const byte *)pdev->mediaType, strlen(pdev->mediaType))
1805 	) {
1806 	memcpy(pdev->mediaType, pmedia.data, pmedia.size);
1807 	pdev->mediaType[pmedia.size] = 0;
1808     }
1809     if (usern.data != 0 &&
1810 	bytes_compare(usern.data, usern.size,
1811 		      (const byte *)pdev->Username, strlen(pdev->Username))
1812 	) {
1813 	memcpy(pdev->Username, usern.data, usern.size);
1814 	pdev->Username[usern.size] = 0;
1815     }
1816     if (bpp != 0 && bpp != old_bpp && pdev->is_open)
1817 	return gs_closedevice(dev);
1818     return 0;
1819 }
1820 
1821 /* ---------------- Images ---------------- */
1822 
1823 private int
lips4v_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)1824 lips4v_copy_mono(gx_device * dev, const byte * data,
1825 		 int data_x, int raster, gx_bitmap_id id, int x, int y, int w,
1826 		 int h, gx_color_index zero, gx_color_index one)
1827 {
1828     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
1829     gx_device_vector *const vdev = (gx_device_vector *) dev;
1830     stream *s = gdev_vector_stream(vdev);
1831     int dpi = dev->x_pixels_per_inch;
1832     gx_drawing_color color;
1833     int code = 0;
1834     floatp r, g, b;
1835 
1836     if (id != gs_no_id && zero == gx_no_color_index &&
1837 	one != gx_no_color_index && data_x == 0) {
1838 	gx_drawing_color dcolor;
1839 
1840 	color_set_pure(&dcolor, one);
1841 	lips4v_setfillcolor(vdev, &dcolor);
1842 
1843 	if (lips4v_copy_text_char(dev, data, raster, id, x, y, w, h) >= 0)
1844 	    return 0;
1845     }
1846     if (pdev->TextMode) {
1847 	sputc(s, LIPS_CSI);
1848 	lputs(s, "&}");
1849 	pdev->TextMode = FALSE;
1850     }
1851     /*
1852        (*dev_proc(vdev->bbox_device, copy_mono))
1853        ((gx_device *)vdev->bbox_device, data, data_x, raster, id,
1854        x, y, w, h, zero, one);
1855      */
1856     if (zero == gx_no_color_index) {
1857 	if (one == gx_no_color_index)
1858 	    return 0;
1859 	/* one �������ᡢƩ��ˤ��� */
1860 	if (pdev->MaskState != 1) {
1861 	    lputs(s, "}H1");
1862 	    sputc(s, LIPS_IS2);
1863 	    pdev->MaskState = 1;
1864 	}
1865 	if (pdev->color_info.depth == 8) {
1866 	    gx_color_index one_color = vdev->color_info.max_gray - one;
1867 
1868 	    lputs(s, "}T");
1869 	    sput_lips_int(s, one_color);
1870 	    sputc(s, LIPS_IS2);
1871 	} else {
1872 	    r = (one >> 16) * 1000.0 / 255.0;
1873 	    g = ((one >> 8) & 0xff) * 1000.0 / 255.0;
1874 	    b = (one & 0xff) * 1000.0 / 255.0;
1875 	    lputs(s, "}T");
1876 	    sput_lips_int(s, r);
1877 	    sput_lips_int(s, g);
1878 	    sput_lips_int(s, b);
1879 	    sputc(s, LIPS_IS2);
1880 	}
1881     } else if (one == gx_no_color_index)
1882 	/* 1bit ��Ʃ�� �ӥå�ȿž��zero ��������� */
1883     {
1884 	gx_color_index zero_color = vdev->color_info.max_gray - zero;
1885 
1886 	if (pdev->MaskState != 1) {
1887 	    lputs(s, "}H1");
1888 	    sputc(s, LIPS_IS2);
1889 	    pdev->MaskState = 1;
1890 	}
1891 	if (pdev->color_info.depth == 8) {
1892 	    lputs(s, "}T");
1893 	    sput_lips_int(s, zero_color);
1894 	    sputc(s, LIPS_IS2);
1895 	} else {
1896 	    r = (zero >> 16) * 1000.0 / 255.0;
1897 	    g = ((zero >> 8) & 0xff) * 1000.0 / 255.0;
1898 	    b = (zero & 0xff) * 1000.0 / 255.0;
1899 	    lputs(s, "}T");
1900 	    sput_lips_int(s, r);
1901 	    sput_lips_int(s, g);
1902 	    sput_lips_int(s, b);
1903 	    sputc(s, LIPS_IS2);
1904 	}
1905     } else if (one == vdev->white) {
1906 	/* �ӥå�ȿž ���ɤ�  zero ��������� */
1907 	gx_color_index zero_color = vdev->color_info.max_gray - zero;
1908 
1909 	if (pdev->MaskState != 0) {
1910 	    lputs(s, "}H0");
1911 	    sputc(s, LIPS_IS2);
1912 	    pdev->MaskState = 0;
1913 	}
1914 	if (pdev->color_info.depth == 8) {
1915 	    lputs(s, "}T");
1916 	    sput_lips_int(s, zero_color);
1917 	    sputc(s, LIPS_IS2);
1918 	} else {
1919 	    r = (zero >> 16) * 1000.0 / 255.0;
1920 	    g = ((zero >> 8) & 0xff) * 1000.0 / 255.0;
1921 	    b = (zero & 0xff) * 1000.0 / 255.0;
1922 	    lputs(s, "}T");
1923 	    sput_lips_int(s, r);
1924 	    sput_lips_int(s, g);
1925 	    sput_lips_int(s, b);
1926 	    sputc(s, LIPS_IS2);
1927 	}
1928     } else {
1929 	if (zero != gx_no_color_index) {
1930 	    code = (*dev_proc(dev, fill_rectangle)) (dev, x, y, w, h, zero);
1931 	    if (code < 0)
1932 		return code;
1933 	}
1934 	if (pdev->MaskState != 1) {
1935 	    lputs(s, "}H1");
1936 	    sputc(s, LIPS_IS2);
1937 	    pdev->MaskState = 1;
1938 	}
1939 	color_set_pure(&color, one);
1940 	code = gdev_vector_update_fill_color((gx_device_vector *) pdev,
1941 					     &color);
1942     }
1943     if (code < 0)
1944 	return 0;
1945     lputs(s, "}P");
1946     sput_lips_int(s, x);	/* Position X */
1947     sput_lips_int(s, y);	/* Position Y */
1948     sput_lips_int(s, dpi * 100);
1949     sput_lips_int(s, dpi * 100);
1950     sput_lips_int(s, h);	/* Height */
1951     sput_lips_int(s, w);	/* Width */
1952     lputs(s, "100110");
1953     sputc(s, LIPS_IS2);
1954 
1955     lputs(s, "}Q11");
1956 
1957     {
1958 	int i, j;
1959 	uint width_bytes = (w + 7) >> 3;
1960 	uint num_bytes = round_up(width_bytes, 4) * h;
1961 	byte *buf = gs_alloc_bytes(vdev->memory, num_bytes,
1962 				   "lips4v_copy_mono(buf)");
1963 
1964 	if (data_x % 8 == 0) {
1965 	    for (i = 0; i < h; ++i) {
1966 		memcpy(buf + i * width_bytes,
1967 		       data + (data_x >> 3) + i * raster, width_bytes);
1968 	    }
1969 	} else {
1970 	    for (i = 0; i < h; ++i) {
1971 		for (j = 0; j < width_bytes; j++) {
1972 		    *(buf + i * width_bytes + j) =
1973 			*(data + (data_x >> 3) + i * raster +
1974 			  j) << (data_x % 8) | *(data + (data_x >> 3) +
1975 						 i * raster + j + 1) >> (8 -
1976 									 data_x
1977 									 % 8);
1978 		}
1979 	    }
1980 	}
1981 
1982 
1983 	if (one == gx_no_color_index
1984 	    || (one == vdev->white
1985 		&& zero != gx_no_color_index)) lips4v_write_image_data(vdev,
1986 								       buf,
1987 								       num_bytes,
1988 								       TRUE);
1989 	else
1990 	    lips4v_write_image_data(vdev, buf, num_bytes, FALSE);
1991 
1992 	gs_free_object(vdev->memory, buf, "lips4v_copy_mono(buf)");
1993     }
1994 
1995     return 0;
1996 }
1997 
1998 /* Copy a color bitmap. */
1999 private int
lips4v_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)2000 lips4v_copy_color(gx_device * dev,
2001 		  const byte * data, int data_x, int raster, gx_bitmap_id id,
2002 		  int x, int y, int w, int h)
2003 {
2004     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
2005     gx_device_vector *const vdev = (gx_device_vector *) dev;
2006 
2007     stream *s = gdev_vector_stream(vdev);
2008     int depth = dev->color_info.depth;
2009     int dpi = dev->x_pixels_per_inch;
2010     int num_components = (depth < 24 ? 1 : 3);
2011     uint width_bytes = w * num_components;
2012 
2013 
2014     if (dev->color_info.depth == 8) {
2015 	gx_drawing_color dcolor;
2016 
2017 	/* LIPS IV �Ǥϥ��졼���������ñ�����᡼�������顼����̿���
2018 	   �ƶ������Τǹ�������ꤷ�ʤ���Фʤ�ʤ��� */
2019 	color_set_pure(&dcolor, vdev->black);
2020 	lips4v_setfillcolor(vdev, &dcolor);
2021     } else {
2022 	if (pdev->TextMode) {
2023 	    sputc(s, LIPS_CSI);
2024 	    lputs(s, "&}");
2025 	    pdev->TextMode = FALSE;
2026 	}
2027     }
2028 
2029     if (pdev->MaskState != 0) {
2030 	lputs(s, "}H0");	/* ������������̿�� */
2031 	sputc(s, LIPS_IS2);
2032 	pdev->MaskState = 0;
2033     }
2034     lputs(s, "}P");
2035     sput_lips_int(s, x);
2036     sput_lips_int(s, y);
2037     sput_lips_int(s, dpi * 100);
2038     sput_lips_int(s, dpi * 100);
2039     sput_lips_int(s, h);
2040     sput_lips_int(s, w);
2041     sput_lips_int(s, depth / num_components);
2042     sputc(s, depth < 24 ? '0' : ':');	/* 24 bit �ΤȤ����缡 */
2043     lputs(s, "0110");
2044     sputc(s, LIPS_IS2);
2045 
2046     {
2047 	int i;
2048 	uint num_bytes = width_bytes * h;
2049 	byte *buf = gs_alloc_bytes(vdev->memory, num_bytes,
2050 				   "lips4v_copy_color(buf)");
2051 
2052 	lputs(s, "}Q11");
2053 
2054 	for (i = 0; i < h; ++i) {
2055 	    memcpy(buf + i * width_bytes,
2056 		   data + ((data_x * depth) >> 3) + i * raster, width_bytes);
2057 	}
2058 
2059 	if (dev->color_info.depth == 8)
2060 	    lips4v_write_image_data(vdev, buf, num_bytes, TRUE);
2061 	else
2062 	    lips4v_write_image_data(vdev, buf, num_bytes, FALSE);
2063 
2064 	gs_free_object(vdev->memory, buf, "lips4v_copy_color(buf)");
2065     }
2066 
2067     return 0;
2068 }
2069 
2070 /* Fill a mask. */
2071 private int
lips4v_fill_mask(gx_device * dev,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int w,int h,const gx_drawing_color * pdcolor,int depth,gs_logical_operation_t lop,const gx_clip_path * pcpath)2072 lips4v_fill_mask(gx_device * dev,
2073 		 const byte * data, int data_x, int raster, gx_bitmap_id id,
2074 		 int x, int y, int w, int h,
2075 		 const gx_drawing_color * pdcolor, int depth,
2076 		 gs_logical_operation_t lop, const gx_clip_path * pcpath)
2077 {
2078     gx_device_vector *const vdev = (gx_device_vector *) dev;
2079     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
2080     stream *s = gdev_vector_stream(vdev);
2081     int dpi = dev->x_pixels_per_inch;
2082 
2083     if (w <= 0 || h <= 0)
2084 	return 0;
2085     if (depth > 1 ||
2086 	gdev_vector_update_fill_color(vdev, pdcolor) < 0 ||
2087 	gdev_vector_update_clip_path(vdev, pcpath) < 0 ||
2088 	gdev_vector_update_log_op(vdev, lop) < 0)
2089 	return gx_default_fill_mask(dev, data, data_x, raster, id,
2090 				    x, y, w, h, pdcolor, depth, lop, pcpath);
2091 #if 1
2092     (*dev_proc(vdev->bbox_device, fill_mask))
2093 	((gx_device *) vdev->bbox_device, data, data_x, raster, id,
2094 	 x, y, w, h, pdcolor, depth, lop, pcpath);
2095 #endif
2096     if (id != gs_no_id && data_x == 0) {
2097 	if (lips4v_copy_text_char(dev, data, raster, id, x, y, w, h) >= 0)
2098 	    return 0;
2099     }
2100     if (pdev->TextMode) {
2101 	sputc(s, LIPS_CSI);
2102 	lputs(s, "&}");
2103 	pdev->TextMode = FALSE;
2104     }
2105     /* ������ */
2106     if (pdev->MaskState != 1) {
2107 	lputs(s, "}H1");	/* ������������̿�� */
2108 	sputc(s, LIPS_IS2);
2109 	pdev->MaskState = 1;
2110     }
2111     lputs(s, "}P");
2112     sput_lips_int(s, x);
2113     sput_lips_int(s, y);
2114     sput_lips_int(s, dpi * 100);
2115     sput_lips_int(s, dpi * 100);
2116     sput_lips_int(s, h);
2117     sput_lips_int(s, w);
2118     lputs(s, "100110");
2119     sputc(s, LIPS_IS2);
2120 
2121     lputs(s, "}Q11");
2122 
2123     {
2124 	int i;
2125 	uint width_bytes = (w + 7) >> 3;
2126 	uint num_bytes = round_up(width_bytes, 4) * h;
2127 	byte *buf = gs_alloc_bytes(vdev->memory, num_bytes,
2128 				   "lips4v_fill_mask(buf)");
2129 
2130 	for (i = 0; i < h; ++i) {
2131 	    memcpy(buf + i * width_bytes, data + (data_x >> 3) + i * raster,
2132 		   width_bytes);
2133 	}
2134 
2135 	lips4v_write_image_data(vdev, buf, num_bytes, FALSE);
2136 
2137 	gs_free_object(vdev->memory, buf, "lips4v_fill_mask(buf)");
2138     }
2139 
2140     return 0;
2141 }
2142 
2143 /* ---------------- High-level images ---------------- */
2144 
2145 private image_enum_proc_plane_data(lips4v_image_plane_data);
2146 private image_enum_proc_end_image(lips4v_image_end_image);
2147 private const gx_image_enum_procs_t lips4v_image_enum_procs = {
2148     lips4v_image_plane_data, lips4v_image_end_image
2149 };
2150 
2151 /* Start processing an image. */
2152 private int
lips4v_begin_image(gx_device * dev,const gs_imager_state * pis,const gs_image_t * pim,gs_image_format_t format,const gs_int_rect * prect,const gx_drawing_color * pdcolor,const gx_clip_path * pcpath,gs_memory_t * mem,gx_image_enum_common_t ** pinfo)2153 lips4v_begin_image(gx_device * dev,
2154 		   const gs_imager_state * pis, const gs_image_t * pim,
2155 		   gs_image_format_t format, const gs_int_rect * prect,
2156 		   const gx_drawing_color * pdcolor,
2157 		   const gx_clip_path * pcpath, gs_memory_t * mem,
2158 		   gx_image_enum_common_t ** pinfo)
2159 {
2160     gx_device_vector *const vdev = (gx_device_vector *) dev;
2161     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
2162     gdev_vector_image_enum_t *pie =
2163 	gs_alloc_struct(mem, gdev_vector_image_enum_t,
2164 			&st_vector_image_enum, "lips4v_begin_image");
2165     const gs_color_space *pcs = pim->ColorSpace;
2166     gs_color_space_index index;
2167     int num_components = 1;
2168     bool can_do = prect == 0 &&
2169 	(pim->format == gs_image_format_chunky ||
2170 
2171 	 pim->format == gs_image_format_component_planar);
2172 
2173     int code;
2174 
2175     if (pie == 0)
2176 	return_error(gs_error_VMerror);
2177     pie->memory = mem;
2178     code = gdev_vector_begin_image(vdev, pis, pim, format, prect,
2179 				   pdcolor, pcpath, mem,
2180 				   &lips4v_image_enum_procs, pie);
2181     if (code < 0)
2182 	return code;
2183     *pinfo = (gx_image_enum_common_t *) pie;
2184 
2185     if (!pim->ImageMask) {
2186 	index = gs_color_space_get_index(pcs);
2187 	num_components = gs_color_space_num_components(pcs);
2188 
2189 	if (pim->CombineWithColor)
2190 	    can_do = false;
2191 	else {
2192 	    switch (index) {
2193 		case gs_color_space_index_DeviceGray:
2194 		if ((pim->Decode[0] != 0 || pim->Decode[1] != 1)
2195 		    && (pim->Decode[0] != 1 || pim->Decode[1] != 0))
2196 		    can_do = false;
2197 		break;
2198 		case gs_color_space_index_DeviceRGB:
2199 		/* LIPS �Ǥ� RGB ��ȿž���뤳�ȤϤǤ��ʤ� */
2200 		if (pim->Decode[0] != 0 || pim->Decode[1] != 1 ||
2201 		    pim->Decode[2] != 0 || pim->Decode[3] != 1 ||
2202 		    pim->Decode[4] != 0)
2203 		    can_do = false;
2204 		break;
2205 		default:
2206 		/*
2207 		   LIPS �Ǥ� L*a*b* �����Υ��顼���ڡ������Ȥ��ޤ���
2208 		   CIEBasedABC ��Ȥä�ɽ���Ǥ��ʤ����Ȥ�ʤ��ΤǤ�����
2209 		   ư���ǧ�Ǥ��ʤ��Τ����٥�δؿ��ˤޤ����뤳�Ȥ�
2210 		   �����㤤�ޤ���
2211 		   ������� CMYK �Υ��顼���ڡ������ߤ���...
2212 		 */
2213 		can_do = false;
2214 	    }
2215 	}
2216     }
2217     if (!can_do)
2218 	return gx_default_begin_image(dev, pis, pim, format, prect,
2219 				      pdcolor, pcpath, mem,
2220 				      &pie->default_info);
2221     else if (index == gs_color_space_index_DeviceGray) {
2222 	gx_drawing_color dcolor;
2223 
2224 	/* LIPS IV �Ǥϥ��졼���������ñ�����᡼�������顼����̿���
2225 	   �ƶ������Τǹ���������Ū�˻��ꤷ�ʤ���Фʤ�ʤ��� */
2226 	color_set_pure(&dcolor, vdev->black);
2227 	lips4v_setfillcolor(vdev, &dcolor);
2228     }
2229     if (pim->ImageMask || (pim->BitsPerComponent == 1 && num_components == 1)) {
2230 	if (pim->Decode[0] > pim->Decode[1])
2231 	    pdev->MaskReverse = 1;
2232 	else
2233 	    pdev->MaskReverse = 0;
2234     }
2235     /* Write the image/colorimage/imagemask preamble. */
2236     {
2237 	stream *s = gdev_vector_stream((gx_device_vector *) pdev);
2238 	int ax, ay, bx, by, cx, cy, dx, dy;
2239 	int tbyte;
2240 	gs_matrix imat;
2241 	int interpolate = 0;
2242 
2243 	if (pdev->TextMode) {
2244 	    sputc(s, LIPS_CSI);
2245 	    lputs(s, "&}");
2246 	    pdev->TextMode = FALSE;
2247 	}
2248 	gs_matrix_invert(&pim->ImageMatrix, &imat);
2249 	gs_matrix_multiply(&imat, &ctm_only(pis), &imat);
2250 	/*
2251 	   [xx xy yx yy tx ty]
2252 	   LIPS �κ�ɸ�Ϥ��Ѵ���Ԥʤ���
2253 
2254 	   }U{Ax}{Ay}{Bx}{By}{Cx}{Cy}{pie->height}{pie->width}
2255 	   {pim->BitsPerComponent}{0}{0}{1} LIPS_IS2
2256 	 */
2257 
2258 	/* }Q110{byte} LIPS_IS2 */
2259 	ax = imat.tx;
2260 	ay = imat.ty;
2261 	bx = imat.xx * pim->Width + imat.yx * pim->Height + imat.tx;
2262 	by = imat.xy * pim->Width + imat.yy * pim->Height + imat.ty;
2263 	cx = imat.yx * pim->Height + imat.tx;
2264 	cy = imat.yy * pim->Height + imat.ty;
2265 	dx = imat.xx * pim->Width + imat.tx;
2266 	dy = imat.xy * pim->Width + imat.ty;
2267 
2268 	if (pim->ImageMask) {
2269 	    tbyte =
2270 		(pie->width * pim->BitsPerComponent +
2271 		 7) / 8 * num_components * pie->height;
2272 	    pdev->ncomp = 1;
2273 	    if (tbyte == 1) {
2274 		/* LIPS IV �Ǥ� 1 dot �Υ��᡼�����ѷ�����Ⱥ�ɸ�������Х���
2275 		   ���롣��ä� 1 dot �Υ��᡼���϶���Ȥ��ƽ������롣 */
2276 		pdev->OneBitMask = true;
2277 		/* Draw Rectangle */
2278 		lputs(s, "2");
2279 		sput_lips_int(s, ax);
2280 		sput_lips_int(s, ay);
2281 		sput_lips_int(s, cx - ax);
2282 		sput_lips_int(s, cy - ay);
2283 		sput_lips_int(s, bx - cx);
2284 		sput_lips_int(s, by - cy);
2285 		sput_lips_int(s, dx - bx);
2286 		sput_lips_int(s, dy - by);
2287 		sputc(s, LIPS_IS2);
2288 		return 0;
2289 	    } else {
2290 		/* ������������̿�� - Ʃ�� */
2291 		if (pdev->MaskState != 1) {
2292 		    lputs(s, "}H1");
2293 		    sputc(s, LIPS_IS2);
2294 		    pdev->MaskState = 1;
2295 		}
2296 	    }
2297 	} else {
2298 	    /* ������������̿�� - ���ɤ� */
2299 	    if (pdev->MaskState != 0) {
2300 		lputs(s, "}H0");
2301 		sputc(s, LIPS_IS2);
2302 		pdev->MaskState = 0;
2303 	    }
2304 	    pdev->ncomp = num_components;
2305 	}
2306 
2307 	lputs(s, "}U");
2308 	sput_lips_int(s, ax);
2309 	sput_lips_int(s, ay);
2310 	sput_lips_int(s, bx);
2311 	sput_lips_int(s, by);
2312 	sput_lips_int(s, cx);
2313 	sput_lips_int(s, cy);
2314 	sput_lips_int(s, pie->height);
2315 	sput_lips_int(s, pie->width);
2316 	sput_lips_int(s, pim->BitsPerComponent);
2317 
2318 	if (pim->Interpolate) {
2319 	    if (pim->BitsPerComponent * pie->num_planes == 1)
2320 		interpolate = 1;
2321 	    else
2322 		interpolate = 3;
2323 	}
2324 	if (pim->ImageMask) {	/* 1bit �ΤȤ� */
2325 	    lputs(s, "0");
2326 	} else {
2327 	    if (index == gs_color_space_index_DeviceGray)
2328 		lputs(s, "0");
2329 	    else {
2330 		if (format == gs_image_format_chunky)	/* RGBRGBRGB... */
2331 		    sputc(s, 0x3a);
2332 		else		/* RRR...GGG...BBB... */
2333 		    sputc(s, 0x3b);
2334 	    }
2335 	}
2336 	if (interpolate > 0)
2337 	    sput_lips_int(s, interpolate);
2338 	sputc(s, LIPS_IS2);
2339     }
2340     return 0;
2341 }
2342 
2343 /* Process the next piece of an image. */
2344 private int
lips4v_image_plane_data(gx_image_enum_common_t * info,const gx_image_plane_t * planes,int height,int * rows_used)2345 lips4v_image_plane_data(gx_image_enum_common_t * info,
2346 			const gx_image_plane_t * planes, int height,
2347 			int *rows_used)
2348 {
2349     gx_device *dev = info->dev;
2350     gx_device_vector *const vdev = (gx_device_vector *) dev;
2351     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
2352     gdev_vector_image_enum_t *pie = (gdev_vector_image_enum_t *) info;
2353 
2354     stream *s = gdev_vector_stream((gx_device_vector *) pdev);
2355     int y;
2356 
2357     if (pdev->OneBitMask) {
2358 	/*
2359 	   lputs(s, "\200");
2360 	 */
2361 	pie->y += height;
2362 	return 1;
2363     }
2364     if (pie->default_info)
2365 	return gx_image_plane_data(pie->default_info, planes, height);
2366     gx_image_plane_data(pie->bbox_info, planes, height);
2367     {
2368 	int plane;
2369 	int width_bytes, tbyte;
2370 	byte *buf;
2371 
2372 	width_bytes =
2373 	    (pie->width * pie->bits_per_pixel / pdev->ncomp +
2374 	     7) / 8 * pdev->ncomp;
2375 	tbyte = width_bytes * height;
2376 	buf = gs_alloc_bytes(vdev->memory, tbyte, "lips4v_image_data(buf)");
2377 
2378 	for (plane = 0; plane < pie->num_planes; ++plane)
2379 	    for (y = 0; y < height; ++y) {
2380 		memcpy(buf + y * width_bytes,
2381 		       planes[plane].data +
2382 		       ((planes[plane].data_x * pie->bits_per_pixel) >> 3)
2383 		       + y * planes[plane].raster, width_bytes);
2384 	    }
2385 
2386 	lputs(s, "}Q10");
2387 
2388 	if ((pie->bits_per_pixel > 1 && pdev->ncomp == 1) ||
2389 	    pdev->MaskReverse == 0) {
2390 	    lips4v_write_image_data(vdev, buf, tbyte, TRUE);
2391 	} else
2392 	    lips4v_write_image_data(vdev, buf, tbyte, FALSE);
2393 
2394 	gs_free_object(vdev->memory, buf, "lips4v_image_data(buf)");
2395 
2396     }
2397 
2398     return (pie->y += height) >= pie->height;
2399 }
2400 
2401 private int
lips4v_image_end_image(gx_image_enum_common_t * info,bool draw_last)2402 lips4v_image_end_image(gx_image_enum_common_t * info, bool draw_last)
2403 {
2404     gx_device *dev = info->dev;
2405     gx_device_vector *const vdev = (gx_device_vector *) dev;
2406     gx_device_lips4v *const pdev = (gx_device_lips4v *) dev;
2407     gdev_vector_image_enum_t *pie = (gdev_vector_image_enum_t *) info;
2408     stream *s = gdev_vector_stream((gx_device_vector *) pdev);
2409     int code;
2410 
2411     if (pdev->OneBitMask)
2412 	pdev->OneBitMask = false;
2413     else
2414 	lputs(s, "}Q1100");
2415 	sputc(s, LIPS_IS2);	/* End of Image */
2416 
2417     pdev->MaskReverse = -1;
2418 
2419     code = gdev_vector_end_image(vdev, (gdev_vector_image_enum_t *) pie,
2420 				 draw_last, pdev->white);
2421     return code;
2422 }
2423