Coverage Report

Created: 2025-06-10 06:58

/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
13.9M
{
138
13.9M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
13.9M
    const fixed ymax = fixed_pixround(ytop);
140
141
13.9M
    if (ymin >= ymax)
142
4.13M
        return 0;    /* no scan lines to sample */
143
9.85M
    {
144
9.85M
        int iy = fixed2int_var(ymin);
145
9.85M
        const int iy1 = fixed2int_var(ymax);
146
9.85M
        trap_line l, r;
147
9.85M
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
9.85M
        const fixed
152
9.85M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
9.85M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
9.85M
        const fixed /* partial pixel offset to first line to sample */
155
9.85M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
9.85M
        fixed fxl;
157
9.85M
        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
9.35M
            dev_proc_fill_rectangle((*fill_rect)) =
179
9.35M
                dev_proc(dev, fill_rectangle);
180
# endif
181
182
9.85M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
9.85M
        l.h = left->end.y - left->start.y;
185
9.85M
        if (l.h == 0)
186
0
           return 0;
187
9.85M
        r.h = right->end.y - right->start.y;
188
9.85M
        if (r.h == 0)
189
0
           return 0;
190
9.85M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
9.85M
        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
9.85M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
115M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
115M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
9.85M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
9.85M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
3.22M
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
#if LINEAR_COLOR
210
#   define FILL_TRAP_RECT(x,y,w,h)\
211
1.53M
        (!(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
118M
        (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
9.85M
#define YMULT_QUO(ys, tl)\
228
12.5M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
12.5M
   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
142M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
218M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
#endif
264
9.85M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
2.77M
            l.di = 0, l.df = 0;
267
2.77M
            fxl = 0;
268
7.08M
        } else {
269
7.08M
            compute_dx(&l, dxl, ysl);
270
7.08M
            fxl = YMULT_QUO(ysl, l);
271
7.08M
            l.x += fxl;
272
7.08M
        }
273
9.85M
        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
4.03M
                if (l.di == 0 && l.df == 0) {
278
881k
                    rxl = fixed2int_var(l.x);
279
881k
                    rxr = fixed2int_var(r.x);
280
881k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
881k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
881k
                    goto xit;
283
881k
                }
284
3.15M
#     endif
285
3.15M
            r.di = 0, r.df = 0;
286
3.15M
        }
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
5.69M
        else if (dxr == dxl && fxl != 0) {
292
342k
            if (l.di == 0)
293
88.4k
                r.di = 0, r.df = l.df;
294
253k
            else
295
253k
                compute_dx(&r, dxr, ysr);
296
342k
            if (ysr == ysl && r.h == l.h)
297
221k
                r.x += fxl;
298
120k
            else
299
120k
                r.x += YMULT_QUO(ysr, r);
300
5.34M
        } else {
301
5.34M
            compute_dx(&r, dxr, ysr);
302
5.34M
            r.x += YMULT_QUO(ysr, r);
303
5.34M
        }
304
        /* Compute one line's worth of dx/dy. */
305
8.47M
        compute_ldx(&l, ysl);
306
8.47M
        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
8.97M
        l.x += fixed_epsilon;
310
8.97M
        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
505k
            if (code < 0)
330
0
                return code;
331
505k
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
505k
            if (code < 0)
333
0
                return code;
334
335
505k
# endif
336
337
505k
#define rational_floor(tl)\
338
290M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
505k
#define STEP_LINE(ix, tl)\
340
271M
  tl.x += tl.ldi;\
341
271M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
272M
  ix = rational_floor(tl)
343
344
8.97M
        rxl = rational_floor(l);
345
8.97M
        rxr = rational_floor(r);
346
8.97M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
144M
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
#     if LINEAR_COLOR
349
4.02M
                if (rxl != rxr) {
350
1.53M
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
1.53M
                    if (code < 0)
352
0
                        goto xit;
353
1.53M
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
1.53M
                    if (code < 0)
355
0
                        goto xit;
356
1.53M
                }
357
4.02M
                if (++iy == iy1)
358
505k
                    break;
359
3.52M
                STEP_LINE(rxl, l);
360
3.52M
                STEP_LINE(rxr, r);
361
3.52M
                step_gradient(&lg, num_components);
362
3.52M
                step_gradient(&rg, num_components);
363
#     else
364
                register int ixl, ixr;
365
366
132M
                STEP_LINE(ixl, l);
367
132M
                STEP_LINE(ixr, r);
368
132M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
132M
                if (ixl != rxl || ixr != rxr) {
370
109M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
109M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
109M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
109M
                    if (code < 0)
374
0
                        goto xit;
375
109M
                    rxl = ixl, rxr = ixr, ry = iy;
376
109M
                }
377
#     endif
378
3.52M
        }
379
# if !LINEAR_COLOR
380
8.47M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
505k
            code = 0;
383
505k
# endif
384
505k
#undef STEP_LINE
385
505k
#undef SET_MINIMAL_WIDTH
386
505k
#undef CONNECT_RECTANGLES
387
505k
#undef FILL_TRAP_RECT
388
505k
#undef FILL_TRAP_RECT_DIRECT
389
505k
#undef FILL_TRAP_RECT_INRECT
390
505k
#undef YMULT_QUO
391
9.85M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
9.85M
        return_if_interrupt(dev->memory);
394
9.85M
        return code;
395
9.85M
    }
396
9.85M
}
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
23.3k
{
138
23.3k
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
23.3k
    const fixed ymax = fixed_pixround(ytop);
140
141
23.3k
    if (ymin >= ymax)
142
92
        return 0;    /* no scan lines to sample */
143
23.2k
    {
144
23.2k
        int iy = fixed2int_var(ymin);
145
23.2k
        const int iy1 = fixed2int_var(ymax);
146
23.2k
        trap_line l, r;
147
23.2k
        register int rxl, rxr;
148
23.2k
#if !LINEAR_COLOR
149
23.2k
        int ry;
150
23.2k
#endif
151
23.2k
        const fixed
152
23.2k
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
23.2k
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
23.2k
        const fixed /* partial pixel offset to first line to sample */
155
23.2k
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
23.2k
        fixed fxl;
157
23.2k
        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
23.2k
            gx_color_index cindex = pdevc->colors.pure;
178
23.2k
            dev_proc_fill_rectangle((*fill_rect)) =
179
23.2k
                dev_proc(dev, fill_rectangle);
180
23.2k
# endif
181
182
23.2k
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
23.2k
        l.h = left->end.y - left->start.y;
185
23.2k
        if (l.h == 0)
186
0
           return 0;
187
23.2k
        r.h = right->end.y - right->start.y;
188
23.2k
        if (r.h == 0)
189
0
           return 0;
190
23.2k
        l.x = x0l + (fixed_half - fixed_epsilon);
191
23.2k
        r.x = x0r + (fixed_half - fixed_epsilon);
192
23.2k
#if !LINEAR_COLOR
193
23.2k
        ry = iy;
194
23.2k
#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
23.2k
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
23.2k
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
23.2k
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
23.2k
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
23.2k
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
23.2k
   (*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
23.2k
#   define FILL_TRAP_RECT(x,y,w,h)\
214
23.2k
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
23.2k
#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
23.2k
#define YMULT_QUO(ys, tl)\
228
23.2k
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
23.2k
   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
23.2k
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
23.2k
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
23.2k
#endif
264
23.2k
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
1.42k
            l.di = 0, l.df = 0;
267
1.42k
            fxl = 0;
268
21.8k
        } else {
269
21.8k
            compute_dx(&l, dxl, ysl);
270
21.8k
            fxl = YMULT_QUO(ysl, l);
271
21.8k
            l.x += fxl;
272
21.8k
        }
273
23.2k
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
1.20k
#     if !LINEAR_COLOR
277
1.20k
                if (l.di == 0 && l.df == 0) {
278
1.14k
                    rxl = fixed2int_var(l.x);
279
1.14k
                    rxr = fixed2int_var(r.x);
280
1.14k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
1.14k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
1.14k
                    goto xit;
283
1.14k
                }
284
64
#     endif
285
64
            r.di = 0, r.df = 0;
286
64
        }
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.0k
        else if (dxr == dxl && fxl != 0) {
292
4.05k
            if (l.di == 0)
293
2.93k
                r.di = 0, r.df = l.df;
294
1.11k
            else
295
1.11k
                compute_dx(&r, dxr, ysr);
296
4.05k
            if (ysr == ysl && r.h == l.h)
297
4.05k
                r.x += fxl;
298
0
            else
299
0
                r.x += YMULT_QUO(ysr, r);
300
17.9k
        } else {
301
17.9k
            compute_dx(&r, dxr, ysr);
302
17.9k
            r.x += YMULT_QUO(ysr, r);
303
17.9k
        }
304
        /* Compute one line's worth of dx/dy. */
305
22.1k
        compute_ldx(&l, ysl);
306
22.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
22.1k
        l.x += fixed_epsilon;
310
22.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
22.1k
#define rational_floor(tl)\
338
22.1k
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
22.1k
#define STEP_LINE(ix, tl)\
340
22.1k
  tl.x += tl.ldi;\
341
22.1k
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
22.1k
  ix = rational_floor(tl)
343
344
22.1k
        rxl = rational_floor(l);
345
22.1k
        rxr = rational_floor(r);
346
22.1k
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
2.15M
        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.13M
                register int ixl, ixr;
365
366
2.13M
                STEP_LINE(ixl, l);
367
2.13M
                STEP_LINE(ixr, r);
368
2.13M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
2.13M
                if (ixl != rxl || ixr != rxr) {
370
719k
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
719k
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
719k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
719k
                    if (code < 0)
374
0
                        goto xit;
375
719k
                    rxl = ixl, rxr = ixr, ry = iy;
376
719k
                }
377
2.13M
#     endif
378
2.13M
        }
379
22.1k
# if !LINEAR_COLOR
380
22.1k
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
22.1k
#undef STEP_LINE
385
22.1k
#undef SET_MINIMAL_WIDTH
386
22.1k
#undef CONNECT_RECTANGLES
387
22.1k
#undef FILL_TRAP_RECT
388
22.1k
#undef FILL_TRAP_RECT_DIRECT
389
22.1k
#undef FILL_TRAP_RECT_INRECT
390
22.1k
#undef YMULT_QUO
391
23.2k
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
23.2k
        return_if_interrupt(dev->memory);
394
23.2k
        return code;
395
23.2k
    }
396
23.2k
}
gdevddrw.c:gx_fill_trapezoid_as_nd
Line
Count
Source
137
573k
{
138
573k
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
573k
    const fixed ymax = fixed_pixround(ytop);
140
141
573k
    if (ymin >= ymax)
142
5.97k
        return 0;    /* no scan lines to sample */
143
567k
    {
144
567k
        int iy = fixed2int_var(ymin);
145
567k
        const int iy1 = fixed2int_var(ymax);
146
567k
        trap_line l, r;
147
567k
        register int rxl, rxr;
148
567k
#if !LINEAR_COLOR
149
567k
        int ry;
150
567k
#endif
151
567k
        const fixed
152
567k
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
567k
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
567k
        const fixed /* partial pixel offset to first line to sample */
155
567k
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
567k
        fixed fxl;
157
567k
        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
567k
            gx_color_index cindex = pdevc->colors.pure;
178
567k
            dev_proc_fill_rectangle((*fill_rect)) =
179
567k
                dev_proc(dev, fill_rectangle);
180
567k
# endif
181
182
567k
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
567k
        l.h = left->end.y - left->start.y;
185
567k
        if (l.h == 0)
186
0
           return 0;
187
567k
        r.h = right->end.y - right->start.y;
188
567k
        if (r.h == 0)
189
0
           return 0;
190
567k
        l.x = x0l + (fixed_half - fixed_epsilon);
191
567k
        r.x = x0r + (fixed_half - fixed_epsilon);
192
567k
#if !LINEAR_COLOR
193
567k
        ry = iy;
194
567k
#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
567k
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
567k
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
567k
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
567k
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
567k
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
567k
   (*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
567k
#   define FILL_TRAP_RECT(x,y,w,h)\
214
567k
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
567k
#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
567k
#define YMULT_QUO(ys, tl)\
228
567k
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
567k
   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
567k
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
567k
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
567k
#endif
264
567k
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
66.7k
            l.di = 0, l.df = 0;
267
66.7k
            fxl = 0;
268
501k
        } else {
269
501k
            compute_dx(&l, dxl, ysl);
270
501k
            fxl = YMULT_QUO(ysl, l);
271
501k
            l.x += fxl;
272
501k
        }
273
567k
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
59.6k
#     if !LINEAR_COLOR
277
59.6k
                if (l.di == 0 && l.df == 0) {
278
55.6k
                    rxl = fixed2int_var(l.x);
279
55.6k
                    rxr = fixed2int_var(r.x);
280
55.6k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
55.6k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
55.6k
                    goto xit;
283
55.6k
                }
284
3.97k
#     endif
285
3.97k
            r.di = 0, r.df = 0;
286
3.97k
        }
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
508k
        else if (dxr == dxl && fxl != 0) {
292
86.2k
            if (l.di == 0)
293
63.4k
                r.di = 0, r.df = l.df;
294
22.8k
            else
295
22.8k
                compute_dx(&r, dxr, ysr);
296
86.2k
            if (ysr == ysl && r.h == l.h)
297
86.2k
                r.x += fxl;
298
11
            else
299
11
                r.x += YMULT_QUO(ysr, r);
300
422k
        } else {
301
422k
            compute_dx(&r, dxr, ysr);
302
422k
            r.x += YMULT_QUO(ysr, r);
303
422k
        }
304
        /* Compute one line's worth of dx/dy. */
305
512k
        compute_ldx(&l, ysl);
306
512k
        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
512k
        l.x += fixed_epsilon;
310
512k
        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
512k
#define rational_floor(tl)\
338
512k
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
512k
#define STEP_LINE(ix, tl)\
340
512k
  tl.x += tl.ldi;\
341
512k
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
512k
  ix = rational_floor(tl)
343
344
512k
        rxl = rational_floor(l);
345
512k
        rxr = rational_floor(r);
346
512k
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
35.0M
        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
34.5M
                register int ixl, ixr;
365
366
34.5M
                STEP_LINE(ixl, l);
367
34.5M
                STEP_LINE(ixr, r);
368
34.5M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
34.5M
                if (ixl != rxl || ixr != rxr) {
370
23.9M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
23.9M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
23.9M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
23.9M
                    if (code < 0)
374
0
                        goto xit;
375
23.9M
                    rxl = ixl, rxr = ixr, ry = iy;
376
23.9M
                }
377
34.5M
#     endif
378
34.5M
        }
379
512k
# if !LINEAR_COLOR
380
512k
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
512k
#undef STEP_LINE
385
512k
#undef SET_MINIMAL_WIDTH
386
512k
#undef CONNECT_RECTANGLES
387
512k
#undef FILL_TRAP_RECT
388
512k
#undef FILL_TRAP_RECT_DIRECT
389
512k
#undef FILL_TRAP_RECT_INRECT
390
512k
#undef YMULT_QUO
391
567k
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
567k
        return_if_interrupt(dev->memory);
394
567k
        return code;
395
567k
    }
396
567k
}
gdevddrw.c:gx_fill_trapezoid_ns_fd
Line
Count
Source
137
1.17M
{
138
1.17M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
1.17M
    const fixed ymax = fixed_pixround(ytop);
140
141
1.17M
    if (ymin >= ymax)
142
114k
        return 0;    /* no scan lines to sample */
143
1.06M
    {
144
1.06M
        int iy = fixed2int_var(ymin);
145
1.06M
        const int iy1 = fixed2int_var(ymax);
146
1.06M
        trap_line l, r;
147
1.06M
        register int rxl, rxr;
148
1.06M
#if !LINEAR_COLOR
149
1.06M
        int ry;
150
1.06M
#endif
151
1.06M
        const fixed
152
1.06M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
1.06M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
1.06M
        const fixed /* partial pixel offset to first line to sample */
155
1.06M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
1.06M
        fixed fxl;
157
1.06M
        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
1.06M
            gx_color_index cindex = pdevc->colors.pure;
178
1.06M
            dev_proc_fill_rectangle((*fill_rect)) =
179
1.06M
                dev_proc(dev, fill_rectangle);
180
1.06M
# endif
181
182
1.06M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
1.06M
        l.h = left->end.y - left->start.y;
185
1.06M
        if (l.h == 0)
186
0
           return 0;
187
1.06M
        r.h = right->end.y - right->start.y;
188
1.06M
        if (r.h == 0)
189
0
           return 0;
190
1.06M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
1.06M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
1.06M
#if !LINEAR_COLOR
193
1.06M
        ry = iy;
194
1.06M
#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
1.06M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
1.06M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
1.06M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
1.06M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
1.06M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
1.06M
   (*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
1.06M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
1.06M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
1.06M
#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
1.06M
#define YMULT_QUO(ys, tl)\
228
1.06M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
1.06M
   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
1.06M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
1.06M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
1.06M
#endif
264
1.06M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
374k
            l.di = 0, l.df = 0;
267
374k
            fxl = 0;
268
691k
        } else {
269
691k
            compute_dx(&l, dxl, ysl);
270
691k
            fxl = YMULT_QUO(ysl, l);
271
691k
            l.x += fxl;
272
691k
        }
273
1.06M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
426k
#     if !LINEAR_COLOR
277
426k
                if (l.di == 0 && l.df == 0) {
278
103k
                    rxl = fixed2int_var(l.x);
279
103k
                    rxr = fixed2int_var(r.x);
280
103k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
103k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
103k
                    goto xit;
283
103k
                }
284
323k
#     endif
285
323k
            r.di = 0, r.df = 0;
286
323k
        }
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
638k
        else if (dxr == dxl && fxl != 0) {
292
9.18k
            if (l.di == 0)
293
1.25k
                r.di = 0, r.df = l.df;
294
7.92k
            else
295
7.92k
                compute_dx(&r, dxr, ysr);
296
9.18k
            if (ysr == ysl && r.h == l.h)
297
3.20k
                r.x += fxl;
298
5.98k
            else
299
5.98k
                r.x += YMULT_QUO(ysr, r);
300
629k
        } else {
301
629k
            compute_dx(&r, dxr, ysr);
302
629k
            r.x += YMULT_QUO(ysr, r);
303
629k
        }
304
        /* Compute one line's worth of dx/dy. */
305
961k
        compute_ldx(&l, ysl);
306
961k
        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
961k
        l.x += fixed_epsilon;
310
961k
        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
961k
#define rational_floor(tl)\
338
961k
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
961k
#define STEP_LINE(ix, tl)\
340
961k
  tl.x += tl.ldi;\
341
961k
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
961k
  ix = rational_floor(tl)
343
344
961k
        rxl = rational_floor(l);
345
961k
        rxr = rational_floor(r);
346
961k
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
3.28M
        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.32M
                register int ixl, ixr;
365
366
2.32M
                STEP_LINE(ixl, l);
367
2.32M
                STEP_LINE(ixr, r);
368
2.32M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
2.32M
                if (ixl != rxl || ixr != rxr) {
370
1.41M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
1.41M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
1.41M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
1.41M
                    if (code < 0)
374
0
                        goto xit;
375
1.41M
                    rxl = ixl, rxr = ixr, ry = iy;
376
1.41M
                }
377
2.32M
#     endif
378
2.32M
        }
379
961k
# if !LINEAR_COLOR
380
961k
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
961k
#undef STEP_LINE
385
961k
#undef SET_MINIMAL_WIDTH
386
961k
#undef CONNECT_RECTANGLES
387
961k
#undef FILL_TRAP_RECT
388
961k
#undef FILL_TRAP_RECT_DIRECT
389
961k
#undef FILL_TRAP_RECT_INRECT
390
961k
#undef YMULT_QUO
391
1.06M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
1.06M
        return_if_interrupt(dev->memory);
394
1.06M
        return code;
395
1.06M
    }
396
1.06M
}
gdevddrw.c:gx_fill_trapezoid_ns_nd
Line
Count
Source
137
11.3M
{
138
11.3M
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
11.3M
    const fixed ymax = fixed_pixround(ytop);
140
141
11.3M
    if (ymin >= ymax)
142
3.63M
        return 0;    /* no scan lines to sample */
143
7.69M
    {
144
7.69M
        int iy = fixed2int_var(ymin);
145
7.69M
        const int iy1 = fixed2int_var(ymax);
146
7.69M
        trap_line l, r;
147
7.69M
        register int rxl, rxr;
148
7.69M
#if !LINEAR_COLOR
149
7.69M
        int ry;
150
7.69M
#endif
151
7.69M
        const fixed
152
7.69M
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
7.69M
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
7.69M
        const fixed /* partial pixel offset to first line to sample */
155
7.69M
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
7.69M
        fixed fxl;
157
7.69M
        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
7.69M
            gx_color_index cindex = pdevc->colors.pure;
178
7.69M
            dev_proc_fill_rectangle((*fill_rect)) =
179
7.69M
                dev_proc(dev, fill_rectangle);
180
7.69M
# endif
181
182
7.69M
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
7.69M
        l.h = left->end.y - left->start.y;
185
7.69M
        if (l.h == 0)
186
0
           return 0;
187
7.69M
        r.h = right->end.y - right->start.y;
188
7.69M
        if (r.h == 0)
189
0
           return 0;
190
7.69M
        l.x = x0l + (fixed_half - fixed_epsilon);
191
7.69M
        r.x = x0r + (fixed_half - fixed_epsilon);
192
7.69M
#if !LINEAR_COLOR
193
7.69M
        ry = iy;
194
7.69M
#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
7.69M
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
7.69M
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
7.69M
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
7.69M
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
7.69M
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
7.69M
   (*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
7.69M
#   define FILL_TRAP_RECT(x,y,w,h)\
214
7.69M
        (FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
215
7.69M
#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
7.69M
#define YMULT_QUO(ys, tl)\
228
7.69M
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
7.69M
   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
7.69M
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
7.69M
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
7.69M
#endif
264
7.69M
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
2.19M
            l.di = 0, l.df = 0;
267
2.19M
            fxl = 0;
268
5.49M
        } else {
269
5.49M
            compute_dx(&l, dxl, ysl);
270
5.49M
            fxl = YMULT_QUO(ysl, l);
271
5.49M
            l.x += fxl;
272
5.49M
        }
273
7.69M
        if (fixed_floor(r.x) == fixed_pixround(x1r)) {
274
            /* Right edge is vertical.  If both are vertical, */
275
            /* we have a rectangle. */
276
3.55M
#     if !LINEAR_COLOR
277
3.55M
                if (l.di == 0 && l.df == 0) {
278
721k
                    rxl = fixed2int_var(l.x);
279
721k
                    rxr = fixed2int_var(r.x);
280
721k
                    SET_MINIMAL_WIDTH(rxl, rxr, l, r);
281
721k
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
282
721k
                    goto xit;
283
721k
                }
284
2.83M
#     endif
285
2.83M
            r.di = 0, r.df = 0;
286
2.83M
        }
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.14M
        else if (dxr == dxl && fxl != 0) {
292
203k
            if (l.di == 0)
293
12.4k
                r.di = 0, r.df = l.df;
294
190k
            else
295
190k
                compute_dx(&r, dxr, ysr);
296
203k
            if (ysr == ysl && r.h == l.h)
297
102k
                r.x += fxl;
298
100k
            else
299
100k
                r.x += YMULT_QUO(ysr, r);
300
3.94M
        } else {
301
3.94M
            compute_dx(&r, dxr, ysr);
302
3.94M
            r.x += YMULT_QUO(ysr, r);
303
3.94M
        }
304
        /* Compute one line's worth of dx/dy. */
305
6.97M
        compute_ldx(&l, ysl);
306
6.97M
        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
6.97M
        l.x += fixed_epsilon;
310
6.97M
        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
6.97M
#define rational_floor(tl)\
338
6.97M
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
6.97M
#define STEP_LINE(ix, tl)\
340
6.97M
  tl.x += tl.ldi;\
341
6.97M
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
6.97M
  ix = rational_floor(tl)
343
344
6.97M
        rxl = rational_floor(l);
345
6.97M
        rxr = rational_floor(r);
346
6.97M
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
100M
        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
93.2M
                register int ixl, ixr;
365
366
93.2M
                STEP_LINE(ixl, l);
367
93.2M
                STEP_LINE(ixr, r);
368
93.2M
                SET_MINIMAL_WIDTH(ixl, ixr, l, r);
369
93.2M
                if (ixl != rxl || ixr != rxr) {
370
83.0M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
371
83.0M
                    CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
372
83.0M
                    code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
373
83.0M
                    if (code < 0)
374
0
                        goto xit;
375
83.0M
                    rxl = ixl, rxr = ixr, ry = iy;
376
83.0M
                }
377
93.2M
#     endif
378
93.2M
        }
379
6.97M
# if !LINEAR_COLOR
380
6.97M
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
            code = 0;
383
# endif
384
6.97M
#undef STEP_LINE
385
6.97M
#undef SET_MINIMAL_WIDTH
386
6.97M
#undef CONNECT_RECTANGLES
387
6.97M
#undef FILL_TRAP_RECT
388
6.97M
#undef FILL_TRAP_RECT_DIRECT
389
6.97M
#undef FILL_TRAP_RECT_INRECT
390
6.97M
#undef YMULT_QUO
391
7.69M
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
7.69M
        return_if_interrupt(dev->memory);
394
7.69M
        return code;
395
7.69M
    }
396
7.69M
}
gdevddrw.c:gx_fill_trapezoid_as_lc
Line
Count
Source
137
32.9k
{
138
32.9k
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
32.9k
    const fixed ymax = fixed_pixround(ytop);
140
141
32.9k
    if (ymin >= ymax)
142
800
        return 0;    /* no scan lines to sample */
143
32.1k
    {
144
32.1k
        int iy = fixed2int_var(ymin);
145
32.1k
        const int iy1 = fixed2int_var(ymax);
146
32.1k
        trap_line l, r;
147
32.1k
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
32.1k
        const fixed
152
32.1k
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
32.1k
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
32.1k
        const fixed /* partial pixel offset to first line to sample */
155
32.1k
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
32.1k
        fixed fxl;
157
32.1k
        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
32.1k
# if LINEAR_COLOR
165
32.1k
            int num_components = dev->color_info.num_components;
166
32.1k
            frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
32.1k
            int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
32.1k
            int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
32.1k
            frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
170
32.1k
            int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
171
32.1k
            int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
172
32.1k
            frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
173
32.1k
            int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
174
32.1k
            int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
175
32.1k
            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
32.1k
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
32.1k
        l.h = left->end.y - left->start.y;
185
32.1k
        if (l.h == 0)
186
0
           return 0;
187
32.1k
        r.h = right->end.y - right->start.y;
188
32.1k
        if (r.h == 0)
189
0
           return 0;
190
32.1k
        l.x = x0l + (fixed_half - fixed_epsilon);
191
32.1k
        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
32.1k
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
32.1k
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
32.1k
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
32.1k
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
32.1k
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
32.1k
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
32.1k
#if LINEAR_COLOR
210
32.1k
#   define FILL_TRAP_RECT(x,y,w,h)\
211
32.1k
        (!(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
32.1k
#define YMULT_QUO(ys, tl)\
228
32.1k
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
32.1k
   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
32.1k
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
32.1k
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
32.1k
#endif
264
32.1k
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
18.8k
            l.di = 0, l.df = 0;
267
18.8k
            fxl = 0;
268
18.8k
        } else {
269
13.2k
            compute_dx(&l, dxl, ysl);
270
13.2k
            fxl = YMULT_QUO(ysl, l);
271
13.2k
            l.x += fxl;
272
13.2k
        }
273
32.1k
        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
18.4k
            r.di = 0, r.df = 0;
286
18.4k
        }
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
13.6k
        else if (dxr == dxl && fxl != 0) {
292
6.89k
            if (l.di == 0)
293
2.77k
                r.di = 0, r.df = l.df;
294
4.11k
            else
295
4.11k
                compute_dx(&r, dxr, ysr);
296
6.89k
            if (ysr == ysl && r.h == l.h)
297
6.89k
                r.x += fxl;
298
0
            else
299
0
                r.x += YMULT_QUO(ysr, r);
300
6.89k
        } else {
301
6.73k
            compute_dx(&r, dxr, ysr);
302
6.73k
            r.x += YMULT_QUO(ysr, r);
303
6.73k
        }
304
        /* Compute one line's worth of dx/dy. */
305
32.1k
        compute_ldx(&l, ysl);
306
32.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
32.1k
        l.x += fixed_epsilon;
310
32.1k
        r.x += fixed_epsilon;
311
32.1k
# 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
32.1k
            lg.c = lgc;
320
32.1k
            lg.f = lgf;
321
32.1k
            lg.num = lgnum;
322
32.1k
            rg.c = rgc;
323
32.1k
            rg.f = rgf;
324
32.1k
            rg.num = rgnum;
325
32.1k
            xg.c = xgc;
326
32.1k
            xg.f = xgf;
327
32.1k
            xg.num = xgnum;
328
32.1k
            code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
329
32.1k
            if (code < 0)
330
0
                return code;
331
32.1k
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
32.1k
            if (code < 0)
333
0
                return code;
334
335
32.1k
# endif
336
337
32.1k
#define rational_floor(tl)\
338
32.1k
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
32.1k
#define STEP_LINE(ix, tl)\
340
32.1k
  tl.x += tl.ldi;\
341
32.1k
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
32.1k
  ix = rational_floor(tl)
343
344
32.1k
        rxl = rational_floor(l);
345
32.1k
        rxr = rational_floor(r);
346
32.1k
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
402k
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
402k
#     if LINEAR_COLOR
349
402k
                if (rxl != rxr) {
350
368k
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
368k
                    if (code < 0)
352
0
                        goto xit;
353
368k
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
368k
                    if (code < 0)
355
0
                        goto xit;
356
368k
                }
357
402k
                if (++iy == iy1)
358
32.1k
                    break;
359
370k
                STEP_LINE(rxl, l);
360
370k
                STEP_LINE(rxr, r);
361
370k
                step_gradient(&lg, num_components);
362
370k
                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
370k
        }
379
# if !LINEAR_COLOR
380
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
32.1k
            code = 0;
383
32.1k
# endif
384
32.1k
#undef STEP_LINE
385
32.1k
#undef SET_MINIMAL_WIDTH
386
32.1k
#undef CONNECT_RECTANGLES
387
32.1k
#undef FILL_TRAP_RECT
388
32.1k
#undef FILL_TRAP_RECT_DIRECT
389
32.1k
#undef FILL_TRAP_RECT_INRECT
390
32.1k
#undef YMULT_QUO
391
32.1k
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
32.1k
        return_if_interrupt(dev->memory);
394
32.1k
        return code;
395
32.1k
    }
396
32.1k
}
gdevddrw.c:gx_fill_trapezoid_ns_lc
Line
Count
Source
137
849k
{
138
849k
    const fixed ymin = fixed_pixround(ybot) + fixed_half;
139
849k
    const fixed ymax = fixed_pixround(ytop);
140
141
849k
    if (ymin >= ymax)
142
375k
        return 0;    /* no scan lines to sample */
143
473k
    {
144
473k
        int iy = fixed2int_var(ymin);
145
473k
        const int iy1 = fixed2int_var(ymax);
146
473k
        trap_line l, r;
147
473k
        register int rxl, rxr;
148
#if !LINEAR_COLOR
149
        int ry;
150
#endif
151
473k
        const fixed
152
473k
            x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
153
473k
            x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
154
473k
        const fixed /* partial pixel offset to first line to sample */
155
473k
            ysl = ymin - left->start.y, ysr = ymin - right->start.y;
156
473k
        fixed fxl;
157
473k
        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
473k
# if LINEAR_COLOR
165
473k
            int num_components = dev->color_info.num_components;
166
473k
            frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
473k
            int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
473k
            int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
473k
            frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
170
473k
            int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
171
473k
            int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
172
473k
            frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
173
473k
            int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
174
473k
            int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
175
473k
            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
473k
        if_debug2m('z', dev->memory, "[z]y=[%d,%d]\n", iy, iy1);
183
184
473k
        l.h = left->end.y - left->start.y;
185
473k
        if (l.h == 0)
186
0
           return 0;
187
473k
        r.h = right->end.y - right->start.y;
188
473k
        if (r.h == 0)
189
0
           return 0;
190
473k
        l.x = x0l + (fixed_half - fixed_epsilon);
191
473k
        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
473k
#define FILL_TRAP_RECT_INDIRECT(x,y,w,h)\
203
473k
  (SWAP_AXES ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, fa) :\
204
473k
   gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, fa))
205
473k
#define FILL_TRAP_RECT_DIRECT(x,y,w,h)\
206
473k
  (SWAP_AXES ? (*fill_rect)(dev, y, x, h, w, cindex) :\
207
473k
   (*fill_rect)(dev, x, y, w, h, cindex))
208
209
473k
#if LINEAR_COLOR
210
473k
#   define FILL_TRAP_RECT(x,y,w,h)\
211
473k
        (!(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
473k
#define YMULT_QUO(ys, tl)\
228
473k
  (ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
229
473k
   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
473k
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
262
473k
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
263
473k
#endif
264
473k
        if (fixed_floor(l.x) == fixed_pixround(x1l)) {
265
            /* Left edge is vertical, we don't need to increment. */
266
111k
            l.di = 0, l.df = 0;
267
111k
            fxl = 0;
268
361k
        } else {
269
361k
            compute_dx(&l, dxl, ysl);
270
361k
            fxl = YMULT_QUO(ysl, l);
271
361k
            l.x += fxl;
272
361k
        }
273
473k
        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
110k
            r.di = 0, r.df = 0;
286
110k
        }
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
362k
        else if (dxr == dxl && fxl != 0) {
292
32.3k
            if (l.di == 0)
293
5.54k
                r.di = 0, r.df = l.df;
294
26.8k
            else
295
26.8k
                compute_dx(&r, dxr, ysr);
296
32.3k
            if (ysr == ysl && r.h == l.h)
297
18.0k
                r.x += fxl;
298
14.2k
            else
299
14.2k
                r.x += YMULT_QUO(ysr, r);
300
330k
        } else {
301
330k
            compute_dx(&r, dxr, ysr);
302
330k
            r.x += YMULT_QUO(ysr, r);
303
330k
        }
304
        /* Compute one line's worth of dx/dy. */
305
473k
        compute_ldx(&l, ysl);
306
473k
        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
473k
        l.x += fixed_epsilon;
310
473k
        r.x += fixed_epsilon;
311
473k
# 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
473k
            lg.c = lgc;
320
473k
            lg.f = lgf;
321
473k
            lg.num = lgnum;
322
473k
            rg.c = rgc;
323
473k
            rg.f = rgf;
324
473k
            rg.num = rgnum;
325
473k
            xg.c = xgc;
326
473k
            xg.f = xgf;
327
473k
            xg.num = xgnum;
328
473k
            code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
329
473k
            if (code < 0)
330
0
                return code;
331
473k
            code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
332
473k
            if (code < 0)
333
0
                return code;
334
335
473k
# endif
336
337
473k
#define rational_floor(tl)\
338
473k
  fixed2int_var(fixed_is_int(tl.x) && tl.xf == -tl.h ? tl.x - fixed_1 : tl.x)
339
473k
#define STEP_LINE(ix, tl)\
340
473k
  tl.x += tl.ldi;\
341
473k
  if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
342
473k
  ix = rational_floor(tl)
343
344
473k
        rxl = rational_floor(l);
345
473k
        rxr = rational_floor(r);
346
473k
        SET_MINIMAL_WIDTH(rxl, rxr, l, r);
347
3.62M
        while (LINEAR_COLOR ? 1 : ++iy != iy1) {
348
3.62M
#     if LINEAR_COLOR
349
3.62M
                if (rxl != rxr) {
350
1.16M
                    code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
351
1.16M
                    if (code < 0)
352
0
                        goto xit;
353
1.16M
                    code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
354
1.16M
                    if (code < 0)
355
0
                        goto xit;
356
1.16M
                }
357
3.62M
                if (++iy == iy1)
358
473k
                    break;
359
3.15M
                STEP_LINE(rxl, l);
360
3.15M
                STEP_LINE(rxr, r);
361
3.15M
                step_gradient(&lg, num_components);
362
3.15M
                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
3.15M
        }
379
# if !LINEAR_COLOR
380
            code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
381
# else
382
473k
            code = 0;
383
473k
# endif
384
473k
#undef STEP_LINE
385
473k
#undef SET_MINIMAL_WIDTH
386
473k
#undef CONNECT_RECTANGLES
387
473k
#undef FILL_TRAP_RECT
388
473k
#undef FILL_TRAP_RECT_DIRECT
389
473k
#undef FILL_TRAP_RECT_INRECT
390
473k
#undef YMULT_QUO
391
473k
xit:  if (code < 0 && FILL_DIRECT)
392
0
            return_error(code);
393
473k
        return_if_interrupt(dev->memory);
394
473k
        return code;
395
473k
    }
396
473k
}
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