/src/ghostpdl/base/gxdtfill.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Configurable algorithm for filling a trapezoid */ |
18 | | |
19 | | /* |
20 | | * Since we need several statically defined variants of this agorithm, |
21 | | * we store it in .h file and include several times into gdevddrw.c and |
22 | | * into gxfill.h . Configuration flags (macros) are : |
23 | | * |
24 | | * GX_FILL_TRAPEZOID - a name of method |
25 | | * CONTIGUOUS_FILL - prevent dropouts in narrow trapezoids |
26 | | * SWAP_AXES - assume swapped axes |
27 | | * FILL_DIRECT - See LOOP_FILL_RECTANGLE_DIRECT. |
28 | | * LINEAR_COLOR - Fill with a linear color. |
29 | | * EDGE_TYPE - a type of edge structure. |
30 | | * FILL_ATTRS - operation attributes. |
31 | | */ |
32 | | |
33 | | /* |
34 | | * Fill a trapezoid. left.start => left.end and right.start => right.end |
35 | | * define the sides; ybot and ytop define the top and bottom. Requires: |
36 | | * {left,right}->start.y <= ybot <= ytop <= {left,right}->end.y. |
37 | | * Lines where left.x >= right.x will not be drawn. Thanks to Paul Haeberli |
38 | | * for an early floating point version of this algorithm. |
39 | | */ |
40 | | |
41 | | /* |
42 | | * With CONTIGUOUS_FILL is off, |
43 | | * this algorithm paints pixels, which centers fall between |
44 | | * the left and the right side of the trapezoid, excluding the |
45 | | * right side (see PLRM3, 7.5. Scan conversion details). |
46 | | * Particularly 0-width trapezoids are not painted. |
47 | | * |
48 | | * Similarly, it paints pixels, which centers |
49 | | * fall between ybot and ytop, excluding ytop. |
50 | | * Particularly 0-height trapezoids are not painted. |
51 | | * |
52 | | * With CONTIGUOUS_FILL is on, it paints a contigous area, |
53 | | * adding a minimal number of pixels outside the trapezoid. |
54 | | * Particularly it may paint pixels on the right and on the top sides, |
55 | | * if they are necessary for the contiguity. |
56 | | * |
57 | | * With LINEAR_COLOR returns 1 if the gradient arithmetics overflows.. |
58 | | */ |
59 | | |
60 | | /* |
61 | | We must paint pixels with index i such that |
62 | | |
63 | | Xl <= i + 0.5 < Xr |
64 | | |
65 | | The condition is is equivalent to |
66 | | |
67 | | Xl - 0.5 <= i < Xr - 0.5 |
68 | | |
69 | | which is equivalent to |
70 | | |
71 | | (is_integer(Xl - 0.5) ? Xl - 0.5 : ceil(Xl - 0.5)) <= i < |
72 | | (is_integer(Xr - 0.5) ? Xr - 0.5 : floor(Xr - 0.5) + 1) |
73 | | |
74 | | (the last '+1" happens due to the strong comparizon '<') |
75 | | which is equivalent to |
76 | | |
77 | | ceil(Xl - 0.5) <= i < ceil(Xr - 0.5) |
78 | | |
79 | | trap_line represents the intersection coordinate as a rational value : |
80 | | |
81 | | Xl = xl + e - fl |
82 | | Xr = xr + e - fr |
83 | | |
84 | | Where 'e' is 'fixed_epsilon', 0.5 is 'fixed_half', and fl == l.fx / l.h, fr == - r.fx / r.h, |
85 | | e <= fl < 0, e <= fr < 0. |
86 | | Let |
87 | | |
88 | | xl' := xl + 0.5 |
89 | | xr' := xr + 0.5 |
90 | | |
91 | | Then |
92 | | |
93 | | xl = xl' - 0.5 |
94 | | xr = xr' - 0.5 |
95 | | |
96 | | Xl = xl' - 0.5 + e - fl |
97 | | Xr = xr' - 0.5 + e - fr |
98 | | |
99 | | ceil(xl' - 0.5 + e - fl - 0.5) <= i < ceil(xr' - 0.5 + e - fr - 0.5) |
100 | | |
101 | | which is equivalent to |
102 | | |
103 | | ceil(xl' + e - fl) - 1 <= i < ceil(xr' + e - fr) - 1 |
104 | | |
105 | | which is equivalent to |
106 | | |
107 | | (is_integer(xl' + e - fl) ? xl' + e - fl - 1 : ceil(xl' + e - fl) - 1) <= i < |
108 | | (is_integer(xr' + e - fr) ? xr' + e - fr - 1 : ceil(xr' + e - fr) - 1) |
109 | | |
110 | | which is equivalent to |
111 | | |
112 | | (is_integer(xl' + e - fl) ? xl' + e - fl - 1 : floor(xl' + e - fl)) <= i < |
113 | | (is_integer(xr' + e - fr) ? xr' + e - fr - 1 : floor(xr' + e - fr)) |
114 | | |
115 | | which is equivalent to |
116 | | |
117 | | (is_integer(xl') && e == fl ? xl' - 1 : floor(xl' + e - fl)) <= i < |
118 | | (is_integer(xr') && e == fr ? xr' - 1 : floor(xr' + e - fr)) |
119 | | |
120 | | Note that e != fl ==> floor(xl' + e - fl) == floor(xl') due to e - fl < LeastSignificantBit(xl') ; |
121 | | e == fl ==> floor(xl' + e - fl) == floor(xl') due to e - fl == 0; |
122 | | |
123 | | thus the condition is is equivalent to |
124 | | |
125 | | (is_integer(xl') && e == fl ? xl' - 1 : floor(xl')) <= i < |
126 | | (is_integer(xr') && e == fr ? xr' - 1 : floor(xr')) |
127 | | |
128 | | It is computed with the macro 'rational_floor'. |
129 | | |
130 | | */ |
131 | | |
132 | | #if defined(GX_FILL_TRAPEZOID) && defined(EDGE_TYPE) |
133 | | |
134 | | GX_FILL_TRAPEZOID (gx_device * dev, const EDGE_TYPE * left, |
135 | | const EDGE_TYPE * right, fixed ybot, fixed ytop, int flags, |
136 | | const gx_device_color * pdevc, FILL_ATTRS fa) |
137 | 85.0k | { |
138 | 85.0k | const fixed ymin = fixed_pixround(ybot) + fixed_half; |
139 | 85.0k | const fixed ymax = fixed_pixround(ytop); |
140 | | |
141 | 85.0k | if (ymin >= ymax) |
142 | 2 | return 0; /* no scan lines to sample */ |
143 | 85.0k | { |
144 | 85.0k | int iy = fixed2int_var(ymin); |
145 | 85.0k | const int iy1 = fixed2int_var(ymax); |
146 | 85.0k | trap_line l, r; |
147 | 85.0k | register int rxl, rxr; |
148 | | #if !LINEAR_COLOR |
149 | | int ry; |
150 | | #endif |
151 | 85.0k | const fixed |
152 | 85.0k | x0l = left->start.x, x1l = left->end.x, x0r = right->start.x, |
153 | 85.0k | x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r; |
154 | 85.0k | const fixed /* partial pixel offset to first line to sample */ |
155 | 85.0k | ysl = ymin - left->start.y, ysr = ymin - right->start.y; |
156 | 85.0k | fixed fxl; |
157 | 85.0k | int code; |
158 | | # if CONTIGUOUS_FILL |
159 | | const bool peak0 = ((flags & 1) != 0); |
160 | | const bool peak1 = ((flags & 2) != 0); |
161 | 0 | int peak_y0 = ybot + fixed_half; |
162 | 0 | int peak_y1 = ytop - fixed_half; |
163 | | # endif |
164 | | # if LINEAR_COLOR |
165 | | int num_components = dev->color_info.num_components; |
166 | | frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
167 | | int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
168 | | int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
169 | | frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
170 | | int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
171 | | int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
172 | | frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
173 | | int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
174 | | int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; |
175 | | trap_gradient lg, rg, xg; |
176 | | # else |
177 | | gx_color_index cindex = pdevc->colors.pure; |
178 | 85.0k | dev_proc_fill_rectangle((*fill_rect)) = |
179 | 85.0k | dev_proc(dev, fill_rectangle); |
180 | | # endif |
181 | | |
182 | 85.0k | if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1); |
183 | | |
184 | 85.0k | l.h = left->end.y - left->start.y; |
185 | 85.0k | if (l.h == 0) |
186 | 0 | return 0; |
187 | 85.0k | r.h = right->end.y - right->start.y; |
188 | 85.0k | if (r.h == 0) |
189 | 0 | return 0; |
190 | 85.0k | l.x = x0l + (fixed_half - fixed_epsilon); |
191 | 85.0k | r.x = x0r + (fixed_half - fixed_epsilon); |
192 | | #if !LINEAR_COLOR |
193 | | ry = iy; |
194 | | #endif |
195 | | |
196 | | /* |
197 | | * Free variables of FILL_TRAP_RECT: |
198 | | * SWAP_AXES, pdevc, dev, fa |
199 | | * Free variables of FILL_TRAP_RECT_DIRECT: |
200 | | * SWAP_AXES, fill_rect, dev, cindex |
201 | | */ |
202 | 85.0k | #define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\ |
203 | 2.47M | (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\ |
204 | 2.47M | gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa)) |
205 | 85.0k | #define FILL_TRAP_RECT_DIRECT(x,y,w,h)\ |
206 | 791k | (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\ |
207 | 791k | (*fill_rect)(dev, x, y, w, h, cindex)) |
208 | | |
209 | | #if LINEAR_COLOR |
210 | | # define FILL_TRAP_RECT(x,y,w,h)\ |
211 | 0 | (!(w) ? 0 : dev_proc(dev, fill_linear_color_scanline)(dev, fa, x, y, w, xg.c, xg.f, xg.num, xg.den)) |
212 | | #else |
213 | | # define FILL_TRAP_RECT(x,y,w,h)\ |
214 | 3.26M | (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h)) |
215 | | #endif |
216 | | |
217 | | /* Compute the dx/dy ratios. */ |
218 | | |
219 | | /* |
220 | | * Compute the x offsets at the first scan line to sample. We need |
221 | | * to be careful in computing ys# * dx#f {/,%} h# because the |
222 | | * multiplication may overflow. We know that all the quantities |
223 | | * involved are non-negative, and that ys# is usually less than 1 (as |
224 | | * a fixed, of course); this gives us a cheap conservative check for |
225 | | * overflow in the multiplication. |
226 | | */ |
227 | 85.0k | #define YMULT_QUO(ys, tl)\ |
228 | 85.0k | (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\ |
229 | 55.8k | fixed_mult_quo(ys, tl.df, tl.h)) |
230 | | |
231 | | #if CONTIGUOUS_FILL |
232 | | /* |
233 | | * If left and right boundary round to same pixel index, |
234 | | * we would not paing the scan and would get a dropout. |
235 | | * Check for this case and choose one of two pixels |
236 | | * which is closer to the "axis". We need to exclude |
237 | | * 'peak' because it would paint an excessive pixel. |
238 | | */ |
239 | | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) \ |
240 | 0 | if (ixl == ixr) \ |
241 | 0 | if ((!peak0 || iy >= peak_y0) && (!peak1 || iy <= peak_y1)) {\ |
242 | 0 | fixed x = int2fixed(ixl) + fixed_half;\ |
243 | 0 | if (x - l.x < r.x - x)\ |
244 | 0 | ++ixr;\ |
245 | 0 | else\ |
246 | 0 | --ixl;\ |
247 | 0 | } |
248 | | |
249 | | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill)\ |
250 | 0 | if (adj1 < adj2) {\ |
251 | 0 | if (iy - ry > 1) {\ |
252 | 0 | code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\ |
253 | 0 | if (code < 0)\ |
254 | 0 | goto xit;\ |
255 | 0 | ry = iy - 1;\ |
256 | 0 | }\ |
257 | 0 | adj1 = adj2 = (adj2 + adj2) / 2;\ |
258 | 0 | } |
259 | | |
260 | | #else |
261 | 3.85M | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING |
262 | 6.35M | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING |
263 | | #endif |
264 | 85.0k | if (fixed_floor(l.x) == fixed_pixround(x1l)) { |
265 | | /* Left edge is vertical, we don't need to increment. */ |
266 | 55.6k | l.di = 0, l.df = 0; |
267 | 55.6k | fxl = 0; |
268 | 55.6k | } else { |
269 | 29.3k | compute_dx(&l, dxl, ysl); |
270 | 29.3k | fxl = YMULT_QUO(ysl, l); |
271 | 29.3k | l.x += fxl; |
272 | 29.3k | } |
273 | 85.0k | if (fixed_floor(r.x) == fixed_pixround(x1r)) { |
274 | | /* Right edge is vertical. If both are vertical, */ |
275 | | /* we have a rectangle. */ |
276 | | # if !LINEAR_COLOR |
277 | 58.2k | if (l.di == 0 && l.df == 0) { |
278 | 52.0k | rxl = fixed2int_var(l.x); |
279 | 52.0k | rxr = fixed2int_var(r.x); |
280 | 52.0k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); |
281 | 52.0k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry); |
282 | 52.0k | goto xit; |
283 | 52.0k | } |
284 | 6.13k | # endif |
285 | 6.13k | r.di = 0, r.df = 0; |
286 | 6.13k | } |
287 | | /* |
288 | | * The test for fxl != 0 is required because the right edge might |
289 | | * cross some pixel centers even if the left edge doesn't. |
290 | | */ |
291 | 26.8k | else if (dxr == dxl && fxl != 0) { |
292 | 626 | if (l.di == 0) |
293 | 18 | r.di = 0, r.df = l.df; |
294 | 608 | else |
295 | 608 | compute_dx(&r, dxr, ysr); |
296 | 626 | if (ysr == ysl && r.h == l.h) |
297 | 260 | r.x += fxl; |
298 | 366 | else |
299 | 366 | r.x += YMULT_QUO(ysr, r); |
300 | 26.1k | } else { |
301 | 26.1k | compute_dx(&r, dxr, ysr); |
302 | 26.1k | r.x += YMULT_QUO(ysr, r); |
303 | 26.1k | } |
304 | | /* Compute one line's worth of dx/dy. */ |
305 | 32.9k | compute_ldx(&l, ysl); |
306 | 32.9k | compute_ldx(&r, ysr); |
307 | | /* We subtracted fixed_epsilon from l.x, r.x to simplify rounding |
308 | | when the rational part is zero. Now add it back to get xl', xr' */ |
309 | 32.9k | l.x += fixed_epsilon; |
310 | 32.9k | r.x += fixed_epsilon; |
311 | | # if LINEAR_COLOR |
312 | | # ifdef DEBUG |
313 | | if (check_gradient_overflow(left, right)) { |
314 | | /* The caller must care of. |
315 | | Checking it here looses some performance with triangles. */ |
316 | | return_error(gs_error_unregistered); |
317 | | } |
318 | | # endif |
319 | | lg.c = lgc; |
320 | | lg.f = lgf; |
321 | | lg.num = lgnum; |
322 | | rg.c = rgc; |
323 | | rg.f = rgf; |
324 | | rg.num = rgnum; |
325 | | xg.c = xgc; |
326 | | xg.f = xgf; |
327 | | xg.num = xgnum; |
328 | | code = init_gradient(&lg, fa, left, right, &l, ymin, num_components); |
329 | 0 | if (code < 0) |
330 | 0 | return code; |
331 | 0 | code = init_gradient(&rg, fa, right, left, &r, ymin, num_components); |
332 | 0 | if (code < 0) |
333 | 0 | return code; |
334 | | |
335 | 0 | # endif |
336 | | |
337 | 0 | #define rational_floor(tl)\ |
338 | 7.59M | fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x) |
339 | 0 | #define STEP_LINE(ix, tl)\ |
340 | 7.53M | tl.x += tl.ldi;\ |
341 | 7.53M | if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\ |
342 | 7.53M | ix = rational_floor(tl) |
343 | | |
344 | 32.9k | rxl = rational_floor(l); |
345 | 32.9k | rxr = rational_floor(r); |
346 | 32.9k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); |
347 | 3.79M | while (LINEAR_COLOR ? 1 : ++iy != iy1) { |
348 | | # if LINEAR_COLOR |
349 | 0 | if (rxl != rxr) { |
350 | 0 | code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components); |
351 | 0 | if (code < 0) |
352 | 0 | goto xit; |
353 | 0 | code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1); |
354 | 0 | if (code < 0) |
355 | 0 | goto xit; |
356 | 0 | } |
357 | 0 | if (++iy == iy1) |
358 | 0 | break; |
359 | 0 | STEP_LINE(rxl, l); |
360 | 0 | STEP_LINE(rxr, r); |
361 | 0 | step_gradient(&lg, num_components); |
362 | 0 | step_gradient(&rg, num_components); |
363 | | # else |
364 | | register int ixl, ixr; |
365 | | |
366 | 3.76M | STEP_LINE(ixl, l); |
367 | 3.76M | STEP_LINE(ixr, r); |
368 | 3.76M | SET_MINIMAL_WIDTH(ixl, ixr, l, r); |
369 | 3.76M | if (ixl != rxl || ixr != rxr) { |
370 | 3.17M | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT); |
371 | 3.17M | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT); |
372 | 3.17M | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); |
373 | 3.17M | if (code < 0) |
374 | 0 | goto xit; |
375 | 3.17M | rxl = ixl, rxr = ixr, ry = iy; |
376 | 3.17M | } |
377 | | # endif |
378 | 0 | } |
379 | | # if !LINEAR_COLOR |
380 | 32.9k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); |
381 | | # else |
382 | 0 | code = 0; |
383 | 0 | # endif |
384 | 0 | #undef STEP_LINE |
385 | 0 | #undef SET_MINIMAL_WIDTH |
386 | 0 | #undef CONNECT_RECTANGLES |
387 | 0 | #undef FILL_TRAP_RECT |
388 | 0 | #undef FILL_TRAP_RECT_DIRECT |
389 | 0 | #undef FILL_TRAP_RECT_INRECT |
390 | 0 | #undef YMULT_QUO |
391 | 85.0k | xit: if (code < 0 && FILL_DIRECT) |
392 | 0 | return_error(code); |
393 | 85.0k | return_if_interrupt(dev->memory); |
394 | 85.0k | return code; |
395 | 85.0k | } |
396 | 85.0k | } Unexecuted instantiation: gx_fill_trapezoid_cf_fd Unexecuted instantiation: gx_fill_trapezoid_cf_nd Unexecuted instantiation: gdevddrw.c:gx_fill_trapezoid_as_fd Unexecuted instantiation: gdevddrw.c:gx_fill_trapezoid_as_nd gdevddrw.c:gx_fill_trapezoid_ns_fd Line | Count | Source | 137 | 69.4k | { | 138 | 69.4k | const fixed ymin = fixed_pixround(ybot) + fixed_half; | 139 | 69.4k | const fixed ymax = fixed_pixround(ytop); | 140 | | | 141 | 69.4k | if (ymin >= ymax) | 142 | 2 | return 0; /* no scan lines to sample */ | 143 | 69.4k | { | 144 | 69.4k | int iy = fixed2int_var(ymin); | 145 | 69.4k | const int iy1 = fixed2int_var(ymax); | 146 | 69.4k | trap_line l, r; | 147 | 69.4k | register int rxl, rxr; | 148 | 69.4k | #if !LINEAR_COLOR | 149 | 69.4k | int ry; | 150 | 69.4k | #endif | 151 | 69.4k | const fixed | 152 | 69.4k | x0l = left->start.x, x1l = left->end.x, x0r = right->start.x, | 153 | 69.4k | x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r; | 154 | 69.4k | const fixed /* partial pixel offset to first line to sample */ | 155 | 69.4k | ysl = ymin - left->start.y, ysr = ymin - right->start.y; | 156 | 69.4k | fixed fxl; | 157 | 69.4k | int code; | 158 | | # if CONTIGUOUS_FILL | 159 | | const bool peak0 = ((flags & 1) != 0); | 160 | | const bool peak1 = ((flags & 2) != 0); | 161 | | int peak_y0 = ybot + fixed_half; | 162 | | int peak_y1 = ytop - fixed_half; | 163 | | # endif | 164 | | # if LINEAR_COLOR | 165 | | int num_components = dev->color_info.num_components; | 166 | | frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 167 | | int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 168 | | int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 169 | | frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 170 | | int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 171 | | int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 172 | | frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 173 | | int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 174 | | int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 175 | | trap_gradient lg, rg, xg; | 176 | | # else | 177 | 69.4k | gx_color_index cindex = pdevc->colors.pure; | 178 | 69.4k | dev_proc_fill_rectangle((*fill_rect)) = | 179 | 69.4k | dev_proc(dev, fill_rectangle); | 180 | 69.4k | # endif | 181 | | | 182 | 69.4k | if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1); | 183 | | | 184 | 69.4k | l.h = left->end.y - left->start.y; | 185 | 69.4k | if (l.h == 0) | 186 | 0 | return 0; | 187 | 69.4k | r.h = right->end.y - right->start.y; | 188 | 69.4k | if (r.h == 0) | 189 | 0 | return 0; | 190 | 69.4k | l.x = x0l + (fixed_half - fixed_epsilon); | 191 | 69.4k | r.x = x0r + (fixed_half - fixed_epsilon); | 192 | 69.4k | #if !LINEAR_COLOR | 193 | 69.4k | ry = iy; | 194 | 69.4k | #endif | 195 | | | 196 | | /* | 197 | | * Free variables of FILL_TRAP_RECT: | 198 | | * SWAP_AXES, pdevc, dev, fa | 199 | | * Free variables of FILL_TRAP_RECT_DIRECT: | 200 | | * SWAP_AXES, fill_rect, dev, cindex | 201 | | */ | 202 | 69.4k | #define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\ | 203 | 69.4k | (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\ | 204 | 69.4k | gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa)) | 205 | 69.4k | #define FILL_TRAP_RECT_DIRECT(x,y,w,h)\ | 206 | 69.4k | (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\ | 207 | 69.4k | (*fill_rect)(dev, x, y, w, h, cindex)) | 208 | | | 209 | | #if LINEAR_COLOR | 210 | | # define FILL_TRAP_RECT(x,y,w,h)\ | 211 | | (!(w) ? 0 : dev_proc(dev, fill_linear_color_scanline)(dev, fa, x, y, w, xg.c, xg.f, xg.num, xg.den)) | 212 | | #else | 213 | 69.4k | # define FILL_TRAP_RECT(x,y,w,h)\ | 214 | 69.4k | (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h)) | 215 | 69.4k | #endif | 216 | | | 217 | | /* Compute the dx/dy ratios. */ | 218 | | | 219 | | /* | 220 | | * Compute the x offsets at the first scan line to sample. We need | 221 | | * to be careful in computing ys# * dx#f {/,%} h# because the | 222 | | * multiplication may overflow. We know that all the quantities | 223 | | * involved are non-negative, and that ys# is usually less than 1 (as | 224 | | * a fixed, of course); this gives us a cheap conservative check for | 225 | | * overflow in the multiplication. | 226 | | */ | 227 | 69.4k | #define YMULT_QUO(ys, tl)\ | 228 | 69.4k | (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\ | 229 | 69.4k | fixed_mult_quo(ys, tl.df, tl.h)) | 230 | | | 231 | | #if CONTIGUOUS_FILL | 232 | | /* | 233 | | * If left and right boundary round to same pixel index, | 234 | | * we would not paing the scan and would get a dropout. | 235 | | * Check for this case and choose one of two pixels | 236 | | * which is closer to the "axis". We need to exclude | 237 | | * 'peak' because it would paint an excessive pixel. | 238 | | */ | 239 | | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) \ | 240 | | if (ixl == ixr) \ | 241 | | if ((!peak0 || iy >= peak_y0) && (!peak1 || iy <= peak_y1)) {\ | 242 | | fixed x = int2fixed(ixl) + fixed_half;\ | 243 | | if (x - l.x < r.x - x)\ | 244 | | ++ixr;\ | 245 | | else\ | 246 | | --ixl;\ | 247 | | } | 248 | | | 249 | | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill)\ | 250 | | if (adj1 < adj2) {\ | 251 | | if (iy - ry > 1) {\ | 252 | | code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\ | 253 | | if (code < 0)\ | 254 | | goto xit;\ | 255 | | ry = iy - 1;\ | 256 | | }\ | 257 | | adj1 = adj2 = (adj2 + adj2) / 2;\ | 258 | | } | 259 | | | 260 | | #else | 261 | 69.4k | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING | 262 | 69.4k | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING | 263 | 69.4k | #endif | 264 | 69.4k | if (fixed_floor(l.x) == fixed_pixround(x1l)) { | 265 | | /* Left edge is vertical, we don't need to increment. */ | 266 | 47.6k | l.di = 0, l.df = 0; | 267 | 47.6k | fxl = 0; | 268 | 47.6k | } else { | 269 | 21.7k | compute_dx(&l, dxl, ysl); | 270 | 21.7k | fxl = YMULT_QUO(ysl, l); | 271 | 21.7k | l.x += fxl; | 272 | 21.7k | } | 273 | 69.4k | if (fixed_floor(r.x) == fixed_pixround(x1r)) { | 274 | | /* Right edge is vertical. If both are vertical, */ | 275 | | /* we have a rectangle. */ | 276 | 47.1k | # if !LINEAR_COLOR | 277 | 47.1k | if (l.di == 0 && l.df == 0) { | 278 | 44.2k | rxl = fixed2int_var(l.x); | 279 | 44.2k | rxr = fixed2int_var(r.x); | 280 | 44.2k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); | 281 | 44.2k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry); | 282 | 44.2k | goto xit; | 283 | 44.2k | } | 284 | 2.88k | # endif | 285 | 2.88k | r.di = 0, r.df = 0; | 286 | 2.88k | } | 287 | | /* | 288 | | * The test for fxl != 0 is required because the right edge might | 289 | | * cross some pixel centers even if the left edge doesn't. | 290 | | */ | 291 | 22.2k | else if (dxr == dxl && fxl != 0) { | 292 | 616 | if (l.di == 0) | 293 | 18 | r.di = 0, r.df = l.df; | 294 | 598 | else | 295 | 598 | compute_dx(&r, dxr, ysr); | 296 | 616 | if (ysr == ysl && r.h == l.h) | 297 | 260 | r.x += fxl; | 298 | 356 | else | 299 | 356 | r.x += YMULT_QUO(ysr, r); | 300 | 21.6k | } else { | 301 | 21.6k | compute_dx(&r, dxr, ysr); | 302 | 21.6k | r.x += YMULT_QUO(ysr, r); | 303 | 21.6k | } | 304 | | /* Compute one line's worth of dx/dy. */ | 305 | 25.1k | compute_ldx(&l, ysl); | 306 | 25.1k | compute_ldx(&r, ysr); | 307 | | /* We subtracted fixed_epsilon from l.x, r.x to simplify rounding | 308 | | when the rational part is zero. Now add it back to get xl', xr' */ | 309 | 25.1k | l.x += fixed_epsilon; | 310 | 25.1k | r.x += fixed_epsilon; | 311 | | # if LINEAR_COLOR | 312 | | # ifdef DEBUG | 313 | | if (check_gradient_overflow(left, right)) { | 314 | | /* The caller must care of. | 315 | | Checking it here looses some performance with triangles. */ | 316 | | return_error(gs_error_unregistered); | 317 | | } | 318 | | # endif | 319 | | lg.c = lgc; | 320 | | lg.f = lgf; | 321 | | lg.num = lgnum; | 322 | | rg.c = rgc; | 323 | | rg.f = rgf; | 324 | | rg.num = rgnum; | 325 | | xg.c = xgc; | 326 | | xg.f = xgf; | 327 | | xg.num = xgnum; | 328 | | code = init_gradient(&lg, fa, left, right, &l, ymin, num_components); | 329 | | if (code < 0) | 330 | | return code; | 331 | | code = init_gradient(&rg, fa, right, left, &r, ymin, num_components); | 332 | | if (code < 0) | 333 | | return code; | 334 | | | 335 | | # endif | 336 | | | 337 | 25.1k | #define rational_floor(tl)\ | 338 | 25.1k | fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x) | 339 | 25.1k | #define STEP_LINE(ix, tl)\ | 340 | 25.1k | tl.x += tl.ldi;\ | 341 | 25.1k | if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\ | 342 | 25.1k | ix = rational_floor(tl) | 343 | | | 344 | 25.1k | rxl = rational_floor(l); | 345 | 25.1k | rxr = rational_floor(r); | 346 | 25.1k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); | 347 | 976k | while (LINEAR_COLOR ? 1 : ++iy != iy1) { | 348 | | # if LINEAR_COLOR | 349 | | if (rxl != rxr) { | 350 | | code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components); | 351 | | if (code < 0) | 352 | | goto xit; | 353 | | code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1); | 354 | | if (code < 0) | 355 | | goto xit; | 356 | | } | 357 | | if (++iy == iy1) | 358 | | break; | 359 | | STEP_LINE(rxl, l); | 360 | | STEP_LINE(rxr, r); | 361 | | step_gradient(&lg, num_components); | 362 | | step_gradient(&rg, num_components); | 363 | | # else | 364 | 951k | register int ixl, ixr; | 365 | | | 366 | 951k | STEP_LINE(ixl, l); | 367 | 951k | STEP_LINE(ixr, r); | 368 | 951k | SET_MINIMAL_WIDTH(ixl, ixr, l, r); | 369 | 951k | if (ixl != rxl || ixr != rxr) { | 370 | 721k | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT); | 371 | 721k | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT); | 372 | 721k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); | 373 | 721k | if (code < 0) | 374 | 0 | goto xit; | 375 | 721k | rxl = ixl, rxr = ixr, ry = iy; | 376 | 721k | } | 377 | 951k | # endif | 378 | 951k | } | 379 | 25.1k | # if !LINEAR_COLOR | 380 | 25.1k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); | 381 | | # else | 382 | | code = 0; | 383 | | # endif | 384 | 25.1k | #undef STEP_LINE | 385 | 25.1k | #undef SET_MINIMAL_WIDTH | 386 | 25.1k | #undef CONNECT_RECTANGLES | 387 | 25.1k | #undef FILL_TRAP_RECT | 388 | 25.1k | #undef FILL_TRAP_RECT_DIRECT | 389 | 25.1k | #undef FILL_TRAP_RECT_INRECT | 390 | 25.1k | #undef YMULT_QUO | 391 | 69.4k | xit: if (code < 0 && FILL_DIRECT) | 392 | 0 | return_error(code); | 393 | 69.4k | return_if_interrupt(dev->memory); | 394 | 69.4k | return code; | 395 | 69.4k | } | 396 | 69.4k | } |
gdevddrw.c:gx_fill_trapezoid_ns_nd Line | Count | Source | 137 | 15.6k | { | 138 | 15.6k | const fixed ymin = fixed_pixround(ybot) + fixed_half; | 139 | 15.6k | const fixed ymax = fixed_pixround(ytop); | 140 | | | 141 | 15.6k | if (ymin >= ymax) | 142 | 0 | return 0; /* no scan lines to sample */ | 143 | 15.6k | { | 144 | 15.6k | int iy = fixed2int_var(ymin); | 145 | 15.6k | const int iy1 = fixed2int_var(ymax); | 146 | 15.6k | trap_line l, r; | 147 | 15.6k | register int rxl, rxr; | 148 | 15.6k | #if !LINEAR_COLOR | 149 | 15.6k | int ry; | 150 | 15.6k | #endif | 151 | 15.6k | const fixed | 152 | 15.6k | x0l = left->start.x, x1l = left->end.x, x0r = right->start.x, | 153 | 15.6k | x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r; | 154 | 15.6k | const fixed /* partial pixel offset to first line to sample */ | 155 | 15.6k | ysl = ymin - left->start.y, ysr = ymin - right->start.y; | 156 | 15.6k | fixed fxl; | 157 | 15.6k | int code; | 158 | | # if CONTIGUOUS_FILL | 159 | | const bool peak0 = ((flags & 1) != 0); | 160 | | const bool peak1 = ((flags & 2) != 0); | 161 | | int peak_y0 = ybot + fixed_half; | 162 | | int peak_y1 = ytop - fixed_half; | 163 | | # endif | 164 | | # if LINEAR_COLOR | 165 | | int num_components = dev->color_info.num_components; | 166 | | frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 167 | | int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 168 | | int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 169 | | frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 170 | | int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 171 | | int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 172 | | frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 173 | | int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 174 | | int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS]; | 175 | | trap_gradient lg, rg, xg; | 176 | | # else | 177 | 15.6k | gx_color_index cindex = pdevc->colors.pure; | 178 | 15.6k | dev_proc_fill_rectangle((*fill_rect)) = | 179 | 15.6k | dev_proc(dev, fill_rectangle); | 180 | 15.6k | # endif | 181 | | | 182 | 15.6k | if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1); | 183 | | | 184 | 15.6k | l.h = left->end.y - left->start.y; | 185 | 15.6k | if (l.h == 0) | 186 | 0 | return 0; | 187 | 15.6k | r.h = right->end.y - right->start.y; | 188 | 15.6k | if (r.h == 0) | 189 | 0 | return 0; | 190 | 15.6k | l.x = x0l + (fixed_half - fixed_epsilon); | 191 | 15.6k | r.x = x0r + (fixed_half - fixed_epsilon); | 192 | 15.6k | #if !LINEAR_COLOR | 193 | 15.6k | ry = iy; | 194 | 15.6k | #endif | 195 | | | 196 | | /* | 197 | | * Free variables of FILL_TRAP_RECT: | 198 | | * SWAP_AXES, pdevc, dev, fa | 199 | | * Free variables of FILL_TRAP_RECT_DIRECT: | 200 | | * SWAP_AXES, fill_rect, dev, cindex | 201 | | */ | 202 | 15.6k | #define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\ | 203 | 15.6k | (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\ | 204 | 15.6k | gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa)) | 205 | 15.6k | #define FILL_TRAP_RECT_DIRECT(x,y,w,h)\ | 206 | 15.6k | (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\ | 207 | 15.6k | (*fill_rect)(dev, x, y, w, h, cindex)) | 208 | | | 209 | | #if LINEAR_COLOR | 210 | | # define FILL_TRAP_RECT(x,y,w,h)\ | 211 | | (!(w) ? 0 : dev_proc(dev, fill_linear_color_scanline)(dev, fa, x, y, w, xg.c, xg.f, xg.num, xg.den)) | 212 | | #else | 213 | 15.6k | # define FILL_TRAP_RECT(x,y,w,h)\ | 214 | 15.6k | (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h)) | 215 | 15.6k | #endif | 216 | | | 217 | | /* Compute the dx/dy ratios. */ | 218 | | | 219 | | /* | 220 | | * Compute the x offsets at the first scan line to sample. We need | 221 | | * to be careful in computing ys# * dx#f {/,%} h# because the | 222 | | * multiplication may overflow. We know that all the quantities | 223 | | * involved are non-negative, and that ys# is usually less than 1 (as | 224 | | * a fixed, of course); this gives us a cheap conservative check for | 225 | | * overflow in the multiplication. | 226 | | */ | 227 | 15.6k | #define YMULT_QUO(ys, tl)\ | 228 | 15.6k | (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\ | 229 | 15.6k | fixed_mult_quo(ys, tl.df, tl.h)) | 230 | | | 231 | | #if CONTIGUOUS_FILL | 232 | | /* | 233 | | * If left and right boundary round to same pixel index, | 234 | | * we would not paing the scan and would get a dropout. | 235 | | * Check for this case and choose one of two pixels | 236 | | * which is closer to the "axis". We need to exclude | 237 | | * 'peak' because it would paint an excessive pixel. | 238 | | */ | 239 | | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) \ | 240 | | if (ixl == ixr) \ | 241 | | if ((!peak0 || iy >= peak_y0) && (!peak1 || iy <= peak_y1)) {\ | 242 | | fixed x = int2fixed(ixl) + fixed_half;\ | 243 | | if (x - l.x < r.x - x)\ | 244 | | ++ixr;\ | 245 | | else\ | 246 | | --ixl;\ | 247 | | } | 248 | | | 249 | | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill)\ | 250 | | if (adj1 < adj2) {\ | 251 | | if (iy - ry > 1) {\ | 252 | | code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\ | 253 | | if (code < 0)\ | 254 | | goto xit;\ | 255 | | ry = iy - 1;\ | 256 | | }\ | 257 | | adj1 = adj2 = (adj2 + adj2) / 2;\ | 258 | | } | 259 | | | 260 | | #else | 261 | 15.6k | #define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING | 262 | 15.6k | #define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING | 263 | 15.6k | #endif | 264 | 15.6k | if (fixed_floor(l.x) == fixed_pixround(x1l)) { | 265 | | /* Left edge is vertical, we don't need to increment. */ | 266 | 8.02k | l.di = 0, l.df = 0; | 267 | 8.02k | fxl = 0; | 268 | 8.02k | } else { | 269 | 7.58k | compute_dx(&l, dxl, ysl); | 270 | 7.58k | fxl = YMULT_QUO(ysl, l); | 271 | 7.58k | l.x += fxl; | 272 | 7.58k | } | 273 | 15.6k | if (fixed_floor(r.x) == fixed_pixround(x1r)) { | 274 | | /* Right edge is vertical. If both are vertical, */ | 275 | | /* we have a rectangle. */ | 276 | 11.0k | # if !LINEAR_COLOR | 277 | 11.0k | if (l.di == 0 && l.df == 0) { | 278 | 7.81k | rxl = fixed2int_var(l.x); | 279 | 7.81k | rxr = fixed2int_var(r.x); | 280 | 7.81k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); | 281 | 7.81k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry); | 282 | 7.81k | goto xit; | 283 | 7.81k | } | 284 | 3.25k | # endif | 285 | 3.25k | r.di = 0, r.df = 0; | 286 | 3.25k | } | 287 | | /* | 288 | | * The test for fxl != 0 is required because the right edge might | 289 | | * cross some pixel centers even if the left edge doesn't. | 290 | | */ | 291 | 4.54k | else if (dxr == dxl && fxl != 0) { | 292 | 10 | if (l.di == 0) | 293 | 0 | r.di = 0, r.df = l.df; | 294 | 10 | else | 295 | 10 | compute_dx(&r, dxr, ysr); | 296 | 10 | if (ysr == ysl && r.h == l.h) | 297 | 0 | r.x += fxl; | 298 | 10 | else | 299 | 10 | r.x += YMULT_QUO(ysr, r); | 300 | 4.53k | } else { | 301 | 4.53k | compute_dx(&r, dxr, ysr); | 302 | 4.53k | r.x += YMULT_QUO(ysr, r); | 303 | 4.53k | } | 304 | | /* Compute one line's worth of dx/dy. */ | 305 | 7.79k | compute_ldx(&l, ysl); | 306 | 7.79k | compute_ldx(&r, ysr); | 307 | | /* We subtracted fixed_epsilon from l.x, r.x to simplify rounding | 308 | | when the rational part is zero. Now add it back to get xl', xr' */ | 309 | 7.79k | l.x += fixed_epsilon; | 310 | 7.79k | r.x += fixed_epsilon; | 311 | | # if LINEAR_COLOR | 312 | | # ifdef DEBUG | 313 | | if (check_gradient_overflow(left, right)) { | 314 | | /* The caller must care of. | 315 | | Checking it here looses some performance with triangles. */ | 316 | | return_error(gs_error_unregistered); | 317 | | } | 318 | | # endif | 319 | | lg.c = lgc; | 320 | | lg.f = lgf; | 321 | | lg.num = lgnum; | 322 | | rg.c = rgc; | 323 | | rg.f = rgf; | 324 | | rg.num = rgnum; | 325 | | xg.c = xgc; | 326 | | xg.f = xgf; | 327 | | xg.num = xgnum; | 328 | | code = init_gradient(&lg, fa, left, right, &l, ymin, num_components); | 329 | | if (code < 0) | 330 | | return code; | 331 | | code = init_gradient(&rg, fa, right, left, &r, ymin, num_components); | 332 | | if (code < 0) | 333 | | return code; | 334 | | | 335 | | # endif | 336 | | | 337 | 7.79k | #define rational_floor(tl)\ | 338 | 7.79k | fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x) | 339 | 7.79k | #define STEP_LINE(ix, tl)\ | 340 | 7.79k | tl.x += tl.ldi;\ | 341 | 7.79k | if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\ | 342 | 7.79k | ix = rational_floor(tl) | 343 | | | 344 | 7.79k | rxl = rational_floor(l); | 345 | 7.79k | rxr = rational_floor(r); | 346 | 7.79k | SET_MINIMAL_WIDTH(rxl, rxr, l, r); | 347 | 2.82M | while (LINEAR_COLOR ? 1 : ++iy != iy1) { | 348 | | # if LINEAR_COLOR | 349 | | if (rxl != rxr) { | 350 | | code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components); | 351 | | if (code < 0) | 352 | | goto xit; | 353 | | code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1); | 354 | | if (code < 0) | 355 | | goto xit; | 356 | | } | 357 | | if (++iy == iy1) | 358 | | break; | 359 | | STEP_LINE(rxl, l); | 360 | | STEP_LINE(rxr, r); | 361 | | step_gradient(&lg, num_components); | 362 | | step_gradient(&rg, num_components); | 363 | | # else | 364 | 2.81M | register int ixl, ixr; | 365 | | | 366 | 2.81M | STEP_LINE(ixl, l); | 367 | 2.81M | STEP_LINE(ixr, r); | 368 | 2.81M | SET_MINIMAL_WIDTH(ixl, ixr, l, r); | 369 | 2.81M | if (ixl != rxl || ixr != rxr) { | 370 | 2.45M | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT); | 371 | 2.45M | CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT); | 372 | 2.45M | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); | 373 | 2.45M | if (code < 0) | 374 | 0 | goto xit; | 375 | 2.45M | rxl = ixl, rxr = ixr, ry = iy; | 376 | 2.45M | } | 377 | 2.81M | # endif | 378 | 2.81M | } | 379 | 7.79k | # if !LINEAR_COLOR | 380 | 7.79k | code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry); | 381 | | # else | 382 | | code = 0; | 383 | | # endif | 384 | 7.79k | #undef STEP_LINE | 385 | 7.79k | #undef SET_MINIMAL_WIDTH | 386 | 7.79k | #undef CONNECT_RECTANGLES | 387 | 7.79k | #undef FILL_TRAP_RECT | 388 | 7.79k | #undef FILL_TRAP_RECT_DIRECT | 389 | 7.79k | #undef FILL_TRAP_RECT_INRECT | 390 | 7.79k | #undef YMULT_QUO | 391 | 15.6k | xit: if (code < 0 && FILL_DIRECT) | 392 | 0 | return_error(code); | 393 | 15.6k | return_if_interrupt(dev->memory); | 394 | 15.6k | return code; | 395 | 15.6k | } | 396 | 15.6k | } |
Unexecuted instantiation: gdevddrw.c:gx_fill_trapezoid_as_lc Unexecuted instantiation: gdevddrw.c:gx_fill_trapezoid_ns_lc |
397 | | |
398 | | #undef GX_FILL_TRAPEZOID |
399 | | #undef CONTIGUOUS_FILL |
400 | | #undef SWAP_AXES |
401 | | #undef FLAGS_TYPE |
402 | | |
403 | | #else |
404 | | int dummy; |
405 | | #endif |