gspaint.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /* Copyright (C) 1989, 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved.
  2. This software is provided AS-IS with no warranty, either express or
  3. implied.
  4. This software is distributed under license and may not be copied,
  5. modified or distributed except as expressly authorized under the terms
  6. of the license contained in the file LICENSE in this distribution.
  7. For more information about licensing, please refer to
  8. http://www.ghostscript.com/licensing/. For information on
  9. commercial licensing, go to http://www.artifex.com/licensing/ or
  10. contact Artifex Software, Inc., 101 Lucas Valley Road #110,
  11. San Rafael, CA 94903, U.S.A., +1(415)492-9861.
  12. */
  13. /* $Id: gspaint.c,v 1.10 2005/10/12 17:59:55 leonardo Exp $ */
  14. /* Painting procedures for Ghostscript library */
  15. #include "math_.h" /* for fabs */
  16. #include "gx.h"
  17. #include "gpcheck.h"
  18. #include "gserrors.h"
  19. #include "gsropt.h" /* for gxpaint.h */
  20. #include "gxfixed.h"
  21. #include "gxmatrix.h" /* for gs_state */
  22. #include "gspaint.h"
  23. #include "gspath.h"
  24. #include "gzpath.h"
  25. #include "gxpaint.h"
  26. #include "gzstate.h"
  27. #include "gxdevice.h"
  28. #include "gxdevmem.h"
  29. #include "gzcpath.h"
  30. #include "gxhldevc.h"
  31. /* Define the nominal size for alpha buffers. */
  32. #define abuf_nominal_SMALL 500
  33. #define abuf_nominal_LARGE 2000
  34. #if arch_small_memory
  35. # define abuf_nominal abuf_nominal_SMALL
  36. #else
  37. # define abuf_nominal\
  38. (gs_debug_c('.') ? abuf_nominal_SMALL : abuf_nominal_LARGE)
  39. #endif
  40. /* Erase the page */
  41. int
  42. gs_erasepage(gs_state * pgs)
  43. {
  44. /*
  45. * We can't just fill with device white; we must take the
  46. * transfer function into account.
  47. */
  48. int code;
  49. if ((code = gs_gsave(pgs)) < 0)
  50. return code;
  51. if ((code = gs_setgray(pgs, 1.0)) >= 0) {
  52. /* Fill the page directly, ignoring clipping. */
  53. code = gs_fillpage(pgs);
  54. }
  55. gs_grestore(pgs);
  56. return code;
  57. }
  58. /* Fill the page with the current color. */
  59. int
  60. gs_fillpage(gs_state * pgs)
  61. {
  62. gx_device *dev;
  63. int code = 0;
  64. gs_logical_operation_t save_lop;
  65. bool hl_color_available = gx_hld_is_hl_color_available((gs_imager_state *)pgs,
  66. pgs->dev_color);
  67. gx_set_dev_color(pgs);
  68. dev = gs_currentdevice(pgs);
  69. /* Fill the page directly, ignoring clipping. */
  70. /* Use the default RasterOp. */
  71. save_lop = pgs->log_op;
  72. gs_init_rop(pgs);
  73. if (hl_color_available) {
  74. gs_fixed_rect rect;
  75. rect.p.x = rect.p.y = 0;
  76. rect.q.x = int2fixed(dev->width);
  77. rect.q.y = int2fixed(dev->height);
  78. code = dev_proc(pgs->device, fill_rectangle_hl_color)(pgs->device,
  79. &rect, (const gs_imager_state *)pgs, pgs->dev_color, NULL);
  80. }
  81. if (!hl_color_available || code == gs_error_rangecheck)
  82. code = gx_fill_rectangle(0, 0, dev->width, dev->height,
  83. pgs->dev_color, pgs);
  84. pgs->log_op = save_lop;
  85. if (code < 0)
  86. return code;
  87. return (*dev_proc(dev, sync_output)) (dev);
  88. }
  89. /*
  90. * Determine the number of bits of alpha buffer for a stroke or fill.
  91. * We should do alpha buffering iff this value is >1.
  92. */
  93. private int
  94. alpha_buffer_bits(gs_state * pgs)
  95. {
  96. gx_device *dev;
  97. if (!color_is_pure(pgs->dev_color))
  98. return 0;
  99. dev = gs_currentdevice_inline(pgs);
  100. if (gs_device_is_abuf(dev)) {
  101. /* We're already writing into an alpha buffer. */
  102. return 0;
  103. }
  104. return (*dev_proc(dev, get_alpha_bits))
  105. (dev, (pgs->in_cachedevice ? go_text : go_graphics));
  106. }
  107. /*
  108. * Set up an alpha buffer for a stroke or fill operation. Return 0
  109. * if no buffer could be allocated, 1 if a buffer was installed,
  110. * or the usual negative error code.
  111. *
  112. * The fill/stroke code sets up a clipping device if needed; however,
  113. * since we scale up all the path coordinates, we either need to scale up
  114. * the clipping region, or do clipping after, rather than before,
  115. * alpha buffering. Either of these is a little inconvenient, but
  116. * the former is less inconvenient.
  117. */
  118. private int
  119. scale_paths(gs_state * pgs, int log2_scale_x, int log2_scale_y, bool do_path)
  120. {
  121. /*
  122. * Because of clip and clippath, any of path, clip_path, and view_clip
  123. * may be aliases for each other. The only reliable way to detect
  124. * this is by comparing the segments pointers. Note that we must
  125. * scale the non-segment parts of the paths even if the segments are
  126. * aliased.
  127. */
  128. const gx_path_segments *seg_clip =
  129. (pgs->clip_path->path_valid ? pgs->clip_path->path.segments : 0);
  130. const gx_clip_rect_list *list_clip = pgs->clip_path->rect_list;
  131. const gx_path_segments *seg_view_clip;
  132. const gx_clip_rect_list *list_view_clip;
  133. const gx_path_segments *seg_effective_clip =
  134. (pgs->effective_clip_path->path_valid ?
  135. pgs->effective_clip_path->path.segments : 0);
  136. const gx_clip_rect_list *list_effective_clip =
  137. pgs->effective_clip_path->rect_list;
  138. gx_cpath_scale_exp2_shared(pgs->clip_path, log2_scale_x, log2_scale_y,
  139. false, false);
  140. if (pgs->view_clip != 0 && pgs->view_clip != pgs->clip_path) {
  141. seg_view_clip =
  142. (pgs->view_clip->path_valid ? pgs->view_clip->path.segments : 0);
  143. list_view_clip = pgs->view_clip->rect_list;
  144. gx_cpath_scale_exp2_shared(pgs->view_clip, log2_scale_x, log2_scale_y,
  145. list_view_clip == list_clip,
  146. seg_view_clip && seg_view_clip == seg_clip);
  147. } else
  148. seg_view_clip = 0, list_view_clip = 0;
  149. if (pgs->effective_clip_path != pgs->clip_path &&
  150. pgs->effective_clip_path != pgs->view_clip
  151. )
  152. gx_cpath_scale_exp2_shared(pgs->effective_clip_path, log2_scale_x,
  153. log2_scale_y,
  154. list_effective_clip == list_clip ||
  155. list_effective_clip == list_view_clip,
  156. seg_effective_clip &&
  157. (seg_effective_clip == seg_clip ||
  158. seg_effective_clip == seg_view_clip));
  159. if (do_path) {
  160. const gx_path_segments *seg_path = pgs->path->segments;
  161. gx_path_scale_exp2_shared(pgs->path, log2_scale_x, log2_scale_y,
  162. seg_path == seg_clip ||
  163. seg_path == seg_view_clip ||
  164. seg_path == seg_effective_clip);
  165. }
  166. return 0;
  167. }
  168. private void
  169. scale_dash_pattern(gs_state * pgs, floatp scale)
  170. {
  171. int i;
  172. for (i = 0; i < pgs->line_params.dash.pattern_size; ++i)
  173. pgs->line_params.dash.pattern[i] *= scale;
  174. pgs->line_params.dash.offset *= scale;
  175. pgs->line_params.dash.pattern_length *= scale;
  176. pgs->line_params.dash.init_dist_left *= scale;
  177. if (pgs->line_params.dot_length_absolute)
  178. pgs->line_params.dot_length *= scale;
  179. }
  180. private int
  181. alpha_buffer_init(gs_state * pgs, fixed extra_x, fixed extra_y, int alpha_bits)
  182. {
  183. gx_device *dev = gs_currentdevice_inline(pgs);
  184. int log2_alpha_bits = ilog2(alpha_bits);
  185. gs_fixed_rect bbox;
  186. gs_int_rect ibox;
  187. uint width, raster, band_space;
  188. uint height;
  189. gs_log2_scale_point log2_scale;
  190. gs_memory_t *mem;
  191. gx_device_memory *mdev;
  192. log2_scale.x = log2_scale.y = log2_alpha_bits;
  193. gx_path_bbox(pgs->path, &bbox);
  194. ibox.p.x = fixed2int(bbox.p.x - extra_x) - 1;
  195. ibox.p.y = fixed2int(bbox.p.y - extra_y) - 1;
  196. ibox.q.x = fixed2int_ceiling(bbox.q.x + extra_x) + 1;
  197. ibox.q.y = fixed2int_ceiling(bbox.q.y + extra_y) + 1;
  198. width = (ibox.q.x - ibox.p.x) << log2_scale.x;
  199. raster = bitmap_raster(width);
  200. band_space = raster << log2_scale.y;
  201. height = (abuf_nominal / band_space) << log2_scale.y;
  202. if (height == 0)
  203. height = 1 << log2_scale.y;
  204. mem = pgs->memory;
  205. mdev = gs_alloc_struct(mem, gx_device_memory, &st_device_memory,
  206. "alpha_buffer_init");
  207. if (mdev == 0)
  208. return 0; /* if no room, don't buffer */
  209. gs_make_mem_abuf_device(mdev, mem, dev, &log2_scale,
  210. alpha_bits, ibox.p.x << log2_scale.x);
  211. mdev->width = width;
  212. mdev->height = height;
  213. mdev->bitmap_memory = mem;
  214. if ((*dev_proc(mdev, open_device)) ((gx_device *) mdev) < 0) {
  215. /* No room for bits, punt. */
  216. gs_free_object(mem, mdev, "alpha_buffer_init");
  217. return 0;
  218. }
  219. gx_set_device_only(pgs, (gx_device *) mdev);
  220. scale_paths(pgs, log2_scale.x, log2_scale.y, true);
  221. return 1;
  222. }
  223. /* Release an alpha buffer. */
  224. private void
  225. alpha_buffer_release(gs_state * pgs, bool newpath)
  226. {
  227. gx_device_memory *mdev =
  228. (gx_device_memory *) gs_currentdevice_inline(pgs);
  229. (*dev_proc(mdev, close_device)) ((gx_device *) mdev);
  230. scale_paths(pgs, -mdev->log2_scale.x, -mdev->log2_scale.y,
  231. !(newpath && !gx_path_is_shared(pgs->path)));
  232. /* Reference counting will free mdev. */
  233. gx_set_device_only(pgs, mdev->target);
  234. }
  235. /* Fill the current path using a specified rule. */
  236. private int
  237. fill_with_rule(gs_state * pgs, int rule)
  238. {
  239. int code;
  240. /* If we're inside a charpath, just merge the current path */
  241. /* into the parent's path. */
  242. if (pgs->in_charpath)
  243. code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
  244. pgs->in_charpath);
  245. else if (gs_is_null_device(pgs->device)) {
  246. /* Handle separately to prevent gs_state_color_load - bug 688308. */
  247. gs_newpath(pgs);
  248. code = 0;
  249. } else {
  250. int abits, acode;
  251. gx_set_dev_color(pgs);
  252. code = gs_state_color_load(pgs);
  253. if (code < 0)
  254. return code;
  255. abits = alpha_buffer_bits(pgs);
  256. if (abits > 1) {
  257. acode = alpha_buffer_init(pgs, pgs->fill_adjust.x,
  258. pgs->fill_adjust.y, abits);
  259. if (acode < 0)
  260. return acode;
  261. } else
  262. acode = 0;
  263. code = gx_fill_path(pgs->path, pgs->dev_color, pgs, rule,
  264. pgs->fill_adjust.x, pgs->fill_adjust.y);
  265. if (acode > 0)
  266. alpha_buffer_release(pgs, code >= 0);
  267. if (code >= 0)
  268. gs_newpath(pgs);
  269. }
  270. return code;
  271. }
  272. /* Fill using the winding number rule */
  273. int
  274. gs_fill(gs_state * pgs)
  275. {
  276. return fill_with_rule(pgs, gx_rule_winding_number);
  277. }
  278. /* Fill using the even/odd rule */
  279. int
  280. gs_eofill(gs_state * pgs)
  281. {
  282. return fill_with_rule(pgs, gx_rule_even_odd);
  283. }
  284. /* Stroke the current path */
  285. int
  286. gs_stroke(gs_state * pgs)
  287. {
  288. int code;
  289. /*
  290. * If we're inside a charpath, just merge the current path
  291. * into the parent's path.
  292. */
  293. if (pgs->in_charpath) {
  294. if (pgs->in_charpath == cpm_true_charpath) {
  295. /*
  296. * A stroke inside a true charpath should do the
  297. * equivalent of strokepath.
  298. */
  299. code = gs_strokepath(pgs);
  300. if (code < 0)
  301. return code;
  302. }
  303. code = gx_path_add_char_path(pgs->show_gstate->path, pgs->path,
  304. pgs->in_charpath);
  305. } else if (gs_is_null_device(pgs->device)) {
  306. /* Handle separately to prevent gs_state_color_load. */
  307. gs_newpath(pgs);
  308. code = 0;
  309. } else {
  310. int abits, acode;
  311. gx_set_dev_color(pgs);
  312. code = gs_state_color_load(pgs);
  313. if (code < 0)
  314. return code;
  315. abits = alpha_buffer_bits(pgs);
  316. if (abits > 1) {
  317. /*
  318. * Expand the bounding box by the line width.
  319. * This is expensive to compute, so we only do it
  320. * if we know we're going to buffer.
  321. */
  322. float xxyy = fabs(pgs->ctm.xx) + fabs(pgs->ctm.yy);
  323. float xyyx = fabs(pgs->ctm.xy) + fabs(pgs->ctm.yx);
  324. float scale = (float)(1 << (abits / 2));
  325. float orig_width = gs_currentlinewidth(pgs);
  326. float new_width = orig_width * scale;
  327. fixed extra_adjust =
  328. float2fixed(max(xxyy, xyyx) * new_width / 2);
  329. float orig_flatness = gs_currentflat(pgs);
  330. gx_path spath;
  331. /* Scale up the line width, dash pattern, and flatness. */
  332. if (extra_adjust < fixed_1)
  333. extra_adjust = fixed_1;
  334. acode = alpha_buffer_init(pgs,
  335. pgs->fill_adjust.x + extra_adjust,
  336. pgs->fill_adjust.y + extra_adjust,
  337. abits);
  338. if (acode < 0)
  339. return acode;
  340. gs_setlinewidth(pgs, new_width);
  341. scale_dash_pattern(pgs, scale);
  342. gs_setflat(pgs, orig_flatness * scale);
  343. /*
  344. * The alpha-buffer device requires that we fill the
  345. * entire path as a single unit.
  346. */
  347. gx_path_init_local(&spath, pgs->memory);
  348. code = gx_stroke_add(pgs->path, &spath, pgs);
  349. gs_setlinewidth(pgs, orig_width);
  350. scale_dash_pattern(pgs, 1.0 / scale);
  351. if (code >= 0)
  352. code = gx_fill_path(&spath, pgs->dev_color, pgs,
  353. gx_rule_winding_number,
  354. pgs->fill_adjust.x,
  355. pgs->fill_adjust.y);
  356. gs_setflat(pgs, orig_flatness);
  357. gx_path_free(&spath, "gs_stroke");
  358. if (acode > 0)
  359. alpha_buffer_release(pgs, code >= 0);
  360. } else
  361. code = gx_stroke_fill(pgs->path, pgs);
  362. if (code >= 0)
  363. gs_newpath(pgs);
  364. }
  365. return code;
  366. }
  367. /* Compute the stroked outline of the current path */
  368. int
  369. gs_strokepath(gs_state * pgs)
  370. {
  371. gx_path spath;
  372. int code;
  373. gx_path_init_local(&spath, pgs->path->memory);
  374. code = gx_stroke_add(pgs->path, &spath, pgs);
  375. if (code < 0) {
  376. gx_path_free(&spath, "gs_strokepath");
  377. return code;
  378. }
  379. code = gx_path_assign_free(pgs->path, &spath);
  380. if (code < 0)
  381. return code;
  382. gx_setcurrentpoint(pgs, fixed2float(spath.position.x), fixed2float(spath.position.y));
  383. return 0;
  384. }