gdevdsp.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. /* Copyright (C) 2001, Ghostgum Software Pty Ltd. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
  4. or distributor accepts any responsibility for the consequences of using it,
  5. or for whether it serves any particular purpose or works at all, unless he
  6. or she says so in writing. Refer to the Aladdin Ghostscript Free Public
  7. License (the "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License,
  9. normally in a plain ASCII text file named PUBLIC. The License grants you
  10. the right to copy, modify and redistribute AFPL Ghostscript, but only
  11. under certain conditions described in the License. Among other things, the
  12. License requires that the copyright notice and this notice be preserved on
  13. all copies.
  14. */
  15. /* gdevdsp.c */
  16. /*
  17. * DLL based display device driver.
  18. *
  19. * by Russell Lang, Ghostgum Software Pty Ltd
  20. *
  21. * This device is intended to be used for displays when
  22. * Ghostscript is loaded as a DLL/shared library/static library.
  23. * It is intended to work for Windows, OS/2, Linux, Mac OS 9 and
  24. * hopefully others.
  25. *
  26. * Before this device is opened, the address of a structure must
  27. * be provided using gsapi_set_display_callback(minst, callback);
  28. * This structure contains callback functions to notify the
  29. * caller when the device is opened, closed, resized, showpage etc.
  30. * The structure is defined in gdevdsp.h.
  31. *
  32. * Not all combinatinos of display formats have been tested.
  33. * At the end of this file is some example code showing which
  34. * formats have been tested.
  35. */
  36. #include "string_.h"
  37. #include "gx.h"
  38. #include "gserrors.h"
  39. #include "gxdevice.h"
  40. #include "gp.h"
  41. #include "gpcheck.h"
  42. #include "gsparam.h"
  43. #include "gdevpccm.h" /* 4-bit PC color */
  44. #include "gxdevmem.h"
  45. #include "gdevdsp.h"
  46. #include "gdevdsp2.h"
  47. /* Initial values for width and height */
  48. #define INITIAL_RESOLUTION 96
  49. #define INITIAL_WIDTH (INITIAL_RESOLUTION * 85 / 10 + 1)
  50. #define INITIAL_HEIGHT (INITIAL_RESOLUTION * 11 + 1)
  51. /* Device procedures */
  52. /* See gxdevice.h for the definitions of the procedures. */
  53. private dev_proc_open_device(display_open);
  54. private dev_proc_get_initial_matrix(display_get_initial_matrix);
  55. private dev_proc_sync_output(display_sync_output);
  56. private dev_proc_output_page(display_output_page);
  57. private dev_proc_close_device(display_close);
  58. private dev_proc_map_rgb_color(display_map_rgb_color_device4);
  59. private dev_proc_map_color_rgb(display_map_color_rgb_device4);
  60. private dev_proc_map_rgb_color(display_map_rgb_color_device8);
  61. private dev_proc_map_color_rgb(display_map_color_rgb_device8);
  62. private dev_proc_map_rgb_color(display_map_rgb_color_device16);
  63. private dev_proc_map_color_rgb(display_map_color_rgb_device16);
  64. private dev_proc_map_rgb_color(display_map_rgb_color_rgb);
  65. private dev_proc_map_color_rgb(display_map_color_rgb_rgb);
  66. private dev_proc_map_rgb_color(display_map_rgb_color_bgr24);
  67. private dev_proc_map_color_rgb(display_map_color_rgb_bgr24);
  68. private dev_proc_fill_rectangle(display_fill_rectangle);
  69. private dev_proc_copy_mono(display_copy_mono);
  70. private dev_proc_copy_color(display_copy_color);
  71. private dev_proc_get_bits(display_get_bits);
  72. private dev_proc_get_params(display_get_params);
  73. private dev_proc_put_params(display_put_params);
  74. private dev_proc_map_rgb_alpha_color(display_map_rgb_alpha_color);
  75. private dev_proc_map_color_rgb_alpha(display_map_color_rgb_alpha);
  76. private dev_proc_finish_copydevice(display_finish_copydevice);
  77. private const gx_device_procs display_procs =
  78. {
  79. display_open,
  80. display_get_initial_matrix,
  81. display_sync_output,
  82. display_output_page,
  83. display_close,
  84. gx_default_w_b_map_rgb_color,
  85. gx_default_w_b_map_color_rgb,
  86. display_fill_rectangle,
  87. NULL, /* tile rectangle */
  88. display_copy_mono,
  89. display_copy_color,
  90. NULL, /* draw line */
  91. display_get_bits,
  92. display_get_params,
  93. display_put_params,
  94. gx_default_cmyk_map_cmyk_color, /* map_cmyk_color */
  95. gx_default_get_xfont_procs,
  96. NULL, /* get_xfont_device */
  97. NULL, /* map_rgb_alpha_color */
  98. gx_page_device_get_page_device,
  99. /* extra entries */
  100. NULL, /* get_alpha_bits */
  101. NULL, /* copy_alpha */
  102. NULL, /* get_band */
  103. NULL, /* copy_rop */
  104. NULL, /* fill_path */
  105. NULL, /* stroke_path */
  106. NULL, /* fill_mask */
  107. NULL, /* fill_trapezoid */
  108. NULL, /* fill_parallelogram */
  109. NULL, /* fill_triangle */
  110. NULL, /* draw_thin_line */
  111. NULL, /* begin_image */
  112. NULL, /* image_data */
  113. NULL, /* end_image */
  114. NULL, /* strip_tile_rectangle */
  115. NULL, /* strip_copy_rop */
  116. NULL, /* get_clipping_box */
  117. NULL, /* begin_typed_image */
  118. NULL, /* get_bits_rectangle */
  119. NULL, /* map_color_rgb_alpha */
  120. NULL, /* create_compositor */
  121. NULL, /* get_hardware_params */
  122. NULL, /* text_begin */
  123. display_finish_copydevice /* finish_copydevice */
  124. };
  125. /* GC descriptor */
  126. public_st_device_display();
  127. private
  128. ENUM_PTRS_WITH(display_enum_ptrs, gx_device_display *ddev) return 0;
  129. case 0:
  130. if (ddev->mdev) {
  131. return ENUM_OBJ(gx_device_enum_ptr((gx_device *)ddev->mdev));
  132. }
  133. return 0; /* if mdev is NULL, then pBitmap will be also */
  134. case 1:
  135. if (ddev->callback &&
  136. !ddev->callback->display_memalloc &&
  137. !ddev->callback->display_memfree &&
  138. ddev->pBitmap) {
  139. /* we allocated the bitmap */
  140. return ENUM_OBJ(ddev->pBitmap);
  141. }
  142. return 0;
  143. ENUM_PTRS_END
  144. private
  145. RELOC_PTRS_WITH(display_reloc_ptrs, gx_device_display *ddev)
  146. if (ddev->mdev) {
  147. ddev->mdev = (gx_device_memory *)
  148. gx_device_reloc_ptr((gx_device *)ddev->mdev, gcst);
  149. }
  150. RELOC_PTRS_END
  151. const gx_device_display gs_display_device =
  152. {
  153. std_device_std_body_type(gx_device_display, &display_procs, "display",
  154. &st_device_display,
  155. INITIAL_WIDTH, INITIAL_HEIGHT,
  156. INITIAL_RESOLUTION, INITIAL_RESOLUTION),
  157. {0}, /* std_procs */
  158. NULL, /* mdev */
  159. NULL, /* callback */
  160. NULL, /* pHandle */
  161. 0, /* nFormat */
  162. NULL, /* pBitmap */
  163. 0, /* ulBitmapSize */
  164. };
  165. /* prototypes for internal procedures */
  166. private int display_check_structure(gx_device_display *dev);
  167. private void display_free_bitmap(gx_device_display * dev);
  168. private int display_alloc_bitmap(gx_device_display *, gx_device *);
  169. private int display_set_color_format(gx_device_display *dev, int nFormat);
  170. /* Open the display driver. */
  171. private int
  172. display_open(gx_device * dev)
  173. {
  174. gx_device_display *ddev = (gx_device_display *) dev;
  175. int ccode;
  176. /* Erase these, in case we are opening a copied device. */
  177. ddev->mdev = NULL;
  178. ddev->pBitmap = NULL;
  179. ddev->ulBitmapSize = 0;
  180. /* Allow device to be opened "disabled" without a callback. */
  181. /* The callback will be set later and the device re-opened. */
  182. if (ddev->callback == NULL)
  183. return 0;
  184. /* Make sure we have been passed a valid callback structure. */
  185. if ((ccode = display_check_structure(ddev)) < 0)
  186. return_error(ccode);
  187. /* set color info */
  188. if ((ccode = display_set_color_format(ddev, ddev->nFormat)) < 0)
  189. return_error(ccode);
  190. /* Tell caller that the device is open. */
  191. /* This is always the first callback */
  192. ccode = (*(ddev->callback->display_open))(ddev->pHandle, dev);
  193. if (ccode < 0)
  194. return_error(ccode);
  195. /* Tell caller the proposed device parameters */
  196. ccode = (*(ddev->callback->display_presize)) (ddev->pHandle, dev,
  197. dev->width, dev->height, gdev_mem_raster(dev), ddev->nFormat);
  198. if (ccode < 0) {
  199. (*(ddev->callback->display_close))(ddev->pHandle, dev);
  200. return_error(ccode);
  201. }
  202. /* allocate the image */
  203. ccode = display_alloc_bitmap(ddev, dev);
  204. if (ccode < 0) {
  205. (*(ddev->callback->display_close))(ddev->pHandle, dev);
  206. return_error(ccode);
  207. }
  208. /* Tell caller the device parameters */
  209. ccode = (*(ddev->callback->display_size)) (ddev->pHandle, dev,
  210. dev->width, dev->height, gdev_mem_raster(dev), ddev->nFormat,
  211. ddev->mdev->base);
  212. if (ccode < 0) {
  213. display_free_bitmap(ddev);
  214. (*(ddev->callback->display_close))(ddev->pHandle, dev);
  215. return_error(ccode);
  216. }
  217. return 0;
  218. }
  219. private void
  220. display_get_initial_matrix(gx_device * dev, gs_matrix * pmat)
  221. {
  222. gx_device_display *ddev = (gx_device_display *) dev;
  223. if ((ddev->nFormat & DISPLAY_FIRSTROW_MASK) == DISPLAY_TOPFIRST)
  224. gx_default_get_initial_matrix(dev, pmat);
  225. else
  226. gx_upright_get_initial_matrix(dev, pmat); /* Windows / OS/2 */
  227. }
  228. /* Update the display. */
  229. int
  230. display_sync_output(gx_device * dev)
  231. {
  232. gx_device_display *ddev = (gx_device_display *) dev;
  233. if (ddev->callback == NULL)
  234. return 0;
  235. (*(ddev->callback->display_sync))(ddev->pHandle, dev);
  236. return (0);
  237. }
  238. /* Update the display, bring to foreground. */
  239. /* If you want to pause on showpage, delay your return from callback */
  240. int
  241. display_output_page(gx_device * dev, int copies, int flush)
  242. {
  243. gx_device_display *ddev = (gx_device_display *) dev;
  244. int code;
  245. if (ddev->callback == NULL)
  246. return 0;
  247. code = (*(ddev->callback->display_page))
  248. (ddev->pHandle, dev, copies, flush);
  249. if (code >= 0)
  250. code = gx_finish_output_page(dev, copies, flush);
  251. return code;
  252. }
  253. /* Close the display driver */
  254. private int
  255. display_close(gx_device * dev)
  256. {
  257. gx_device_display *ddev = (gx_device_display *) dev;
  258. if (ddev->callback == NULL)
  259. return 0;
  260. /* Tell caller that device is about to be closed. */
  261. (*(ddev->callback->display_preclose))(ddev->pHandle, dev);
  262. /* Release memory. */
  263. display_free_bitmap(ddev);
  264. /* Tell caller that device is closed. */
  265. /* This is always the last callback */
  266. (*(ddev->callback->display_close))(ddev->pHandle, dev);
  267. return 0;
  268. }
  269. /* DISPLAY_COLORS_NATIVE, 4bit/pixel */
  270. /* Map a r-g-b color to a color code */
  271. private gx_color_index
  272. display_map_rgb_color_device4(gx_device * dev,
  273. gx_color_value r, gx_color_value g, gx_color_value b)
  274. {
  275. gx_device_display *ddev = (gx_device_display *) dev;
  276. if ((r == g) && (g == b) && (r >= gx_max_color_value / 3 * 2 - 1)
  277. && (r < gx_max_color_value / 4 * 3))
  278. return ((gx_color_index) 8); /* light gray */
  279. return pc_4bit_map_rgb_color(dev, r, g, b);
  280. }
  281. /* Map a color code to r-g-b. */
  282. private int
  283. display_map_color_rgb_device4(gx_device * dev, gx_color_index color,
  284. gx_color_value prgb[3])
  285. {
  286. if (color == 8) /* VGA light grey */
  287. prgb[0] = prgb[1] = prgb[2] = (gx_max_color_value / 4 * 3);
  288. else
  289. pc_4bit_map_color_rgb(dev, color, prgb);
  290. return 0;
  291. }
  292. /* DISPLAY_COLORS_NATIVE, 8bit/pixel */
  293. /* Map a r-g-b color to a color code */
  294. private gx_color_index
  295. display_map_rgb_color_device8(gx_device * dev,
  296. gx_color_value r, gx_color_value g, gx_color_value b)
  297. {
  298. /* palette of 96 colors */
  299. /* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
  300. if ((r == g) && (g == b))
  301. return ((r >> (gx_color_value_bits - 5)) + 0x40);
  302. return ((r >> (gx_color_value_bits - 2)) << 4) +
  303. ((g >> (gx_color_value_bits - 2)) << 2) +
  304. ((b >> (gx_color_value_bits - 2)));
  305. }
  306. /* Map a color code to r-g-b. */
  307. private int
  308. display_map_color_rgb_device8(gx_device * dev, gx_color_index color,
  309. gx_color_value prgb[3])
  310. {
  311. gx_color_value one;
  312. /* palette of 96 colors */
  313. /* 0->63 = 00RRGGBB, 64->95 = 010YYYYY */
  314. if (color < 64) {
  315. one = (gx_color_value) (gx_max_color_value / 3);
  316. prgb[0] = ((color >> 4) & 3) * one;
  317. prgb[1] = ((color >> 2) & 3) * one;
  318. prgb[2] = ((color) & 3) * one;
  319. }
  320. else if (color < 96) {
  321. one = (gx_color_value) (gx_max_color_value / 31);
  322. prgb[0] = prgb[1] = prgb[2] = (color & 0x1f) * one;
  323. }
  324. else {
  325. prgb[0] = prgb[1] = prgb[2] = 0;
  326. }
  327. return 0;
  328. }
  329. /* DISPLAY_COLORS_NATIVE, 16bit/pixel */
  330. /* Map a r-g-b color to a color code */
  331. private gx_color_index
  332. display_map_rgb_color_device16(gx_device * dev,
  333. gx_color_value r, gx_color_value g, gx_color_value b)
  334. {
  335. gx_device_display *ddev = (gx_device_display *) dev;
  336. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
  337. if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
  338. /* byte0=0RRRRRGG byte1=GGGBBBBB */
  339. return ((r >> (gx_color_value_bits - 5)) << 10) +
  340. ((g >> (gx_color_value_bits - 5)) << 5) +
  341. (b >> (gx_color_value_bits - 5));
  342. else
  343. /* byte0=RRRRRGGG byte1=GGGBBBBB */
  344. return ((r >> (gx_color_value_bits - 5)) << 11) +
  345. ((g >> (gx_color_value_bits - 6)) << 5) +
  346. (b >> (gx_color_value_bits - 5));
  347. }
  348. if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555)
  349. /* byte0=GGGBBBBB byte1=0RRRRRGG */
  350. return ((r >> (gx_color_value_bits - 5)) << 2) +
  351. (((g >> (gx_color_value_bits - 5)) & 0x7) << 13) +
  352. (((g >> (gx_color_value_bits - 5)) & 0x18) >> 3) +
  353. ((b >> (gx_color_value_bits - 5)) << 8);
  354. /* byte0=GGGBBBBB byte1=RRRRRGGG */
  355. return ((r >> (gx_color_value_bits - 5)) << 3) +
  356. (((g >> (gx_color_value_bits - 6)) & 0x7) << 13) +
  357. (((g >> (gx_color_value_bits - 6)) & 0x38) >> 3) +
  358. ((b >> (gx_color_value_bits - 5)) << 8);
  359. }
  360. /* Map a color code to r-g-b. */
  361. private int
  362. display_map_color_rgb_device16(gx_device * dev, gx_color_index color,
  363. gx_color_value prgb[3])
  364. {
  365. gx_device_display *ddev = (gx_device_display *) dev;
  366. gx_color_value one;
  367. ushort value;
  368. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
  369. if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
  370. /* byte0=0RRRRRGG byte1=GGGBBBBB */
  371. value = color >> 10;
  372. prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
  373. (value >> 4)) >> (16 - gx_color_value_bits);
  374. value = (color >> 5) & 0x1f;
  375. prgb[1] = ((value << 11) + (value << 6) + (value << 1) +
  376. (value >> 4)) >> (16 - gx_color_value_bits);
  377. value = color & 0x1f;
  378. prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
  379. (value >> 4)) >> (16 - gx_color_value_bits);
  380. }
  381. else {
  382. /* byte0=RRRRRGGG byte1=GGGBBBBB */
  383. value = color >> 11;
  384. prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
  385. (value >> 4)) >> (16 - gx_color_value_bits);
  386. value = (color >> 5) & 0x3f;
  387. prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
  388. >> (16 - gx_color_value_bits);
  389. value = color & 0x1f;
  390. prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
  391. (value >> 4)) >> (16 - gx_color_value_bits);
  392. }
  393. }
  394. else {
  395. if ((ddev->nFormat & DISPLAY_555_MASK) == DISPLAY_NATIVE_555) {
  396. /* byte0=GGGBBBBB byte1=0RRRRRGG */
  397. value = (color >> 2) & 0x1f;
  398. prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
  399. (value >> 4)) >> (16 - gx_color_value_bits);
  400. value = ((color << 3) & 0x18) + ((color >> 13) & 0x7);
  401. prgb[1] = ((value << 11) + (value << 6) + (value << 1) +
  402. (value >> 4)) >> (16 - gx_color_value_bits);
  403. value = color & 0x1f;
  404. prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
  405. (value >> 4)) >> (16 - gx_color_value_bits);
  406. }
  407. else {
  408. /* byte0=GGGBBBBB byte1=RRRRRGGG */
  409. value = (color >> 3) & 0x1f;
  410. prgb[0] = ((value << 11) + (value << 6) + (value << 1) +
  411. (value >> 4)) >> (16 - gx_color_value_bits);
  412. value = ((color << 3) & 0x38) + ((color >> 13) & 0x7);
  413. prgb[1] = ((value << 10) + (value << 4) + (value >> 2))
  414. >> (16 - gx_color_value_bits);
  415. value = color & 0x1f;
  416. prgb[2] = ((value << 11) + (value << 6) + (value << 1) +
  417. (value >> 4)) >> (16 - gx_color_value_bits);
  418. }
  419. }
  420. return 0;
  421. }
  422. /* Map a r-g-b color to a color code */
  423. private gx_color_index
  424. display_map_rgb_color_rgb(gx_device * dev, gx_color_value r, gx_color_value g,
  425. gx_color_value b)
  426. {
  427. gx_device_display *ddev = (gx_device_display *) dev;
  428. int drop;
  429. gx_color_value red, green, blue;
  430. if ((ddev->nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)
  431. drop = gx_color_value_bits - (dev->color_info.depth / 3);
  432. else
  433. drop = gx_color_value_bits - (dev->color_info.depth / 4);
  434. red = r >> drop;
  435. green = g >> drop;
  436. blue = b >> drop;
  437. switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
  438. case DISPLAY_ALPHA_NONE:
  439. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
  440. return gx_default_rgb_map_rgb_color(dev, r, g, b); /* RGB */
  441. else
  442. return (blue<<16) + (green<<8) + red; /* BGR */
  443. case DISPLAY_ALPHA_FIRST:
  444. case DISPLAY_UNUSED_FIRST:
  445. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
  446. return (red<<16) + (green<<8) + blue; /* xRGB */
  447. else
  448. return (blue<<16) + (green<<8) + red; /* xBGR */
  449. case DISPLAY_ALPHA_LAST:
  450. case DISPLAY_UNUSED_LAST:
  451. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
  452. return (red<<24) + (green<<16) + (blue<<8); /* RGBx */
  453. else
  454. return (blue<<24) + (green<<16) + (red<<8); /* BGRx */
  455. }
  456. return 0;
  457. }
  458. /* Map a color code to r-g-b. */
  459. private int
  460. display_map_color_rgb_rgb(gx_device * dev, gx_color_index color,
  461. gx_color_value prgb[3])
  462. {
  463. gx_device_display *ddev = (gx_device_display *) dev;
  464. uint bits_per_color;
  465. uint color_mask;
  466. if ((ddev->nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)
  467. bits_per_color = dev->color_info.depth / 3;
  468. else
  469. bits_per_color = dev->color_info.depth / 4;
  470. color_mask = (1 << bits_per_color) - 1;
  471. switch (ddev->nFormat & DISPLAY_ALPHA_MASK) {
  472. case DISPLAY_ALPHA_NONE:
  473. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN)
  474. return gx_default_rgb_map_color_rgb(dev, color, prgb); /* RGB */
  475. else {
  476. /* BGR */
  477. prgb[0] = ((color) & color_mask) *
  478. (ulong) gx_max_color_value / color_mask;
  479. prgb[1] = ((color >> bits_per_color) & color_mask) *
  480. (ulong) gx_max_color_value / color_mask;
  481. prgb[2] = ((color >> 2*bits_per_color) & color_mask) *
  482. (ulong) gx_max_color_value / color_mask;
  483. }
  484. break;
  485. case DISPLAY_ALPHA_FIRST:
  486. case DISPLAY_UNUSED_FIRST:
  487. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
  488. /* xRGB */
  489. prgb[0] = ((color) & 2*color_mask) *
  490. (ulong) gx_max_color_value / color_mask;
  491. prgb[1] = ((color >> bits_per_color) & color_mask) *
  492. (ulong) gx_max_color_value / color_mask;
  493. prgb[2] = ((color) & color_mask) *
  494. (ulong) gx_max_color_value / color_mask;
  495. }
  496. else {
  497. /* xBGR */
  498. prgb[0] = ((color) & color_mask) *
  499. (ulong) gx_max_color_value / color_mask;
  500. prgb[1] = ((color >> bits_per_color) & color_mask) *
  501. (ulong) gx_max_color_value / color_mask;
  502. prgb[2] = ((color >> 2*bits_per_color) & color_mask) *
  503. (ulong) gx_max_color_value / color_mask;
  504. }
  505. break;
  506. case DISPLAY_ALPHA_LAST:
  507. case DISPLAY_UNUSED_LAST:
  508. if ((ddev->nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
  509. /* RGBx */
  510. prgb[0] = ((color >> 3*bits_per_color) & color_mask) *
  511. (ulong) gx_max_color_value / color_mask;
  512. prgb[1] = ((color >> 2*bits_per_color) & color_mask) *
  513. (ulong) gx_max_color_value / color_mask;
  514. prgb[2] = ((color >> bits_per_color) & color_mask) *
  515. (ulong) gx_max_color_value / color_mask;
  516. }
  517. else {
  518. /* BGRx */
  519. prgb[0] = ((color >> bits_per_color) & color_mask) *
  520. (ulong) gx_max_color_value / color_mask;
  521. prgb[1] = ((color >> 2*bits_per_color) & color_mask) *
  522. (ulong) gx_max_color_value / color_mask;
  523. prgb[2] = ((color >> 3*bits_per_color) & color_mask) *
  524. (ulong) gx_max_color_value / color_mask;
  525. }
  526. }
  527. return 0;
  528. }
  529. /* Map a r-g-b color to a color code */
  530. private gx_color_index
  531. display_map_rgb_color_bgr24(gx_device * dev, gx_color_value r, gx_color_value g,
  532. gx_color_value b)
  533. {
  534. return (gx_color_value_to_byte(b)<<16) +
  535. (gx_color_value_to_byte(g)<<8) +
  536. gx_color_value_to_byte(r);
  537. }
  538. /* Map a color code to r-g-b. */
  539. private int
  540. display_map_color_rgb_bgr24(gx_device * dev, gx_color_index color,
  541. gx_color_value prgb[3])
  542. {
  543. prgb[0] = gx_color_value_from_byte(color & 0xff);
  544. prgb[1] = gx_color_value_from_byte((color >> 8) & 0xff);
  545. prgb[2] = gx_color_value_from_byte((color >> 16) & 0xff);
  546. return 0;
  547. }
  548. /* Fill a rectangle */
  549. private int
  550. display_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
  551. gx_color_index color)
  552. {
  553. gx_device_display *ddev = (gx_device_display *) dev;
  554. if (ddev->callback == NULL)
  555. return 0;
  556. dev_proc(ddev->mdev, fill_rectangle)((gx_device *)ddev->mdev,
  557. x, y, w, h, color);
  558. if (ddev->callback->display_update)
  559. (*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
  560. return 0;
  561. }
  562. /* Copy a monochrome bitmap */
  563. private int
  564. display_copy_mono(gx_device * dev,
  565. const byte * base, int sourcex, int raster, gx_bitmap_id id,
  566. int x, int y, int w, int h,
  567. gx_color_index zero, gx_color_index one)
  568. {
  569. gx_device_display *ddev = (gx_device_display *) dev;
  570. if (ddev->callback == NULL)
  571. return 0;
  572. dev_proc(ddev->mdev, copy_mono)((gx_device *)ddev->mdev,
  573. base, sourcex, raster, id, x, y, w, h, zero, one);
  574. if (ddev->callback->display_update)
  575. (*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
  576. return 0;
  577. }
  578. /* Copy a color pixel map */
  579. private int
  580. display_copy_color(gx_device * dev,
  581. const byte * base, int sourcex, int raster, gx_bitmap_id id,
  582. int x, int y, int w, int h)
  583. {
  584. gx_device_display *ddev = (gx_device_display *) dev;
  585. if (ddev->callback == NULL)
  586. return 0;
  587. dev_proc(ddev->mdev, copy_color)((gx_device *)ddev->mdev,
  588. base, sourcex, raster, id, x, y, w, h);
  589. if (ddev->callback->display_update)
  590. (*(ddev->callback->display_update))(ddev->pHandle, dev, x, y, w, h);
  591. return 0;
  592. }
  593. private int
  594. display_get_bits(gx_device * dev, int y, byte * str, byte ** actual_data)
  595. {
  596. gx_device_display *ddev = (gx_device_display *) dev;
  597. if (ddev->callback == NULL)
  598. return 0;
  599. return dev_proc(ddev->mdev, get_bits)((gx_device *)ddev->mdev,
  600. y, str, actual_data);
  601. }
  602. private int
  603. display_get_params(gx_device * dev, gs_param_list * plist)
  604. {
  605. gx_device_display *ddev = (gx_device_display *) dev;
  606. int code = gx_default_get_params(dev, plist);
  607. (void)(code < 0 ||
  608. (code = param_write_long(plist,
  609. "DisplayHandle", (long *)(&ddev->pHandle))) < 0 ||
  610. (code = param_write_int(plist,
  611. "DisplayFormat", &ddev->nFormat)) < 0 );
  612. return code;
  613. }
  614. /* Put parameters. */
  615. /* The parameters "DisplayHandle" and "DisplayFormat"
  616. * can be changed when the device is closed, but not when open.
  617. * The device width and height can be changed when open.
  618. */
  619. private int
  620. display_put_params(gx_device * dev, gs_param_list * plist)
  621. {
  622. gx_device_display *ddev = (gx_device_display *) dev;
  623. int ecode = 0, code;
  624. bool is_open = dev->is_open;
  625. int old_width = dev->width;
  626. int old_height = dev->height;
  627. int old_format = ddev->nFormat;
  628. void *old_handle = ddev->pHandle;
  629. int format;
  630. void *handle;
  631. /* Handle extra parameters */
  632. switch (code = param_read_int(plist, "DisplayFormat", &format)) {
  633. case 0:
  634. if (dev->is_open) {
  635. if (ddev->nFormat != format)
  636. ecode = gs_error_rangecheck;
  637. else
  638. break;
  639. }
  640. else {
  641. code = display_set_color_format(ddev, format);
  642. if (code < 0)
  643. ecode = code;
  644. else
  645. break;
  646. }
  647. goto cfe;
  648. default:
  649. ecode = code;
  650. cfe:param_signal_error(plist, "DisplayFormat", ecode);
  651. case 1:
  652. break;
  653. }
  654. switch (code = param_read_long(plist, "DisplayHandle", (long *)(&handle))) {
  655. case 0:
  656. if (dev->is_open) {
  657. if (ddev->pHandle != handle)
  658. ecode = gs_error_rangecheck;
  659. else
  660. break;
  661. }
  662. else
  663. ddev->pHandle = handle;
  664. break;
  665. goto hdle;
  666. default:
  667. ecode = code;
  668. hdle:param_signal_error(plist, "DisplayHandle", ecode);
  669. case 1:
  670. break;
  671. }
  672. if (ecode >= 0) {
  673. /* Prevent gx_default_put_params from closing the device. */
  674. dev->is_open = false;
  675. ecode = gx_default_put_params(dev, plist);
  676. dev->is_open = is_open;
  677. }
  678. if (ecode < 0) {
  679. if (format != old_format)
  680. display_set_color_format(ddev, old_format);
  681. ddev->pHandle = old_handle;
  682. dev->width = old_width;
  683. dev->height = old_height;
  684. return ecode;
  685. }
  686. if ( is_open && ddev->callback &&
  687. ((old_width != dev->width) || (old_height != dev->height)) ) {
  688. /* We can resize this device while it is open, but we cannot
  689. * change the color format or handle.
  690. */
  691. /* Tell caller we are about to change the device parameters */
  692. if ((*ddev->callback->display_presize)(ddev->pHandle, dev,
  693. dev->width, dev->height, gdev_mem_raster(dev),
  694. ddev->nFormat) < 0) {
  695. /* caller won't let us change the size */
  696. /* restore parameters then return an error */
  697. display_set_color_format(ddev, old_format);
  698. ddev->nFormat = old_format;
  699. ddev->pHandle = old_handle;
  700. dev->width = old_width;
  701. dev->height = old_height;
  702. return_error(gs_error_rangecheck);
  703. }
  704. display_free_bitmap(ddev);
  705. code = display_alloc_bitmap(ddev, dev);
  706. if (code < 0) {
  707. /* No bitmap, so tell the caller it is zero size */
  708. (*ddev->callback->display_size)(ddev->pHandle, dev,
  709. 0, 0, 0, ddev->nFormat, NULL);
  710. return_error(code);
  711. }
  712. /* tell caller about the new size */
  713. if ((*ddev->callback->display_size)(ddev->pHandle, dev,
  714. dev->width, dev->height, gdev_mem_raster(dev),
  715. ddev->nFormat, ddev->mdev->base) < 0)
  716. return_error(gs_error_rangecheck);
  717. }
  718. return 0;
  719. }
  720. /* Clean up the instance after making a copy. */
  721. int
  722. display_finish_copydevice(gx_device *dev, const gx_device *from_dev)
  723. {
  724. gx_device_display *ddev = (gx_device_display *) dev;
  725. /* Mark the new instance as closed. */
  726. ddev->is_open = false;
  727. /* Clear pointers */
  728. ddev->mdev = NULL;
  729. ddev->pBitmap = NULL;
  730. ddev->ulBitmapSize = 0;
  731. return 0;
  732. }
  733. /* ------ Internal routines ------ */
  734. /* Make sure we have been given a valid structure */
  735. /* Return 0 on success, gs_error_rangecheck on failure */
  736. private int display_check_structure(gx_device_display *ddev)
  737. {
  738. if (ddev->callback == 0)
  739. return_error(gs_error_rangecheck);
  740. if (ddev->callback->size != sizeof(display_callback))
  741. return_error(gs_error_rangecheck);
  742. if (ddev->callback->version_major != DISPLAY_VERSION_MAJOR)
  743. return_error(gs_error_rangecheck);
  744. /* complain if caller asks for newer features */
  745. if (ddev->callback->version_minor > DISPLAY_VERSION_MINOR)
  746. return_error(gs_error_rangecheck);
  747. if ((ddev->callback->display_open == NULL) ||
  748. (ddev->callback->display_close == NULL) ||
  749. (ddev->callback->display_presize == NULL) ||
  750. (ddev->callback->display_size == NULL) ||
  751. (ddev->callback->display_sync == NULL) ||
  752. (ddev->callback->display_page == NULL))
  753. return_error(gs_error_rangecheck);
  754. /* don't test display_update, display_memalloc or display_memfree
  755. * since these may be NULL if not provided
  756. */
  757. return 0;
  758. }
  759. private void
  760. display_free_bitmap(gx_device_display * ddev)
  761. {
  762. if (ddev->callback == NULL)
  763. return;
  764. if (ddev->pBitmap) {
  765. if (ddev->callback->display_memalloc
  766. && ddev->callback->display_memfree
  767. && ddev->pBitmap) {
  768. (*ddev->callback->display_memfree)(ddev->pHandle, ddev,
  769. ddev->pBitmap);
  770. }
  771. else {
  772. gs_free_object(gs_memory_stable(ddev->memory),
  773. ddev->pBitmap, "display_free_bitmap");
  774. }
  775. ddev->pBitmap = NULL;
  776. if (ddev->mdev)
  777. ddev->mdev->base = NULL;
  778. }
  779. if (ddev->mdev) {
  780. dev_proc(ddev->mdev, close_device)((gx_device *)ddev->mdev);
  781. gx_device_retain((gx_device *)(ddev->mdev), false);
  782. ddev->mdev = NULL;
  783. }
  784. }
  785. /* Allocate the backing bitmap. */
  786. private int
  787. display_alloc_bitmap(gx_device_display * ddev, gx_device * param_dev)
  788. {
  789. int ccode;
  790. const gx_device_memory *mdproto;
  791. if (ddev->callback == NULL)
  792. return 0;
  793. /* free old bitmap (if any) */
  794. display_free_bitmap(ddev);
  795. /* allocate a memory device for rendering */
  796. mdproto = gdev_mem_device_for_bits(ddev->color_info.depth);
  797. if (mdproto == 0)
  798. return_error(gs_error_rangecheck);
  799. ccode = gs_copydevice((gx_device **)&(ddev->mdev),
  800. (const gx_device *)mdproto,
  801. gs_memory_stable(ddev->memory));
  802. if (ccode < 0)
  803. return ccode;
  804. gs_make_mem_device(ddev->mdev, mdproto, gs_memory_stable(ddev->memory),
  805. 0, (gx_device *) NULL);
  806. gx_device_fill_in_procs((gx_device *)(ddev->mdev));
  807. /* Mark the memory device as retained. When the bitmap is closed,
  808. * we will clear this and the memory device will be then be freed.
  809. */
  810. gx_device_retain((gx_device *)(ddev->mdev), true);
  811. ddev->mdev->width = param_dev->width;
  812. ddev->mdev->height = param_dev->height;
  813. ddev->ulBitmapSize = gdev_mem_bitmap_size(ddev->mdev);
  814. /* allocate bitmap */
  815. if (ddev->callback->display_memalloc
  816. && ddev->callback->display_memfree) {
  817. ddev->pBitmap = (*ddev->callback->display_memalloc)(ddev->pHandle,
  818. ddev, ddev->ulBitmapSize);
  819. }
  820. else {
  821. ddev->pBitmap = gs_alloc_bytes_immovable(gs_memory_stable(ddev->memory),
  822. (uint)ddev->ulBitmapSize, "display_alloc_bitmap");
  823. }
  824. if (ddev->pBitmap == NULL) {
  825. ddev->mdev->width = 0;
  826. ddev->mdev->height = 0;
  827. return_error(gs_error_VMerror);
  828. }
  829. ddev->mdev->base = (byte *) ddev->pBitmap;
  830. ddev->mdev->foreign_bits = true;
  831. ccode = dev_proc(ddev->mdev, open_device)((gx_device *)ddev->mdev);
  832. if (ccode < 0)
  833. display_free_bitmap(ddev);
  834. /* erase bitmap - before display gets redrawn */
  835. if (ccode == 0)
  836. dev_proc(ddev, fill_rectangle)((gx_device *)ddev,
  837. 0, 0, ddev->width, ddev->height,
  838. ddev->procs.map_rgb_color((gx_device *)ddev,
  839. gx_max_color_value, gx_max_color_value, gx_max_color_value));
  840. return ccode;
  841. }
  842. /* Set the color_info and mapping functions for this instance of the device */
  843. private int
  844. display_set_color_format(gx_device_display *ddev, int nFormat)
  845. {
  846. gx_device_color_info dci = ddev->color_info;
  847. int bpc; /* bits per component */
  848. int bpp; /* bits per pixel */
  849. int maxvalue;
  850. switch (nFormat & DISPLAY_DEPTH_MASK) {
  851. case DISPLAY_DEPTH_1:
  852. bpc = 1;
  853. break;
  854. case DISPLAY_DEPTH_2:
  855. bpc = 2;
  856. break;
  857. case DISPLAY_DEPTH_4:
  858. bpc = 4;
  859. break;
  860. case DISPLAY_DEPTH_8:
  861. bpc = 8;
  862. break;
  863. case DISPLAY_DEPTH_12:
  864. bpc = 12;
  865. break;
  866. case DISPLAY_DEPTH_16:
  867. bpc = 16;
  868. break;
  869. default:
  870. return_error(gs_error_rangecheck);
  871. }
  872. maxvalue = (1 << bpc) - 1;
  873. switch (nFormat & DISPLAY_COLORS_MASK) {
  874. case DISPLAY_COLORS_NATIVE:
  875. switch (nFormat & DISPLAY_DEPTH_MASK) {
  876. case DISPLAY_DEPTH_1:
  877. /* 1bit/pixel, black is 1, white is 0 */
  878. dci.num_components = 1;
  879. dci.depth = 1;
  880. dci.max_gray = 1;
  881. dci.max_color = 0;
  882. dci.dither_grays = 2;
  883. dci.dither_colors = 0;
  884. ddev->procs.map_rgb_color = gx_default_b_w_map_rgb_color;
  885. ddev->procs.map_color_rgb = gx_default_b_w_map_color_rgb;
  886. break;
  887. case DISPLAY_DEPTH_4:
  888. /* 4bit/pixel VGA color */
  889. dci.num_components = 3;
  890. dci.depth = 4;
  891. dci.max_gray = 3;
  892. dci.max_color = 2;
  893. dci.dither_grays = 4;
  894. dci.dither_colors = 3;
  895. ddev->procs.map_rgb_color = display_map_rgb_color_device4;
  896. ddev->procs.map_color_rgb = display_map_color_rgb_device4;
  897. break;
  898. case DISPLAY_DEPTH_8:
  899. /* 8bit/pixel 96 color palette */
  900. dci.num_components = 3;
  901. dci.depth = 8;
  902. dci.max_gray = 31;
  903. dci.max_color = 3;
  904. dci.dither_grays = 32;
  905. dci.dither_colors = 4;
  906. ddev->procs.map_rgb_color = display_map_rgb_color_device8;
  907. ddev->procs.map_color_rgb = display_map_color_rgb_device8;
  908. break;
  909. case DISPLAY_DEPTH_16:
  910. /* Windows 16-bit display */
  911. dci.num_components = 3;
  912. dci.depth = 16;
  913. dci.max_gray = 63;
  914. dci.max_color = 63;
  915. dci.dither_grays = 64;
  916. dci.dither_colors = 64;
  917. ddev->procs.map_rgb_color = display_map_rgb_color_device16;
  918. ddev->procs.map_color_rgb = display_map_color_rgb_device16;
  919. break;
  920. default:
  921. return_error(gs_error_rangecheck);
  922. }
  923. break;
  924. case DISPLAY_COLORS_GRAY:
  925. dci.num_components = 1;
  926. dci.depth = bpc;
  927. dci.max_gray = maxvalue;
  928. dci.max_color = 0;
  929. dci.dither_grays = maxvalue+1;
  930. dci.dither_colors = 0;
  931. if (bpc == 1) {
  932. ddev->procs.map_rgb_color = gx_default_w_b_map_rgb_color;
  933. ddev->procs.map_color_rgb = gx_default_w_b_map_color_rgb;
  934. }
  935. else {
  936. ddev->procs.map_rgb_color = gx_default_gray_map_rgb_color;
  937. ddev->procs.map_color_rgb = gx_default_gray_map_color_rgb;
  938. }
  939. break;
  940. case DISPLAY_COLORS_RGB:
  941. if ((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)
  942. bpp = bpc * 3;
  943. else
  944. bpp = bpc * 4;
  945. dci.num_components = 3;
  946. dci.depth = bpp;
  947. dci.max_gray = maxvalue;
  948. dci.max_color = maxvalue;
  949. dci.dither_grays = maxvalue+1;
  950. dci.dither_colors = maxvalue+1;
  951. if (((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) &&
  952. ((nFormat & DISPLAY_ALPHA_MASK) == DISPLAY_ALPHA_NONE)) {
  953. if ((nFormat & DISPLAY_ENDIAN_MASK) == DISPLAY_BIGENDIAN) {
  954. ddev->procs.map_rgb_color = gx_default_rgb_map_rgb_color;
  955. ddev->procs.map_color_rgb = gx_default_rgb_map_color_rgb;
  956. }
  957. else {
  958. ddev->procs.map_rgb_color = display_map_rgb_color_bgr24;
  959. ddev->procs.map_color_rgb = display_map_color_rgb_bgr24;
  960. }
  961. }
  962. else {
  963. /* slower flexible functions for alpha/unused component */
  964. ddev->procs.map_rgb_color = display_map_rgb_color_rgb;
  965. ddev->procs.map_color_rgb = display_map_color_rgb_rgb;
  966. }
  967. break;
  968. case DISPLAY_COLORS_CMYK:
  969. dci.num_components = 4;
  970. dci.depth = bpc * 4;
  971. dci.max_gray = maxvalue;
  972. dci.max_color = maxvalue;
  973. dci.dither_grays = maxvalue+1;
  974. dci.dither_colors = maxvalue+1;
  975. if ((nFormat & DISPLAY_ALPHA_MASK) != DISPLAY_ALPHA_NONE)
  976. return_error(gs_error_rangecheck);
  977. if ((nFormat & DISPLAY_ENDIAN_MASK) != DISPLAY_BIGENDIAN)
  978. return_error(gs_error_rangecheck);
  979. if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_1) {
  980. ddev->procs.map_cmyk_color = cmyk_1bit_map_cmyk_color;
  981. ddev->procs.map_color_rgb = cmyk_1bit_map_color_rgb;
  982. }
  983. else if ((nFormat & DISPLAY_DEPTH_MASK) == DISPLAY_DEPTH_8) {
  984. ddev->procs.map_cmyk_color = cmyk_8bit_map_cmyk_color;
  985. ddev->procs.map_color_rgb = cmyk_8bit_map_color_rgb;
  986. }
  987. else
  988. return_error(gs_error_rangecheck);
  989. break;
  990. default:
  991. return_error(gs_error_rangecheck);
  992. }
  993. /* restore old anti_alias info */
  994. dci.anti_alias = ddev->color_info.anti_alias;
  995. ddev->color_info = dci;
  996. ddev->nFormat = nFormat;
  997. return 0;
  998. }
  999. /* ------ Begin Test Code ------ */
  1000. /*********************************************************************
  1001. typedef struct test_mode_s test_mode;
  1002. struct test_mode_s {
  1003. char *name;
  1004. unsigned int format;
  1005. };
  1006. test_mode test_modes[] = {
  1007. {"1bit/pixel native, black is 1, Windows",
  1008. DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
  1009. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1010. {"4bit/pixel native, Windows VGA 16 color palette",
  1011. DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
  1012. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1013. {"8bit/pixel native, Windows SVGA 96 color palette",
  1014. DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1015. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1016. {"16bit/pixel native, Windows BGR555",
  1017. DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
  1018. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_555},
  1019. {"16bit/pixel native, Windows BGR565",
  1020. DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_16 |
  1021. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST | DISPLAY_NATIVE_565},
  1022. {"1bit/pixel gray, black is 0, topfirst",
  1023. DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 |
  1024. DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
  1025. {"4bit/pixel gray, bottom first",
  1026. DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_4 |
  1027. DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
  1028. {"8bit/pixel gray, bottom first",
  1029. DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1030. DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
  1031. {"24bit/pixel color, bottom first, Windows BGR24",
  1032. DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1033. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1034. {"24bit/pixel color, bottom first, RGB24",
  1035. DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1036. DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
  1037. {"24bit/pixel color, top first, GdkRgb RGB24",
  1038. DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1039. DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
  1040. {"32bit/pixel color, top first, Macintosh xRGB",
  1041. DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
  1042. DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST},
  1043. {"32bit/pixel color, bottom first, xBGR",
  1044. DISPLAY_COLORS_RGB | DISPLAY_UNUSED_FIRST | DISPLAY_DEPTH_8 |
  1045. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1046. {"32bit/pixel color, bottom first, Windows BGRx",
  1047. DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
  1048. DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST},
  1049. {"32bit/pixel color, bottom first, RGBx",
  1050. DISPLAY_COLORS_RGB | DISPLAY_UNUSED_LAST | DISPLAY_DEPTH_8 |
  1051. DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST},
  1052. {"32bit/pixel CMYK, bottom first",
  1053. DISPLAY_COLORS_CMYK | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 |
  1054. DISPLAY_BIGENDIAN | DISPLAY_BOTTOMFIRST}
  1055. };
  1056. void
  1057. test(int index)
  1058. {
  1059. char buf[1024];
  1060. sprintf(buf, "gs -dDisplayFormat=%d examples/colorcir.ps -c quit", test_modes[index].format);
  1061. system(buf);
  1062. }
  1063. int main(int argc, char *argv[])
  1064. {
  1065. int i;
  1066. int dotest = 0;
  1067. if (argc >=2) {
  1068. if (strcmp(argv[1], "-t") == 0)
  1069. dotest = 1;
  1070. else {
  1071. fprintf(stdout, "To show modes: disp\nTo run test: disp -t\n");
  1072. return 1;
  1073. }
  1074. }
  1075. for (i=0; i < sizeof(test_modes)/sizeof(test_mode); i++) {
  1076. fprintf(stdout, "%d: %s\n", test_modes[i].format,
  1077. test_modes[i].name);
  1078. if (dotest)
  1079. test(i);
  1080. }
  1081. return 0;
  1082. }
  1083. *********************************************************************/
  1084. /* ------ End Test Code ------ */