gxfill.c 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011
  1. /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved.
  2. This file is part of AFPL Ghostscript.
  3. AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
  4. distributor accepts any responsibility for the consequences of using it, or
  5. for whether it serves any particular purpose or works at all, unless he or
  6. she says so in writing. Refer to the Aladdin Free Public License (the
  7. "License") for full details.
  8. Every copy of AFPL Ghostscript must include a copy of the License, normally
  9. in a plain ASCII text file named PUBLIC. The License grants you the right
  10. to copy, modify and redistribute AFPL Ghostscript, but only under certain
  11. conditions described in the License. Among other things, the License
  12. requires that the copyright notice and this notice be preserved on all
  13. copies.
  14. */
  15. /*$Id: gxfill.c,v 1.8 2001/05/10 18:35:14 igorm Exp $ */
  16. /* Lower-level path filling procedures */
  17. #include "gx.h"
  18. #include "gserrors.h"
  19. #include "gsstruct.h"
  20. #include "gxfixed.h"
  21. #include "gxdevice.h"
  22. #include "gzpath.h"
  23. #include "gzcpath.h"
  24. #include "gxdcolor.h"
  25. #include "gxhttile.h"
  26. #include "gxistate.h"
  27. #include "gxpaint.h" /* for prototypes */
  28. #include "gsptype2.h"
  29. /*
  30. * Define which fill algorithm(s) to use. At least one of the following
  31. * two #defines must be included (not commented out).
  32. */
  33. #define FILL_SCAN_LINES
  34. #define FILL_TRAPEZOIDS
  35. /*
  36. * Define whether to sample curves when using the scan line algorithm
  37. * rather than flattening them. This produces more accurate output, at
  38. * some cost in time.
  39. */
  40. #define FILL_CURVES
  41. /* ---------------- Statistics ---------------- */
  42. #ifdef DEBUG
  43. struct stats_fill_s {
  44. long
  45. fill, fill_alloc, y_up, y_down, horiz, x_step, slow_x, iter, find_y,
  46. band, band_step, band_fill, afill, slant, slant_shallow, sfill,
  47. mq_cross, cross_slow, cross_low, order, slow_order;
  48. } stats_fill;
  49. # define INCR(x) (++(stats_fill.x))
  50. # define INCR_EXPR(x) INCR(x)
  51. # define INCR_BY(x,n) (stats_fill.x += (n))
  52. #else
  53. # define INCR(x) DO_NOTHING
  54. # define INCR_EXPR(x) discard(0)
  55. # define INCR_BY(x,n) DO_NOTHING
  56. #endif
  57. /* ---------------- Active line management ---------------- */
  58. /* Define the structure for keeping track of active lines. */
  59. typedef struct active_line_s active_line;
  60. struct active_line_s {
  61. gs_fixed_point start; /* x,y where line starts */
  62. gs_fixed_point end; /* x,y where line ends */
  63. gs_fixed_point diff; /* end - start */
  64. #define AL_DX(alp) ((alp)->diff.x)
  65. #define AL_DY(alp) ((alp)->diff.y)
  66. fixed y_fast_max; /* can do x_at_y in fixed point */
  67. /* if y <= y_fast_max */
  68. fixed num_adjust; /* 0 if diff.x >= 0, -diff.y + epsilon if */
  69. /* diff.x < 0 and division truncates */
  70. #if ARCH_DIV_NEG_POS_TRUNCATES
  71. /* neg/pos truncates, we must bias the numberator. */
  72. # define SET_NUM_ADJUST(alp) \
  73. (alp)->num_adjust =\
  74. ((alp)->diff.x >= 0 ? 0 : -(alp)->diff.y + fixed_epsilon)
  75. # define ADD_NUM_ADJUST(num, alp) ((num) + (alp)->num_adjust)
  76. # define MAX_MINUS_NUM_ADJUST(alp) ADD_NUM_ADJUST(max_fixed, alp)
  77. #else
  78. /* neg/pos takes the floor, no special action is needed. */
  79. # define SET_NUM_ADJUST(alp) DO_NOTHING
  80. # define ADD_NUM_ADJUST(num, alp) (num)
  81. # define MAX_MINUS_NUM_ADJUST(alp) max_fixed
  82. #endif
  83. #define SET_AL_POINTS(alp, startp, endp)\
  84. BEGIN\
  85. (alp)->diff.y = (endp).y - (startp).y;\
  86. (alp)->diff.x = (endp).x - (startp).x;\
  87. SET_NUM_ADJUST(alp);\
  88. (alp)->y_fast_max = MAX_MINUS_NUM_ADJUST(alp) /\
  89. (((alp)->diff.x >= 0 ? (alp)->diff.x : -(alp)->diff.x) | 1) +\
  90. (startp).y;\
  91. (alp)->start = startp, (alp)->end = endp;\
  92. END
  93. /*
  94. * We know that alp->start.y <= yv <= alp->end.y, because the fill loop
  95. * guarantees that the only lines being considered are those with this
  96. * property.
  97. */
  98. #define AL_X_AT_Y(alp, yv)\
  99. ((yv) == (alp)->end.y ? (alp)->end.x :\
  100. ((yv) <= (alp)->y_fast_max ?\
  101. ADD_NUM_ADJUST(((yv) - (alp)->start.y) * AL_DX(alp), alp) / AL_DY(alp) :\
  102. (INCR_EXPR(slow_x),\
  103. fixed_mult_quo(AL_DX(alp), (yv) - (alp)->start.y, AL_DY(alp)))) +\
  104. (alp)->start.x)
  105. fixed x_current; /* current x position */
  106. fixed x_next; /* x position at end of band */
  107. const segment *pseg; /* endpoint of this line */
  108. int direction; /* direction of line segment */
  109. #define DIR_UP 1
  110. #define DIR_HORIZONTAL 0 /* (these are handled specially) */
  111. #define DIR_DOWN (-1)
  112. int curve_k; /* # of subdivisions for curves,-1 for lines */
  113. curve_cursor cursor; /* cursor for curves, unused for lines */
  114. /*
  115. * "Pending" lines (not reached in the Y ordering yet) use next and prev
  116. * to order lines by increasing starting Y. "Active" lines (being scanned)
  117. * use next and prev to order lines by increasing current X, or if the
  118. * current Xs are equal, by increasing final X.
  119. */
  120. active_line *prev, *next;
  121. /* Link together active_lines allocated individually */
  122. active_line *alloc_next;
  123. };
  124. /*
  125. * Define the ordering criterion for active lines that overlap in Y.
  126. * Return -1, 0, or 1 if lp1 precedes, coincides with, or follows lp2.
  127. *
  128. * The lines' x_current values are correct for some Y value that crosses
  129. * both of them and that is not both the start of one and the end of the
  130. * other. (Neither line is horizontal.) We want the ordering at this
  131. * Y value, or, of the x_current values are equal, greater Y values
  132. * (if any: this Y value might be the end of both lines).
  133. */
  134. private int
  135. x_order(const active_line *lp1, const active_line *lp2)
  136. {
  137. bool s1;
  138. INCR(order);
  139. if (lp1->x_current < lp2->x_current)
  140. return -1;
  141. else if (lp1->x_current > lp2->x_current)
  142. return 1;
  143. /*
  144. * We need to compare the slopes of the lines. Start by
  145. * checking one fast case, where the slopes have opposite signs.
  146. */
  147. if ((s1 = lp1->start.x < lp1->end.x) != (lp2->start.x < lp2->end.x))
  148. return (s1 ? 1 : -1);
  149. /*
  150. * We really do have to compare the slopes. Fortunately, this isn't
  151. * needed very often. We want the sign of the comparison
  152. * dx1/dy1 - dx2/dy2, or (since we know dy1 and dy2 are positive)
  153. * dx1 * dy2 - dx2 * dy1. In principle, we can't simply do this using
  154. * doubles, since we need complete accuracy and doubles don't have
  155. * enough fraction bits. However, with the usual 20+12-bit fixeds and
  156. * 64-bit doubles, both of the factors would have to exceed 2^15
  157. * device space pixels for the result to be inaccurate, so we
  158. * simply disregard this possibility. ****** FIX SOMEDAY ******
  159. */
  160. INCR(slow_order);
  161. {
  162. fixed dx1 = lp1->end.x - lp1->start.x,
  163. dy1 = lp1->end.y - lp1->start.y;
  164. fixed dx2 = lp2->end.x - lp2->start.x,
  165. dy2 = lp2->end.y - lp2->start.y;
  166. double diff = (double)dx1 * dy2 - (double)dx2 * dy1;
  167. return (diff < 0 ? -1 : diff > 0 ? 1 : 0);
  168. }
  169. }
  170. /*
  171. * The active_line structure isn't really simple, but since its instances
  172. * only exist temporarily during a fill operation, we don't have to
  173. * worry about a garbage collection occurring.
  174. */
  175. gs_private_st_simple(st_active_line, active_line, "active_line");
  176. #ifdef DEBUG
  177. /* Internal procedures for printing and checking active lines. */
  178. private void
  179. print_active_line(const char *label, const active_line * alp)
  180. {
  181. dlprintf5("[f]%s 0x%lx(%d): x_current=%f x_next=%f\n",
  182. label, (ulong) alp, alp->direction,
  183. fixed2float(alp->x_current), fixed2float(alp->x_next));
  184. dlprintf5(" start=(%f,%f) pt_end=0x%lx(%f,%f)\n",
  185. fixed2float(alp->start.x), fixed2float(alp->start.y),
  186. (ulong) alp->pseg,
  187. fixed2float(alp->end.x), fixed2float(alp->end.y));
  188. dlprintf2(" prev=0x%lx next=0x%lx\n",
  189. (ulong) alp->prev, (ulong) alp->next);
  190. }
  191. private void
  192. print_line_list(const active_line * flp)
  193. {
  194. const active_line *lp;
  195. for (lp = flp; lp != 0; lp = lp->next) {
  196. fixed xc = lp->x_current, xn = lp->x_next;
  197. dlprintf3("[f]0x%lx(%d): x_current/next=%g",
  198. (ulong) lp, lp->direction,
  199. fixed2float(xc));
  200. if (xn != xc)
  201. dprintf1("/%g", fixed2float(xn));
  202. dputc('\n');
  203. }
  204. }
  205. inline private void
  206. print_al(const char *label, const active_line * alp)
  207. {
  208. if (gs_debug_c('F'))
  209. print_active_line(label, alp);
  210. }
  211. private int
  212. check_line_list(const active_line * flp)
  213. {
  214. const active_line *alp;
  215. if (flp != 0)
  216. for (alp = flp->prev->next; alp != 0; alp = alp->next)
  217. if (alp->next != 0 && alp->next->x_current < alp->x_current) {
  218. lprintf("[f]Lines out of order!\n");
  219. print_active_line(" 1:", alp);
  220. print_active_line(" 2:", alp->next);
  221. return_error(gs_error_Fatal);
  222. }
  223. return 0;
  224. }
  225. #else
  226. #define print_al(label,alp) DO_NOTHING
  227. #endif
  228. /* Line list structure */
  229. struct line_list_s {
  230. gs_memory_t *memory;
  231. active_line *active_area; /* allocated active_line list */
  232. active_line *next_active; /* next allocation slot */
  233. active_line *limit; /* limit of local allocation */
  234. int close_count; /* # of added closing lines */
  235. active_line *y_list; /* Y-sorted list of pending lines */
  236. active_line *y_line; /* most recently inserted line */
  237. active_line x_head; /* X-sorted list of active lines */
  238. #define x_list x_head.next
  239. /* Put the arrays last so the scalars will have */
  240. /* small displacements. */
  241. /* Allocate a few active_lines locally */
  242. /* to avoid round trips through the allocator. */
  243. #if arch_small_memory
  244. # define MAX_LOCAL_ACTIVE 6 /* don't overburden the stack */
  245. #else
  246. # define MAX_LOCAL_ACTIVE 20
  247. #endif
  248. active_line local_active[MAX_LOCAL_ACTIVE];
  249. };
  250. typedef struct line_list_s line_list;
  251. typedef line_list *ll_ptr;
  252. /* Forward declarations */
  253. private void init_line_list(P2(ll_ptr, gs_memory_t *));
  254. private void unclose_path(P2(gx_path *, int));
  255. private void free_line_list(P1(ll_ptr));
  256. private int add_y_list(P5(gx_path *, ll_ptr, fixed, fixed,
  257. const gs_fixed_rect *));
  258. private int add_y_line(P4(const segment *, const segment *, int, ll_ptr));
  259. private void insert_x_new(P2(active_line *, ll_ptr));
  260. private bool end_x_line(P2(active_line *, bool));
  261. #define FILL_LOOP_PROC(proc)\
  262. int proc(P11(ll_ptr, gx_device *,\
  263. const gx_fill_params *, const gx_device_color *, gs_logical_operation_t,\
  264. const gs_fixed_rect *, fixed, fixed, fixed, fixed, fixed))
  265. private FILL_LOOP_PROC(fill_loop_by_scan_lines);
  266. private FILL_LOOP_PROC(fill_loop_by_trapezoids);
  267. /*
  268. * This is the general path filling algorithm.
  269. * It uses the center-of-pixel rule for filling.
  270. * We can implement Microsoft's upper-left-corner-of-pixel rule
  271. * by subtracting (0.5, 0.5) from all the coordinates in the path.
  272. *
  273. * The adjust parameters are a hack for keeping regions
  274. * from coming out too faint: they specify an amount by which to expand
  275. * the sides of every filled region.
  276. * Setting adjust = fixed_half is supposed to produce the effect of Adobe's
  277. * any-part-of-pixel rule, but it doesn't quite, because of the
  278. * closed/open interval rule for regions. We detect this as a special case
  279. * and do the slightly ugly things necessary to make it work.
  280. */
  281. /*
  282. * Tweak the fill adjustment if necessary so that (nearly) empty
  283. * rectangles are guaranteed to produce some output. This is a hack
  284. * to work around a bug in the Microsoft Windows PostScript driver,
  285. * which draws thin lines by filling zero-width rectangles, and in
  286. * some other drivers that try to fill epsilon-width rectangles.
  287. */
  288. void
  289. gx_adjust_if_empty(const gs_fixed_rect * pbox, gs_fixed_point * adjust)
  290. {
  291. /*
  292. * For extremely large coordinates, the obvious subtractions could
  293. * overflow. We can work around this easily by noting that since
  294. * we know q.{x,y} >= p.{x,y}, the subtraction overflows iff the
  295. * result is negative.
  296. */
  297. const fixed
  298. dx = pbox->q.x - pbox->p.x, dy = pbox->q.y - pbox->p.y;
  299. if (dx < fixed_half && dx > 0 && (dy >= int2fixed(2) || dy < 0)) {
  300. adjust->x = arith_rshift_1(fixed_1 + fixed_epsilon - dx);
  301. if_debug1('f', "[f]thin adjust_x=%g\n",
  302. fixed2float(adjust->x));
  303. } else if (dy < fixed_half && dy > 0 && (dx >= int2fixed(2) || dx < 0)) {
  304. adjust->y = arith_rshift_1(fixed_1 + fixed_epsilon - dy);
  305. if_debug1('f', "[f]thin adjust_y=%g\n",
  306. fixed2float(adjust->y));
  307. }
  308. }
  309. /*
  310. * The general fill path algorithm.
  311. */
  312. private int
  313. gx_general_fill_path(gx_device * pdev, const gs_imager_state * pis,
  314. gx_path * ppath, const gx_fill_params * params,
  315. const gx_device_color * pdevc, const gx_clip_path * pcpath)
  316. {
  317. gs_fixed_point adjust;
  318. gs_logical_operation_t lop = pis->log_op;
  319. gs_fixed_rect ibox, bbox;
  320. gx_device_clip cdev;
  321. gx_device *dev = pdev;
  322. gx_device *save_dev = dev;
  323. gx_path ffpath;
  324. gx_path *pfpath;
  325. int code;
  326. fixed adjust_left, adjust_right, adjust_below, adjust_above;
  327. int max_fill_band = dev->max_fill_band;
  328. #define NO_BAND_MASK ((fixed)(-1) << (sizeof(fixed) * 8 - 1))
  329. bool fill_by_trapezoids;
  330. line_list lst;
  331. adjust = params->adjust;
  332. /*
  333. * Compute the bounding box before we flatten the path.
  334. * This can save a lot of time if the path has curves.
  335. * If the path is neither fully within nor fully outside
  336. * the quick-check boxes, we could recompute the bounding box
  337. * and make the checks again after flattening the path,
  338. * but right now we don't bother.
  339. */
  340. gx_path_bbox(ppath, &ibox);
  341. if (params->fill_zero_width)
  342. gx_adjust_if_empty(&ibox, &adjust);
  343. /* Check the bounding boxes. */
  344. if_debug6('f', "[f]adjust=%g,%g bbox=(%g,%g),(%g,%g)\n",
  345. fixed2float(adjust.x), fixed2float(adjust.y),
  346. fixed2float(ibox.p.x), fixed2float(ibox.p.y),
  347. fixed2float(ibox.q.x), fixed2float(ibox.q.y));
  348. if (pcpath)
  349. gx_cpath_inner_box(pcpath, &bbox);
  350. else
  351. (*dev_proc(dev, get_clipping_box)) (dev, &bbox);
  352. if (!rect_within(ibox, bbox)) {
  353. /*
  354. * Intersect the path box and the clip bounding box.
  355. * If the intersection is empty, this fill is a no-op.
  356. */
  357. if (pcpath)
  358. gx_cpath_outer_box(pcpath, &bbox);
  359. if_debug4('f', " outer_box=(%g,%g),(%g,%g)\n",
  360. fixed2float(bbox.p.x), fixed2float(bbox.p.y),
  361. fixed2float(bbox.q.x), fixed2float(bbox.q.y));
  362. rect_intersect(ibox, bbox);
  363. if (ibox.p.x - adjust.x >= ibox.q.x + adjust.x ||
  364. ibox.p.y - adjust.y >= ibox.q.y + adjust.y
  365. ) { /* Intersection of boxes is empty! */
  366. return 0;
  367. }
  368. /*
  369. * The path is neither entirely inside the inner clip box
  370. * nor entirely outside the outer clip box.
  371. * If we had to flatten the path, this is where we would
  372. * recompute its bbox and make the tests again,
  373. * but we don't bother right now.
  374. *
  375. * If there is a clipping path, set up a clipping device.
  376. */
  377. if (pcpath) {
  378. dev = (gx_device *) & cdev;
  379. gx_make_clip_device(&cdev, gx_cpath_list(pcpath));
  380. cdev.target = save_dev;
  381. cdev.max_fill_band = save_dev->max_fill_band;
  382. (*dev_proc(dev, open_device)) (dev);
  383. }
  384. }
  385. /*
  386. * Compute the proper adjustment values.
  387. * To get the effect of the any-part-of-pixel rule,
  388. * we may have to tweak them slightly.
  389. * NOTE: We changed the adjust_right/above value from 0.5+epsilon
  390. * to 0.5 in release 5.01; even though this does the right thing
  391. * in every case we could imagine, we aren't confident that it's
  392. * correct. (The old values were definitely incorrect, since they
  393. * caused 1-pixel-wide/high objects to color 2 pixels even if
  394. * they fell exactly on pixel boundaries.)
  395. */
  396. if (adjust.x == fixed_half)
  397. adjust_left = fixed_half - fixed_epsilon,
  398. adjust_right = fixed_half /* + fixed_epsilon */ ; /* see above */
  399. else
  400. adjust_left = adjust_right = adjust.x;
  401. if (adjust.y == fixed_half)
  402. adjust_below = fixed_half - fixed_epsilon,
  403. adjust_above = fixed_half /* + fixed_epsilon */ ; /* see above */
  404. else
  405. adjust_below = adjust_above = adjust.y;
  406. /* Initialize the active line list. */
  407. init_line_list(&lst, ppath->memory);
  408. /*
  409. * We have a choice of two different filling algorithms:
  410. * scan-line-based and trapezoid-based. They compare as follows:
  411. *
  412. * Scan Trap
  413. * ---- ----
  414. * skip +draw 0-height horizontal lines
  415. * slow +fast rectangles
  416. * +fast slow curves
  417. * +yes no write pixels at most once when adjust != 0
  418. *
  419. * Normally we use the scan line algorithm for characters, where curve
  420. * speed is important, and for non-idempotent RasterOps, where double
  421. * pixel writing must be avoided, and the trapezoid algorithm otherwise.
  422. * However, we always use the trapezoid algorithm for rectangles.
  423. */
  424. #define DOUBLE_WRITE_OK() lop_is_idempotent(lop)
  425. #ifdef FILL_SCAN_LINES
  426. # ifdef FILL_TRAPEZOIDS
  427. fill_by_trapezoids =
  428. (!gx_path_has_curves(ppath) || params->flatness >= 1.0);
  429. # else
  430. fill_by_trapezoids = false;
  431. # endif
  432. #else
  433. fill_by_trapezoids = true;
  434. #endif
  435. #ifdef FILL_TRAPEZOIDS
  436. if (fill_by_trapezoids && !DOUBLE_WRITE_OK()) {
  437. /* Avoid filling rectangles by scan line. */
  438. gs_fixed_rect rbox;
  439. if (gx_path_is_rectangular(ppath, &rbox)) {
  440. int x0 = fixed2int_pixround(rbox.p.x - adjust_left);
  441. int y0 = fixed2int_pixround(rbox.p.y - adjust_below);
  442. int x1 = fixed2int_pixround(rbox.q.x + adjust_right);
  443. int y1 = fixed2int_pixround(rbox.q.y + adjust_above);
  444. return gx_fill_rectangle_device_rop(x0, y0, x1 - x0, y1 - y0,
  445. pdevc, dev, lop);
  446. }
  447. fill_by_trapezoids = false; /* avoid double write */
  448. }
  449. #endif
  450. #undef DOUBLE_WRITE_OK
  451. /*
  452. * Pre-process curves. When filling by trapezoids, we need to
  453. * flatten the path completely; when filling by scan lines, we only
  454. * need to monotonize it, unless FILL_CURVES is undefined.
  455. */
  456. gx_path_init_local(&ffpath, ppath->memory);
  457. if (!gx_path_has_curves(ppath)) /* don't need to flatten */
  458. pfpath = ppath;
  459. else
  460. #if defined(FILL_CURVES) && defined(FILL_SCAN_LINES)
  461. /* Filling curves is possible. */
  462. # ifdef FILL_TRAPEZOIDS
  463. /* Not filling curves is also possible. */
  464. if (fill_by_trapezoids)
  465. # endif
  466. #endif
  467. #if !defined(FILL_CURVES) || defined(FILL_TRAPEZOIDS)
  468. /* Not filling curves is possible. */
  469. {
  470. gx_path_init_local(&ffpath, ppath->memory);
  471. code = gx_path_add_flattened_accurate(ppath, &ffpath,
  472. params->flatness,
  473. pis->accurate_curves);
  474. if (code < 0)
  475. return code;
  476. pfpath = &ffpath;
  477. }
  478. #endif
  479. #if defined(FILL_CURVES) && defined(FILL_SCAN_LINES)
  480. /* Filling curves is possible. */
  481. # ifdef FILL_TRAPEZOIDS
  482. /* Not filling curves is also possible. */
  483. else
  484. # endif
  485. if (gx_path_is_monotonic(ppath))
  486. pfpath = ppath;
  487. else {
  488. gx_path_init_local(&ffpath, ppath->memory);
  489. code = gx_path_add_monotonized(ppath, &ffpath);
  490. if (code < 0)
  491. return code;
  492. pfpath = &ffpath;
  493. }
  494. #endif
  495. if ((code = add_y_list(pfpath, &lst, adjust_below, adjust_above, &ibox)) < 0)
  496. goto nope;
  497. {
  498. FILL_LOOP_PROC((*fill_loop));
  499. /* Some short-sighted compilers won't allow a conditional here.... */
  500. if (fill_by_trapezoids)
  501. fill_loop = fill_loop_by_trapezoids;
  502. else
  503. fill_loop = fill_loop_by_scan_lines;
  504. code = (*fill_loop)
  505. (&lst, dev, params, pdevc, lop, &ibox,
  506. adjust_left, adjust_right, adjust_below, adjust_above,
  507. (max_fill_band == 0 ? NO_BAND_MASK : int2fixed(-max_fill_band)));
  508. }
  509. nope:if (lst.close_count != 0)
  510. unclose_path(pfpath, lst.close_count);
  511. free_line_list(&lst);
  512. if (pfpath != ppath) /* had to flatten */
  513. gx_path_free(pfpath, "gx_default_fill_path(flattened path)");
  514. #ifdef DEBUG
  515. if (gs_debug_c('f')) {
  516. dlputs("[f] # alloc up down horiz step slowx iter find band bstep bfill\n");
  517. dlprintf5(" %5ld %5ld %5ld %5ld %5ld",
  518. stats_fill.fill, stats_fill.fill_alloc,
  519. stats_fill.y_up, stats_fill.y_down,
  520. stats_fill.horiz);
  521. dlprintf4(" %5ld %5ld %5ld %5ld",
  522. stats_fill.x_step, stats_fill.slow_x,
  523. stats_fill.iter, stats_fill.find_y);
  524. dlprintf3(" %5ld %5ld %5ld\n",
  525. stats_fill.band, stats_fill.band_step,
  526. stats_fill.band_fill);
  527. dlputs("[f] afill slant shall sfill mqcrs order slowo\n");
  528. dlprintf7(" %5ld %5ld %5ld %5ld %5ld %5ld %5ld\n",
  529. stats_fill.afill, stats_fill.slant,
  530. stats_fill.slant_shallow, stats_fill.sfill,
  531. stats_fill.mq_cross, stats_fill.order,
  532. stats_fill.slow_order);
  533. }
  534. #endif
  535. return code;
  536. }
  537. /*
  538. * Fill a path. This is the default implementation of the driver
  539. * fill_path procedure.
  540. */
  541. int
  542. gx_default_fill_path(gx_device * pdev, const gs_imager_state * pis,
  543. gx_path * ppath, const gx_fill_params * params,
  544. const gx_device_color * pdevc, const gx_clip_path * pcpath)
  545. {
  546. if (gx_dc_is_pattern2_color(pdevc)) {
  547. /* Optimization for shading fill :
  548. The general path filling algorithm subdivides fill region with
  549. trapezoid or rectangle subregions and then paints each subregion
  550. with given color. If the color is shading, each subregion to be
  551. subdivided into areas of constant color. But with radial
  552. shading each area is a high order polygon, being
  553. subdivided into smaller subregions, so as total number of
  554. subregions grows huge. Faster processing is done here by changing
  555. the order of subdivision cycles : we first subdivide the shading into
  556. areas of constant color, then apply the general path filling algorithm
  557. (i.e. subdivide each area into trapezoids or rectangles), using the
  558. filling path as clip mask.
  559. */
  560. gx_clip_path cpath_intersection;
  561. gx_path path_intersection;
  562. int code;
  563. /* Shading fill algorithm uses "current path" parameter of the general
  564. path filling algorithm as boundary of constant color area,
  565. so we need to intersect the filling path with the clip path now,
  566. reducing the number of pathes passed to it :
  567. */
  568. gx_path_init_local(&path_intersection, pdev->memory);
  569. gx_cpath_init_local_shared(&cpath_intersection, pcpath, pdev->memory);
  570. if ((code = gx_cpath_intersect(&cpath_intersection, ppath, params->rule, (gs_imager_state *)pis)) >= 0)
  571. code = gx_cpath_to_path(&cpath_intersection, &path_intersection);
  572. /* Do fill : */
  573. if (code >= 0)
  574. code = gx_dc_pattern2_fill_path_adjusted(pdevc, &path_intersection, NULL, pdev);
  575. /* Destruct local data and return :*/
  576. gx_path_free(&path_intersection, "shading_fill_path_intersection");
  577. gx_cpath_free(&cpath_intersection, "shading_fill_cpath_intersection");
  578. return code;
  579. }
  580. return gx_general_fill_path(pdev, pis, ppath, params, pdevc, pcpath);
  581. }
  582. /* Initialize the line list for a path. */
  583. private void
  584. init_line_list(ll_ptr ll, gs_memory_t * mem)
  585. {
  586. ll->memory = mem;
  587. ll->active_area = 0;
  588. ll->next_active = ll->local_active;
  589. ll->limit = ll->next_active + MAX_LOCAL_ACTIVE;
  590. ll->close_count = 0;
  591. ll->y_list = 0;
  592. ll->y_line = 0;
  593. INCR(fill);
  594. }
  595. /* Unlink any line_close segments added temporarily. */
  596. private void
  597. unclose_path(gx_path * ppath, int count)
  598. {
  599. subpath *psub;
  600. for (psub = ppath->first_subpath; count != 0;
  601. psub = (subpath *) psub->last->next
  602. )
  603. if (psub->last == (segment *) & psub->closer) {
  604. segment *prev = psub->closer.prev, *next = psub->closer.next;
  605. prev->next = next;
  606. if (next)
  607. next->prev = prev;
  608. psub->last = prev;
  609. count--;
  610. }
  611. }
  612. /* Free the line list. */
  613. private void
  614. free_line_list(ll_ptr ll)
  615. {
  616. /* Free any individually allocated active_lines. */
  617. gs_memory_t *mem = ll->memory;
  618. active_line *alp;
  619. while ((alp = ll->active_area) != 0) {
  620. active_line *next = alp->alloc_next;
  621. gs_free_object(mem, alp, "active line");
  622. ll->active_area = next;
  623. }
  624. }
  625. /*
  626. * Construct a Y-sorted list of segments for rasterizing a path. We assume
  627. * the path is non-empty. Only include non-horizontal lines or (monotonic)
  628. * curve segments where one endpoint is locally Y-minimal, and horizontal
  629. * lines that might color some additional pixels.
  630. */
  631. private int
  632. add_y_list(gx_path * ppath, ll_ptr ll, fixed adjust_below, fixed adjust_above,
  633. const gs_fixed_rect * pbox)
  634. {
  635. segment *pseg = (segment *) ppath->first_subpath;
  636. int close_count = 0;
  637. /* fixed xmin = pbox->p.x; *//* not currently used */
  638. fixed ymin = pbox->p.y;
  639. /* fixed xmax = pbox->q.x; *//* not currently used */
  640. fixed ymax = pbox->q.y;
  641. int code;
  642. while (pseg) {
  643. /* We know that pseg points to a subpath head (s_start). */
  644. subpath *psub = (subpath *) pseg;
  645. segment *plast = psub->last;
  646. int dir = 2; /* hack to skip first segment */
  647. int first_dir, prev_dir;
  648. segment *prev;
  649. if (plast->type != s_line_close) {
  650. /* Create a fake s_line_close */
  651. line_close_segment *lp = &psub->closer;
  652. segment *next = plast->next;
  653. lp->next = next;
  654. lp->prev = plast;
  655. plast->next = (segment *) lp;
  656. if (next)
  657. next->prev = (segment *) lp;
  658. lp->type = s_line_close;
  659. lp->pt = psub->pt;
  660. lp->sub = psub;
  661. psub->last = plast = (segment *) lp;
  662. ll->close_count++;
  663. }
  664. while ((prev_dir = dir, prev = pseg,
  665. (pseg = pseg->next) != 0 && pseg->type != s_start)
  666. ) {
  667. /* This element is either a line or a monotonic curve segment. */
  668. fixed iy = pseg->pt.y;
  669. fixed py = prev->pt.y;
  670. /*
  671. * Segments falling entirely outside the ibox in Y
  672. * are treated as though they were horizontal, *
  673. * i.e., they are never put on the list.
  674. */
  675. #define COMPUTE_DIR(xo, xe, yo, ye)\
  676. (ye > yo ? (ye <= ymin || yo >= ymax ? 0 : DIR_UP) :\
  677. ye < yo ? (yo <= ymin || ye >= ymax ? 0 : DIR_DOWN) :\
  678. 2)
  679. #define ADD_DIR_LINES(prev2, prev, this, pdir, dir)\
  680. BEGIN\
  681. if (pdir)\
  682. { if ((code = add_y_line(prev2, prev, pdir, ll)) < 0) return code; }\
  683. if (dir)\
  684. { if ((code = add_y_line(prev, this, dir, ll)) < 0) return code; }\
  685. END
  686. dir = COMPUTE_DIR(prev->pt.x, pseg->pt.x, py, iy);
  687. if (dir == 2) { /* Put horizontal lines on the list */
  688. /* if they would color any pixels. */
  689. if (fixed2int_pixround(iy - adjust_below) <
  690. fixed2int_pixround(iy + adjust_above)
  691. ) {
  692. INCR(horiz);
  693. if ((code = add_y_line(prev, pseg,
  694. DIR_HORIZONTAL, ll)) < 0
  695. )
  696. return code;
  697. }
  698. dir = 0;
  699. }
  700. if (dir > prev_dir) {
  701. ADD_DIR_LINES(prev->prev, prev, pseg, prev_dir, dir);
  702. } else if (prev_dir == 2) /* first segment */
  703. first_dir = dir;
  704. if (pseg == plast) {
  705. /*
  706. * We skipped the first segment of the subpath, so the last
  707. * segment must receive special consideration. Note that we
  708. * have `closed' all subpaths.
  709. */
  710. if (first_dir > dir) {
  711. ADD_DIR_LINES(prev, pseg, psub->next, dir, first_dir);
  712. }
  713. }
  714. }
  715. #undef COMPUTE_DIR
  716. #undef ADD_DIR_LINES
  717. }
  718. return close_count;
  719. }
  720. /*
  721. * Internal routine to test a segment and add it to the pending list if
  722. * appropriate.
  723. */
  724. private int
  725. add_y_line(const segment * prev_lp, const segment * lp, int dir, ll_ptr ll)
  726. {
  727. gs_fixed_point this, prev;
  728. active_line *alp = ll->next_active;
  729. fixed y_start;
  730. if (alp == ll->limit) { /* Allocate separately */
  731. alp = gs_alloc_struct(ll->memory, active_line,
  732. &st_active_line, "active line");
  733. if (alp == 0)
  734. return_error(gs_error_VMerror);
  735. alp->alloc_next = ll->active_area;
  736. ll->active_area = alp;
  737. INCR(fill_alloc);
  738. } else
  739. ll->next_active++;
  740. this.x = lp->pt.x;
  741. this.y = lp->pt.y;
  742. prev.x = prev_lp->pt.x;
  743. prev.y = prev_lp->pt.y;
  744. switch ((alp->direction = dir)) {
  745. case DIR_UP:
  746. y_start = prev.y;
  747. SET_AL_POINTS(alp, prev, this);
  748. alp->pseg = lp;
  749. break;
  750. case DIR_DOWN:
  751. y_start = this.y;
  752. SET_AL_POINTS(alp, this, prev);
  753. alp->pseg = prev_lp;
  754. break;
  755. case DIR_HORIZONTAL:
  756. y_start = this.y; /* = prev.y */
  757. alp->start = prev;
  758. alp->end = this;
  759. /* Don't need to set dx or y_fast_max */
  760. alp->pseg = prev_lp; /* may not need this either */
  761. break;
  762. default: /* can't happen */
  763. return_error(gs_error_unregistered);
  764. }
  765. /* Insert the new line in the Y ordering */
  766. {
  767. active_line *yp = ll->y_line;
  768. active_line *nyp;
  769. if (yp == 0) {
  770. alp->next = alp->prev = 0;
  771. ll->y_list = alp;
  772. } else if (y_start >= yp->start.y) { /* Insert the new line after y_line */
  773. while (INCR_EXPR(y_up),
  774. ((nyp = yp->next) != NULL &&
  775. y_start > nyp->start.y)
  776. )
  777. yp = nyp;
  778. alp->next = nyp;
  779. alp->prev = yp;
  780. yp->next = alp;
  781. if (nyp)
  782. nyp->prev = alp;
  783. } else { /* Insert the new line before y_line */
  784. while (INCR_EXPR(y_down),
  785. ((nyp = yp->prev) != NULL &&
  786. y_start < nyp->start.y)
  787. )
  788. yp = nyp;
  789. alp->prev = nyp;
  790. alp->next = yp;
  791. yp->prev = alp;
  792. if (nyp)
  793. nyp->next = alp;
  794. else
  795. ll->y_list = alp;
  796. }
  797. }
  798. ll->y_line = alp;
  799. print_al("add ", alp);
  800. return 0;
  801. }
  802. /* ---------------- Filling loop utilities ---------------- */
  803. /* Insert a newly active line in the X ordering. */
  804. private void
  805. insert_x_new(active_line * alp, ll_ptr ll)
  806. {
  807. active_line *next;
  808. active_line *prev = &ll->x_head;
  809. alp->x_current = alp->start.x;
  810. while (INCR_EXPR(x_step),
  811. (next = prev->next) != 0 && x_order(next, alp) < 0
  812. )
  813. prev = next;
  814. alp->next = next;
  815. alp->prev = prev;
  816. if (next != 0)
  817. next->prev = alp;
  818. prev->next = alp;
  819. }
  820. /*
  821. * Handle a line segment that just ended. Return true iff this was
  822. * the end of a line sequence.
  823. */
  824. private bool
  825. end_x_line(active_line *alp, bool update)
  826. {
  827. const segment *pseg = alp->pseg;
  828. /*
  829. * The computation of next relies on the fact that
  830. * all subpaths have been closed. When we cycle
  831. * around to the other end of a subpath, we must be
  832. * sure not to process the start/end point twice.
  833. */
  834. const segment *next =
  835. (alp->direction == DIR_UP ?
  836. ( /* Upward line, go forward along path. */
  837. pseg->type == s_line_close ? /* end of subpath */
  838. ((const line_close_segment *)pseg)->sub->next :
  839. pseg->next) :
  840. ( /* Downward line, go backward along path. */
  841. pseg->type == s_start ? /* start of subpath */
  842. ((const subpath *)pseg)->last->prev :
  843. pseg->prev)
  844. );
  845. gs_fixed_point npt;
  846. npt.y = next->pt.y;
  847. if (!update)
  848. return npt.y <= pseg->pt.y;
  849. if_debug5('F', "[F]ended 0x%lx: pseg=0x%lx y=%f next=0x%lx npt.y=%f\n",
  850. (ulong) alp, (ulong) pseg, fixed2float(pseg->pt.y),
  851. (ulong) next, fixed2float(npt.y));
  852. if (npt.y <= pseg->pt.y) { /* End of a line sequence */
  853. active_line *nlp = alp->next;
  854. alp->prev->next = nlp;
  855. if (nlp)
  856. nlp->prev = alp->prev;
  857. if_debug1('F', "[F]drop 0x%lx\n", (ulong) alp);
  858. return true;
  859. }
  860. alp->pseg = next;
  861. npt.x = next->pt.x;
  862. SET_AL_POINTS(alp, alp->end, npt);
  863. print_al("repl", alp);
  864. return false;
  865. }
  866. #define LOOP_FILL_RECTANGLE(x, y, w, h)\
  867. gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, lop)
  868. #define LOOP_FILL_RECTANGLE_DIRECT(x, y, w, h)\
  869. (fill_direct ?\
  870. (*fill_rect)(dev, x, y, w, h, cindex) :\
  871. gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, lop))
  872. /* ---------------- Trapezoid filling loop ---------------- */
  873. /* Forward references */
  874. private int fill_slant_adjust(P12(fixed, fixed, fixed, fixed, fixed,
  875. fixed, fixed, fixed, const gs_fixed_rect *,
  876. const gx_device_color *, gx_device *, gs_logical_operation_t));
  877. private void resort_x_line(P1(active_line *));
  878. /****** PATCH ******/
  879. #define LOOP_FILL_TRAPEZOID_FIXED(fx0, fw0, fy0, fx1, fw1, fh)\
  880. loop_fill_trap(dev, fx0, fw0, fy0, fx1, fw1, fh, pbox, pdevc, lop)
  881. private int
  882. loop_fill_trap(gx_device * dev, fixed fx0, fixed fw0, fixed fy0,
  883. fixed fx1, fixed fw1, fixed fh, const gs_fixed_rect * pbox,
  884. const gx_device_color * pdevc, gs_logical_operation_t lop)
  885. {
  886. fixed fy1 = fy0 + fh;
  887. fixed ybot = max(fy0, pbox->p.y);
  888. fixed ytop = min(fy1, pbox->q.y);
  889. gs_fixed_edge left, right;
  890. if (ybot >= ytop)
  891. return 0;
  892. left.start.y = right.start.y = fy0;
  893. left.end.y = right.end.y = fy1;
  894. right.start.x = (left.start.x = fx0) + fw0;
  895. right.end.x = (left.end.x = fx1) + fw1;
  896. return (*dev_proc(dev, fill_trapezoid))
  897. (dev, &left, &right, ybot, ytop, false, pdevc, lop);
  898. }
  899. /****** END PATCH ******/
  900. /* Main filling loop. Takes lines off of y_list and adds them to */
  901. /* x_list as needed. band_mask limits the size of each band, */
  902. /* by requiring that ((y1 - 1) & band_mask) == (y0 & band_mask). */
  903. private int
  904. fill_loop_by_trapezoids(ll_ptr ll, gx_device * dev,
  905. const gx_fill_params * params, const gx_device_color * pdevc,
  906. gs_logical_operation_t lop, const gs_fixed_rect * pbox,
  907. fixed adjust_left, fixed adjust_right,
  908. fixed adjust_below, fixed adjust_above, fixed band_mask)
  909. {
  910. int rule = params->rule;
  911. const fixed y_limit = pbox->q.y;
  912. active_line *yll = ll->y_list;
  913. fixed y;
  914. int code;
  915. bool fill_direct = color_writes_pure(pdevc, lop);
  916. gx_color_index cindex;
  917. dev_proc_fill_rectangle((*fill_rect));
  918. /*
  919. * Define a faster test for
  920. * fixed2int_pixround(y - below) != fixed2int_pixround(y + above)
  921. * where we know
  922. * 0 <= below <= _fixed_pixround_v,
  923. * 0 <= above <= min(fixed_half, fixed_1 - below).
  924. * Subtracting out the integer parts, this is equivalent to
  925. * fixed2int_pixround(fixed_fraction(y) - below) !=
  926. * fixed2int_pixround(fixed_fraction(y) + above)
  927. * or to
  928. * fixed2int(fixed_fraction(y) + _fixed_pixround_v - below) !=
  929. * fixed2int(fixed_fraction(y) + _fixed_pixround_v + above)
  930. * Letting A = _fixed_pixround_v - below and B = _fixed_pixround_v + above,
  931. * we can rewrite this as
  932. * fixed2int(fixed_fraction(y) + A) != fixed2int(fixed_fraction(y) + B)
  933. * Because of the range constraints given above, this is true precisely when
  934. * fixed_fraction(y) + A < fixed_1 && fixed_fraction(y) + B >= fixed_1
  935. * or equivalently
  936. * fixed_fraction(y + B) < B - A.
  937. * i.e.
  938. * fixed_fraction(y + _fixed_pixround_v + above) < below + above
  939. */
  940. fixed y_span_delta = _fixed_pixround_v + adjust_above;
  941. fixed y_span_limit = adjust_below + adjust_above;
  942. #define ADJUSTED_Y_SPANS_PIXEL(y)\
  943. (fixed_fraction((y) + y_span_delta) < y_span_limit)
  944. if (yll == 0)
  945. return 0; /* empty list */
  946. if (fill_direct)
  947. cindex = pdevc->colors.pure,
  948. fill_rect = dev_proc(dev, fill_rectangle);
  949. y = yll->start.y; /* first Y value */
  950. ll->x_list = 0;
  951. ll->x_head.x_current = min_fixed; /* stop backward scan */
  952. while (1) {
  953. fixed y1;
  954. active_line *endp, *alp, *stopx;
  955. fixed x;
  956. int draw;
  957. INCR(iter);
  958. /* Move newly active lines from y to x list. */
  959. while (yll != 0 && yll->start.y == y) {
  960. active_line *ynext = yll->next; /* insert smashes next/prev links */
  961. if (yll->direction == DIR_HORIZONTAL) {
  962. /*
  963. * This is a hack to make sure that isolated horizontal
  964. * lines get stroked.
  965. */
  966. int yi = fixed2int_pixround(y - adjust_below);
  967. int xi, wi;
  968. if (yll->start.x <= yll->end.x)
  969. xi = fixed2int_pixround(yll->start.x -
  970. adjust_left),
  971. wi = fixed2int_pixround(yll->end.x +
  972. adjust_right) - xi;
  973. else
  974. xi = fixed2int_pixround(yll->end.x -
  975. adjust_left),
  976. wi = fixed2int_pixround(yll->start.x +
  977. adjust_right) - xi;
  978. code = LOOP_FILL_RECTANGLE_DIRECT(xi, yi, wi, 1);
  979. if (code < 0)
  980. return code;
  981. } else
  982. insert_x_new(yll, ll);
  983. yll = ynext;
  984. }
  985. /* Check whether we've reached the maximum y. */
  986. if (y >= y_limit)
  987. break;
  988. if (ll->x_list == 0) { /* No active lines, skip to next start */
  989. if (yll == 0)
  990. break; /* no lines left */
  991. y = yll->start.y;
  992. continue;
  993. }
  994. /* Find the next evaluation point. */
  995. /* Start by finding the smallest y value */
  996. /* at which any currently active line ends */
  997. /* (or the next to-be-active line begins). */
  998. y1 = (yll != 0 ? yll->start.y : y_limit);
  999. /* Make sure we don't exceed the maximum band height. */
  1000. {
  1001. fixed y_band = y | ~band_mask;
  1002. if (y1 > y_band)
  1003. y1 = y_band + 1;
  1004. }
  1005. for (alp = ll->x_list; alp != 0; alp = alp->next)
  1006. if (alp->end.y < y1)
  1007. y1 = alp->end.y;
  1008. #ifdef DEBUG
  1009. if (gs_debug_c('F')) {
  1010. dlprintf2("[F]before loop: y=%f y1=%f:\n",
  1011. fixed2float(y), fixed2float(y1));
  1012. print_line_list(ll->x_list);
  1013. }
  1014. #endif
  1015. /* Now look for line intersections before y1. */
  1016. x = min_fixed;
  1017. #define HAVE_PIXELS()\
  1018. (fixed_pixround(y - adjust_below) < fixed_pixround(y1 + adjust_above))
  1019. draw = (HAVE_PIXELS()? 1 : -1);
  1020. /*
  1021. * Loop invariants:
  1022. * alp = endp->next;
  1023. * for all lines lp from stopx up to alp,
  1024. * lp->x_next = AL_X_AT_Y(lp, y1).
  1025. */
  1026. for (alp = stopx = ll->x_list;
  1027. INCR_EXPR(find_y), alp != 0;
  1028. endp = alp, alp = alp->next
  1029. ) {
  1030. fixed nx = AL_X_AT_Y(alp, y1);
  1031. fixed dx_old, dx_den;
  1032. /* Check for intersecting lines. */
  1033. if (nx >= x)
  1034. x = nx;
  1035. else if
  1036. (draw >= 0 && /* don't bother if no pixels */
  1037. (dx_old = alp->x_current - endp->x_current) >= 0 &&
  1038. (dx_den = dx_old + endp->x_next - nx) > dx_old
  1039. ) { /* Make a good guess at the intersection */
  1040. /* Y value using only local information. */
  1041. fixed dy = y1 - y, y_new;
  1042. if_debug3('F', "[F]cross: dy=%g, dx_old=%g, dx_new=%g\n",
  1043. fixed2float(dy), fixed2float(dx_old),
  1044. fixed2float(dx_den - dx_old));
  1045. /* Do the computation in single precision */
  1046. /* if the values are small enough. */
  1047. y_new =
  1048. ((dy | dx_old) < 1L << (size_of(fixed) * 4 - 1) ?
  1049. dy * dx_old / dx_den :
  1050. (INCR_EXPR(mq_cross), fixed_mult_quo(dy, dx_old, dx_den)))
  1051. + y;
  1052. /* The crossing value doesn't have to be */
  1053. /* very accurate, but it does have to be */
  1054. /* greater than y and less than y1. */
  1055. if_debug3('F', "[F]cross y=%g, y_new=%g, y1=%g\n",
  1056. fixed2float(y), fixed2float(y_new),
  1057. fixed2float(y1));
  1058. stopx = alp;
  1059. if (y_new <= y) {
  1060. /*
  1061. * This isn't possible. Recompute the intersection
  1062. * accurately.
  1063. */
  1064. fixed ys, xs0, xs1, ye, xe0, xe1, dy, dx0, dx1;
  1065. INCR(cross_slow);
  1066. if (endp->start.y < alp->start.y)
  1067. ys = alp->start.y,
  1068. xs0 = AL_X_AT_Y(endp, ys), xs1 = alp->start.x;
  1069. else
  1070. ys = endp->start.y,
  1071. xs0 = endp->start.x, xs1 = AL_X_AT_Y(alp, ys);
  1072. if (endp->end.y > alp->end.y)
  1073. ye = alp->end.y,
  1074. xe0 = AL_X_AT_Y(endp, ye), xe1 = alp->end.x;
  1075. else
  1076. ye = endp->end.y,
  1077. xe0 = endp->end.x, xe1 = AL_X_AT_Y(alp, ye);
  1078. dy = ye - ys;
  1079. dx0 = xe0 - xs0;
  1080. dx1 = xe1 - xs1;
  1081. /* We need xs0 + cross * dx0 == xs1 + cross * dx1. */
  1082. if (dx0 == dx1) {
  1083. /* The two lines are coincident. Do nothing. */
  1084. y_new = y1;
  1085. } else {
  1086. double cross = (double)(xs0 - xs1) / (dx1 - dx0);
  1087. y_new = (fixed)(ys + cross * dy);
  1088. if (y_new <= y) {
  1089. /*
  1090. * This can only happen through some kind of
  1091. * numeric disaster, but we have to check.
  1092. */
  1093. INCR(cross_low);
  1094. y_new = y + fixed_epsilon;
  1095. }
  1096. }
  1097. }
  1098. if (y_new < y1) {
  1099. y1 = y_new;
  1100. nx = AL_X_AT_Y(alp, y1);
  1101. draw = 0;
  1102. }
  1103. if (nx > x)
  1104. x = nx;
  1105. }
  1106. alp->x_next = nx;
  1107. }
  1108. /* Recompute next_x for lines before the intersection. */
  1109. for (alp = ll->x_list; alp != stopx; alp = alp->next)
  1110. alp->x_next = AL_X_AT_Y(alp, y1);
  1111. #ifdef DEBUG
  1112. if (gs_debug_c('F')) {
  1113. dlprintf1("[F]after loop: y1=%f\n", fixed2float(y1));
  1114. print_line_list(ll->x_list);
  1115. }
  1116. #endif
  1117. /* Fill a multi-trapezoid band for the active lines. */
  1118. /* Don't bother if no pixel centers lie within the band. */
  1119. if (draw > 0 || (draw == 0 && HAVE_PIXELS())) {
  1120. fixed height = y1 - y;
  1121. fixed xlbot, xltop; /* as of last "outside" line */
  1122. int inside = 0;
  1123. active_line *nlp;
  1124. INCR(band);
  1125. for (x = min_fixed, alp = ll->x_list; alp != 0; alp = nlp) {
  1126. fixed xbot = alp->x_current;
  1127. fixed xtop = alp->x_current = alp->x_next;
  1128. fixed wtop;
  1129. int xi, xli;
  1130. int code;
  1131. print_al("step", alp);
  1132. INCR(band_step);
  1133. nlp = alp->next;
  1134. /* Handle ended or out-of-order lines. After this, */
  1135. /* the only member of alp we use is alp->direction. */
  1136. if (alp->end.y != y1 || !end_x_line(alp, true)) {
  1137. if (xtop <= x)
  1138. resort_x_line(alp);
  1139. else
  1140. x = xtop;
  1141. }
  1142. /* rule = -1 for winding number rule, i.e. */
  1143. /* we are inside if the winding number is non-zero; */
  1144. /* rule = 1 for even-odd rule, i.e. */
  1145. /* we are inside if the winding number is odd. */
  1146. #define INSIDE_PATH_P() ((inside & rule) != 0)
  1147. if (!INSIDE_PATH_P()) { /* i.e., outside */
  1148. inside += alp->direction;
  1149. if (INSIDE_PATH_P()) /* about to go in */
  1150. xlbot = xbot, xltop = xtop;
  1151. continue;
  1152. }
  1153. /* We're inside a region being filled. */
  1154. inside += alp->direction;
  1155. if (INSIDE_PATH_P()) /* not about to go out */
  1156. continue;
  1157. #undef INSIDE_PATH_P
  1158. /* We just went from inside to outside, so fill the region. */
  1159. wtop = xtop - xltop;
  1160. INCR(band_fill);
  1161. /*
  1162. * If lines are temporarily out of order, we might have
  1163. * xtop < xltop. Patch this up now if necessary. Note that
  1164. * we can't test wtop < 0, because the subtraction might
  1165. * overflow.
  1166. */
  1167. if (xtop < xltop) {
  1168. if_debug2('f', "[f]patch %g,%g\n",
  1169. fixed2float(xltop), fixed2float(xtop));
  1170. xtop = xltop += arith_rshift(wtop, 1);
  1171. wtop = 0;
  1172. }
  1173. if ((adjust_left | adjust_right) != 0) {
  1174. xlbot -= adjust_left;
  1175. xbot += adjust_right;
  1176. xltop -= adjust_left;
  1177. xtop += adjust_right;
  1178. wtop = xtop - xltop;
  1179. }
  1180. if ((xli = fixed2int_var_pixround(xltop)) ==
  1181. fixed2int_var_pixround(xlbot) &&
  1182. (xi = fixed2int_var_pixround(xtop)) ==
  1183. fixed2int_var_pixround(xbot)
  1184. ) { /* Rectangle. */
  1185. int yi = fixed2int_pixround(y - adjust_below);
  1186. int wi = fixed2int_pixround(y1 + adjust_above) - yi;
  1187. code = LOOP_FILL_RECTANGLE_DIRECT(xli, yi,
  1188. xi - xli, wi);
  1189. } else if ((adjust_below | adjust_above) != 0) {
  1190. /*
  1191. * We want to get the effect of filling an area whose
  1192. * outline is formed by dragging a square of side adj2
  1193. * along the border of the trapezoid. This is *not*
  1194. * equivalent to simply expanding the corners by
  1195. * adjust: There are 3 cases needing different
  1196. * algorithms, plus rectangles as a fast special case.
  1197. */
  1198. fixed wbot = xbot - xlbot;
  1199. if (xltop <= xlbot) {
  1200. if (xtop >= xbot) { /* Top wider than bottom. */
  1201. code = LOOP_FILL_TRAPEZOID_FIXED(
  1202. xlbot, wbot, y - adjust_below,
  1203. xltop, wtop, height);
  1204. if (ADJUSTED_Y_SPANS_PIXEL(y1)) {
  1205. if (code < 0)
  1206. return code;
  1207. INCR(afill);
  1208. code = LOOP_FILL_RECTANGLE_DIRECT(
  1209. xli, fixed2int_pixround(y1 - adjust_below),
  1210. fixed2int_var_pixround(xtop) - xli, 1);
  1211. }
  1212. } else { /* Slanted trapezoid. */
  1213. code = fill_slant_adjust(xlbot, xbot, y,
  1214. xltop, xtop, height, adjust_below,
  1215. adjust_above, pbox,
  1216. pdevc, dev, lop);
  1217. }
  1218. } else {
  1219. if (xtop <= xbot) { /* Bottom wider than top. */
  1220. if (ADJUSTED_Y_SPANS_PIXEL(y)) {
  1221. INCR(afill);
  1222. xli = fixed2int_var_pixround(xlbot);
  1223. code = LOOP_FILL_RECTANGLE_DIRECT(
  1224. xli, fixed2int_pixround(y - adjust_below),
  1225. fixed2int_var_pixround(xbot) - xli, 1);
  1226. if (code < 0)
  1227. return code;
  1228. }
  1229. code = LOOP_FILL_TRAPEZOID_FIXED(
  1230. xlbot, wbot, y + adjust_above,
  1231. xltop, wtop, height);
  1232. } else { /* Slanted trapezoid. */
  1233. code = fill_slant_adjust(xlbot, xbot, y,
  1234. xltop, xtop, height, adjust_below,
  1235. adjust_above, pbox,
  1236. pdevc, dev, lop);
  1237. }
  1238. }
  1239. } else /* No Y adjustment. */
  1240. code = LOOP_FILL_TRAPEZOID_FIXED(xlbot, xbot - xlbot,
  1241. y, xltop, wtop, height);
  1242. if (code < 0)
  1243. return code;
  1244. }
  1245. } else {
  1246. /* Just scan for ended or out-of-order lines. */
  1247. active_line *nlp;
  1248. for (x = min_fixed, alp = ll->x_list; alp != 0;
  1249. alp = nlp
  1250. ) {
  1251. fixed nx = alp->x_current = alp->x_next;
  1252. nlp = alp->next;
  1253. if_debug4('F',
  1254. "[F]check 0x%lx,x=%g 0x%lx,x=%g\n",
  1255. (ulong) alp->prev, fixed2float(x),
  1256. (ulong) alp, fixed2float(nx));
  1257. if (alp->end.y == y1) {
  1258. if (end_x_line(alp, true))
  1259. continue;
  1260. }
  1261. if (nx <= x)
  1262. resort_x_line(alp);
  1263. else
  1264. x = nx;
  1265. }
  1266. }
  1267. #ifdef DEBUG
  1268. if (gs_debug_c('f')) {
  1269. int code = check_line_list(ll->x_list);
  1270. if (code < 0)
  1271. return code;
  1272. }
  1273. #endif
  1274. y = y1;
  1275. }
  1276. return 0;
  1277. }
  1278. /*
  1279. * Handle the case of a slanted trapezoid with adjustment.
  1280. * To do this exactly right requires filling a central trapezoid
  1281. * (or rectangle) plus two horizontal almost-rectangles.
  1282. */
  1283. private int
  1284. fill_slant_adjust(fixed xlbot, fixed xbot, fixed y,
  1285. fixed xltop, fixed xtop, fixed height, fixed adjust_below,
  1286. fixed adjust_above, const gs_fixed_rect * pbox,
  1287. const gx_device_color * pdevc, gx_device * dev,
  1288. gs_logical_operation_t lop)
  1289. {
  1290. fixed y1 = y + height;
  1291. dev_proc_fill_trapezoid((*fill_trap)) =
  1292. dev_proc(dev, fill_trapezoid);
  1293. const fixed yb = y - adjust_below;
  1294. const fixed ya = y + adjust_above;
  1295. const fixed y1b = y1 - adjust_below;
  1296. const fixed y1a = y1 + adjust_above;
  1297. const gs_fixed_edge *plbot;
  1298. const gs_fixed_edge *prbot;
  1299. const gs_fixed_edge *pltop;
  1300. const gs_fixed_edge *prtop;
  1301. gs_fixed_edge vert_left, slant_left, vert_right, slant_right;
  1302. int code;
  1303. INCR(slant);
  1304. /* Set up all the edges, even though we may not need them all. */
  1305. if (xlbot < xltop) { /* && xbot < xtop */
  1306. vert_left.start.x = vert_left.end.x = xlbot;
  1307. vert_left.start.y = yb, vert_left.end.y = ya;
  1308. vert_right.start.x = vert_right.end.x = xtop;
  1309. vert_right.start.y = y1b, vert_right.end.y = y1a;
  1310. slant_left.start.y = ya, slant_left.end.y = y1a;
  1311. slant_right.start.y = yb, slant_right.end.y = y1b;
  1312. plbot = &vert_left, prbot = &slant_right,
  1313. pltop = &slant_left, prtop = &vert_right;
  1314. } else {
  1315. vert_left.start.x = vert_left.end.x = xltop;
  1316. vert_left.start.y = y1b, vert_left.end.y = y1a;
  1317. vert_right.start.x = vert_right.end.x = xbot;
  1318. vert_right.start.y = yb, vert_right.end.y = ya;
  1319. slant_left.start.y = yb, slant_left.end.y = y1b;
  1320. slant_right.start.y = ya, slant_right.end.y = y1a;
  1321. plbot = &slant_left, prbot = &vert_right,
  1322. pltop = &vert_left, prtop = &slant_right;
  1323. }
  1324. slant_left.start.x = xlbot, slant_left.end.x = xltop;
  1325. slant_right.start.x = xbot, slant_right.end.x = xtop;
  1326. if (ya >= y1b) {
  1327. /*
  1328. * The upper and lower adjustment bands overlap.
  1329. * Since the entire entity is less than 2 pixels high
  1330. * in this case, we could handle it very efficiently
  1331. * with no more than 2 rectangle fills, but for right now
  1332. * we don't attempt to do this.
  1333. */
  1334. int iyb = fixed2int_var_pixround(yb);
  1335. int iya = fixed2int_var_pixround(ya);
  1336. int iy1b = fixed2int_var_pixround(y1b);
  1337. int iy1a = fixed2int_var_pixround(y1a);
  1338. INCR(slant_shallow);
  1339. if (iy1b > iyb) {
  1340. code = (*fill_trap) (dev, plbot, prbot,
  1341. yb, y1b, false, pdevc, lop);
  1342. if (code < 0)
  1343. return code;
  1344. }
  1345. if (iya > iy1b) {
  1346. int ix = fixed2int_var_pixround(vert_left.start.x);
  1347. int iw = fixed2int_var_pixround(vert_right.start.x) - ix;
  1348. code = LOOP_FILL_RECTANGLE(ix, iy1b, iw, iya - iy1b);
  1349. if (code < 0)
  1350. return code;
  1351. }
  1352. if (iy1a > iya)
  1353. code = (*fill_trap) (dev, pltop, prtop,
  1354. ya, y1a, false, pdevc, lop);
  1355. else
  1356. code = 0;
  1357. } else {
  1358. /*
  1359. * Clip the trapezoid if possible. This can save a lot
  1360. * of work when filling paths that cross band boundaries.
  1361. */
  1362. fixed yac;
  1363. if (pbox->p.y < ya) {
  1364. code = (*fill_trap) (dev, plbot, prbot,
  1365. yb, ya, false, pdevc, lop);
  1366. if (code < 0)
  1367. return code;
  1368. yac = ya;
  1369. } else
  1370. yac = pbox->p.y;
  1371. if (pbox->q.y > y1b) {
  1372. code = (*fill_trap) (dev, &slant_left, &slant_right,
  1373. yac, y1b, false, pdevc, lop);
  1374. if (code < 0)
  1375. return code;
  1376. code = (*fill_trap) (dev, pltop, prtop,
  1377. y1b, y1a, false, pdevc, lop);
  1378. } else
  1379. code = (*fill_trap) (dev, &slant_left, &slant_right,
  1380. yac, pbox->q.y, false, pdevc, lop);
  1381. }
  1382. return code;
  1383. }
  1384. /* Re-sort the x list by moving alp backward to its proper spot. */
  1385. private void
  1386. resort_x_line(active_line * alp)
  1387. {
  1388. active_line *prev = alp->prev;
  1389. active_line *next = alp->next;
  1390. prev->next = next;
  1391. if (next)
  1392. next->prev = prev;
  1393. while (x_order(prev, alp) > 0) {
  1394. if_debug2('F', "[F]swap 0x%lx,0x%lx\n",
  1395. (ulong) alp, (ulong) prev);
  1396. next = prev, prev = prev->prev;
  1397. }
  1398. alp->next = next;
  1399. alp->prev = prev;
  1400. /* next might be null, if alp was in the correct spot already. */
  1401. if (next)
  1402. next->prev = alp;
  1403. prev->next = alp;
  1404. }
  1405. /* ---------------- Range list management ---------------- */
  1406. /*
  1407. * We originally thought we would store fixed values in coordinate ranges,
  1408. * but it turned out we want to store integers.
  1409. */
  1410. typedef int coord_value_t;
  1411. #define MIN_COORD_VALUE min_int
  1412. #define MAX_COORD_VALUE max_int
  1413. /*
  1414. * The invariant for coord_range_ts in a coord_range_list_t:
  1415. * if prev == 0:
  1416. * next != 0
  1417. * rmin == rmax == MIN_COORD_VALUE
  1418. * else if next == 0:
  1419. * prev != 0
  1420. * rmin == rmax == MAX_COORD_VALUE
  1421. * else
  1422. * rmin < rmax
  1423. * if prev != 0:
  1424. * prev->next == this
  1425. * prev->rmax < rmin
  1426. * if next != 0:
  1427. * next->prev = this
  1428. * next->rmin > rmax
  1429. * A coord_range_list_t has a boundary element at each end to avoid having
  1430. * to test for null pointers in the insertion loop. The boundary elements
  1431. * are the only empty ranges.
  1432. */
  1433. typedef struct coord_range_s coord_range_t;
  1434. struct coord_range_s {
  1435. coord_value_t rmin, rmax;
  1436. coord_range_t *prev, *next;
  1437. coord_range_t *alloc_next;
  1438. };
  1439. /* We declare coord_range_ts as simple because they only exist transiently. */
  1440. gs_private_st_simple(st_coord_range, coord_range_t, "coord_range_t");
  1441. typedef struct coord_range_list_s {
  1442. gs_memory_t *memory;
  1443. struct rl_ {
  1444. coord_range_t *first, *next, *limit;
  1445. } local;
  1446. coord_range_t *allocated;
  1447. coord_range_t *freed;
  1448. coord_range_t *current;
  1449. coord_range_t first, last;
  1450. } coord_range_list_t;
  1451. private coord_range_t *
  1452. range_alloc(coord_range_list_t *pcrl)
  1453. {
  1454. coord_range_t *pcr;
  1455. if (pcrl->freed) {
  1456. pcr = pcrl->freed;
  1457. pcrl->freed = pcr->next;
  1458. } else if (pcrl->local.next < pcrl->local.limit)
  1459. pcr = pcrl->local.next++;
  1460. else {
  1461. pcr = gs_alloc_struct(pcrl->memory, coord_range_t, &st_coord_range,
  1462. "range_alloc");
  1463. if (pcr == 0)
  1464. return 0;
  1465. pcr->alloc_next = pcrl->allocated;
  1466. pcrl->allocated = pcr;
  1467. }
  1468. return pcr;
  1469. }
  1470. private void
  1471. range_delete(coord_range_list_t *pcrl, coord_range_t *pcr)
  1472. {
  1473. if_debug3('Q', "[Qr]delete 0x%lx: [%d,%d)\n", (ulong)pcr, pcr->rmin,
  1474. pcr->rmax);
  1475. pcr->prev->next = pcr->next;
  1476. pcr->next->prev = pcr->prev;
  1477. pcr->next = pcrl->freed;
  1478. pcrl->freed = pcr;
  1479. }
  1480. private void
  1481. range_list_clear(coord_range_list_t *pcrl)
  1482. {
  1483. if_debug0('Q', "[Qr]clearing\n");
  1484. pcrl->first.next = &pcrl->last;
  1485. pcrl->last.prev = &pcrl->first;
  1486. pcrl->current = &pcrl->last;
  1487. }
  1488. /* ------ "Public" procedures ------ */
  1489. /* Initialize a range list. We require num_local >= 2. */
  1490. private void range_list_clear(P1(coord_range_list_t *));
  1491. private void
  1492. range_list_init(coord_range_list_t *pcrl, coord_range_t *pcr_local,
  1493. int num_local, gs_memory_t *mem)
  1494. {
  1495. pcrl->memory = mem;
  1496. pcrl->local.first = pcrl->local.next = pcr_local;
  1497. pcrl->local.limit = pcr_local + num_local;
  1498. pcrl->allocated = pcrl->freed = 0;
  1499. pcrl->first.rmin = pcrl->first.rmax = MIN_COORD_VALUE;
  1500. pcrl->first.prev = 0;
  1501. pcrl->last.rmin = pcrl->last.rmax = MAX_COORD_VALUE;
  1502. pcrl->last.next = 0;
  1503. range_list_clear(pcrl);
  1504. }
  1505. /* Reset an initialized range list to the empty state. */
  1506. private void
  1507. range_list_reset(coord_range_list_t *pcrl)
  1508. {
  1509. if (pcrl->first.next != &pcrl->last) {
  1510. pcrl->last.prev->next = pcrl->freed;
  1511. pcrl->freed = pcrl->first.next;
  1512. range_list_clear(pcrl);
  1513. }
  1514. }
  1515. /*
  1516. * Move the cursor to the beginning of a range list, in the belief that
  1517. * the next added ranges will roughly parallel the existing ones.
  1518. * (Only affects performance, not function.)
  1519. */
  1520. inline private void
  1521. range_list_rescan(coord_range_list_t *pcrl)
  1522. {
  1523. pcrl->current = pcrl->first.next;
  1524. }
  1525. /* Free a range list. */
  1526. private void
  1527. range_list_free(coord_range_list_t *pcrl)
  1528. {
  1529. coord_range_t *pcr;
  1530. while ((pcr = pcrl->allocated) != 0) {
  1531. coord_range_t *next = pcr->alloc_next;
  1532. gs_free_object(pcrl->memory, pcr, "range_list_free");
  1533. pcrl->allocated = next;
  1534. }
  1535. }
  1536. /* Add a range. */
  1537. private int
  1538. range_list_add(coord_range_list_t *pcrl, coord_value_t rmin, coord_value_t rmax)
  1539. {
  1540. coord_range_t *pcr = pcrl->current;
  1541. if (rmin >= rmax)
  1542. return 0;
  1543. /*
  1544. * Usually, ranges are added in increasing order within each scan line,
  1545. * and overlapping ranges don't differ much. Optimize accordingly.
  1546. */
  1547. top:
  1548. if (rmax < pcr->rmin) {
  1549. if (rmin > pcr->prev->rmax)
  1550. goto ins;
  1551. pcr = pcr->prev;
  1552. goto top;
  1553. }
  1554. if (rmin > pcr->rmax) {
  1555. pcr = pcr->next;
  1556. if (rmax < pcr->rmin)
  1557. goto ins;
  1558. goto top;
  1559. }
  1560. /*
  1561. * Now we know that (rmin,rmax) overlaps (pcr->rmin,pcr->rmax).
  1562. * Don't delete or merge into the special min and max ranges.
  1563. */
  1564. while (rmin <= pcr->prev->rmax) {
  1565. /* Merge the range below pcr into this one. */
  1566. if (!pcr->prev->prev)
  1567. break; /* don't merge into the min range */
  1568. pcr->rmin = pcr->prev->rmin;
  1569. range_delete(pcrl, pcr->prev);
  1570. }
  1571. while (rmax >= pcr->next->rmin) {
  1572. /* Merge the range above pcr into this one. */
  1573. if (!pcr->next->next)
  1574. break; /* don't merge into the max range */
  1575. pcr->rmax = pcr->next->rmax;
  1576. range_delete(pcrl, pcr->next);
  1577. }
  1578. /*
  1579. * Now we know that the union of (rmin,rmax) and (pcr->rmin,pcr->rmax)
  1580. * doesn't overlap or abut either adjacent range, except that it may
  1581. * abut if the adjacent range is the special min or max range.
  1582. */
  1583. if (rmin < pcr->rmin) {
  1584. if_debug3('Q', "[Qr]update 0x%lx => [%d,%d)\n", (ulong)pcr, rmin,
  1585. pcr->rmax);
  1586. pcr->rmin = rmin;
  1587. }
  1588. if (rmax > pcr->rmax) {
  1589. if_debug3('Q', "[Qr]update 0x%lx => [%d,%d)\n", (ulong)pcr, pcr->rmin,
  1590. rmax);
  1591. pcr->rmax = rmax;
  1592. }
  1593. pcrl->current = pcr->next;
  1594. return 0;
  1595. ins:
  1596. /* Insert a new range below pcr. */
  1597. {
  1598. coord_range_t *prev = range_alloc(pcrl);
  1599. if (prev == 0)
  1600. return_error(gs_error_VMerror);
  1601. if_debug3('Q', "[Qr]insert 0x%lx: [%d,%d)\n", (ulong)prev, rmin, rmax);
  1602. prev->rmin = rmin, prev->rmax = rmax;
  1603. (prev->prev = pcr->prev)->next = prev;
  1604. prev->next = pcr;
  1605. pcr->prev = prev;
  1606. }
  1607. pcrl->current = pcr;
  1608. return 0;
  1609. }
  1610. /* ---------------- Scan line filling loop ---------------- */
  1611. /* Forward references */
  1612. private int merge_ranges(P6(coord_range_list_t *pcrl, ll_ptr ll,
  1613. fixed y_min, fixed y_top,
  1614. fixed adjust_left, fixed adjust_right));
  1615. private void set_scan_line_points(P2(active_line *, fixed));
  1616. /* Main filling loop. */
  1617. private int
  1618. fill_loop_by_scan_lines(ll_ptr ll, gx_device * dev,
  1619. const gx_fill_params * params,
  1620. const gx_device_color * pdevc,
  1621. gs_logical_operation_t lop, const gs_fixed_rect * pbox,
  1622. fixed adjust_left, fixed adjust_right,
  1623. fixed adjust_below, fixed adjust_above,
  1624. fixed band_mask)
  1625. {
  1626. int rule = params->rule;
  1627. fixed fixed_flat = float2fixed(params->flatness);
  1628. bool fill_direct = color_writes_pure(pdevc, lop);
  1629. gx_color_index cindex;
  1630. dev_proc_fill_rectangle((*fill_rect));
  1631. active_line *yll = ll->y_list;
  1632. fixed y_limit = pbox->q.y;
  1633. /*
  1634. * The meaning of adjust_below (B) and adjust_above (A) is that the
  1635. * pixels that would normally be painted at coordinate Y get "smeared"
  1636. * to coordinates Y-B through Y+A-epsilon, inclusive. This is
  1637. * equivalent to saying that the pixels actually painted at coordinate Y
  1638. * are those contributed by scan lines Y-A+epsilon through Y+B,
  1639. * inclusive. (A = B = 0 is a special case, equivalent to B = 0, A =
  1640. * epsilon.)
  1641. */
  1642. fixed y_frac_min =
  1643. (adjust_above == fixed_0 ? fixed_half :
  1644. fixed_half + fixed_epsilon - adjust_above);
  1645. fixed y_frac_max =
  1646. fixed_half + adjust_below;
  1647. int y0 = fixed2int(min_fixed);
  1648. fixed y_bot = min_fixed; /* normally int2fixed(y0) + y_frac_min */
  1649. fixed y_top = min_fixed; /* normally int2fixed(y0) + y_frac_max */
  1650. coord_range_list_t rlist;
  1651. coord_range_t rlocal[MAX_LOCAL_ACTIVE];
  1652. int code = 0;
  1653. if (yll == 0) /* empty list */
  1654. return 0;
  1655. range_list_init(&rlist, rlocal, countof(rlocal), ll->memory);
  1656. if (fill_direct)
  1657. cindex = pdevc->colors.pure,
  1658. fill_rect = dev_proc(dev, fill_rectangle);
  1659. ll->x_list = 0;
  1660. ll->x_head.x_current = min_fixed; /* stop backward scan */
  1661. while (code >= 0) {
  1662. active_line *alp, *nlp;
  1663. fixed y, x;
  1664. bool new_band;
  1665. INCR(iter);
  1666. /*
  1667. * Find the next sampling point, either the bottom of a sampling
  1668. * band or a line start.
  1669. */
  1670. if (ll->x_list == 0)
  1671. y = (yll == 0 ? y_limit : yll->start.y);
  1672. else {
  1673. y = y_bot + fixed_1;
  1674. if (yll != 0)
  1675. y = min(y, yll->start.y);
  1676. for (alp = ll->x_list; alp != 0; alp = alp->next)
  1677. if (!end_x_line(alp, false))
  1678. y = min(y, alp->end.y);
  1679. }
  1680. /* Move newly active lines from y to x list. */
  1681. while (yll != 0 && yll->start.y == y) {
  1682. active_line *ynext = yll->next; /* insert smashes next/prev links */
  1683. if (yll->direction == DIR_HORIZONTAL) {
  1684. /* Ignore for now. */
  1685. } else {
  1686. insert_x_new(yll, ll);
  1687. set_scan_line_points(yll, fixed_flat);
  1688. }
  1689. yll = ynext;
  1690. }
  1691. /* Update active lines to y. */
  1692. x = min_fixed;
  1693. for (alp = ll->x_list; alp != 0; alp = nlp) {
  1694. fixed nx;
  1695. nlp = alp->next;
  1696. e:if (alp->end.y <= y) {
  1697. if (end_x_line(alp, true))
  1698. continue;
  1699. set_scan_line_points(alp, fixed_flat);
  1700. goto e;
  1701. }
  1702. nx = alp->x_current =
  1703. (alp->start.y >= y ? alp->start.x :
  1704. alp->curve_k < 0 ?
  1705. AL_X_AT_Y(alp, y) :
  1706. gx_curve_x_at_y(&alp->cursor, y));
  1707. if (nx < x) {
  1708. /* Move this line backward in the list. */
  1709. active_line *ilp = alp;
  1710. while (nx < (ilp = ilp->prev)->x_current)
  1711. DO_NOTHING;
  1712. /* Now ilp->x_current <= nx < ilp->next->x_cur. */
  1713. alp->prev->next = alp->next;
  1714. if (alp->next)
  1715. alp->next->prev = alp->prev;
  1716. if (ilp->next)
  1717. ilp->next->prev = alp;
  1718. alp->next = ilp->next;
  1719. ilp->next = alp;
  1720. alp->prev = ilp;
  1721. continue;
  1722. }
  1723. x = nx;
  1724. }
  1725. if (y > y_top || y >= y_limit) {
  1726. /* We're beyond the end of the previous sampling band. */
  1727. const coord_range_t *pcr;
  1728. /* Fill the ranges for y0. */
  1729. for (pcr = rlist.first.next; pcr != &rlist.last;
  1730. pcr = pcr->next
  1731. ) {
  1732. int x0 = pcr->rmin, x1 = pcr->rmax;
  1733. if_debug4('Q', "[Qr]draw 0x%lx: [%d,%d),%d\n", (ulong)pcr,
  1734. x0, x1, y0);
  1735. code = LOOP_FILL_RECTANGLE_DIRECT(x0, y0, x1 - x0, 1);
  1736. if_debug3('F', "[F]drawing [%d:%d),%d\n", x0, x1, y0);
  1737. if (code < 0)
  1738. goto done;
  1739. }
  1740. range_list_reset(&rlist);
  1741. /* Check whether we've reached the maximum y. */
  1742. if (y >= y_limit)
  1743. break;
  1744. /* Reset the sampling band. */
  1745. y0 = fixed2int(y);
  1746. if (fixed_fraction(y) < y_frac_min)
  1747. --y0;
  1748. y_bot = int2fixed(y0) + y_frac_min;
  1749. y_top = int2fixed(y0) + y_frac_max;
  1750. new_band = true;
  1751. } else
  1752. new_band = false;
  1753. if (y <= y_top) {
  1754. /*
  1755. * We're within the same Y pixel. Merge regions for segments
  1756. * starting here (at y), up to y_top or the end of the segment.
  1757. * If this is the first sampling within the band, run the
  1758. * fill/eofill algorithm.
  1759. */
  1760. fixed y_min;
  1761. if (new_band) {
  1762. /*
  1763. * rule = -1 for winding number rule, i.e.
  1764. * we are inside if the winding number is non-zero;
  1765. * rule = 1 for even-odd rule, i.e.
  1766. * we are inside if the winding number is odd.
  1767. */
  1768. int inside = 0;
  1769. #define INSIDE_PATH_P() ((inside & rule) != 0)
  1770. INCR(band);
  1771. for (alp = ll->x_list; alp != 0; alp = alp->next) {
  1772. int x0 = fixed2int_pixround(alp->x_current - adjust_left);
  1773. for (;;) {
  1774. /* We're inside a filled region. */
  1775. print_al("step", alp);
  1776. INCR(band_step);
  1777. inside += alp->direction;
  1778. if (!INSIDE_PATH_P())
  1779. break;
  1780. /*
  1781. * Since we're dealing with closed paths, the test
  1782. * for alp == 0 shouldn't be needed, but we may have
  1783. * omitted lines that are to the right of the
  1784. * clipping region.
  1785. */
  1786. if ((alp = alp->next) == 0)
  1787. goto out;
  1788. }
  1789. #undef INSIDE_PATH_P
  1790. /* We just went from inside to outside, so fill the region. */
  1791. code = range_list_add(&rlist, x0,
  1792. fixed2int_rounded(alp->x_current +
  1793. adjust_right));
  1794. if (code < 0)
  1795. goto done;
  1796. }
  1797. out:
  1798. y_min = min_fixed;
  1799. } else
  1800. y_min = y;
  1801. code = merge_ranges(&rlist, ll, y_min, y_top, adjust_left,
  1802. adjust_right);
  1803. } /* else y < y_bot + 1, do nothing */
  1804. }
  1805. done:
  1806. range_list_free(&rlist);
  1807. return code;
  1808. }
  1809. /*
  1810. * Merge regions for active segments starting at a given Y, or all active
  1811. * segments, up to the end of the sampling band or the end of the segment,
  1812. * into the range list.
  1813. */
  1814. private int
  1815. merge_ranges(coord_range_list_t *pcrl, ll_ptr ll, fixed y_min, fixed y_top,
  1816. fixed adjust_left, fixed adjust_right)
  1817. {
  1818. active_line *alp, *nlp;
  1819. int code = 0;
  1820. range_list_rescan(pcrl);
  1821. for (alp = ll->x_list; alp != 0 && code >= 0; alp = nlp) {
  1822. fixed x0 = alp->x_current, x1, xt;
  1823. nlp = alp->next;
  1824. if (alp->start.y < y_min)
  1825. continue;
  1826. if (alp->end.y < y_top)
  1827. x1 = alp->end.x;
  1828. else if (alp->curve_k < 0)
  1829. x1 = AL_X_AT_Y(alp, y_top);
  1830. else
  1831. x1 = gx_curve_x_at_y(&alp->cursor, y_top);
  1832. if (x0 > x1)
  1833. xt = x0, x0 = x1, x1 = xt;
  1834. code = range_list_add(pcrl,
  1835. fixed2int_pixround(x0 - adjust_left),
  1836. fixed2int_rounded(x1 + adjust_right));
  1837. }
  1838. return code;
  1839. }
  1840. /*
  1841. * Set curve_k and, if necessary, the curve rendering parameters for
  1842. * the current segment of an active line.
  1843. */
  1844. private void
  1845. set_scan_line_points(active_line * alp, fixed fixed_flat)
  1846. {
  1847. const segment *pseg = alp->pseg;
  1848. const gs_fixed_point *pp0;
  1849. if (alp->direction < 0) {
  1850. pseg =
  1851. (pseg->type == s_line_close ?
  1852. ((const line_close_segment *)pseg)->sub->next :
  1853. pseg->next);
  1854. if (pseg->type != s_curve) {
  1855. alp->curve_k = -1;
  1856. return;
  1857. }
  1858. pp0 = &alp->end;
  1859. } else {
  1860. if (pseg->type != s_curve) {
  1861. alp->curve_k = -1;
  1862. return;
  1863. }
  1864. pp0 = &alp->start;
  1865. }
  1866. {
  1867. const curve_segment *const pcseg = (const curve_segment *)pseg;
  1868. alp->curve_k =
  1869. gx_curve_log2_samples(pp0->x, pp0->y, pcseg, fixed_flat);
  1870. gx_curve_cursor_init(&alp->cursor, pp0->x, pp0->y, pcseg,
  1871. alp->curve_k);
  1872. }
  1873. }