1 /* Copyright (C) 1994-2003 artofcode LLC. All rights reserved.
2
3 This file is part of Aladdin Ghostscript.
4
5 Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
6 or distributor accepts any responsibility for the consequences of using it,
7 or for whether it serves any particular purpose or works at all, unless he
8 or she says so in writing. Refer to the Aladdin Ghostscript Free Public
9 License (the "License") for full details.
10
11 Every copy of Aladdin Ghostscript must include a copy of the License,
12 normally in a plain ASCII text file named PUBLIC. The License grants you
13 the right to copy, modify and redistribute Aladdin Ghostscript, but only
14 under certain conditions described in the License. Among other things, the
15 License requires that the copyright notice and this notice be preserved on
16 all copies.
17 */
18
19 /* $Id: gdevmac.c,v 1.8 2003/04/08 12:17:17 giles Exp $ */
20 /* MacOS bitmap output device. This code is superceeded by
21 the newer gsapi_* interface and the DISPLAY device. Please
22 use that instead. See doc/API.htm for more information */
23
24 #include "gdevmac.h"
25 #include "gsparam.h"
26 #include "gsdll.h"
27
28
29
30 /* The device descriptor */
31
32 gx_device_procs gs_mac_procs = {
33 mac_open, /* open_device */
34 mac_get_initial_matrix, /* get_initial_matrix */
35 mac_sync_output, /* sync_output */
36 mac_output_page, /* output_page */
37 mac_close, /* close_device */
38 gx_default_rgb_map_rgb_color, /* map_rgb_color */
39 gx_default_rgb_map_color_rgb, /* map_color_rgb */
40 mac_fill_rectangle, /* fill_rectangle */
41 NULL, /* tile_rectangle */
42 mac_copy_mono, /* copy_mono */
43 NULL,// mac_copy_color, /* copy_color */
44 mac_draw_line, /* draw_line */
45 NULL, /* get_bits */
46 mac_get_params, /* get_params */
47 mac_put_params, /* put_params */
48 NULL, /* map_cmyk_color */
49 mac_get_xfont_procs, /* get_xfont_procs */
50 NULL, /* get_xfont_device */
51 NULL, /* map_rgb_alpha_color */
52 gx_page_device_get_page_device, /* get_page_device */
53 gx_default_get_alpha_bits, /* get_alpha_bits */
54 mac_copy_alpha, /* copy_alpha */
55 NULL, /* get_band */
56 NULL, /* copy_rop */
57 NULL, /* fill_path */
58 NULL, /* stroke_path */
59 NULL, /* fill_mask */
60 NULL, /* fill_trapezoid */
61 NULL, /* fill_parallelogram */
62 NULL, /* fill_triangle */
63 NULL, /* draw_thin_line */
64 NULL, /* begin_image */
65 NULL, /* image_data */
66 NULL, /* end_image */
67 NULL //mac_strip_tile_rectangle /* strip_tile_rectangle */
68 };
69
70
71
72 /* The instance is public. */
73
74 gx_device_macos gs_macos_device = {
75 std_device_color_body(gx_device_macos,
76 &gs_mac_procs,
77 DEV_MAC_NAME,
78 DEFAULT_DEV_WIDTH, /* x and y extent (nominal) */
79 DEFAULT_DEV_HEIGHT,
80 DEFAULT_DEV_DPI, /* x and y density (nominal) */
81 DEFAULT_DEV_DPI,
82 /*dci_color(*/8, 255, 256/*)*/),
83 { 0 }, /* std_procs */
84 "", /* Output Filename */
85 NULL, /* Output File */
86 NULL, /* PicHandle to "draw" into */
87 NULL, /* PicPtr */
88 false, /* outputPage */
89 false, /* use XFont interface (render with local TrueType fonts) */
90 -1, /* lastFontFace */
91 -1, /* lastFontSize */
92 -1, /* lastFontID */
93 0 /* numUsedFonts */
94 };
95
96
97
98
99
100 private int
mac_open(register gx_device * dev)101 mac_open(register gx_device *dev)
102 {
103 gx_device_macos * mdev = (gx_device_macos *)dev;
104
105 static short picHeader[42] = { 0x0000, // picture size
106 0x0000, 0x0000, 0x0318, 0x0264, // bounding rect at 72dpi
107 0x0011, 0x02ff, 0x0c00, 0xfffe, 0x0000, // version/header opcodes
108 0x0048, 0x0000, // best x resolution
109 0x0048, 0x0000, // best y resolution
110 0x0000, 0x0000, 0x0318, 0x0264, // optimal src rect at 72dpi
111 0x0000, // reserved
112
113 0x0000, 0x001e, // DefHilite
114 0x0008, 0x0048, // PenMode
115 0x001a, 0x0000, 0x0000, 0x0000, // RGBFgCol = Black
116 0x001b, 0xFFFF, 0xFFFF, 0xFFFF, // RGBBkCol = White
117
118 0x0001, 0x000A, // set clipping
119 0x0000, 0x0000, 0x0318, 0x0264, // clipping rect
120 0x0032, 0x0000, 0x0000, 0x0318, 0x0264 // erase rect
121 };
122
123
124 mac_set_colordepth(dev, mdev->color_info.depth);
125
126 mdev->numUsedFonts = 0;
127 mdev->lastFontFace = -1;
128 mdev->lastFontSize = -1;
129 mdev->lastFontID = -1;
130
131 mdev->pic = (PicHandle) NewHandle(500000);
132 if (mdev->pic == 0) // error, not enough memory
133 return gs_error_VMerror;
134
135 HLockHi((Handle) mdev->pic); // move handle high and lock it
136
137 mdev->currPicPos = (short*) *mdev->pic;
138 memcpy(mdev->currPicPos, picHeader, 42*2);
139 mdev->currPicPos += 42;
140
141 // enter correct dimensions and resolutions
142 ((short*)(*mdev->pic))[ 3] = mdev->MediaSize[1];
143 ((short*)(*mdev->pic))[ 4] = mdev->MediaSize[0];
144
145 ((short*)(*mdev->pic))[16] = ((short*)(*mdev->pic))[35] = ((short*)(*mdev->pic))[40] = mdev->height;
146 ((short*)(*mdev->pic))[17] = ((short*)(*mdev->pic))[36] = ((short*)(*mdev->pic))[41] = mdev->width;
147
148 ((short*)(*mdev->pic))[10] = (((long) X2Fix( mdev->x_pixels_per_inch )) & 0xFFFF0000) >> 16;
149 ((short*)(*mdev->pic))[11] = ((long) X2Fix( mdev->x_pixels_per_inch )) & 0x0000FFFF;
150 ((short*)(*mdev->pic))[12] = (((long) X2Fix( mdev->y_pixels_per_inch )) & 0xFFFF0000) >> 16;
151 ((short*)(*mdev->pic))[13] = ((long) X2Fix( mdev->y_pixels_per_inch )) & 0x0000FFFF;
152
153 // finish picture, but dont increment pointer, we want to go on drawing
154 *mdev->currPicPos = 0x00ff;
155
156 // notify the caller that a new device was opened
157 if (pgsdll_callback)
158 (*pgsdll_callback) (GSDLL_DEVICE, (char *)mdev, 1);
159
160 return 0;
161 }
162
163
164
165 private void
mac_get_initial_matrix(register gx_device * dev,register gs_matrix * pmat)166 mac_get_initial_matrix(register gx_device *dev, register gs_matrix *pmat)
167 {
168 pmat->xx = dev->x_pixels_per_inch / 72.0;
169 pmat->xy = 0;
170 pmat->yx = 0;
171 pmat->yy = dev->y_pixels_per_inch / -72.0;
172 pmat->tx = 0;
173 pmat->ty = dev->height;
174 }
175
176
177
178 /* Make the output appear on the screen. */
179 int
mac_sync_output(gx_device * dev)180 mac_sync_output(gx_device * dev)
181 {
182 gx_device_macos * mdev = (gx_device_macos *)dev;
183
184 // finish picture, but dont increment pointer, we want to go on drawing
185 *mdev->currPicPos = 0x00ff;
186
187 // tell the caller to sync
188 if (pgsdll_callback)
189 (*pgsdll_callback) (GSDLL_SYNC, (char *)mdev, 0);
190
191 return (0);
192 }
193
194
195
196 int
mac_output_page(gx_device * dev,int copies,int flush)197 mac_output_page(gx_device * dev, int copies, int flush)
198 {
199 gx_device_macos * mdev = (gx_device_macos *)dev;
200 int code = 0;
201
202 mdev->outputPage = true;
203
204 if (strcmp(mdev->outputFileName, "")) {
205 // save file
206 code = mac_save_pict(dev);
207 }
208
209 // tell the caller that the page is done
210 if (pgsdll_callback)
211 (*pgsdll_callback) (GSDLL_PAGE, (char *)mdev, 0);
212
213 gx_finish_output_page(dev, copies, flush);
214
215 return code;
216 }
217
218
219 private int
mac_save_pict(gx_device * dev)220 mac_save_pict(gx_device * dev)
221 {
222 gx_device_macos * mdev = (gx_device_macos *)dev;
223 int code = 0;
224 int i;
225
226 if (mdev->outputFile == NULL) {
227 code = gx_device_open_output_file(dev, mdev->outputFileName, true, true, &(mdev->outputFile));
228 if (code < 0) return code;
229 }
230
231 for (i=0; i<512; i++) fputc(0, mdev->outputFile);
232 fwrite(*(mdev->pic), sizeof(char), ((long) mdev->currPicPos - (long) *mdev->pic + 2), mdev->outputFile);
233
234 gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile);
235 mdev->outputFile = NULL;
236
237 return code;
238 }
239
240
241 /* Close the device. */
242 private int
mac_close(register gx_device * dev)243 mac_close(register gx_device *dev)
244 {
245 gx_device_macos * mdev = (gx_device_macos *)dev;
246
247 long len;
248
249 HUnlock((Handle) mdev->pic); // no more changes in the pict -> unlock handle
250 if (strcmp(mdev->outputFileName, "")) {
251 DisposeHandle((Handle) mdev->pic);
252 gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile);
253 mdev->outputFile = 0;
254 } else {
255 len = (long)mdev->currPicPos - (long)*mdev->pic;
256 SetHandleSize((Handle) mdev->pic, len + 10); // +10 just for the case
257 }
258
259 // notify the caller that the device was closed
260 // it has to dispose the PICT handle when it is ready!
261 if (pgsdll_callback)
262 (*pgsdll_callback) (GSDLL_DEVICE, (char *)mdev, 0);
263
264 return 0;
265 }
266
267
268
269 /* Fill a rectangle with a color. */
270 private int
mac_fill_rectangle(register gx_device * dev,int x,int y,int w,int h,gx_color_index color)271 mac_fill_rectangle(register gx_device *dev,
272 int x, int y, int w, int h,
273 gx_color_index color)
274 {
275 gx_device_macos * mdev = (gx_device_macos *)dev;
276
277 /* ignore a fullpage rect directly after an output_page, this would clear the pict */
278 if (mdev->outputPage &&
279 (x == 0) && (y == 0) && (w == mdev->width) && (h == mdev->height)) {
280 return 0;
281 }
282
283 CheckMem(1024, 100*1024);
284 ResetPage();
285
286 GSSetFgCol(dev, mdev->currPicPos, color);
287 PICT_fillRect(mdev->currPicPos, x, y, w, h);
288
289 PICT_OpEndPicGoOn(mdev->currPicPos);
290
291 return 0;
292 }
293
294
295
296 /* Draw a line */
297 private int
mac_draw_line(register gx_device * dev,int x0,int y0,int x1,int y1,gx_color_index color)298 mac_draw_line (register gx_device *dev,
299 int x0, int y0,
300 int x1, int y1,
301 gx_color_index color)
302 {
303 gx_device_macos * mdev = (gx_device_macos *)dev;
304
305 CheckMem(1024, 100*1024);
306 ResetPage();
307
308 GSSetFgCol(dev, mdev->currPicPos, color);
309 PICT_Line(mdev->currPicPos, x0, y0, x1, y1);
310
311 PICT_OpEndPicGoOn(mdev->currPicPos);
312
313 return 0;
314 }
315
316
317
318 /* Copy a monochrome bitmap. */
319 private int
mac_copy_mono(register gx_device * dev,const unsigned char * base,int data_x,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index color_0,gx_color_index color_1)320 mac_copy_mono (register gx_device *dev,
321 const unsigned char *base, int data_x, int raster, gx_bitmap_id id,
322 int x, int y, int w, int h,
323 gx_color_index color_0, gx_color_index color_1)
324 {
325 gx_device_macos * mdev = (gx_device_macos *)dev;
326
327 int byteCount = raster * h;
328 short copyMode;
329
330 // this case doesn't change the picture -> return without wasting time
331 if (color_0 == gx_no_color_index && color_1 == gx_no_color_index)
332 return 0;
333
334 fit_copy(dev, base, data_x, raster, id, x, y, w, h);
335
336 CheckMem(10*1024 + byteCount*10, 100*1024 + byteCount*10);
337 ResetPage();
338
339 if (color_0 == gx_no_color_index)
340 copyMode = srcOr;
341 else if (color_1 == gx_no_color_index)
342 copyMode = notSrcBic; // this mode is untested ! (no file found which is using it)
343 else
344 copyMode = srcCopy;
345
346 copyMode += ditherCopy;
347
348 GSSetBkCol(dev, mdev->currPicPos, color_0);
349 GSSetFgCol(dev, mdev->currPicPos, color_1);
350
351 PICTWriteOpcode(mdev->currPicPos, 0x0098);
352 PICTWriteInt(mdev->currPicPos, raster);
353 PICTWriteRect(mdev->currPicPos, 0, 0, raster*8, h);
354 PICTWriteRect(mdev->currPicPos, data_x, 0, w, h);
355 PICTWriteRect(mdev->currPicPos, x, y, w, h);
356 PICTWriteInt(mdev->currPicPos, copyMode);
357 PICTWriteDataPackBits(mdev->currPicPos, base, raster, h);
358
359 PICT_OpEndPicGoOn(mdev->currPicPos);
360
361 return 0;
362 }
363
364
365
366 /* Fill a region with a color and apply a per-pixel alpha-value */
367 /* alpha value is simulated by changed the value to white. Full transparency means white color */
368 /* that's why this will only work on a fully white background!!!! */
369 private int
mac_copy_alpha(gx_device * dev,const unsigned char * base,int data_x,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index color,int depth)370 mac_copy_alpha(gx_device *dev, const unsigned char *base, int data_x,
371 int raster, gx_bitmap_id id, int x, int y, int w, int h,
372 gx_color_index color, int depth)
373 {
374 gx_device_macos * mdev = (gx_device_macos *)dev;
375
376 ColorSpec *colorTable;
377 short copyMode, shade, maxShade = (1 << depth) - 1, byteCount = raster * h;
378 gx_color_value rgb[3];
379 colorHSV colHSV;
380 colorRGB colRGB;
381 float saturation, value;
382
383 fit_copy(dev, base, data_x, raster, id, x, y, w, h);
384
385 CheckMem( byteCount*4 + 200*1024, byteCount*4 + 500*1024 );
386 ResetPage();
387
388 colorTable = (ColorSpec*) malloc(sizeof(ColorSpec) * (maxShade+1));
389 if (colorTable == NULL)
390 return gs_error_VMerror;
391
392 (*dev_proc(dev, map_color_rgb))(dev, color, rgb);
393 colRGB.red = rgb[0];
394 colRGB.green = rgb[1];
395 colRGB.blue = rgb[2];
396 mac_convert_rgb_hsv(&colRGB, &colHSV);
397 saturation = colHSV.s;
398 value = colHSV.v;
399
400 for (shade=0; shade <= maxShade; shade++) {
401 colorTable[shade].value = maxShade - shade;
402
403 colHSV.s = saturation * (1.0 - (float)shade/(float)maxShade);
404 colHSV.v = value + ((1.0 - value) * (float)shade/(float)maxShade);
405
406 mac_convert_hsv_rgb(&colHSV, &colRGB);
407 colorTable[shade].rgb.red = colRGB.red;
408 colorTable[shade].rgb.green = colRGB.green;
409 colorTable[shade].rgb.blue = colRGB.blue;
410 }
411 copyMode = srcCopy + ditherCopy;
412
413 GSSetStdCol(mdev->currPicPos);
414
415 if (raster < 8) {
416 PICTWriteOpcode(mdev->currPicPos, 0x0090);
417 } else {
418 PICTWriteOpcode(mdev->currPicPos, 0x0098);
419 }
420 PICTWritePixMap(mdev->currPicPos, 0, 0, raster*8/depth, h, raster, 0, 0,
421 X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), depth);
422 PICTWriteColorTable(mdev->currPicPos, 0, maxShade+1, colorTable);
423 PICTWriteRect(mdev->currPicPos, data_x, 0, w, h);
424 PICTWriteRect(mdev->currPicPos, x, y, w, h);
425 PICTWriteInt(mdev->currPicPos, copyMode);
426 PICTWriteDataPackBits(mdev->currPicPos, base, raster, h);
427
428 PICT_OpEndPicGoOn(mdev->currPicPos);
429
430 free(colorTable);
431
432 return 0;
433 }
434
435
436
437 void
mac_convert_rgb_hsv(colorRGB * inRGB,colorHSV * HSV)438 mac_convert_rgb_hsv(colorRGB *inRGB, colorHSV *HSV)
439 {
440 #define NORMALIZE_RGB(col) ((float)col/(float)0xFFFF)
441
442 float min = 1.0, temp;
443 float r = NORMALIZE_RGB(inRGB->red),
444 g = NORMALIZE_RGB(inRGB->green),
445 b = NORMALIZE_RGB(inRGB->blue);
446
447 HSV->h = 0;
448
449 HSV->v = r;
450 if (g > HSV->v) HSV->v = g;
451 if (b > HSV->v) HSV->v = b;
452
453 min = r;
454 if (g < min) min = g;
455 if (b < min) min = b;
456
457 temp = HSV->v - min;
458
459 if (HSV->v > 0)
460 HSV->s = temp / HSV->v;
461 else
462 HSV->s = 0;
463
464 if (HSV->s > 0) {
465 float rd = (HSV->v - r) / temp,
466 gd = (HSV->v - g) / temp,
467 bd = (HSV->v - b) / temp;
468
469 if (HSV->v == r) {
470 if (min == g) HSV->h = 5 + bd;
471 else HSV->h = 1 - gd;
472 } else if (HSV->v == g) {
473 if (min == b) HSV->h = 1 + rd;
474 else HSV->h = 3 - bd;
475 } else {
476 if (min == r) HSV->h = 3 + gd;
477 else HSV->h = 5 - rd;
478 }
479
480 if (HSV->h < 6) HSV->h *= 60;
481 else HSV->h = 0;
482 }
483 }
484
485
486 void
mac_convert_hsv_rgb(colorHSV * inHSV,colorRGB * RGB)487 mac_convert_hsv_rgb(colorHSV *inHSV, colorRGB *RGB)
488 {
489 if (inHSV->s == 0) {
490 RGB->red = RGB->green = RGB->blue = inHSV->v * 0xFFFF;
491 } else {
492 float h = inHSV->h / 60;
493 int i = trunc(h);
494 float fract = h - i;
495 unsigned short t1 = (inHSV->v * (1 - inHSV->s)) * 0xFFFF,
496 t2 = (inHSV->v * (1 - inHSV->s * fract)) * 0xFFFF,
497 t3 = (inHSV->v * (1 - inHSV->s * (1 - fract))) * 0xFFFF,
498 v = inHSV->v * 0xFFFF;
499
500 switch(i) {
501 case 0: RGB->red = v;
502 RGB->green = t3;
503 RGB->blue = t1;
504 break;
505
506 case 1: RGB->red = t2;
507 RGB->green = v;
508 RGB->blue = t1;
509 break;
510
511 case 2: RGB->red = t1;
512 RGB->green = v;
513 RGB->blue = t3;
514 break;
515
516 case 3: RGB->red = t1;
517 RGB->green = t2;
518 RGB->blue = v;
519 break;
520
521 case 4: RGB->red = t3;
522 RGB->green = t1;
523 RGB->blue = v;
524 break;
525
526 case 5: RGB->red = v;
527 RGB->green = t1;
528 RGB->blue = t2;
529 break;
530 }
531 }
532 }
533
534
535
536 // set color info and procedures according to pixeldepth
537 private int
mac_set_colordepth(gx_device * dev,int depth)538 mac_set_colordepth(gx_device *dev, int depth)
539 {
540 gx_device_macos * mdev = (gx_device_macos *)dev;
541 gx_device_color_info * ci = &mdev->color_info;
542
543 if (depth != 1 && depth != 4 && depth != 7 && depth != 8 && depth != 24)
544 return gs_error_rangecheck;
545
546 mdev->color_info.depth = depth;
547 switch (depth)
548 {
549 case 1: // Black/White
550 ci->num_components = 1;
551 ci->max_gray = 1; ci->max_color = 0;
552 ci->dither_grays = 2; ci->dither_colors = 0;
553 set_dev_proc(dev, map_rgb_color, gx_default_b_w_map_rgb_color);
554 set_dev_proc(dev, map_color_rgb, gx_default_b_w_map_color_rgb);
555 break;
556
557 case 4: // 4Bit-Gray
558 ci->num_components = 1;
559 ci->max_gray = 15; ci->max_color = 0;
560 ci->dither_grays = 16; ci->dither_colors = 0;
561 set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color);
562 set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb);
563 break;
564
565 case 7: // 8Bit-Gray
566 ci->depth = 7;
567 ci->num_components = 1;
568 ci->max_gray = 255; ci->max_color = 0;
569 ci->dither_grays = 256; ci->dither_colors = 0;
570 set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color);
571 set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb);
572 break;
573
574 case 8: // 8Bit-Color
575 ci->num_components = 3;
576 ci->max_gray = 15; ci->max_color = 5;
577 ci->dither_grays = 16; ci->dither_colors = 6;
578 set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
579 set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
580 break;
581
582 /* case 16: // 16Bit-Color
583 ci->num_components = 3;
584 ci->max_gray = 255; ci->max_color = 65535;
585 ci->dither_grays = 256; ci->dither_colors = 65536;
586 set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
587 set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
588 break;
589 */
590 case 24: // 24Bit-Color
591 ci->num_components = 3;
592 ci->max_gray = 255; ci->max_color = 16777215;
593 ci->dither_grays = 256; ci->dither_colors = 16777216;
594 set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color);
595 set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb);
596 break;
597 }
598
599 return 0;
600 }
601
602
603 private int
mac_put_params(gx_device * dev,gs_param_list * plist)604 mac_put_params(gx_device *dev, gs_param_list *plist)
605 {
606 gx_device_macos *mdev = (gx_device_macos *)dev;
607
608 int isOpen = mdev->is_open;
609 int code;
610 bool useXFonts;
611 int depth;
612 gs_param_string outputFile;
613
614 // Get the UseExternalFonts Parameter
615 code = param_read_bool(plist, "UseExternalFonts", &useXFonts);
616 if (!code)
617 mdev->useXFonts = useXFonts;
618
619 // Get the BitsPerPixel Parameter
620 code = param_read_int(plist, "BitsPerPixel", &depth);
621 if (!code) {
622 code = mac_set_colordepth(dev, depth);
623 if (code)
624 param_return_error(plist, "BitsPerPixel", gs_error_rangecheck);
625 }
626
627 // Get OutputFile
628 code = param_read_string(plist, "OutputFile", &outputFile);
629 if (code < 0) {
630 param_signal_error(plist, "OutputFile", code);
631 return code;
632 } else if (code == 0) {
633
634 if (dev->LockSafetyParams &&
635 bytes_compare(outputFile.data, outputFile.size,
636 (const byte *)mdev->outputFileName, strlen(mdev->outputFileName))) {
637 param_signal_error(plist, "OutputFile", gs_error_invalidaccess);
638 return gs_error_invalidaccess;
639 }
640 if (outputFile.size > (gp_file_name_sizeof - 1)) {
641 param_signal_error(plist, "OutputFile", gs_error_limitcheck);
642 return gs_error_limitcheck;
643 }
644
645 /* If filename changed, close file. */
646 if (outputFile.data != 0 &&
647 bytes_compare(outputFile.data, outputFile.size,
648 (const byte *)mdev->outputFileName, strlen(mdev->outputFileName))) {
649 /* Close the file if it's open. */
650 if (mdev->outputFile != NULL) {
651 gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile);
652 memcpy(mdev->outputFileName, outputFile.data, outputFile.size);
653 mdev->outputFileName[outputFile.size] = 0;
654 gx_device_open_output_file(dev, mdev->outputFileName, true, true, &(mdev->outputFile));
655 } else {
656 memcpy(mdev->outputFileName, outputFile.data, outputFile.size);
657 mdev->outputFileName[outputFile.size] = 0;
658 }
659 }
660 }
661
662 // Get the Default Parameters
663 mdev->is_open = 0;
664 code = gx_default_put_params( dev, plist );
665 mdev->is_open = isOpen;
666
667 return code;
668 }
669
670
671 private int
mac_get_params(gx_device * dev,gs_param_list * plist)672 mac_get_params(gx_device *dev, gs_param_list *plist)
673 {
674 gx_device_macos *mdev = (gx_device_macos *)dev;
675
676 int code;
677 gs_param_string outputFile;
678
679 code = gx_default_get_params(dev, plist);
680 if (code < 0)
681 return code;
682
683 // UseExternalFonts
684 code = param_write_bool(plist, "UseExternalFonts", &(mdev->useXFonts));
685
686 // color depth
687 code = param_write_int(plist, "BitsPerPixel", &(mdev->color_info.depth));
688
689 // output file name
690 outputFile.data = (const byte *) mdev->outputFileName;
691 outputFile.size = strlen(mdev->outputFileName);
692 outputFile.persistent = false;
693 code = param_write_string(plist, "OutputFile", &outputFile);
694
695 return code;
696 }
697
698
699
700 /* let the caller get the device PictHandle, he has to draw it to screen */
701 int GSDLLAPI
gsdll_get_pict(unsigned char * dev,PicHandle * thePict)702 gsdll_get_pict(unsigned char *dev, PicHandle *thePict)
703 {
704 gx_device_macos * mdev = (gx_device_macos *)dev;
705
706 *thePict = mdev->pic;
707
708 return 0;
709 }
710
711
712
713
714
715
716 /*************************************************************************************/
717 /*************************************************************************************/
718 /** Experimental functions! **/
719 /*************************************************************************************/
720 /*************************************************************************************/
721
722
723
724
725 #if 0
726 /* NOT FUNCTIONAL !!! */
727 /* Copy a color bitmap. */
728 private int
729 mac_copy_color (register gx_device *dev,
730 const unsigned char *base, int data_x, int raster, gx_bitmap_id id,
731 int x, int y, int w, int h)
732 {
733 gx_device_macos * mdev = (gx_device_macos *)dev;
734
735 int byteCount = raster * h, color;
736 gx_color_value rgb[3];
737
738 fit_copy(dev, base, data_x, raster, id, x, y, w, h);
739
740 CheckMem(10*1024 + byteCount*4, 100*1024 + byteCount*4);
741 ResetPage();
742
743 GSSetStdCol(mdev->currPicPos); // Sets FgCol to Black and BkCol to White
744
745 if (mdev->color_info.depth == 24) {
746 PICTWriteOpcode(mdev->currPicPos, 0x009A);
747 PICTWriteLong(mdev->currPicPos, 0x000000FF);
748 PICTWritePixMap(mdev->currPicPos, 0, 0, raster/4, h, raster, 2, 0,
749 X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), 32);
750 PICTWriteRect(mdev->currPicPos, data_x, 0, w, h);
751 PICTWriteRect(mdev->currPicPos, x, y, w, h);
752 PICTWriteInt(mdev->currPicPos, srcCopy);
753
754 /* memcpy(mdev->currPicPos, base, byteCount);
755 (char*)(mdev->currPicPos) += byteCount;*/
756
757 {
758 short i;
759 byteCount = 0;
760
761 for (i=0; i<raster/4*h; i++) {
762 // PICTWriteByte(mdev->currPicPos, 0x00);
763 PICTWriteByte(mdev->currPicPos, 0x00);
764 PICTWriteByte(mdev->currPicPos, 0x00);
765 PICTWriteByte(mdev->currPicPos, 0x00);
766 byteCount += 3;
767 }
768 }
769
770 if (byteCount % 2)
771 PICTWriteFillByte(mdev->currPicPos);
772
773 } else if (mdev->color_info.depth <= 8) {
774 ColorSpec *colorTable;
775
776 colorTable = (ColorSpec*) malloc(sizeof(ColorSpec) * (1 << mdev->color_info.depth));
777 for (color=0; color < (1 << mdev->color_info.depth); color++) {
778 (*dev_proc(dev, map_color_rgb))(dev, color, rgb);
779 colorTable[color].value = color;
780 colorTable[color].rgb.red = rgb[0];
781 colorTable[color].rgb.green = rgb[1];
782 colorTable[color].rgb.blue = rgb[2];
783 }
784
785 PICTWriteOpcode(mdev->currPicPos, 0x0098);
786 PICTWritePixMap(mdev->currPicPos, 0, 0, raster*8/mdev->color_info.depth, h, raster, 1, 0,
787 X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch),
788 mdev->color_info.depth);
789 PICTWriteColorTable(mdev->currPicPos, 0, (1 << mdev->color_info.depth), colorTable);
790 PICTWriteRect(mdev->currPicPos, data_x, 0, w, h);
791 PICTWriteRect(mdev->currPicPos, x, y, w, h);
792 PICTWriteInt(mdev->currPicPos, srcCopy);
793
794 PICTWriteDataPackBits(mdev->currPicPos, base, raster, h);
795
796 free(colorTable);
797 } else {
798 gx_default_copy_color( dev, base, data_x, raster, id, x, y, w, h );
799 }
800
801 PICT_OpEndPicGoOn(mdev->currPicPos);
802
803 return 0;
804 }
805 #endif
806
807
808
809 #if 0
810 /* tile a rectangle with a bitmap or pixmap */
811 private int
812 mac_strip_tile_rectangle(register gx_device *dev, const gx_strip_bitmap *tile,
813 int x, int y, int w, int h,
814 gx_color_index color_0, gx_color_index color_1,
815 int phase_x, int phase_y)
816 {
817 gx_device_macos * mdev = (gx_device_macos *)dev;
818
819 int byteCount = tile->raster * tile->size.y;
820 /*
821 // tile is a pixmap
822 if (color_0 == gx_no_color_index && color_1 == gx_no_color_index)
823 return 0;// gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y);
824
825 if (color_0 != gx_no_color_index && color_1 != gx_no_color_index) {
826 // monochrome tiles
827 if (phase_x != 0 ||�phase_y != 0 || tile->shift != 0 ||
828 tile->strip_height != 0 ||�tile->strip_shift != 0) {
829 return gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y);
830 }
831
832 } else {
833 return 0;//gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y);
834 }
835 */
836 }
837 #endif
838
839
840
841
842
843
844
845
846
847
848