133
132
#define pclxl_device_procs(map_rgb_color, map_color_rgb)\
136
NULL, /* get_initial_matrix */\
137
NULL, /* sync_output */\
140
map_rgb_color, /* differs */\
141
map_color_rgb, /* differs */\
142
gdev_vector_fill_rectangle,\
143
NULL, /* tile_rectangle */\
146
NULL, /* draw_line */\
147
NULL, /* get_bits */\
150
NULL, /* map_cmyk_color */\
151
NULL, /* get_xfont_procs */\
152
NULL, /* get_xfont_device */\
153
NULL, /* map_rgb_alpha_color */\
154
gx_page_device_get_page_device,\
155
NULL, /* get_alpha_bits */\
156
NULL, /* copy_alpha */\
157
NULL, /* get_band */\
158
NULL, /* copy_rop */\
159
gdev_vector_fill_path,\
160
gdev_vector_stroke_path,\
162
gdev_vector_fill_trapezoid,\
163
gdev_vector_fill_parallelogram,\
164
gdev_vector_fill_triangle,\
165
NULL /****** WRONG ******/, /* draw_thin_line */\
167
NULL, /* image_data */\
168
NULL, /* end_image */\
169
NULL, /* strip_tile_rectangle */\
170
pclxl_strip_copy_rop\
135
NULL, /* get_initial_matrix */\
136
NULL, /* sync_output */\
139
map_rgb_color, /* differs */\
140
map_color_rgb, /* differs */\
141
gdev_vector_fill_rectangle,\
142
NULL, /* tile_rectangle */\
145
NULL, /* draw_line */\
146
NULL, /* get_bits */\
149
NULL, /* map_cmyk_color */\
150
NULL, /* get_xfont_procs */\
151
NULL, /* get_xfont_device */\
152
NULL, /* map_rgb_alpha_color */\
153
gx_page_device_get_page_device,\
154
NULL, /* get_alpha_bits */\
155
NULL, /* copy_alpha */\
156
NULL, /* get_band */\
157
NULL, /* copy_rop */\
158
gdev_vector_fill_path,\
159
gdev_vector_stroke_path,\
161
gdev_vector_fill_trapezoid,\
162
gdev_vector_fill_parallelogram,\
163
gdev_vector_fill_triangle,\
164
NULL /****** WRONG ******/, /* draw_thin_line */\
166
NULL, /* image_data */\
167
NULL, /* end_image */\
168
NULL, /* strip_tile_rectangle */\
169
pclxl_strip_copy_rop\
173
172
const gx_device_pclxl gs_pxlmono_device = {
215
214
pclxl_set_color_space(gx_device_pclxl * xdev, pxeColorSpace_t color_space)
217
216
if (xdev->color_space != color_space) {
218
stream *s = pclxl_stream(xdev);
217
stream *s = pclxl_stream(xdev);
220
px_put_ub(s, (byte)color_space);
221
px_put_ac(s, pxaColorSpace, pxtSetColorSpace);
222
xdev->color_space = color_space;
223
xdev->palette.size = 0; /* purge the cached palette */
219
px_put_ub(s, (byte)color_space);
220
px_put_ac(s, pxaColorSpace, pxtSetColorSpace);
221
xdev->color_space = color_space;
222
xdev->palette.size = 0; /* purge the cached palette */
227
226
pclxl_set_color_palette(gx_device_pclxl * xdev, pxeColorSpace_t color_space,
228
const byte * palette, uint palette_size)
227
const byte * palette, uint palette_size)
230
229
if (xdev->color_space != color_space ||
231
xdev->palette.size != palette_size ||
232
memcmp(xdev->palette.data, palette, palette_size)
234
stream *s = pclxl_stream(xdev);
235
static const byte csp_[] = {
237
DUB(e8Bit), DA(pxaPaletteDepth),
230
xdev->palette.size != palette_size ||
231
memcmp(xdev->palette.data, palette, palette_size)
233
stream *s = pclxl_stream(xdev);
234
static const byte csp_[] = {
236
DUB(e8Bit), DA(pxaPaletteDepth),
241
px_put_ub(s, (byte)color_space);
243
px_put_u(s, palette_size);
244
px_put_bytes(s, palette, palette_size);
245
px_put_ac(s, pxaPaletteData, pxtSetColorSpace);
246
xdev->color_space = color_space;
247
xdev->palette.size = palette_size;
248
memcpy(xdev->palette.data, palette, palette_size);
240
px_put_ub(s, (byte)color_space);
242
px_put_u(s, palette_size);
243
px_put_bytes(s, palette, palette_size);
244
px_put_ac(s, pxaPaletteData, pxtSetColorSpace);
245
xdev->color_space = color_space;
246
xdev->palette.size = palette_size;
247
memcpy(xdev->palette.data, palette, palette_size);
279
278
/* Set a drawing RGB color. */
281
280
pclxl_set_color(gx_device_pclxl * xdev, const gx_drawing_color * pdc,
282
px_attribute_t null_source, px_tag_t op)
281
px_attribute_t null_source, px_tag_t op)
284
283
stream *s = pclxl_stream(xdev);
286
285
if (gx_dc_is_pure(pdc)) {
287
gx_color_index color = gx_dc_pure_color(pdc);
289
if (op == pxtSetPenSource) xdev->pen_null = false;
290
if (op == pxtSetBrushSource) xdev->brush_null = false;
292
if (xdev->color_info.num_components == 1 || RGB_IS_GRAY(color)) {
293
pclxl_set_color_space(xdev, eGray);
294
px_put_uba(s, (byte) color, pxaGrayLevel);
296
pclxl_set_color_space(xdev, eRGB);
297
spputc(s, pxt_ubyte_array);
299
spputc(s, (byte) (color >> 16));
300
spputc(s, (byte) (color >> 8));
301
spputc(s, (byte) color);
302
px_put_a(s, pxaRGBColor);
286
gx_color_index color = gx_dc_pure_color(pdc);
288
if (op == pxtSetPenSource) xdev->pen_null = false;
289
if (op == pxtSetBrushSource) xdev->brush_null = false;
291
if (xdev->color_info.num_components == 1 || RGB_IS_GRAY(color)) {
292
pclxl_set_color_space(xdev, eGray);
293
px_put_uba(s, (byte) color, pxaGrayLevel);
295
pclxl_set_color_space(xdev, eRGB);
296
spputc(s, pxt_ubyte_array);
298
spputc(s, (byte) (color >> 16));
299
spputc(s, (byte) (color >> 8));
300
spputc(s, (byte) color);
301
px_put_a(s, pxaRGBColor);
304
303
} else if (gx_dc_is_null(pdc) || !color_is_set(pdc)) {
305
if (op == pxtSetPenSource || op == pxtSetBrushSource)
306
return pclxl_set_cached_nulls(xdev, null_source, op);
308
px_put_uba(s, 0, null_source);
304
if (op == pxtSetPenSource || op == pxtSetBrushSource)
305
return pclxl_set_cached_nulls(xdev, null_source, op);
307
px_put_uba(s, 0, null_source);
310
return_error(gs_error_rangecheck);
309
return_error(gs_error_rangecheck);
311
310
spputc(s, (byte)op);
439
438
int count = xdev->points.count;
442
stream *s = pclxl_stream(xdev);
444
int x = xdev->points.current.x, y = xdev->points.current.y;
445
int uor = 0, sor = 0;
446
pxeDataType_t data_type;
448
byte diffs[NUM_POINTS * 2];
451
int temp_origin_x = 0, temp_origin_y = 0;
452
int count_smalls = 0;
454
if (xdev->points.type != POINTS_NONE) {
455
for (i = 0; i < count; ++i) {
456
if ((abs(xdev->points.data[i].x) > 0x7FFF) || (abs(xdev->points.data[i].y) > 0x7FFF))
458
if ((abs(xdev->points.data[i].x) < 0x8000) && (abs(xdev->points.data[i].y) < 0x8000)) {
459
if ((temp_origin_x != xdev->points.data[i].x) || (temp_origin_y != xdev->points.data[i].y)) {
460
temp_origin_x = xdev->points.data[i].x;
461
temp_origin_y = xdev->points.data[i].y;
467
/* if there are some points with small co-ordinates, we set origin to it
468
before scaling, an unset afterwards. This works around problems
469
for small co-ordinates being moved snapped to 32767 x 32767 grid points;
470
if there are more than 1, the other points
471
will be in-accurate, unfortunately */
473
pclxl_set_page_origin(s, temp_origin_x, temp_origin_y);
475
for (i = 0; i < count; ++i) {
476
x_scale = max(((floatp) abs(xdev->points.data[i].x - temp_origin_x))/0x7FFF , x_scale);
477
y_scale = max(((floatp) abs(xdev->points.data[i].y - temp_origin_y))/0x7FFF , y_scale);
479
for (i = 0; i < count; ++i) {
480
xdev->points.data[i].x = (int)((xdev->points.data[i].x - temp_origin_x)/x_scale + 0.5);
481
xdev->points.data[i].y = (int)((xdev->points.data[i].y - temp_origin_y)/y_scale + 0.5);
483
x = (int)((x - temp_origin_x)/x_scale + 0.5);
484
y = (int)((y - temp_origin_y)/y_scale + 0.5);
485
pclxl_set_page_scale(xdev, x_scale, y_scale);
487
/* don't reset origin if we did not scale */
492
* Writing N lines using a point list requires 11 + 4*N or 11 +
493
* 2*N bytes, as opposed to 8*N bytes using separate commands;
494
* writing N curves requires 11 + 12*N or 11 + 6*N bytes
495
* vs. 22*N. So it's always shorter to write curves with a
496
* list (except for N = 1 with full-size coordinates, but since
497
* the difference is only 1 byte, we don't bother to ever use
498
* the non-list form), but lines are shorter only if N >= 3
499
* (again, with a 1-byte difference if N = 2 and byte
502
switch (xdev->points.type) {
508
for (i = 0; i < count; ++i) {
509
px_put_ssp(s, xdev->points.data[i].x,
510
xdev->points.data[i].y);
511
px_put_a(s, pxaEndPoint);
514
pclxl_unset_page_scale(xdev);
516
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
519
/* See if we can use byte values. */
520
for (i = di = 0; i < count; ++i, di += 2) {
521
int dx = xdev->points.data[i].x - x;
522
int dy = xdev->points.data[i].y - y;
524
diffs[di] = (byte) dx;
525
diffs[di + 1] = (byte) dy;
527
sor |= (dx + 0x80) | (dy + 0x80);
532
else if (!(sor & ~0xff))
537
/* Use byte values. */
538
useb:px_put_np(s, count, data_type);
540
px_put_data_length(s, count * 2); /* 2 bytes per point */
541
px_put_bytes(s, diffs, count * 2);
542
pclxl_unset_page_scale(xdev);
544
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
548
/* See if we can use byte values. */
549
for (i = di = 0; i < count; i += 3, di += 6) {
550
int dx1 = xdev->points.data[i].x - x;
551
int dy1 = xdev->points.data[i].y - y;
552
int dx2 = xdev->points.data[i + 1].x - x;
553
int dy2 = xdev->points.data[i + 1].y - y;
554
int dx = xdev->points.data[i + 2].x - x;
555
int dy = xdev->points.data[i + 2].y - y;
557
diffs[di] = (byte) dx1;
558
diffs[di + 1] = (byte) dy1;
559
diffs[di + 2] = (byte) dx2;
560
diffs[di + 3] = (byte) dy2;
561
diffs[di + 4] = (byte) dx;
562
diffs[di + 5] = (byte) dy;
563
uor |= dx1 | dy1 | dx2 | dy2 | dx | dy;
564
sor |= (dx1 + 0x80) | (dy1 + 0x80) |
565
(dx2 + 0x80) | (dy2 + 0x80) |
566
(dx + 0x80) | (dy + 0x80);
571
else if (!(sor & ~0xff))
575
op = pxtBezierRelPath;
577
default: /* can't happen */
578
return_error(gs_error_unknownerror);
580
px_put_np(s, count, eSInt16);
582
px_put_data_length(s, count * 4); /* 2 UInt16s per point */
583
for (i = 0; i < count; ++i) {
584
px_put_s(s, xdev->points.data[i].x);
585
px_put_s(s, xdev->points.data[i].y);
587
pclxl_unset_page_scale(xdev);
589
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
441
stream *s = pclxl_stream(xdev);
443
int x = xdev->points.current.x, y = xdev->points.current.y;
444
int uor = 0, sor = 0;
445
pxeDataType_t data_type;
447
byte diffs[NUM_POINTS * 2];
450
int temp_origin_x = 0, temp_origin_y = 0;
451
int count_smalls = 0;
453
if (xdev->points.type != POINTS_NONE) {
454
for (i = 0; i < count; ++i) {
455
if ((abs(xdev->points.data[i].x) > 0x7FFF) || (abs(xdev->points.data[i].y) > 0x7FFF))
457
if ((abs(xdev->points.data[i].x) < 0x8000) && (abs(xdev->points.data[i].y) < 0x8000)) {
458
if ((temp_origin_x != xdev->points.data[i].x) || (temp_origin_y != xdev->points.data[i].y)) {
459
temp_origin_x = xdev->points.data[i].x;
460
temp_origin_y = xdev->points.data[i].y;
466
/* if there are some points with small co-ordinates, we set origin to it
467
before scaling, an unset afterwards. This works around problems
468
for small co-ordinates being moved snapped to 32767 x 32767 grid points;
469
if there are more than 1, the other points
470
will be in-accurate, unfortunately */
472
pclxl_set_page_origin(s, temp_origin_x, temp_origin_y);
474
for (i = 0; i < count; ++i) {
475
x_scale = max(((floatp) abs(xdev->points.data[i].x - temp_origin_x))/0x7FFF , x_scale);
476
y_scale = max(((floatp) abs(xdev->points.data[i].y - temp_origin_y))/0x7FFF , y_scale);
478
for (i = 0; i < count; ++i) {
479
xdev->points.data[i].x = (int)((xdev->points.data[i].x - temp_origin_x)/x_scale + 0.5);
480
xdev->points.data[i].y = (int)((xdev->points.data[i].y - temp_origin_y)/y_scale + 0.5);
482
x = (int)((x - temp_origin_x)/x_scale + 0.5);
483
y = (int)((y - temp_origin_y)/y_scale + 0.5);
484
pclxl_set_page_scale(xdev, x_scale, y_scale);
486
/* don't reset origin if we did not scale */
491
* Writing N lines using a point list requires 11 + 4*N or 11 +
492
* 2*N bytes, as opposed to 8*N bytes using separate commands;
493
* writing N curves requires 11 + 12*N or 11 + 6*N bytes
494
* vs. 22*N. So it's always shorter to write curves with a
495
* list (except for N = 1 with full-size coordinates, but since
496
* the difference is only 1 byte, we don't bother to ever use
497
* the non-list form), but lines are shorter only if N >= 3
498
* (again, with a 1-byte difference if N = 2 and byte
501
switch (xdev->points.type) {
507
for (i = 0; i < count; ++i) {
508
px_put_ssp(s, xdev->points.data[i].x,
509
xdev->points.data[i].y);
510
px_put_a(s, pxaEndPoint);
513
pclxl_unset_page_scale(xdev);
515
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
518
/* See if we can use byte values. */
519
for (i = di = 0; i < count; ++i, di += 2) {
520
int dx = xdev->points.data[i].x - x;
521
int dy = xdev->points.data[i].y - y;
523
diffs[di] = (byte) dx;
524
diffs[di + 1] = (byte) dy;
526
sor |= (dx + 0x80) | (dy + 0x80);
531
else if (!(sor & ~0xff))
536
/* Use byte values. */
537
useb:px_put_np(s, count, data_type);
539
px_put_data_length(s, count * 2); /* 2 bytes per point */
540
px_put_bytes(s, diffs, count * 2);
541
pclxl_unset_page_scale(xdev);
543
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
547
/* See if we can use byte values. */
548
for (i = di = 0; i < count; i += 3, di += 6) {
549
int dx1 = xdev->points.data[i].x - x;
550
int dy1 = xdev->points.data[i].y - y;
551
int dx2 = xdev->points.data[i + 1].x - x;
552
int dy2 = xdev->points.data[i + 1].y - y;
553
int dx = xdev->points.data[i + 2].x - x;
554
int dy = xdev->points.data[i + 2].y - y;
556
diffs[di] = (byte) dx1;
557
diffs[di + 1] = (byte) dy1;
558
diffs[di + 2] = (byte) dx2;
559
diffs[di + 3] = (byte) dy2;
560
diffs[di + 4] = (byte) dx;
561
diffs[di + 5] = (byte) dy;
562
uor |= dx1 | dy1 | dx2 | dy2 | dx | dy;
563
sor |= (dx1 + 0x80) | (dy1 + 0x80) |
564
(dx2 + 0x80) | (dy2 + 0x80) |
565
(dx + 0x80) | (dy + 0x80);
570
else if (!(sor & ~0xff))
574
op = pxtBezierRelPath;
576
default: /* can't happen */
577
return_error(gs_error_unknownerror);
579
px_put_np(s, count, eSInt16);
581
px_put_data_length(s, count * 4); /* 2 UInt16s per point */
582
for (i = 0; i < count; ++i) {
583
px_put_s(s, xdev->points.data[i].x);
584
px_put_s(s, xdev->points.data[i].y);
586
pclxl_unset_page_scale(xdev);
588
pclxl_set_page_origin(s, -temp_origin_x, -temp_origin_y);
590
589
zap:xdev->points.type = POINTS_NONE;
591
xdev->points.count = 0;
590
xdev->points.count = 0;
634
633
px_put_usa(s, y, pxaStartLine);
635
634
px_put_usa(s, height, pxaBlockHeight);
637
stream_RLE_state rlstate;
638
stream_cursor_write w;
639
stream_cursor_read r;
642
* H-P printers require that all the data for an operator be
643
* contained in a single data block. Thus, we must allocate a
644
* temporary buffer for the compressed data. Currently we don't go
645
* to the trouble of doing two passes if we can't allocate a buffer
646
* large enough for the entire transfer.
648
byte *buf = gs_alloc_bytes(xdev->v_memory, num_bytes,
649
"pclxl_write_image_data");
653
s_RLE_set_defaults_inline(&rlstate);
654
rlstate.EndOfData = false;
655
s_RLE_init_inline(&rlstate);
657
w.limit = w.ptr + num_bytes;
659
* If we ever overrun the buffer, it means that the compressed
660
* data was larger than the uncompressed. If this happens,
661
* write the data uncompressed.
663
for (i = 0; i < height; ++i) {
664
r.ptr = data + i * raster - 1;
665
r.limit = r.ptr + width_bytes;
666
if ((*s_RLE_template.process)
667
((stream_state *) & rlstate, &r, &w, true) != 0 ||
671
r.ptr = (const byte *)"\000\000\000\000\000";
672
r.limit = r.ptr + (-(int)width_bytes & 3);
673
if ((*s_RLE_template.process)
674
((stream_state *) & rlstate, &r, &w, true) != 0 ||
680
if ((*s_RLE_template.process)
681
((stream_state *) & rlstate, &r, &w, true) != 0
685
uint count = w.ptr + 1 - buf;
687
px_put_ub(s, eRLECompression);
688
px_put_ac(s, pxaCompressMode, pxtReadImage);
689
px_put_data_length(s, count);
690
px_put_bytes(s, buf, count);
692
gs_free_object(xdev->v_memory, buf, "pclxl_write_image_data");
636
stream_RLE_state rlstate;
637
stream_cursor_write w;
638
stream_cursor_read r;
641
* H-P printers require that all the data for an operator be
642
* contained in a single data block. Thus, we must allocate a
643
* temporary buffer for the compressed data. Currently we don't go
644
* to the trouble of doing two passes if we can't allocate a buffer
645
* large enough for the entire transfer.
647
byte *buf = gs_alloc_bytes(xdev->v_memory, num_bytes,
648
"pclxl_write_image_data");
652
s_RLE_set_defaults_inline(&rlstate);
653
rlstate.EndOfData = false;
654
s_RLE_init_inline(&rlstate);
656
w.limit = w.ptr + num_bytes;
658
* If we ever overrun the buffer, it means that the compressed
659
* data was larger than the uncompressed. If this happens,
660
* write the data uncompressed.
662
for (i = 0; i < height; ++i) {
663
r.ptr = data + i * raster - 1;
664
r.limit = r.ptr + width_bytes;
665
if ((*s_RLE_template.process)
666
((stream_state *) & rlstate, &r, &w, true) != 0 ||
670
r.ptr = (const byte *)"\000\000\000\000\000";
671
r.limit = r.ptr + (-(int)width_bytes & 3);
672
if ((*s_RLE_template.process)
673
((stream_state *) & rlstate, &r, &w, true) != 0 ||
679
if ((*s_RLE_template.process)
680
((stream_state *) & rlstate, &r, &w, true) != 0
684
uint count = w.ptr + 1 - buf;
686
px_put_ub(s, eRLECompression);
687
px_put_ac(s, pxaCompressMode, pxtReadImage);
688
px_put_data_length(s, count);
689
px_put_bytes(s, buf, count);
691
gs_free_object(xdev->v_memory, buf, "pclxl_write_image_data");
694
693
ncfree:gs_free_object(xdev->v_memory, buf, "pclxl_write_image_data");
950
949
stream *s = pclxl_stream(xdev);
952
951
if (size > MAX_CHAR_SIZE)
954
953
index = pclxl_char_index(xdev, id);
955
954
if ((ccode = xdev->chars.table[index]) < 2) {
956
/* Enter the character in the table. */
957
while (xdev->chars.used + size > MAX_CHAR_DATA ||
958
xdev->chars.count >= MAX_CACHED_CHARS - 2
960
ccode = xdev->chars.next_out;
961
index = pclxl_char_index(xdev, xdev->chars.data[ccode].id);
962
pclxl_remove_char(xdev, index);
963
xdev->chars.next_out =
964
(ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
966
index = pclxl_char_index(xdev, id);
967
ccode = xdev->chars.next_in;
968
xdev->chars.data[ccode].id = id;
969
xdev->chars.data[ccode].size = size;
970
xdev->chars.table[index] = ccode;
971
xdev->chars.next_in =
972
(ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
973
if (!xdev->chars.count++) {
974
/* This is the very first character. */
975
pclxl_write_font_name(xdev);
976
pclxl_define_bitmap_font(xdev);
978
xdev->chars.used += size;
979
pclxl_write_font_name(xdev);
980
pclxl_define_bitmap_char(xdev, ccode, data, raster, w, h);
955
/* Enter the character in the table. */
956
while (xdev->chars.used + size > MAX_CHAR_DATA ||
957
xdev->chars.count >= MAX_CACHED_CHARS - 2
959
ccode = xdev->chars.next_out;
960
index = pclxl_char_index(xdev, xdev->chars.data[ccode].id);
961
pclxl_remove_char(xdev, index);
962
xdev->chars.next_out =
963
(ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
965
index = pclxl_char_index(xdev, id);
966
ccode = xdev->chars.next_in;
967
xdev->chars.data[ccode].id = id;
968
xdev->chars.data[ccode].size = size;
969
xdev->chars.table[index] = ccode;
970
xdev->chars.next_in =
971
(ccode == MAX_CACHED_CHARS - 1 ? 2 : ccode + 1);
972
if (!xdev->chars.count++) {
973
/* This is the very first character. */
974
pclxl_write_font_name(xdev);
975
pclxl_define_bitmap_font(xdev);
977
xdev->chars.used += size;
978
pclxl_write_font_name(xdev);
979
pclxl_define_bitmap_char(xdev, ccode, data, raster, w, h);
982
981
if (!xdev->font_set) {
983
pclxl_write_font_name(xdev);
984
pclxl_set_font(xdev);
985
xdev->font_set = true;
982
pclxl_write_font_name(xdev);
983
pclxl_set_font(xdev);
984
xdev->font_set = true;
989
cc_bytes[0] = (byte) ccode;
990
cc_bytes[1] = ccode >> 8;
991
px_put_string(s, cc_bytes, 1, cc_bytes[1] != 0);
988
cc_bytes[0] = (byte) ccode;
989
cc_bytes[1] = ccode >> 8;
990
px_put_string(s, cc_bytes, 1, cc_bytes[1] != 0);
993
992
px_put_ac(s, pxaTextData, pxtText);
1120
1119
pclxl_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop,
1121
gs_logical_operation_t diff)
1120
gs_logical_operation_t diff)
1123
1122
stream *s = gdev_vector_stream(vdev);
1125
1124
if (diff & lop_S_transparent) {
1126
px_put_ub(s, (byte)(lop & lop_S_transparent ? 1 : 0));
1127
px_put_ac(s, pxaTxMode, pxtSetSourceTxMode);
1125
px_put_ub(s, (byte)(lop & lop_S_transparent ? 1 : 0));
1126
px_put_ac(s, pxaTxMode, pxtSetSourceTxMode);
1129
1128
if (diff & lop_T_transparent) {
1130
px_put_ub(s, (byte)(lop & lop_T_transparent ? 1 : 0));
1131
px_put_ac(s, pxaTxMode, pxtSetPaintTxMode);
1129
px_put_ub(s, (byte)(lop & lop_T_transparent ? 1 : 0));
1130
px_put_ac(s, pxaTxMode, pxtSetPaintTxMode);
1133
1132
if (lop_rop(diff)) {
1134
px_put_ub(s, (byte)lop_rop(lop));
1135
px_put_ac(s, pxaROP3, pxtSetROP);
1133
px_put_ub(s, (byte)lop_rop(lop));
1134
px_put_ac(s, pxaROP3, pxtSetROP);
1141
pclxl_can_handle_hl_color(gx_device_vector * vdev, const gs_imager_state * pis,
1140
pclxl_can_handle_hl_color(gx_device_vector * vdev, const gs_imager_state * pis,
1142
1141
const gx_drawing_color * pdc)
1148
pclxl_setfillcolor(gx_device_vector * vdev, const gs_imager_state * pis,
1147
pclxl_setfillcolor(gx_device_vector * vdev, const gs_imager_state * pis,
1149
1148
const gx_drawing_color * pdc)
1151
1150
gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
1210
1209
pclxl_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
1211
gx_path_type_t type)
1210
gx_path_type_t type)
1213
1212
gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
1214
1213
int code = pclxl_flush_points(xdev);
1218
1217
return pclxl_set_cursor(xdev,
1219
xdev->points.current.x = (int)(x+0.5),
1220
xdev->points.current.y = (int)(y+0.5));
1218
xdev->points.current.x = (int)(x+0.5),
1219
xdev->points.current.y = (int)(y+0.5));
1224
1223
pclxl_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y,
1225
gx_path_type_t type)
1224
gx_path_type_t type)
1227
1226
gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
1229
1228
if (xdev->points.type != POINTS_LINES ||
1230
xdev->points.count >= NUM_POINTS
1232
if (xdev->points.type != POINTS_NONE) {
1233
int code = pclxl_flush_points(xdev);
1229
xdev->points.count >= NUM_POINTS
1231
if (xdev->points.type != POINTS_NONE) {
1232
int code = pclxl_flush_points(xdev);
1238
xdev->points.current.x = (int)(x0+0.5);
1239
xdev->points.current.y = (int)(y0+0.5);
1240
xdev->points.type = POINTS_LINES;
1237
xdev->points.current.x = (int)(x0+0.5);
1238
xdev->points.current.y = (int)(y0+0.5);
1239
xdev->points.type = POINTS_LINES;
1242
gs_int_point *ppt = &xdev->points.data[xdev->points.count++];
1241
gs_int_point *ppt = &xdev->points.data[xdev->points.count++];
1244
ppt->x = (int)(x+0.5), ppt->y = (int)(y+0.5);
1243
ppt->x = (int)(x+0.5), ppt->y = (int)(y+0.5);
1250
1249
pclxl_curveto(gx_device_vector * vdev, floatp x0, floatp y0,
1251
floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3,
1252
gx_path_type_t type)
1250
floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3,
1251
gx_path_type_t type)
1254
1253
gx_device_pclxl *const xdev = (gx_device_pclxl *)vdev;
1256
1255
if (xdev->points.type != POINTS_CURVES ||
1257
xdev->points.count >= NUM_POINTS - 2
1259
if (xdev->points.type != POINTS_NONE) {
1260
int code = pclxl_flush_points(xdev);
1256
xdev->points.count >= NUM_POINTS - 2
1258
if (xdev->points.type != POINTS_NONE) {
1259
int code = pclxl_flush_points(xdev);
1265
xdev->points.current.x = (int)(x0+0.5);
1266
xdev->points.current.y = (int)(y0+0.5);
1267
xdev->points.type = POINTS_CURVES;
1264
xdev->points.current.x = (int)(x0+0.5);
1265
xdev->points.current.y = (int)(y0+0.5);
1266
xdev->points.type = POINTS_CURVES;
1270
gs_int_point *ppt = &xdev->points.data[xdev->points.count];
1269
gs_int_point *ppt = &xdev->points.data[xdev->points.count];
1272
ppt->x = (int)(x1+0.5), ppt->y = (int)(y1+0.5), ++ppt;
1273
ppt->x = (int)(x2+0.5), ppt->y = (int)(y2+0.5), ++ppt;
1274
ppt->x = (int)(x3+0.5), ppt->y = (int)(y3+0.5);
1271
ppt->x = (int)(x1+0.5), ppt->y = (int)(y1+0.5), ++ppt;
1272
ppt->x = (int)(x2+0.5), ppt->y = (int)(y2+0.5), ++ppt;
1273
ppt->x = (int)(x3+0.5), ppt->y = (int)(y3+0.5);
1276
1275
xdev->points.count += 3;
1449
1448
fit_copy(dev, data, data_x, raster, id, x, y, w, h);
1450
1449
code = gdev_vector_update_clip_path(vdev, NULL);
1454
1453
/* write_image_data() needs byte-alignment,
1455
1454
* and gx_default_copy_* is more efficient than pxlcl_*
1456
1455
* for small rasters. See details in copy_color().
1458
1457
if ( ((data_x & 7) != 0) || (h == 1) || (w == 1) )
1459
return gx_default_copy_mono(dev, data, data_x, raster, id,
1460
x, y, w, h, zero, one);
1458
return gx_default_copy_mono(dev, data, data_x, raster, id,
1459
x, y, w, h, zero, one);
1462
1461
pclxl_set_cursor(xdev, x, y);
1463
1462
if (id != gs_no_id && zero == gx_no_color_index &&
1464
one != gx_no_color_index && data_x == 0
1466
gx_drawing_color dcolor;
1468
code = gdev_vector_update_log_op(vdev, rop3_T|lop_T_transparent);
1472
set_nonclient_dev_color(&dcolor, one);
1473
pclxl_setfillcolor(vdev, NULL, &dcolor);
1474
if (pclxl_copy_text_char(xdev, data, raster, id, w, h) >= 0)
1463
one != gx_no_color_index && data_x == 0
1465
gx_drawing_color dcolor;
1467
code = gdev_vector_update_log_op(vdev, rop3_T|lop_T_transparent);
1471
set_nonclient_dev_color(&dcolor, one);
1472
pclxl_setfillcolor(vdev, NULL, &dcolor);
1473
if (pclxl_copy_text_char(xdev, data, raster, id, w, h) >= 0)
1478
1477
* The following doesn't work if we're writing white with a mask.
1495
1494
* There is a further refinement to this algorithm - it appears that
1496
1495
* black+mask is treated specially by the vector driver core (rendered
1497
* as transparent on white), and does not work as non-white + mask.
1496
* as transparent on white), and does not work as non-white + mask.
1498
1497
* So Instead we set mask color to white and do (S & D) (i.e. draw
1499
1498
* background on mask, instead of transparent on mask).
1502
1501
if (zero == gx_no_color_index) {
1503
if (one == gx_no_color_index)
1507
lop = (rop3_S & rop3_D);
1509
lop = rop3_S | lop_S_transparent;
1513
lop = rop3_S | (rop3_D & rop3_not(rop3_S));
1502
if (one == gx_no_color_index)
1506
lop = (rop3_S & rop3_D);
1508
lop = rop3_S | lop_S_transparent;
1512
lop = rop3_S | (rop3_D & rop3_not(rop3_S));
1516
1515
} else if (one == gx_no_color_index) {
1517
if (zero != white) {
1518
if (zero == black) {
1519
lop = (rop3_S & rop3_D);
1521
lop = rop3_S | lop_S_transparent;
1525
lop = rop3_S | (rop3_D & rop3_not(rop3_S));
1516
if (zero != white) {
1517
if (zero == black) {
1518
lop = (rop3_S & rop3_D);
1520
lop = rop3_S | lop_S_transparent;
1524
lop = rop3_S | (rop3_D & rop3_not(rop3_S));
1532
1531
if (dev->color_info.num_components == 1 ||
1533
(RGB_IS_GRAY(color0) && RGB_IS_GRAY(color1))
1535
palette[0] = (byte) color0;
1536
palette[1] = (byte) color1;
1538
color_space = eGray;
1539
if_debug2('b', "color palette %02X %02X\n", palette[0], palette[1]);
1532
(RGB_IS_GRAY(color0) && RGB_IS_GRAY(color1))
1534
palette[0] = (byte) color0;
1535
palette[1] = (byte) color1;
1537
color_space = eGray;
1538
if_debug2('b', "color palette %02X %02X\n", palette[0], palette[1]);
1541
palette[0] = (byte) (color0 >> 16);
1542
palette[1] = (byte) (color0 >> 8);
1543
palette[2] = (byte) color0;
1544
palette[3] = (byte) (color1 >> 16);
1545
palette[4] = (byte) (color1 >> 8);
1546
palette[5] = (byte) color1;
1540
palette[0] = (byte) (color0 >> 16);
1541
palette[1] = (byte) (color0 >> 8);
1542
palette[2] = (byte) color0;
1543
palette[3] = (byte) (color1 >> 16);
1544
palette[4] = (byte) (color1 >> 8);
1545
palette[5] = (byte) color1;
1550
1549
code = gdev_vector_update_log_op(vdev, lop);
1553
1552
pclxl_set_color_palette(xdev, color_space, palette, palette_size);
1554
1553
s = pclxl_stream(xdev);
1556
static const byte mi_[] = {
1557
DUB(e1Bit), DA(pxaColorDepth),
1558
DUB(eIndexedPixel), DA(pxaColorMapping)
1555
static const byte mi_[] = {
1556
DUB(e1Bit), DA(pxaColorDepth),
1557
DUB(eIndexedPixel), DA(pxaColorMapping)
1563
1562
pclxl_write_begin_image(xdev, w, h, w, h);
1564
1563
pclxl_write_image_data(xdev, data, data_x, raster, w, 0, h);
1841
1839
pie->rows.raster = row_raster;
1842
1840
*pinfo = (gx_image_enum_common_t *) pie;
1844
gs_logical_operation_t lop = pis->log_op;
1846
if (pim->ImageMask) {
1847
const byte *palette = (const byte *)
1848
(pim->Decode[0] ? "\377\000" : "\000\377");
1849
gx_color_index foreground = gx_dc_pure_color(pdcolor);
1851
code = gdev_vector_update_fill_color(vdev,
1852
NULL, /* use process color */
1856
/* This is similiar to the copy_mono white-on-mask,
1857
* except we are drawing white on the black of a black/white mask,
1858
* so we invert source, compared to copy_mono */
1859
if (foreground == (1 << dev->color_info.depth) - 1) { /* white */
1860
lop = rop3_not(rop3_S) | (rop3_D & rop3_S);
1861
}else if (foreground == 0) { /* black */
1862
lop = (rop3_S & rop3_D);
1863
}else lop |= rop3_S | lop_S_transparent;
1865
code = gdev_vector_update_log_op
1869
pclxl_set_color_palette(xdev, eGray, palette, 2);
1842
gs_logical_operation_t lop = pis->log_op;
1844
if (pim->ImageMask) {
1845
const byte *palette = (const byte *)
1846
(pim->Decode[0] ? "\377\000" : "\000\377");
1847
gx_color_index foreground = gx_dc_pure_color(pdcolor);
1849
code = gdev_vector_update_fill_color(vdev,
1850
NULL, /* use process color */
1854
/* This is similiar to the copy_mono white-on-mask,
1855
* except we are drawing white on the black of a black/white mask,
1856
* so we invert source, compared to copy_mono */
1857
if (foreground == (1 << dev->color_info.depth) - 1) { /* white */
1858
lop = rop3_not(rop3_S) | (rop3_D & rop3_S);
1859
}else if (foreground == 0) { /* black */
1860
lop = (rop3_S & rop3_D);
1861
}else lop |= rop3_S | lop_S_transparent;
1863
code = gdev_vector_update_log_op
1867
pclxl_set_color_palette(xdev, eGray, palette, 2);
1871
1869
if (bits_per_pixel == 24 ) {
1872
1870
code = gdev_vector_update_log_op
1873
1871
(vdev, (pim->CombineWithColor ? lop : rop3_know_T_0(lop)));
1879
1877
pclxl_set_color_space(xdev, eRGB);
1882
int bpc = pim->BitsPerComponent;
1883
int num_components = pie->plane_depths[0] * pie->num_planes / bpc;
1884
int sample_max = (1 << bpc) - 1;
1885
byte palette[256 * 3];
1888
code = gdev_vector_update_log_op
1889
(vdev, (pim->CombineWithColor ? lop : rop3_know_T_0(lop)));
1892
for (i = 0; i < 1 << bits_per_pixel; ++i) {
1894
gx_device_color devc;
1898
for (j = num_components - 1; j >= 0; cv >>= bpc, --j)
1899
cc.paint.values[j] = pim->Decode[j * 2] +
1901
(pim->Decode[j * 2 + 1] - pim->Decode[j * 2]) /
1903
(*pcs->type->remap_color)
1904
(&cc, pcs, &devc, pis, dev, gs_color_select_source);
1905
if (!gx_dc_is_pure(&devc))
1906
return_error(gs_error_Fatal);
1907
ci = gx_dc_pure_color(&devc);
1908
if (dev->color_info.num_components == 1) {
1909
palette[i] = (byte)ci;
1911
byte *ppal = &palette[i * 3];
1913
ppal[0] = (byte) (ci >> 16);
1914
ppal[1] = (byte) (ci >> 8);
1915
ppal[2] = (byte) ci;
1918
if (dev->color_info.num_components == 1)
1919
pclxl_set_color_palette(xdev, eGray, palette,
1920
1 << bits_per_pixel);
1922
pclxl_set_color_palette(xdev, eRGB, palette,
1923
3 << bits_per_pixel);
1880
int bpc = pim->BitsPerComponent;
1881
int num_components = pie->plane_depths[0] * pie->num_planes / bpc;
1882
int sample_max = (1 << bpc) - 1;
1883
byte palette[256 * 3];
1886
code = gdev_vector_update_log_op
1887
(vdev, (pim->CombineWithColor ? lop : rop3_know_T_0(lop)));
1890
for (i = 0; i < 1 << bits_per_pixel; ++i) {
1892
gx_device_color devc;
1896
for (j = num_components - 1; j >= 0; cv >>= bpc, --j)
1897
cc.paint.values[j] = pim->Decode[j * 2] +
1899
(pim->Decode[j * 2 + 1] - pim->Decode[j * 2]) /
1901
(*pcs->type->remap_color)
1902
(&cc, pcs, &devc, pis, dev, gs_color_select_source);
1903
if (!gx_dc_is_pure(&devc))
1904
return_error(gs_error_Fatal);
1905
ci = gx_dc_pure_color(&devc);
1906
if (dev->color_info.num_components == 1) {
1907
palette[i] = (byte)ci;
1909
byte *ppal = &palette[i * 3];
1911
ppal[0] = (byte) (ci >> 16);
1912
ppal[1] = (byte) (ci >> 8);
1913
ppal[2] = (byte) ci;
1916
if (dev->color_info.num_components == 1)
1917
pclxl_set_color_palette(xdev, eGray, palette,
1918
1 << bits_per_pixel);
1920
pclxl_set_color_palette(xdev, eRGB, palette,
1921
3 << bits_per_pixel);