Coverage Report

Created: 2025-06-24 07:01

/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
221M
{
138
221M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
221M
    const fixed ymax = fixed_pixround(ytop);
140
141
221M
    if (ymin >= ymax)
142
63.7M
        return 0;    /* no scan lines to sample */
143
158M
    {
144
158M
        int iy = fixed2int_var(ymin);
145
158M
        const int iy1 = fixed2int_var(ymax);
146
158M
        trap_line l, r;
147
158M
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
158M
        const fixed
152
158M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
158M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
158M
        const fixed /* partial pixel offset to first line to sample */
155
158M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
158M
        fixed fxl;
157
158M
        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
111M
            dev_proc_fill_rectangle((*fill_rect)) =
179
111M
                dev_proc(dev, fill_rectangle);
180
# endif
181
182
158M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
158M
        l.h = left->end.y - left->start.y;
185
158M
        if (l.h == 0)
186
12
           return 0;
187
158M
        r.h = right->end.y - right->start.y;
188
158M
        if (r.h == 0)
189
12
           return 0;
190
158M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
158M
        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
158M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
1.58G
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
1.58G
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
158M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
593M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
593M
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
#if LINEAR_COLOR
210
#   define FILL_TRAP_RECT(x,y,w,h)\
211
130M
        (!(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
2.17G
        (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
158M
#define YMULT_QUO(ys, tl)\
228
216M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
216M
   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
4.68G
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
4.13G
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
#endif
264
158M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
44.1M
            l.di = 0, l.df = 0;
267
44.1M
            fxl = 0;
268
113M
        } else {
269
113M
            compute_dx(&l, dxl, ysl);
270
113M
            fxl = YMULT_QUO(ysl, l);
271
113M
            l.x += fxl;
272
113M
        }
273
158M
        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
37.6M
                if (l.di == 0 && l.df == 0) {
278
20.1M
                    rxl = fixed2int_var(l.x);
279
20.1M
                    rxr = fixed2int_var(r.x);
280
20.1M
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
20.1M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
20.1M
                    goto xit;
283
20.1M
                }
284
17.4M
#     endif
285
17.4M
            r.di = 0, r.df = 0;
286
17.4M
        }
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
109M
        else if (dxr == dxl && fxl != 0) {
292
10.4M
            if (l.di == 0)
293
3.05M
                r.di = 0, r.df = l.df;
294
7.38M
            else
295
7.38M
                compute_dx(&r, dxr, ysr);
296
10.4M
            if (ysr == ysl && r.h == l.h)
297
7.48M
                r.x += fxl;
298
2.95M
            else
299
2.95M
                r.x += YMULT_QUO(ysr, r);
300
99.1M
        } else {
301
99.1M
            compute_dx(&r, dxr, ysr);
302
99.1M
            r.x += YMULT_QUO(ysr, r);
303
99.1M
        }
304
        /* Compute one line's worth of dx/dy. */
305
91.0M
        compute_ldx(&l, ysl);
306
91.0M
        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
137M
        l.x += fixed_epsilon;
310
137M
        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
46.8M
            if (code < 0)
330
0
                return code;
331
46.8M
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
46.8M
            if (code < 0)
333
0
                return code;
334
335
46.8M
# endif
336
337
46.8M
#define rational_floor(tl)\
338
10.2G
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
46.8M
#define STEP_LINE(ix, tl)\
340
9.96G
  tl.x += tl.ldi;\
341
9.96G
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
10.0G
  ix = rational_floor(tl)
343
344
137M
        rxl = rational_floor(l);
345
137M
        rxr = rational_floor(r);
346
137M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
5.11G
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
#     if LINEAR_COLOR
349
505M
                if (rxl != rxr) {
350
130M
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
130M
                    if (code < 0)
352
0
                        goto xit;
353
130M
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
130M
                    if (code < 0)
355
17
                        goto xit;
356
130M
                }
357
505M
                if (++iy == iy1)
358
46.8M
                    break;
359
458M
                STEP_LINE(rxl, l);
360
458M
                STEP_LINE(rxr, r);
361
458M
                step_gradient(&lg, num_components);
362
458M
                step_gradient(&rg, num_components);
363
#     else
364
                register int ixl, ixr;
365
366
4.52G
                STEP_LINE(ixl, l);
367
4.52G
                STEP_LINE(ixr, r);
368
4.52G
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
4.52G
                if (ixl != rxl || ixr != rxr) {
370
2.06G
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
2.06G
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
2.06G
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
2.06G
                    if (code < 0)
374
0
                        goto xit;
375
2.06G
                    rxl = ixl, rxr = ixr, ry = iy;
376
2.06G
                }
377
#     endif
378
458M
        }
379
# if !LINEAR_COLOR
380
91.0M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
46.8M
            code = 0;
383
46.8M
# endif
384
46.8M
#undef STEP_LINE
385
46.8M
#undef SET_MINIMAL_WIDTH
386
46.8M
#undef CONNECT_RECTANGLES
387
46.8M
#undef FILL_TRAP_RECT
388
46.8M
#undef FILL_TRAP_RECT_DIRECT
389
46.8M
#undef FILL_TRAP_RECT_INRECT
390
46.8M
#undef YMULT_QUO
391
158M
xit:  if (code < 0 && FILL_DIRECT)
392
17
            return_error(code);
393
158M
        return_if_interrupt(dev->memory);
394
158M
        return code;
395
158M
    }
396
158M
}
Unexecuted instantiation: gx_fill_trapezoid_cf_fd
Unexecuted instantiation: gx_fill_trapezoid_cf_nd
gdevddrw.c:gx_fill_trapezoid_as_fd
Line
Count
Source
137
4.05M
{
138
4.05M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
4.05M
    const fixed ymax = fixed_pixround(ytop);
140
141
4.05M
    if (ymin >= ymax)
142
181k
        return 0;    /* no scan lines to sample */
143
3.87M
    {
144
3.87M
        int iy = fixed2int_var(ymin);
145
3.87M
        const int iy1 = fixed2int_var(ymax);
146
3.87M
        trap_line l, r;
147
3.87M
        register int rxl, rxr;
148
3.87M
#if !LINEAR_COLOR
149
3.87M
        int ry;
150
3.87M
#endif
151
3.87M
        const fixed
152
3.87M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
3.87M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
3.87M
        const fixed /* partial pixel offset to first line to sample */
155
3.87M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
3.87M
        fixed fxl;
157
3.87M
        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
3.87M
            gx_color_index cindex = pdevc->colors.pure;
178
3.87M
            dev_proc_fill_rectangle((*fill_rect)) =
179
3.87M
                dev_proc(dev, fill_rectangle);
180
3.87M
# endif
181
182
3.87M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
3.87M
        l.h = left->end.y - left->start.y;
185
3.87M
        if (l.h == 0)
186
0
           return 0;
187
3.87M
        r.h = right->end.y - right->start.y;
188
3.87M
        if (r.h == 0)
189
0
           return 0;
190
3.87M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
3.87M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
3.87M
#if !LINEAR_COLOR
193
3.87M
        ry = iy;
194
3.87M
#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
3.87M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
3.87M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
3.87M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
3.87M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
3.87M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
3.87M
   (*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
3.87M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
3.87M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
3.87M
#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
3.87M
#define YMULT_QUO(ys, tl)\
228
3.87M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
3.87M
   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
3.87M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
3.87M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
3.87M
#endif
264
3.87M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
1.28M
            l.di = 0, l.df = 0;
267
1.28M
            fxl = 0;
268
2.58M
        } else {
269
2.58M
            compute_dx(&l, dxl, ysl);
270
2.58M
            fxl = YMULT_QUO(ysl, l);
271
2.58M
            l.x += fxl;
272
2.58M
        }
273
3.87M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
1.10M
#     if !LINEAR_COLOR
277
1.10M
                if (l.di == 0 && l.df == 0) {
278
1.02M
                    rxl = fixed2int_var(l.x);
279
1.02M
                    rxr = fixed2int_var(r.x);
280
1.02M
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
1.02M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
1.02M
                    goto xit;
283
1.02M
                }
284
74.6k
#     endif
285
74.6k
            r.di = 0, r.df = 0;
286
74.6k
        }
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
2.76M
        else if (dxr == dxl && fxl != 0) {
292
1.04M
            if (l.di == 0)
293
560k
                r.di = 0, r.df = l.df;
294
488k
            else
295
488k
                compute_dx(&r, dxr, ysr);
296
1.04M
            if (ysr == ysl && r.h == l.h)
297
1.04M
                r.x += fxl;
298
108
            else
299
108
                r.x += YMULT_QUO(ysr, r);
300
1.72M
        } else {
301
1.72M
            compute_dx(&r, dxr, ysr);
302
1.72M
            r.x += YMULT_QUO(ysr, r);
303
1.72M
        }
304
        /* Compute one line's worth of dx/dy. */
305
2.84M
        compute_ldx(&l, ysl);
306
2.84M
        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
2.84M
        l.x += fixed_epsilon;
310
2.84M
        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
2.84M
#define rational_floor(tl)\
338
2.84M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
2.84M
#define STEP_LINE(ix, tl)\
340
2.84M
  tl.x += tl.ldi;\
341
2.84M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
2.84M
  ix = rational_floor(tl)
343
344
2.84M
        rxl = rational_floor(l);
345
2.84M
        rxr = rational_floor(r);
346
2.84M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
275M
        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
273M
                register int ixl, ixr;
365
366
273M
                STEP_LINE(ixl, l);
367
273M
                STEP_LINE(ixr, r);
368
273M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
273M
                if (ixl != rxl || ixr != rxr) {
370
46.1M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
46.1M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
46.1M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
46.1M
                    if (code < 0)
374
0
                        goto xit;
375
46.1M
                    rxl = ixl, rxr = ixr, ry = iy;
376
46.1M
                }
377
273M
#     endif
378
273M
        }
379
2.84M
# if !LINEAR_COLOR
380
2.84M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
2.84M
#undef STEP_LINE
385
2.84M
#undef SET_MINIMAL_WIDTH
386
2.84M
#undef CONNECT_RECTANGLES
387
2.84M
#undef FILL_TRAP_RECT
388
2.84M
#undef FILL_TRAP_RECT_DIRECT
389
2.84M
#undef FILL_TRAP_RECT_INRECT
390
2.84M
#undef YMULT_QUO
391
3.87M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
3.87M
        return_if_interrupt(dev->memory);
394
3.87M
        return code;
395
3.87M
    }
396
3.87M
}
gdevddrw.c:gx_fill_trapezoid_as_nd
Line
Count
Source
137
4.07M
{
138
4.07M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
4.07M
    const fixed ymax = fixed_pixround(ytop);
140
141
4.07M
    if (ymin >= ymax)
142
54.1k
        return 0;    /* no scan lines to sample */
143
4.02M
    {
144
4.02M
        int iy = fixed2int_var(ymin);
145
4.02M
        const int iy1 = fixed2int_var(ymax);
146
4.02M
        trap_line l, r;
147
4.02M
        register int rxl, rxr;
148
4.02M
#if !LINEAR_COLOR
149
4.02M
        int ry;
150
4.02M
#endif
151
4.02M
        const fixed
152
4.02M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
4.02M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
4.02M
        const fixed /* partial pixel offset to first line to sample */
155
4.02M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
4.02M
        fixed fxl;
157
4.02M
        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
4.02M
            gx_color_index cindex = pdevc->colors.pure;
178
4.02M
            dev_proc_fill_rectangle((*fill_rect)) =
179
4.02M
                dev_proc(dev, fill_rectangle);
180
4.02M
# endif
181
182
4.02M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
4.02M
        l.h = left->end.y - left->start.y;
185
4.02M
        if (l.h == 0)
186
0
           return 0;
187
4.02M
        r.h = right->end.y - right->start.y;
188
4.02M
        if (r.h == 0)
189
0
           return 0;
190
4.02M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
4.02M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
4.02M
#if !LINEAR_COLOR
193
4.02M
        ry = iy;
194
4.02M
#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
4.02M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
4.02M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
4.02M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
4.02M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
4.02M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
4.02M
   (*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
4.02M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
4.02M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
4.02M
#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
4.02M
#define YMULT_QUO(ys, tl)\
228
4.02M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
4.02M
   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
4.02M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
4.02M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
4.02M
#endif
264
4.02M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
922k
            l.di = 0, l.df = 0;
267
922k
            fxl = 0;
268
3.09M
        } else {
269
3.09M
            compute_dx(&l, dxl, ysl);
270
3.09M
            fxl = YMULT_QUO(ysl, l);
271
3.09M
            l.x += fxl;
272
3.09M
        }
273
4.02M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
800k
#     if !LINEAR_COLOR
277
800k
                if (l.di == 0 && l.df == 0) {
278
760k
                    rxl = fixed2int_var(l.x);
279
760k
                    rxr = fixed2int_var(r.x);
280
760k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
760k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
760k
                    goto xit;
283
760k
                }
284
40.7k
#     endif
285
40.7k
            r.di = 0, r.df = 0;
286
40.7k
        }
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
3.21M
        else if (dxr == dxl && fxl != 0) {
292
444k
            if (l.di == 0)
293
266k
                r.di = 0, r.df = l.df;
294
178k
            else
295
178k
                compute_dx(&r, dxr, ysr);
296
444k
            if (ysr == ysl && r.h == l.h)
297
444k
                r.x += fxl;
298
267
            else
299
267
                r.x += YMULT_QUO(ysr, r);
300
2.77M
        } else {
301
2.77M
            compute_dx(&r, dxr, ysr);
302
2.77M
            r.x += YMULT_QUO(ysr, r);
303
2.77M
        }
304
        /* Compute one line's worth of dx/dy. */
305
3.25M
        compute_ldx(&l, ysl);
306
3.25M
        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
3.25M
        l.x += fixed_epsilon;
310
3.25M
        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
3.25M
#define rational_floor(tl)\
338
3.25M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
3.25M
#define STEP_LINE(ix, tl)\
340
3.25M
  tl.x += tl.ldi;\
341
3.25M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
3.25M
  ix = rational_floor(tl)
343
344
3.25M
        rxl = rational_floor(l);
345
3.25M
        rxr = rational_floor(r);
346
3.25M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
400M
        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
397M
                register int ixl, ixr;
365
366
397M
                STEP_LINE(ixl, l);
367
397M
                STEP_LINE(ixr, r);
368
397M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
397M
                if (ixl != rxl || ixr != rxr) {
370
302M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
302M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
302M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
302M
                    if (code < 0)
374
0
                        goto xit;
375
302M
                    rxl = ixl, rxr = ixr, ry = iy;
376
302M
                }
377
397M
#     endif
378
397M
        }
379
3.25M
# if !LINEAR_COLOR
380
3.25M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
3.25M
#undef STEP_LINE
385
3.25M
#undef SET_MINIMAL_WIDTH
386
3.25M
#undef CONNECT_RECTANGLES
387
3.25M
#undef FILL_TRAP_RECT
388
3.25M
#undef FILL_TRAP_RECT_DIRECT
389
3.25M
#undef FILL_TRAP_RECT_INRECT
390
3.25M
#undef YMULT_QUO
391
4.02M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
4.02M
        return_if_interrupt(dev->memory);
394
4.02M
        return code;
395
4.02M
    }
396
4.02M
}
gdevddrw.c:gx_fill_trapezoid_ns_fd
Line
Count
Source
137
52.3M
{
138
52.3M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
52.3M
    const fixed ymax = fixed_pixround(ytop);
140
141
52.3M
    if (ymin >= ymax)
142
9.97M
        return 0;    /* no scan lines to sample */
143
42.4M
    {
144
42.4M
        int iy = fixed2int_var(ymin);
145
42.4M
        const int iy1 = fixed2int_var(ymax);
146
42.4M
        trap_line l, r;
147
42.4M
        register int rxl, rxr;
148
42.4M
#if !LINEAR_COLOR
149
42.4M
        int ry;
150
42.4M
#endif
151
42.4M
        const fixed
152
42.4M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
42.4M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
42.4M
        const fixed /* partial pixel offset to first line to sample */
155
42.4M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
42.4M
        fixed fxl;
157
42.4M
        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
42.4M
            gx_color_index cindex = pdevc->colors.pure;
178
42.4M
            dev_proc_fill_rectangle((*fill_rect)) =
179
42.4M
                dev_proc(dev, fill_rectangle);
180
42.4M
# endif
181
182
42.4M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
42.4M
        l.h = left->end.y - left->start.y;
185
42.4M
        if (l.h == 0)
186
12
           return 0;
187
42.4M
        r.h = right->end.y - right->start.y;
188
42.4M
        if (r.h == 0)
189
12
           return 0;
190
42.4M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
42.4M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
42.4M
#if !LINEAR_COLOR
193
42.4M
        ry = iy;
194
42.4M
#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
42.4M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
42.4M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
42.4M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
42.4M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
42.4M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
42.4M
   (*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
42.4M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
42.4M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
42.4M
#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
42.4M
#define YMULT_QUO(ys, tl)\
228
42.4M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
42.4M
   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
42.4M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
42.4M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
42.4M
#endif
264
42.4M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
16.6M
            l.di = 0, l.df = 0;
267
16.6M
            fxl = 0;
268
25.8M
        } else {
269
25.8M
            compute_dx(&l, dxl, ysl);
270
25.8M
            fxl = YMULT_QUO(ysl, l);
271
25.8M
            l.x += fxl;
272
25.8M
        }
273
42.4M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
16.7M
#     if !LINEAR_COLOR
277
16.7M
                if (l.di == 0 && l.df == 0) {
278
10.9M
                    rxl = fixed2int_var(l.x);
279
10.9M
                    rxr = fixed2int_var(r.x);
280
10.9M
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
10.9M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
10.9M
                    goto xit;
283
10.9M
                }
284
5.74M
#     endif
285
5.74M
            r.di = 0, r.df = 0;
286
5.74M
        }
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
25.7M
        else if (dxr == dxl && fxl != 0) {
292
2.96M
            if (l.di == 0)
293
718k
                r.di = 0, r.df = l.df;
294
2.24M
            else
295
2.24M
                compute_dx(&r, dxr, ysr);
296
2.96M
            if (ysr == ysl && r.h == l.h)
297
1.70M
                r.x += fxl;
298
1.25M
            else
299
1.25M
                r.x += YMULT_QUO(ysr, r);
300
22.7M
        } else {
301
22.7M
            compute_dx(&r, dxr, ysr);
302
22.7M
            r.x += YMULT_QUO(ysr, r);
303
22.7M
        }
304
        /* Compute one line's worth of dx/dy. */
305
31.4M
        compute_ldx(&l, ysl);
306
31.4M
        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
31.4M
        l.x += fixed_epsilon;
310
31.4M
        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
31.4M
#define rational_floor(tl)\
338
31.4M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
31.4M
#define STEP_LINE(ix, tl)\
340
31.4M
  tl.x += tl.ldi;\
341
31.4M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
31.4M
  ix = rational_floor(tl)
343
344
31.4M
        rxl = rational_floor(l);
345
31.4M
        rxr = rational_floor(r);
346
31.4M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
2.23G
        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.20G
                register int ixl, ixr;
365
366
2.20G
                STEP_LINE(ixl, l);
367
2.20G
                STEP_LINE(ixr, r);
368
2.20G
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
2.20G
                if (ixl != rxl || ixr != rxr) {
370
501M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
501M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
501M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
501M
                    if (code < 0)
374
0
                        goto xit;
375
501M
                    rxl = ixl, rxr = ixr, ry = iy;
376
501M
                }
377
2.20G
#     endif
378
2.20G
        }
379
31.4M
# if !LINEAR_COLOR
380
31.4M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
31.4M
#undef STEP_LINE
385
31.4M
#undef SET_MINIMAL_WIDTH
386
31.4M
#undef CONNECT_RECTANGLES
387
31.4M
#undef FILL_TRAP_RECT
388
31.4M
#undef FILL_TRAP_RECT_DIRECT
389
31.4M
#undef FILL_TRAP_RECT_INRECT
390
31.4M
#undef YMULT_QUO
391
42.4M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
42.4M
        return_if_interrupt(dev->memory);
394
42.4M
        return code;
395
42.4M
    }
396
42.4M
}
gdevddrw.c:gx_fill_trapezoid_ns_nd
Line
Count
Source
137
84.4M
{
138
84.4M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
84.4M
    const fixed ymax = fixed_pixround(ytop);
140
141
84.4M
    if (ymin >= ymax)
142
23.5M
        return 0;    /* no scan lines to sample */
143
60.9M
    {
144
60.9M
        int iy = fixed2int_var(ymin);
145
60.9M
        const int iy1 = fixed2int_var(ymax);
146
60.9M
        trap_line l, r;
147
60.9M
        register int rxl, rxr;
148
60.9M
#if !LINEAR_COLOR
149
60.9M
        int ry;
150
60.9M
#endif
151
60.9M
        const fixed
152
60.9M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
60.9M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
60.9M
        const fixed /* partial pixel offset to first line to sample */
155
60.9M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
60.9M
        fixed fxl;
157
60.9M
        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
60.9M
            gx_color_index cindex = pdevc->colors.pure;
178
60.9M
            dev_proc_fill_rectangle((*fill_rect)) =
179
60.9M
                dev_proc(dev, fill_rectangle);
180
60.9M
# endif
181
182
60.9M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
60.9M
        l.h = left->end.y - left->start.y;
185
60.9M
        if (l.h == 0)
186
0
           return 0;
187
60.9M
        r.h = right->end.y - right->start.y;
188
60.9M
        if (r.h == 0)
189
0
           return 0;
190
60.9M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
60.9M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
60.9M
#if !LINEAR_COLOR
193
60.9M
        ry = iy;
194
60.9M
#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
60.9M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
60.9M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
60.9M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
60.9M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
60.9M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
60.9M
   (*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
60.9M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
60.9M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
60.9M
#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
60.9M
#define YMULT_QUO(ys, tl)\
228
60.9M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
60.9M
   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
60.9M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
60.9M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
60.9M
#endif
264
60.9M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
14.4M
            l.di = 0, l.df = 0;
267
14.4M
            fxl = 0;
268
46.4M
        } else {
269
46.4M
            compute_dx(&l, dxl, ysl);
270
46.4M
            fxl = YMULT_QUO(ysl, l);
271
46.4M
            l.x += fxl;
272
46.4M
        }
273
60.9M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
18.9M
#     if !LINEAR_COLOR
277
18.9M
                if (l.di == 0 && l.df == 0) {
278
7.43M
                    rxl = fixed2int_var(l.x);
279
7.43M
                    rxr = fixed2int_var(r.x);
280
7.43M
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
7.43M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
7.43M
                    goto xit;
283
7.43M
                }
284
11.5M
#     endif
285
11.5M
            r.di = 0, r.df = 0;
286
11.5M
        }
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
41.9M
        else if (dxr == dxl && fxl != 0) {
292
2.75M
            if (l.di == 0)
293
346k
                r.di = 0, r.df = l.df;
294
2.40M
            else
295
2.40M
                compute_dx(&r, dxr, ysr);
296
2.75M
            if (ysr == ysl && r.h == l.h)
297
1.79M
                r.x += fxl;
298
955k
            else
299
955k
                r.x += YMULT_QUO(ysr, r);
300
39.1M
        } else {
301
39.1M
            compute_dx(&r, dxr, ysr);
302
39.1M
            r.x += YMULT_QUO(ysr, r);
303
39.1M
        }
304
        /* Compute one line's worth of dx/dy. */
305
53.5M
        compute_ldx(&l, ysl);
306
53.5M
        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
53.5M
        l.x += fixed_epsilon;
310
53.5M
        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
53.5M
#define rational_floor(tl)\
338
53.5M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
53.5M
#define STEP_LINE(ix, tl)\
340
53.5M
  tl.x += tl.ldi;\
341
53.5M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
53.5M
  ix = rational_floor(tl)
343
344
53.5M
        rxl = rational_floor(l);
345
53.5M
        rxr = rational_floor(r);
346
53.5M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
1.70G
        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
1.64G
                register int ixl, ixr;
365
366
1.64G
                STEP_LINE(ixl, l);
367
1.64G
                STEP_LINE(ixr, r);
368
1.64G
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
1.64G
                if (ixl != rxl || ixr != rxr) {
370
1.21G
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
1.21G
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
1.21G
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
1.21G
                    if (code < 0)
374
0
                        goto xit;
375
1.21G
                    rxl = ixl, rxr = ixr, ry = iy;
376
1.21G
                }
377
1.64G
#     endif
378
1.64G
        }
379
53.5M
# if !LINEAR_COLOR
380
53.5M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
53.5M
#undef STEP_LINE
385
53.5M
#undef SET_MINIMAL_WIDTH
386
53.5M
#undef CONNECT_RECTANGLES
387
53.5M
#undef FILL_TRAP_RECT
388
53.5M
#undef FILL_TRAP_RECT_DIRECT
389
53.5M
#undef FILL_TRAP_RECT_INRECT
390
53.5M
#undef YMULT_QUO
391
60.9M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
60.9M
        return_if_interrupt(dev->memory);
394
60.9M
        return code;
395
60.9M
    }
396
60.9M
}
gdevddrw.c:gx_fill_trapezoid_as_lc
Line
Count
Source
137
3.13M
{
138
3.13M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
3.13M
    const fixed ymax = fixed_pixround(ytop);
140
141
3.13M
    if (ymin >= ymax)
142
425k
        return 0;    /* no scan lines to sample */
143
2.70M
    {
144
2.70M
        int iy = fixed2int_var(ymin);
145
2.70M
        const int iy1 = fixed2int_var(ymax);
146
2.70M
        trap_line l, r;
147
2.70M
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
2.70M
        const fixed
152
2.70M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
2.70M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
2.70M
        const fixed /* partial pixel offset to first line to sample */
155
2.70M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
2.70M
        fixed fxl;
157
2.70M
        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
2.70M
# if LINEAR_COLOR
165
2.70M
            int num_components = dev->color_info.num_components;
166
2.70M
            frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
2.70M
            int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
2.70M
            int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
2.70M
            frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
170
2.70M
            int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
171
2.70M
            int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
172
2.70M
            frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
173
2.70M
            int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
174
2.70M
            int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
175
2.70M
            trap_gradient lg, rg, xg;
176
# else
177
            gx_color_index cindex = pdevc->colors.pure;
178
            dev_proc_fill_rectangle((*fill_rect)) =
179
                dev_proc(dev, fill_rectangle);
180
# endif
181
182
2.70M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
2.70M
        l.h = left->end.y - left->start.y;
185
2.70M
        if (l.h == 0)
186
0
           return 0;
187
2.70M
        r.h = right->end.y - right->start.y;
188
2.70M
        if (r.h == 0)
189
0
           return 0;
190
2.70M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
2.70M
        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
2.70M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
2.70M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
2.70M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
2.70M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
2.70M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
2.70M
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
2.70M
#if LINEAR_COLOR
210
2.70M
#   define FILL_TRAP_RECT(x,y,w,h)\
211
2.70M
        (!(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
        (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
2.70M
#define YMULT_QUO(ys, tl)\
228
2.70M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
2.70M
   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
2.70M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
2.70M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
2.70M
#endif
264
2.70M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
1.42M
            l.di = 0, l.df = 0;
267
1.42M
            fxl = 0;
268
1.42M
        } else {
269
1.27M
            compute_dx(&l, dxl, ysl);
270
1.27M
            fxl = YMULT_QUO(ysl, l);
271
1.27M
            l.x += fxl;
272
1.27M
        }
273
2.70M
        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
                if (l.di == 0 && l.df == 0) {
278
                    rxl = fixed2int_var(l.x);
279
                    rxr = fixed2int_var(r.x);
280
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
                    goto xit;
283
                }
284
#     endif
285
1.42M
            r.di = 0, r.df = 0;
286
1.42M
        }
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
1.27M
        else if (dxr == dxl && fxl != 0) {
292
834k
            if (l.di == 0)
293
220k
                r.di = 0, r.df = l.df;
294
613k
            else
295
613k
                compute_dx(&r, dxr, ysr);
296
834k
            if (ysr == ysl && r.h == l.h)
297
834k
                r.x += fxl;
298
113
            else
299
113
                r.x += YMULT_QUO(ysr, r);
300
834k
        } else {
301
444k
            compute_dx(&r, dxr, ysr);
302
444k
            r.x += YMULT_QUO(ysr, r);
303
444k
        }
304
        /* Compute one line's worth of dx/dy. */
305
2.70M
        compute_ldx(&l, ysl);
306
2.70M
        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
2.70M
        l.x += fixed_epsilon;
310
2.70M
        r.x += fixed_epsilon;
311
2.70M
# 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
2.70M
            lg.c = lgc;
320
2.70M
            lg.f = lgf;
321
2.70M
            lg.num = lgnum;
322
2.70M
            rg.c = rgc;
323
2.70M
            rg.f = rgf;
324
2.70M
            rg.num = rgnum;
325
2.70M
            xg.c = xgc;
326
2.70M
            xg.f = xgf;
327
2.70M
            xg.num = xgnum;
328
2.70M
            code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
329
2.70M
            if (code < 0)
330
0
                return code;
331
2.70M
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
2.70M
            if (code < 0)
333
0
                return code;
334
335
2.70M
# endif
336
337
2.70M
#define rational_floor(tl)\
338
2.70M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
2.70M
#define STEP_LINE(ix, tl)\
340
2.70M
  tl.x += tl.ldi;\
341
2.70M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
2.70M
  ix = rational_floor(tl)
343
344
2.70M
        rxl = rational_floor(l);
345
2.70M
        rxr = rational_floor(r);
346
2.70M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
63.1M
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
63.1M
#     if LINEAR_COLOR
349
63.1M
                if (rxl != rxr) {
350
41.9M
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
41.9M
                    if (code < 0)
352
0
                        goto xit;
353
41.9M
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
41.9M
                    if (code < 0)
355
4
                        goto xit;
356
41.9M
                }
357
63.1M
                if (++iy == iy1)
358
2.70M
                    break;
359
60.4M
                STEP_LINE(rxl, l);
360
60.4M
                STEP_LINE(rxr, r);
361
60.4M
                step_gradient(&lg, num_components);
362
60.4M
                step_gradient(&rg, num_components);
363
#     else
364
                register int ixl, ixr;
365
366
                STEP_LINE(ixl, l);
367
                STEP_LINE(ixr, r);
368
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
                if (ixl != rxl || ixr != rxr) {
370
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
                    if (code < 0)
374
                        goto xit;
375
                    rxl = ixl, rxr = ixr, ry = iy;
376
                }
377
#     endif
378
60.4M
        }
379
# if !LINEAR_COLOR
380
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
2.70M
            code = 0;
383
2.70M
# endif
384
2.70M
#undef STEP_LINE
385
2.70M
#undef SET_MINIMAL_WIDTH
386
2.70M
#undef CONNECT_RECTANGLES
387
2.70M
#undef FILL_TRAP_RECT
388
2.70M
#undef FILL_TRAP_RECT_DIRECT
389
2.70M
#undef FILL_TRAP_RECT_INRECT
390
2.70M
#undef YMULT_QUO
391
2.70M
xit:  if (code < 0 && FILL_DIRECT)
392
4
            return_error(code);
393
2.70M
        return_if_interrupt(dev->memory);
394
2.70M
        return code;
395
2.70M
    }
396
2.70M
}
gdevddrw.c:gx_fill_trapezoid_ns_lc
Line
Count
Source
137
73.7M
{
138
73.7M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
73.7M
    const fixed ymax = fixed_pixround(ytop);
140
141
73.7M
    if (ymin >= ymax)
142
29.6M
        return 0;    /* no scan lines to sample */
143
44.1M
    {
144
44.1M
        int iy = fixed2int_var(ymin);
145
44.1M
        const int iy1 = fixed2int_var(ymax);
146
44.1M
        trap_line l, r;
147
44.1M
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
44.1M
        const fixed
152
44.1M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
44.1M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
44.1M
        const fixed /* partial pixel offset to first line to sample */
155
44.1M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
44.1M
        fixed fxl;
157
44.1M
        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
44.1M
# if LINEAR_COLOR
165
44.1M
            int num_components = dev->color_info.num_components;
166
44.1M
            frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
44.1M
            int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
44.1M
            int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
44.1M
            frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
170
44.1M
            int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
171
44.1M
            int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
172
44.1M
            frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
173
44.1M
            int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
174
44.1M
            int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
175
44.1M
            trap_gradient lg, rg, xg;
176
# else
177
            gx_color_index cindex = pdevc->colors.pure;
178
            dev_proc_fill_rectangle((*fill_rect)) =
179
                dev_proc(dev, fill_rectangle);
180
# endif
181
182
44.1M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
44.1M
        l.h = left->end.y - left->start.y;
185
44.1M
        if (l.h == 0)
186
0
           return 0;
187
44.1M
        r.h = right->end.y - right->start.y;
188
44.1M
        if (r.h == 0)
189
0
           return 0;
190
44.1M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
44.1M
        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
44.1M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
44.1M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
44.1M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
44.1M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
44.1M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
44.1M
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
44.1M
#if LINEAR_COLOR
210
44.1M
#   define FILL_TRAP_RECT(x,y,w,h)\
211
44.1M
        (!(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
        (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
44.1M
#define YMULT_QUO(ys, tl)\
228
44.1M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
44.1M
   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
44.1M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
44.1M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
44.1M
#endif
264
44.1M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
9.48M
            l.di = 0, l.df = 0;
267
9.48M
            fxl = 0;
268
34.6M
        } else {
269
34.6M
            compute_dx(&l, dxl, ysl);
270
34.6M
            fxl = YMULT_QUO(ysl, l);
271
34.6M
            l.x += fxl;
272
34.6M
        }
273
44.1M
        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
                if (l.di == 0 && l.df == 0) {
278
                    rxl = fixed2int_var(l.x);
279
                    rxr = fixed2int_var(r.x);
280
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
                    goto xit;
283
                }
284
#     endif
285
9.44M
            r.di = 0, r.df = 0;
286
9.44M
        }
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
34.7M
        else if (dxr == dxl && fxl != 0) {
292
2.39M
            if (l.di == 0)
293
947k
                r.di = 0, r.df = l.df;
294
1.44M
            else
295
1.44M
                compute_dx(&r, dxr, ysr);
296
2.39M
            if (ysr == ysl && r.h == l.h)
297
1.64M
                r.x += fxl;
298
744k
            else
299
744k
                r.x += YMULT_QUO(ysr, r);
300
32.3M
        } else {
301
32.3M
            compute_dx(&r, dxr, ysr);
302
32.3M
            r.x += YMULT_QUO(ysr, r);
303
32.3M
        }
304
        /* Compute one line's worth of dx/dy. */
305
44.1M
        compute_ldx(&l, ysl);
306
44.1M
        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
44.1M
        l.x += fixed_epsilon;
310
44.1M
        r.x += fixed_epsilon;
311
44.1M
# 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
44.1M
            lg.c = lgc;
320
44.1M
            lg.f = lgf;
321
44.1M
            lg.num = lgnum;
322
44.1M
            rg.c = rgc;
323
44.1M
            rg.f = rgf;
324
44.1M
            rg.num = rgnum;
325
44.1M
            xg.c = xgc;
326
44.1M
            xg.f = xgf;
327
44.1M
            xg.num = xgnum;
328
44.1M
            code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
329
44.1M
            if (code < 0)
330
0
                return code;
331
44.1M
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
44.1M
            if (code < 0)
333
0
                return code;
334
335
44.1M
# endif
336
337
44.1M
#define rational_floor(tl)\
338
44.1M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
44.1M
#define STEP_LINE(ix, tl)\
340
44.1M
  tl.x += tl.ldi;\
341
44.1M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
44.1M
  ix = rational_floor(tl)
343
344
44.1M
        rxl = rational_floor(l);
345
44.1M
        rxr = rational_floor(r);
346
44.1M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
442M
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
442M
#     if LINEAR_COLOR
349
442M
                if (rxl != rxr) {
350
89.0M
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
89.0M
                    if (code < 0)
352
0
                        goto xit;
353
89.0M
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
89.0M
                    if (code < 0)
355
13
                        goto xit;
356
89.0M
                }
357
442M
                if (++iy == iy1)
358
44.1M
                    break;
359
398M
                STEP_LINE(rxl, l);
360
398M
                STEP_LINE(rxr, r);
361
398M
                step_gradient(&lg, num_components);
362
398M
                step_gradient(&rg, num_components);
363
#     else
364
                register int ixl, ixr;
365
366
                STEP_LINE(ixl, l);
367
                STEP_LINE(ixr, r);
368
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
                if (ixl != rxl || ixr != rxr) {
370
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
                    if (code < 0)
374
                        goto xit;
375
                    rxl = ixl, rxr = ixr, ry = iy;
376
                }
377
#     endif
378
398M
        }
379
# if !LINEAR_COLOR
380
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
44.1M
            code = 0;
383
44.1M
# endif
384
44.1M
#undef STEP_LINE
385
44.1M
#undef SET_MINIMAL_WIDTH
386
44.1M
#undef CONNECT_RECTANGLES
387
44.1M
#undef FILL_TRAP_RECT
388
44.1M
#undef FILL_TRAP_RECT_DIRECT
389
44.1M
#undef FILL_TRAP_RECT_INRECT
390
44.1M
#undef YMULT_QUO
391
44.1M
xit:  if (code < 0 && FILL_DIRECT)
392
13
            return_error(code);
393
44.1M
        return_if_interrupt(dev->memory);
394
44.1M
        return code;
395
44.1M
    }
396
44.1M
}
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