#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "spdo_prv.h"
#define DEBUG 0
#define LOCAL static
#define ABS(X) ( (X < 0) ? -X : X)
#if DEBUG
#include <stdio.h>
#define SHOW(X) printf("X = %d\n", X)
#else
#define SHOW(X)
#endif
static void sp_add_intercept_screen(PROTO_DECL2 fix15 y,fix31 x);
static void sp_proc_intercepts_screen(PROTO_DECL1);
#if INCL_SCREEN
FUNCTION boolean init_screen(
GDECL
specs_t FONTFAR *specsarg)
{
#if DEBUG
printf("INIT_SCREEN()\n");
#endif
return (TRUE);
}
#endif
#if INCL_SCREEN
FUNCTION boolean begin_char_screen(
GDECL
point_t Psw,
point_t Pmin,
point_t Pmax)
{
#if DEBUG
printf("BEGIN_CHAR_SCREEN(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
(real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
(real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
(real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
#endif
if (sp_globals.pixshift > 8)
sp_intercepts.fracpix = sp_globals.onepix << (8 - sp_globals.pixshift);
else
sp_intercepts.fracpix = sp_globals.onepix >> (sp_globals.pixshift - 8);
init_char_out(Psw,Pmin,Pmax);
return TRUE;
}
#endif
#if INCL_SCREEN
FUNCTION void begin_contour_screen(
GDECL
point_t P1,
boolean outside)
{
#if DEBUG
printf("BEGIN_CONTOUR_SCREEN(%3.1f, %3.1f, %s)\n",
(real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, outside? "outside": "inside");
#endif
sp_globals.x0_spxl = P1.x;
sp_globals.y0_spxl = P1.y;
sp_globals.y_pxl = (sp_globals.y0_spxl + sp_globals.pixrnd) >> sp_globals.pixshift;
}
#endif
#if INCL_SCREEN
static FUNCTION void vert_line_screen(
GDECL
fix31 x,
fix15 y1, fix15 y2)
{
#ifdef DBGCRV
printf("VERT_LINE_SCREEN(%6.4f, %6.4f, %6.4f)\n",
(real)(x - 32768) / 65536.0,
(real)(y1 - 32768) / 65536.0,
(real)(y2 - 32768) / 65536.0);
#endif
if (sp_globals.intercept_oflo)
return;
if (y1 > y2)
{
if (y1 > (sp_globals.y_band.band_max + 1))
y1 = sp_globals.y_band.band_max + 1;
if (y2 < sp_globals.y_band.band_min)
y2 = sp_globals.y_band.band_min;
y1 -= sp_globals.y_band.band_min;
y2 -= sp_globals.y_band.band_min;
while (y2 < y1)
{
sp_add_intercept_screen(--y1, x);
}
}
else if (y2 > y1)
{
if (y1 < sp_globals.y_band.band_min)
y1 = sp_globals.y_band.band_min;
if (y2 > (sp_globals.y_band.band_max + 1))
y2 = sp_globals.y_band.band_max + 1;
y1 -= sp_globals.y_band.band_min;
y2 -= sp_globals.y_band.band_min;
while (y1 < y2)
{
sp_add_intercept_screen(y1++, x);
}
}
}
static FUNCTION void scan_curve_screen(
GDECL
fix31 X0, fix31 Y0, fix31 X1, fix31 Y1, fix31 X2, fix31 Y2, fix31 X3, fix31 Y3)
{
fix31 Pmidx;
fix31 Pmidy;
fix31 Pctrl1x;
fix31 Pctrl1y;
fix31 Pctrl2x;
fix31 Pctrl2y;
#ifdef DBGCRV
printf("SCAN_CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n",
(real)(X0-32768) / 65536.0, (real)(Y0-32768) / 65536.0,
(real)(X1-32768) / 65536.0, (real)(Y1-32768) / 65536.0,
(real)(X2-32768) / 65536.0, (real)(Y2-32768) / 65536.0,
(real)(X3-32768) / 65536.0, (real)(Y3-32768) / 65536.0);
#endif
if (((Y3 >> 16)) == (Y0 >> 16) || (Y3+1) == Y0 || Y3 == (Y0+1))
{
return;
}
if ((X3 >> 16) == (X0 >> 16))
{
vert_line_screen(X3,(fix15)(Y0>>16),(fix15)(Y3>>16));
return;
}
Pmidx = (X0 + (X1 + X2) * 3 + X3 + 4 ) >> 3;
Pmidy = (Y0 + (Y1 + Y2) * 3 + Y3 + 4 ) >> 3;
Pctrl1x = (X0 + X1 + 1 ) >> 1;
Pctrl1y = (Y0 + Y1 + 1) >> 1;
Pctrl2x = (X0 + (X1 << 1) + X2 + 2 ) >> 2;
Pctrl2y = (Y0 + (Y1 << 1) + Y2 + 2 ) >> 2;
scan_curve_screen(X0,Y0, Pctrl1x, Pctrl1y, Pctrl2x,Pctrl2y, Pmidx,Pmidy);
Pctrl1x = (X1 + (X2 << 1) + X3 + 2 ) >> 2;
Pctrl1y = (Y1 + (Y2 << 1) + Y3 + 2 ) >> 2;
Pctrl2x = (X2 + X3 + 1 ) >> 1;
Pctrl2y = (Y2 + Y3 + 1 ) >> 1;
scan_curve_screen(Pmidx,Pmidy, Pctrl1x,Pctrl1y, Pctrl2x,Pctrl2y, X3,Y3);
}
FUNCTION void curve_screen(
GDECL
point_t P1, point_t P2, point_t P3,
fix15 depth)
{
fix31 X0;
fix31 Y0;
fix31 X1;
fix31 Y1;
fix31 X2;
fix31 Y2;
fix31 X3;
fix31 Y3;
#if DEBUG
printf("CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n",
(real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
(real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
(real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
#endif
if (sp_globals.extents_running)
{
if (P3.x > sp_globals.bmap_xmax)
sp_globals.bmap_xmax = P3.x;
if (P3.x < sp_globals.bmap_xmin)
sp_globals.bmap_xmin = P3.x;
if (P3.y > sp_globals.bmap_ymax)
sp_globals.bmap_ymax = P3.y;
if (P3.y < sp_globals.bmap_ymin)
sp_globals.bmap_ymin = P3.y;
}
X0 = ((fix31)sp_globals.x0_spxl << sp_globals.poshift) + (fix31)32768;
Y0 = ((fix31)sp_globals.y0_spxl << sp_globals.poshift) + (fix31)32768;
X1 = ((fix31)P1.x << sp_globals.poshift) + (fix31)32768;
Y1 = ((fix31)P1.y << sp_globals.poshift) + (fix31)32768;
X2 = ((fix31)P2.x << sp_globals.poshift) + (fix31)32768;
Y2 = ((fix31)P2.y << sp_globals.poshift) + (fix31)32768;
X3 = ((fix31)P3.x << sp_globals.poshift) + (fix31)32768;
Y3 = ((fix31)P3.y << sp_globals.poshift) + (fix31)32768;
if (((Y0 - Y3) * sp_globals.tcb.mirror) > 0)
{
sp_intercepts.leftedge = LEFT_INT;
}
else
{
sp_intercepts.leftedge = 0;
}
scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3);
sp_globals.x0_spxl = P3.x;
sp_globals.y0_spxl = P3.y;
sp_globals.y_pxl = (P3.y + sp_globals.pixrnd) >> sp_globals.pixshift;
}
#endif
#if INCL_SCREEN
FUNCTION void line_screen(
GDECL
point_t P1)
{
register fix15 how_many_y;
register fix15 yc;
fix15 temp1;
fix15 temp2;
register fix31 dx_dy;
register fix31 xc;
fix15 x0,y0,x1,y1;
x0 = sp_globals.x0_spxl;
y0 = sp_globals.y0_spxl;
sp_globals.x0_spxl = x1 = P1.x;
sp_globals.y0_spxl = y1 = P1.y;
yc = sp_globals.y_pxl;
sp_globals.y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift;
#if DEBUG
printf("LINE_SCREEN(%3.4f, %3.4f)\n",
(real)P1.x/(real)sp_globals.onepix,
(real)P1.y/(real)sp_globals.onepix);
#endif
if (sp_globals.extents_running)
{
if (sp_globals.x0_spxl > sp_globals.bmap_xmax)
sp_globals.bmap_xmax = sp_globals.x0_spxl;
if (sp_globals.x0_spxl < sp_globals.bmap_xmin)
sp_globals.bmap_xmin = sp_globals.x0_spxl;
if (sp_globals.y0_spxl > sp_globals.bmap_ymax)
sp_globals.bmap_ymax = sp_globals.y0_spxl;
if (sp_globals.y0_spxl < sp_globals.bmap_ymin)
sp_globals.bmap_ymin = sp_globals.y0_spxl;
}
if (sp_globals.intercept_oflo) return;
if ((how_many_y = sp_globals.y_pxl - yc) == 0) return;
xc = (fix31)(x0 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
if (how_many_y < 0)
{
yc--;
}
if ((how_many_y * sp_globals.tcb.mirror) < 0)
{
sp_intercepts.leftedge = LEFT_INT;
}
else
{
sp_intercepts.leftedge = 0;
}
if (yc > sp_globals.y_band.band_max)
{
if (sp_globals.y_pxl > sp_globals.y_band.band_max) return;
how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_max) - 1;
}
if (yc < sp_globals.y_band.band_min)
{
if (sp_globals.y_pxl < sp_globals.y_band.band_min) return;
how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_min);
}
if ( (temp1 = (x1 - x0)) == 0)
{
dx_dy = 0L;
goto skip_calc;
}
dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0);
temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd;
temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15);
if ( (temp2 != (fix15)-1) &&
(temp2 != 0x0000) )
{
if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd))
{
xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift);
}
goto skip_calc;
}
xc += ((fix31)temp1 * dx_dy) >> sp_globals.pixshift;
skip_calc:
yc -= sp_globals.y_band.band_min;
if (how_many_y < 0)
{
if ((how_many_y += yc + 1) < 0) how_many_y = 0;
while(yc >= how_many_y)
{
sp_add_intercept_screen(yc--,xc);
xc -= dx_dy;
}
}
else
{
if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists;
while(yc != how_many_y)
{
sp_add_intercept_screen(yc++,xc);
xc += dx_dy;
}
}
}
#endif
#if INCL_SCREEN
FUNCTION void end_contour_screen()
GDECL
{
#if DEBUG
printf("END_CONTOUR_SCREEN()\n");
#endif
sp_intercepts.inttype[sp_globals.next_offset-1] |= END_INT;
}
#endif
#if INCL_SCREEN
FUNCTION boolean end_char_screen()
GDECL
{
fix31 xorg;
fix31 yorg;
#if INCL_CLIPPING
fix31 em_max, em_min, bmap_max, bmap_min;
#endif
#if DEBUG
printf("END_CHAR_SCREEN()\n");
#endif
if (sp_globals.first_pass)
{
if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin)
{
sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
}
else
{
sp_globals.xmin = sp_globals.xmax = 0;
}
if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin)
{
#if INCL_CLIPPING
switch(sp_globals.tcb0.xtype)
{
case 1:
if (sp_globals.specs.flags & CLIP_TOP)
{
sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
sp_globals.clip_ymin = -1 * sp_globals.clip_ymin;
if (bmap_min < sp_globals.clip_ymin)
sp_globals.ymin = sp_globals.clip_ymin;
else
sp_globals.ymin = bmap_min;
}
if (sp_globals.specs.flags & CLIP_BOTTOM)
{
sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
if (bmap_max < sp_globals.clip_ymax)
sp_globals.ymax = bmap_max;
else
sp_globals.ymax = sp_globals.clip_ymax;
}
sp_globals.clip_xmax = -sp_globals.xmin;
sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) -
sp_globals.xmin;
break;
case 2:
if (sp_globals.specs.flags & CLIP_TOP)
{
sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
if (bmap_min > sp_globals.clip_xmin)
sp_globals.clip_xmin = bmap_min;
sp_globals.clip_xmin -= sp_globals.xmin;
}
if (sp_globals.specs.flags & CLIP_BOTTOM)
{
sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
if (bmap_max < sp_globals.clip_xmax)
sp_globals.xmax = bmap_max;
else
sp_globals.xmax = sp_globals.clip_xmax;
sp_globals.clip_ymax = 0;
if ((sp_globals.specs.flags & CLIP_TOP) &&
(sp_globals.ymax > sp_globals.clip_ymax))
sp_globals.ymax = sp_globals.clip_ymax;
sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
(sp_globals.ymin < sp_globals.clip_ymin))
sp_globals.ymin = sp_globals.clip_ymin;
sp_globals.clip_xmax -= sp_globals.xmin;
}
break;
case 3:
if (sp_globals.specs.flags & CLIP_TOP)
{
sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift;
sp_globals.clip_xmin = -1 * sp_globals.clip_xmin;
bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
if (bmap_min > sp_globals.clip_xmin)
sp_globals.clip_xmin = bmap_min;
sp_globals.clip_xmin -= sp_globals.xmin;
}
if (sp_globals.specs.flags & CLIP_BOTTOM)
{
sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift;
bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift;
if (bmap_max < sp_globals.clip_xmax)
{
sp_globals.xmax = bmap_max;
sp_globals.clip_xmax = bmap_max;
}
else
sp_globals.xmax = sp_globals.clip_xmax;
sp_globals.clip_xmax -= sp_globals.xmin;
}
sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
if ((sp_globals.specs.flags & CLIP_TOP) &&
(sp_globals.ymax > sp_globals.clip_ymax))
sp_globals.ymax = sp_globals.clip_ymax;
sp_globals.clip_ymin = 0;
if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
(sp_globals.ymin < sp_globals.clip_ymin))
sp_globals.ymin = sp_globals.clip_ymin;
break;
default:
if (sp_globals.specs.flags & CLIP_TOP)
{
sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
if (bmap_max > sp_globals.clip_ymax)
sp_globals.ymax = bmap_max;
else
sp_globals.ymax = sp_globals.clip_ymax;
}
if (sp_globals.specs.flags & CLIP_BOTTOM)
{
sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
sp_globals.clip_ymin = - sp_globals.clip_ymin;
bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
if (bmap_min < sp_globals.clip_ymin)
sp_globals.ymin = sp_globals.clip_ymin;
else
sp_globals.ymin = bmap_min;
}
sp_globals.clip_xmin = -sp_globals.xmin;
sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) -
sp_globals.xmin;
break;
}
if ( !(sp_globals.specs.flags & CLIP_TOP))
#endif
sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift;
#if INCL_CLIPPING
if ( !(sp_globals.specs.flags & CLIP_BOTTOM))
#endif
sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift;
}
else
{
sp_globals.ymin = sp_globals.ymax = 0;
}
if (sp_globals.tcb.xmode == 0)
xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
else
if (sp_globals.tcb.xmode == 1)
xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ;
else
xorg = (fix31)sp_globals.xmin << 16;
if (sp_globals.tcb.ymode == 2)
yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift));
else
if (sp_globals.tcb.ymode == 3)
yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift));
else
yorg = (fix31)sp_globals.ymin << 16;
open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg,
sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin);
if (sp_globals.intercept_oflo)
{
sp_globals.y_band.band_min = sp_globals.ymin;
sp_globals.y_band.band_max = sp_globals.ymax;
init_intercepts_out();
sp_globals.first_pass = FALSE;
sp_globals.extents_running = FALSE;
return FALSE;
}
else
{
sp_proc_intercepts_screen();
close_bitmap();
return TRUE;
}
}
else
{
if (sp_globals.intercept_oflo)
{
reduce_band_size_out();
init_intercepts_out();
return FALSE;
}
else
{
sp_proc_intercepts_screen();
if (next_band_out())
{
init_intercepts_out();
return FALSE;
}
close_bitmap();
return TRUE;
}
}
}
#endif
#if INCL_SCREEN
FUNCTION LOCAL void sp_add_intercept_screen(
GDECL
fix15 y,
fix31 x)
{
register fix15 from;
register fix15 to;
register fix15 xloc;
register fix15 xfrac;
#if DEBUG
printf(" Add intercept(%2d, %x)\n", y + sp_globals.y_band.band_min, x);
if (y < 0)
{
printf(" Intecerpt less than 0!!!\007\n");
return;
}
if (y > (sp_globals.no_y_lists - 1))
{
printf(" Intercept too big for band!!!!!\007\n");
return;
}
#endif
sp_intercepts.car[sp_globals.next_offset] = xloc = (fix15)(x >> 16);
sp_intercepts.inttype[sp_globals.next_offset] = sp_intercepts.leftedge | (xfrac = ((x >> 8) & FRACTION));
from = y;
while( (to = sp_intercepts.cdr[from]) != 0)
{
if (xloc < sp_intercepts.car[to])
goto insert_element;
else if (xloc == sp_intercepts.car[to] && xfrac < (sp_intercepts.inttype[to] & FRACTION))
goto insert_element;
from = to;
}
insert_element:
sp_intercepts.cdr[from] = sp_globals.next_offset;
sp_intercepts.cdr[sp_globals.next_offset] = to;
if (++sp_globals.next_offset >= MAX_INTERCEPTS)
{
sp_globals.intercept_oflo = TRUE;
sp_globals.next_offset = sp_globals.first_offset;
}
}
#endif
#if INCL_SCREEN
FUNCTION LOCAL void sp_proc_intercepts_screen()
GDECL
{
register fix15 i,j, jplus1, iminus1;
fix15 k,nextk, previ;
register fix15 from, to;
register fix15 y;
register fix15 scan_line;
fix15 first_y, last_y;
fix15 xsave;
fix15 diff;
#if DEBUG
printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists before:\n");
#endif
#if INCL_CLIPPING
if ((sp_globals.specs.flags & CLIP_LEFT) != 0)
clipleft = TRUE;
else
clipleft = FALSE;
if ((sp_globals.specs.flags & CLIP_RIGHT) != 0)
clipright = TRUE;
else
clipright = FALSE;
if (clipleft || clipright)
{
xmax = sp_globals.clip_xmax + sp_globals.xmin;
xmin = sp_globals.clip_xmin + sp_globals.xmin;
}
if (!clipright)
xmax = ((sp_globals.set_width.x+32768L) >> 16);
#endif
if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax)
first_y = sp_globals.ymax - 1;
if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin)
last_y = sp_globals.ymin;
last_y -= sp_globals.y_band.band_min;
#if DEBUG
scan_line = sp_globals.ymax - first_y - 1;
for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
{
i = y;
while ((i = sp_intercepts.cdr[i]) != 0)
{
if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
from = 0;
i = sp_intercepts.cdr[i];
if (i == 0)
{
printf("****** proc_intercepts: odd number of intercepts\n");
break;
}
if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
to = sp_globals.xmax - sp_globals.xmin;
else
to -= sp_globals.xmin;
printf(" Y = %2d (scanline %2d): %d %d:\n",
y + sp_globals.y_band.band_min, scan_line, from, to);
}
}
#endif
for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--)
{
previ = y;
i = sp_intercepts.cdr[y];
while (i != 0)
{
j = i;
i = sp_intercepts.cdr[i];
if (sp_intercepts.inttype[i] & LEFT_INT)
{
if (sp_intercepts.inttype[j] & LEFT_INT)
{
do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.inttype[i] & LEFT_INT);
do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.cdr[i] && !(sp_intercepts.inttype[sp_intercepts.cdr[i]] & LEFT_INT));
sp_intercepts.cdr[j] = i;
}
else
{
xsave = sp_intercepts.car[j];
sp_intercepts.car[j] = sp_intercepts.car[i];
sp_intercepts.car[i] = xsave;
xsave = sp_intercepts.inttype[j];
sp_intercepts.inttype[j] = sp_intercepts.inttype[i] & FRACTION;
sp_intercepts.inttype[i] = xsave | LEFT_INT;
sp_intercepts.cdr[previ] = i;
sp_intercepts.cdr[j] = sp_intercepts.cdr[i];
sp_intercepts.cdr[i] = j;
i = j;
j = sp_intercepts.cdr[previ];
}
}
if (sp_intercepts.car[j] < sp_globals.xmin)
sp_intercepts.car[j] = sp_globals.xmin;
if (sp_intercepts.car[i] > sp_globals.xmax)
sp_intercepts.car[i] = sp_globals.xmax;
if (sp_intercepts.car[j] >= sp_intercepts.car[i])
{
if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i] & FRACTION) > sp_intercepts.fracpix)
++sp_intercepts.car[i];
else
--sp_intercepts.car[j];
}
if (sp_globals.first_pass)
{
if (sp_intercepts.inttype[i-1] & END_INT)
{
for (iminus1 = i+1; !(sp_intercepts.inttype[iminus1] & END_INT); iminus1++)
;
}
else
iminus1 = i-1;
if (sp_intercepts.inttype[j] & END_INT)
{
for (jplus1 = j-1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1--)
;
jplus1++;
}
else
jplus1 = j+1;
if ((sp_intercepts.inttype[iminus1] & LEFT_INT))
{
if ( sp_intercepts.car[jplus1] > sp_intercepts.car[i])
{
diff = sp_intercepts.car[jplus1] - sp_intercepts.car[i];
sp_intercepts.car[i] += diff/2;
sp_intercepts.car[jplus1] -= diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[i] ++;
else
sp_intercepts.car[jplus1]--;
}
}
}
else if (!(sp_intercepts.inttype[jplus1] & LEFT_INT))
{
if (sp_intercepts.car[iminus1] < sp_intercepts.car[j])
{
diff = sp_intercepts.car[j] - sp_intercepts.car[iminus1];
sp_intercepts.car[j] -= diff/2;
sp_intercepts.car[iminus1] += diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) +
(ufix16)(sp_intercepts.inttype[iminus1] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[iminus1]++;
else
sp_intercepts.car[j]--;
}
}
}
if (sp_globals.tcb.mirror == -1)
{
if (sp_intercepts.inttype[j-1] & END_INT)
{
for (jplus1 = j+1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1++)
;
}
else
{
jplus1 = j-1;
}
}
if (!(sp_intercepts.inttype[jplus1] & LEFT_INT) &&
sp_intercepts.car[j] > sp_intercepts.car[jplus1])
{
k = sp_intercepts.cdr[y - 1];
while (k > 0)
{
nextk = sp_intercepts.cdr[k];
if (!(sp_intercepts.inttype[k] & LEFT_INT) &&
(sp_intercepts.inttype[nextk] & LEFT_INT) &&
sp_intercepts.car[nextk] > sp_intercepts.car[jplus1])
{
if ((diff=sp_intercepts.car[j] - sp_intercepts.car[k]) > 0)
{
if (diff <= (sp_intercepts.car[nextk] - sp_intercepts.car[jplus1]))
{
sp_intercepts.car[j] -= diff/2;
sp_intercepts.car[k] += diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) +
(ufix16)(sp_intercepts.inttype[k] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[j]--;
else
sp_intercepts.car[k]++;
}
}
else
{
diff = sp_intercepts.car[nextk] - sp_intercepts.car[jplus1];
sp_intercepts.car[nextk] -= diff/2;
sp_intercepts.car[jplus1] += diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) +
(ufix16)(sp_intercepts.inttype[nextk] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[nextk]--;
else
sp_intercepts.car[jplus1]++;
}
}
}
break;
}
k = nextk;
}
}
if (j > 0 && sp_intercepts.car[j-1] > sp_intercepts.car[i] && !(sp_intercepts.inttype[j-1] & END_INT))
{
diff = sp_intercepts.car[j-1] - sp_intercepts.car[i];
sp_intercepts.car[i] += diff/2;
sp_intercepts.car[j-1] -= diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[j-1] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[i]++;
else
sp_intercepts.car[j-1]--;
}
}
if (sp_intercepts.car[i+1] < sp_intercepts.car[j] && !(sp_intercepts.inttype[i] & END_INT))
{
diff = sp_intercepts.car[j] - sp_intercepts.car[i+1];
sp_intercepts.car[j] -= diff/2;
sp_intercepts.car[i+1] += diff/2;
if (diff & 1)
{
if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i+1] & FRACTION) > sp_intercepts.fracpix)
sp_intercepts.car[i+1]++;
else
sp_intercepts.car[j]--;
}
}
previ = i;
}
i = sp_intercepts.cdr[i];
}
}
#if DEBUG
printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists after:\n");
scan_line = sp_globals.ymax - first_y - 1;
for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
{
i = y;
while ((i = sp_intercepts.cdr[i]) != 0)
{
if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0)
from = 0;
i = sp_intercepts.cdr[i];
if (i == 0)
{
printf("****** proc_intercepts: odd number of intercepts\n");
break;
}
if ((to = sp_intercepts.car[i]) > sp_globals.xmax)
to = sp_globals.xmax - sp_globals.xmin;
else
to -= sp_globals.xmin;
printf(" Y = %2d (scanline %2d): %d %d:\n",
y + sp_globals.y_band.band_min, scan_line, from, to);
}
}
#endif
scan_line = sp_globals.ymax - first_y - 1;
for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++)
{
i = sp_intercepts.cdr[y];
while (i != 0)
{
from = sp_intercepts.car[i];
i = sp_intercepts.cdr[i];
to = sp_intercepts.car[i];
#if INCL_CLIPPING
if (clipleft)
{
if (to <= xmin)
{
i = sp_intercepts.cdr[i];
continue;
}
if (from < xmin)
from = xmin;
}
if (clipright)
{
if (from >= xmax)
{
i = sp_intercepts.cdr[i];
continue;
}
if (to > xmax)
to = xmax;
}
#endif
set_bitmap_bits(scan_line, from-sp_globals.xmin, to-sp_globals.xmin);
i = sp_intercepts.cdr[i];
}
}
}
#endif