135
135
const fixed ymax = fixed_pixround(ytop);
137
137
if (ymin >= ymax)
138
return 0; /* no scan lines to sample */
138
return 0; /* no scan lines to sample */
140
int iy = fixed2int_var(ymin);
141
const int iy1 = fixed2int_var(ymax);
143
register int rxl, rxr;
146
x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
147
x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
148
const fixed /* partial pixel offset to first line to sample */
149
ysl = ymin - left->start.y, ysr = ymin - right->start.y;
140
int iy = fixed2int_var(ymin);
141
const int iy1 = fixed2int_var(ymax);
143
register int rxl, rxr;
146
x0l = left->start.x, x1l = left->end.x, x0r = right->start.x,
147
x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r;
148
const fixed /* partial pixel offset to first line to sample */
149
ysl = ymin - left->start.y, ysr = ymin - right->start.y;
152
152
# if CONTIGUOUS_FILL
153
const bool peak0 = ((flags & 1) != 0);
154
const bool peak1 = ((flags & 2) != 0);
155
int peak_y0 = ybot + fixed_half;
156
int peak_y1 = ytop - fixed_half;
153
const bool peak0 = ((flags & 1) != 0);
154
const bool peak1 = ((flags & 2) != 0);
155
int peak_y0 = ybot + fixed_half;
156
int peak_y1 = ytop - fixed_half;
158
158
# if LINEAR_COLOR
159
int num_components = dev->color_info.num_components;
160
frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
161
int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
162
int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
163
frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
164
int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
165
int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
166
frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
trap_gradient lg, rg, xg;
159
int num_components = dev->color_info.num_components;
160
frac31 lgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
161
int32_t lgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
162
int32_t lgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
163
frac31 rgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
164
int32_t rgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
165
int32_t rgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
166
frac31 xgc[GX_DEVICE_COLOR_MAX_COMPONENTS];
167
int32_t xgf[GX_DEVICE_COLOR_MAX_COMPONENTS];
168
int32_t xgnum[GX_DEVICE_COLOR_MAX_COMPONENTS];
169
trap_gradient lg, rg, xg;
171
gx_color_index cindex = pdevc->colors.pure;
172
dev_proc_fill_rectangle((*fill_rect)) =
173
dev_proc(dev, fill_rectangle);
171
gx_color_index cindex = pdevc->colors.pure;
172
dev_proc_fill_rectangle((*fill_rect)) =
173
dev_proc(dev, fill_rectangle);
176
if_debug2('z', "[z]y=[%d,%d]\n", iy, iy1);
176
if_debug2('z', "[z]y=[%d,%d]\n", iy, iy1);
178
l.h = left->end.y - left->start.y;
179
r.h = right->end.y - right->start.y;
180
l.x = x0l + (fixed_half - fixed_epsilon);
181
r.x = x0r + (fixed_half - fixed_epsilon);
178
l.h = left->end.y - left->start.y;
179
r.h = right->end.y - right->start.y;
180
l.x = x0l + (fixed_half - fixed_epsilon);
181
r.x = x0r + (fixed_half - fixed_epsilon);
185
185
* Free variables of FILL_TRAP_RECT:
198
198
# define FILL_TRAP_RECT(x,y,w,h)\
199
(!(w) ? 0 : dev_proc(dev, fill_linear_color_scanline)(dev, fa, x, y, w, xg.c, xg.f, xg.num, xg.den))
199
(!(w) ? 0 : dev_proc(dev, fill_linear_color_scanline)(dev, fa, x, y, w, xg.c, xg.f, xg.num, xg.den))
201
201
# define FILL_TRAP_RECT(x,y,w,h)\
202
(FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
202
(FILL_DIRECT ? FILL_TRAP_RECT_DIRECT(x,y,w,h) : FILL_TRAP_RECT_INDIRECT(x,y,w,h))
205
205
#define VD_RECT_SWAPPED(rxl, ry, rxr, iy)\
206
206
vd_rect(int2fixed(SWAP_AXES ? ry : rxl), int2fixed(SWAP_AXES ? rxl : ry),\
207
207
int2fixed(SWAP_AXES ? iy : rxr), int2fixed(SWAP_AXES ? rxr : iy),\
210
/* Compute the dx/dy ratios. */
213
* Compute the x offsets at the first scan line to sample. We need
214
* to be careful in computing ys# * dx#f {/,%} h# because the
215
* multiplication may overflow. We know that all the quantities
216
* involved are non-negative, and that ys# is usually less than 1 (as
217
* a fixed, of course); this gives us a cheap conservative check for
218
* overflow in the multiplication.
210
/* Compute the dx/dy ratios. */
213
* Compute the x offsets at the first scan line to sample. We need
214
* to be careful in computing ys# * dx#f {/,%} h# because the
215
* multiplication may overflow. We know that all the quantities
216
* involved are non-negative, and that ys# is usually less than 1 (as
217
* a fixed, of course); this gives us a cheap conservative check for
218
* overflow in the multiplication.
220
220
#define YMULT_QUO(ys, tl)\
221
221
(ys < fixed_1 && tl.df < YMULT_LIMIT ? ys * tl.df / tl.h :\
222
222
fixed_mult_quo(ys, tl.df, tl.h))
232
232
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) \
233
233
if (ixl == ixr) \
234
if ((!peak0 || iy >= peak_y0) && (!peak1 || iy <= peak_y1)) {\
235
fixed x = int2fixed(ixl) + fixed_half;\
236
if (x - l.x < r.x - x)\
234
if ((!peak0 || iy >= peak_y0) && (!peak1 || iy <= peak_y1)) {\
235
fixed x = int2fixed(ixl) + fixed_half;\
236
if (x - l.x < r.x - x)\
242
242
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill)\
243
243
if (adj1 < adj2) {\
245
VD_RECT_SWAPPED(rxl, ry, rxr, iy - 1);\
246
code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\
251
adj1 = adj2 = (adj2 + adj2) / 2;\
245
VD_RECT_SWAPPED(rxl, ry, rxr, iy - 1);\
246
code = fill(rxl, ry, rxr - rxl, iy - ry - 1);\
251
adj1 = adj2 = (adj2 + adj2) / 2;\
255
255
#define SET_MINIMAL_WIDTH(ixl, ixr, l, r) DO_NOTHING
256
256
#define CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, adj1, adj2, fill) DO_NOTHING
258
if (fixed_floor(l.x) == fixed_pixround(x1l)) {
259
/* Left edge is vertical, we don't need to increment. */
263
compute_dx(&l, dxl, ysl);
264
fxl = YMULT_QUO(ysl, l);
267
if (fixed_floor(r.x) == fixed_pixround(x1r)) {
268
/* Right edge is vertical. If both are vertical, */
269
/* we have a rectangle. */
258
if (fixed_floor(l.x) == fixed_pixround(x1l)) {
259
/* Left edge is vertical, we don't need to increment. */
263
compute_dx(&l, dxl, ysl);
264
fxl = YMULT_QUO(ysl, l);
267
if (fixed_floor(r.x) == fixed_pixround(x1r)) {
268
/* Right edge is vertical. If both are vertical, */
269
/* we have a rectangle. */
270
270
# if !LINEAR_COLOR
271
if (l.di == 0 && l.df == 0) {
272
rxl = fixed2int_var(l.x);
273
rxr = fixed2int_var(r.x);
274
SET_MINIMAL_WIDTH(rxl, rxr, l, r);
275
VD_RECT_SWAPPED(rxl, ry, rxr, iy1);
276
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
271
if (l.di == 0 && l.df == 0) {
272
rxl = fixed2int_var(l.x);
273
rxr = fixed2int_var(r.x);
274
SET_MINIMAL_WIDTH(rxl, rxr, l, r);
275
VD_RECT_SWAPPED(rxl, ry, rxr, iy1);
276
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy1 - ry);
283
* The test for fxl != 0 is required because the right edge might
284
* cross some pixel centers even if the left edge doesn't.
286
else if (dxr == dxl && fxl != 0) {
288
r.di = 0, r.df = l.df;
290
compute_dx(&r, dxr, ysr);
291
if (ysr == ysl && r.h == l.h)
294
r.x += YMULT_QUO(ysr, r);
296
compute_dx(&r, dxr, ysr);
297
r.x += YMULT_QUO(ysr, r);
299
/* Compute one line's worth of dx/dy. */
300
compute_ldx(&l, ysl);
301
compute_ldx(&r, ysr);
302
/* We subtracted fixed_epsilon from l.x, r.x to simplify rounding
303
when the rational part is zero. Now add it back to get xl', xr' */
304
l.x += fixed_epsilon;
305
r.x += fixed_epsilon;
283
* The test for fxl != 0 is required because the right edge might
284
* cross some pixel centers even if the left edge doesn't.
286
else if (dxr == dxl && fxl != 0) {
288
r.di = 0, r.df = l.df;
290
compute_dx(&r, dxr, ysr);
291
if (ysr == ysl && r.h == l.h)
294
r.x += YMULT_QUO(ysr, r);
296
compute_dx(&r, dxr, ysr);
297
r.x += YMULT_QUO(ysr, r);
299
/* Compute one line's worth of dx/dy. */
300
compute_ldx(&l, ysl);
301
compute_ldx(&r, ysr);
302
/* We subtracted fixed_epsilon from l.x, r.x to simplify rounding
303
when the rational part is zero. Now add it back to get xl', xr' */
304
l.x += fixed_epsilon;
305
r.x += fixed_epsilon;
306
306
# if LINEAR_COLOR
308
if (check_gradient_overflow(left, right, num_components)) {
309
/* The caller must care of.
310
Checking it here looses some performance with triangles. */
311
return_error(gs_error_unregistered);
308
if (check_gradient_overflow(left, right, num_components)) {
309
/* The caller must care of.
310
Checking it here looses some performance with triangles. */
311
return_error(gs_error_unregistered);
323
code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
326
code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
323
code = init_gradient(&lg, fa, left, right, &l, ymin, num_components);
326
code = init_gradient(&rg, fa, right, left, &r, ymin, num_components);
336
336
if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++;\
337
337
ix = rational_floor(tl)
339
rxl = rational_floor(l);
340
rxr = rational_floor(r);
341
SET_MINIMAL_WIDTH(rxl, rxr, l, r);
342
while (LINEAR_COLOR ? 1 : ++iy != iy1) {
339
rxl = rational_floor(l);
340
rxr = rational_floor(r);
341
SET_MINIMAL_WIDTH(rxl, rxr, l, r);
342
while (LINEAR_COLOR ? 1 : ++iy != iy1) {
343
343
# if LINEAR_COLOR
345
code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
348
/*VD_RECT_SWAPPED(rxl, iy, rxr, iy + 1);*/
349
code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
357
step_gradient(&lg, num_components);
358
step_gradient(&rg, num_components);
345
code = set_x_gradient(&xg, &lg, &rg, &l, &r, rxl, rxr, num_components);
348
/*VD_RECT_SWAPPED(rxl, iy, rxr, iy + 1);*/
349
code = FILL_TRAP_RECT(rxl, iy, rxr - rxl, 1);
357
step_gradient(&lg, num_components);
358
step_gradient(&rg, num_components);
360
register int ixl, ixr;
360
register int ixl, ixr;
364
SET_MINIMAL_WIDTH(ixl, ixr, l, r);
365
if (ixl != rxl || ixr != rxr) {
366
CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
367
CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
368
VD_RECT_SWAPPED(rxl, ry, rxr, iy);
369
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
372
rxl = ixl, rxr = ixr, ry = iy;
364
SET_MINIMAL_WIDTH(ixl, ixr, l, r);
365
if (ixl != rxl || ixr != rxr) {
366
CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, rxr, ixl, FILL_TRAP_RECT);
367
CONNECT_RECTANGLES(ixl, ixr, rxl, rxr, iy, ry, ixr, rxl, FILL_TRAP_RECT);
368
VD_RECT_SWAPPED(rxl, ry, rxr, iy);
369
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
372
rxl = ixl, rxr = ixr, ry = iy;
376
376
# if !LINEAR_COLOR
377
VD_RECT_SWAPPED(rxl, ry, rxr, iy);
378
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
377
VD_RECT_SWAPPED(rxl, ry, rxr, iy);
378
code = FILL_TRAP_RECT(rxl, ry, rxr - rxl, iy - ry);
383
383
#undef SET_MINIMAL_WIDTH