#include "spdo_prv.h"
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define SHOW(X) printf("X = %d\n", X)
#else
#define SHOW(X)
#endif
#define SQUEEZE_X_ORU(A,B,C) ((((fix31)A * (fix31)B) + C) >> 16)
#define ABS(A) ((A < 0)? -A:A)
#define IMPORT_FACTOR \
shift = 16;\
while (*x_factor > (0x7fffffffL / (isw_scale >> (16 - shift))))\
shift--;\
*x_factor = (*x_factor * (isw_scale>>(16-shift))) >> shift;
static void sp_constr_update(PROTO_DECL1);
static ufix8 FONTFAR *sp_setup_pix_table(PROTO_DECL2 ufix8 FONTFAR *pointer,boolean short_form,fix15 no_X_ctrl_zones,fix15 no_Y_ctrl_zones);
static ufix8 FONTFAR *sp_setup_int_table(PROTO_DECL2 ufix8 FONTFAR *pointer,fix15 no_X_int_zones,fix15 no_Y_int_zones);
FUNCTION void init_tcb()
GDECL
{
sp_globals.tcb = sp_globals.tcb0;
}
FUNCTION void scale_tcb(
GDECL
tcb_t GLOBALFAR *ptcb,
fix15 x_pos,
fix15 y_pos,
fix15 x_scale,
fix15 y_scale)
{
fix15 xx_mult = ptcb->xxmult;
fix15 xy_mult = ptcb->xymult;
fix31 x_offset = ptcb->xoffset;
fix15 yx_mult = ptcb->yxmult;
fix15 yy_mult = ptcb->yymult;
fix31 y_offset = ptcb->yoffset;
ptcb->xxmult = TRANS(xx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT);
ptcb->xymult = TRANS(xy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT);
ptcb->xoffset = MULT16(xx_mult, x_pos) + MULT16(xy_mult, y_pos) + x_offset;
ptcb->yxmult = TRANS(yx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT);
ptcb->yymult = TRANS(yy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT);
ptcb->yoffset = MULT16(yx_mult, x_pos) + MULT16(yy_mult, y_pos) + y_offset;
type_tcb(ptcb);
}
FUNCTION ufix8 FONTFAR *skip_interpolation_table(
GDECL
ufix8 FONTFAR *pointer,
ufix8 format)
{
fix15 i,n;
ufix8 intsize[9];
intsize[0] = 1;
intsize[1] = 2;
intsize[2] = 3;
intsize[3] = 1;
intsize[4] = 2;
intsize[5] = 1;
intsize[6] = 2;
intsize[7] = 0;
intsize[8] = 0;
n = ((format & BIT6)? (fix15)NEXT_BYTE(pointer): 0);
n += ((format & BIT7)? (fix15)NEXT_BYTE(pointer): 0);
for (i = 0; i < n; i++)
{
format = NEXT_BYTE(pointer);
if (format & BIT7)
{
pointer++;
}
else
{
pointer += intsize[format & 0x7];
pointer += intsize[(format >> 3) & 0x7];
}
}
return pointer;
}
FUNCTION ufix8 FONTFAR *skip_control_zone(
GDECL
ufix8 FONTFAR *pointer,
ufix8 format)
{
fix15 i,n;
ufix16 tmpufix16;
n = sp_globals.no_X_orus + sp_globals.no_Y_orus - 2;
for (i = 0; i < n; i++)
{
if (format & BIT4)
pointer++;
else
pointer += 2;
NEXT_BYTES (pointer, tmpufix16);
}
return pointer;
}
#if INCL_RULES
#else
FUNCTION ufix8 FONTFAR *plaid_tcb(
GDECL
ufix8 FONTFAR *pointer,
ufix8 format)
{
fix15 i, n;
sp_globals.no_X_orus = (format & BIT2)?
(fix15)NEXT_BYTE(pointer):
0;
sp_globals.no_Y_orus = (format & BIT3)?
(fix15)NEXT_BYTE(pointer):
0;
pointer = read_oru_table(pointer);
sp_globals.Y_edge_org = sp_globals.no_X_orus;
pointer = skip_control_zone(pointer,format);
pointer = skip_interpolation_table(pointer,format);
return pointer;
}
#endif
#if INCL_RULES
FUNCTION ufix8 FONTFAR *plaid_tcb(
GDECL
ufix8 FONTFAR *pointer,
ufix8 format)
{
fix15 no_X_ctrl_zones;
fix15 no_Y_ctrl_zones;
fix15 no_X_int_zones;
fix15 no_Y_int_zones;
#if INCL_PLAID_OUT
begin_plaid_data();
#endif
sp_constr_update();
sp_globals.no_X_orus = (format & BIT2)?
(fix15)NEXT_BYTE(pointer):
0;
sp_globals.no_Y_orus = (format & BIT3)?
(fix15)NEXT_BYTE(pointer):
0;
pointer = read_oru_table(pointer);
sp_globals.Y_edge_org = sp_globals.no_X_orus;
if (sp_globals.no_X_orus > 1)
sp_globals.tcb.xmode = sp_globals.tcb.xtype;
if (sp_globals.no_Y_orus > 1)
sp_globals.tcb.ymode = sp_globals.tcb.ytype;
no_X_ctrl_zones = sp_globals.no_X_orus - 1;
no_Y_ctrl_zones = sp_globals.no_Y_orus - 1;
pointer = sp_setup_pix_table(pointer, (boolean)(format & BIT4),
no_X_ctrl_zones, no_Y_ctrl_zones);
no_X_int_zones = (format & BIT6)?
(fix15)NEXT_BYTE(pointer):
0;
no_Y_int_zones = (format & BIT7)?
(fix15)NEXT_BYTE(pointer):
0;
sp_globals.Y_int_org = no_X_int_zones;
pointer = sp_setup_int_table(pointer, no_X_int_zones, no_Y_int_zones);
#if INCL_PLAID_OUT
end_plaid_data();
#endif
return pointer;
}
#endif
#if INCL_RULES
FUNCTION static void sp_constr_update()
GDECL
{
fix31 ppo;
fix15 xppo;
fix15 yppo;
ufix8 FONTFAR *pointer;
fix15 no_X_constr;
fix15 no_Y_constr;
fix15 i, j, k, l, n;
fix15 ppm;
ufix8 format;
ufix8 format1;
fix15 limit;
ufix16 constr_org;
fix15 constr_nr;
fix15 size;
fix31 off;
fix15 min;
fix15 orus;
fix15 pix;
ufix16 tmpufix16;
if (sp_globals.constr.data_valid &&
(sp_globals.tcb.xppo == sp_globals.constr.xppo) &&
(sp_globals.tcb.yppo == sp_globals.constr.yppo))
{
return;
}
sp_globals.constr.xppo = xppo = sp_globals.tcb.xppo;
sp_globals.constr.yppo = yppo = sp_globals.tcb.yppo;
sp_globals.constr.data_valid = TRUE;
pointer = sp_globals.constr.org;
no_X_constr = NEXT_BYTES(pointer, tmpufix16);
no_Y_constr = NEXT_BYTES(pointer, tmpufix16);
i = 0;
constr_org = 0;
n = no_X_constr;
ppo = xppo;
for (j = 0; ; j++)
{
sp_globals.c_act[i] = FALSE;
sp_globals.c_pix[i++] = 0;
sp_globals.c_act[i] = FALSE;
sp_globals.c_pix[i++] = sp_globals.onepix;
ppm = (ppo * (fix31)sp_globals.orus_per_em) >> sp_globals.multshift;
for (k = 0; k < n; k++)
{
format = NEXT_BYTE(pointer);
limit = (fix15)NEXT_BYTE(pointer);
sp_globals.c_act[i] =
((ppm < limit) || (limit == 255)) &&
sp_globals.constr.active;
if (sp_globals.c_act[i])
{
if ((format & BIT1) &&
(constr_nr = constr_org +
((format & BIT0)?
NEXT_WORD(pointer):
(fix15)NEXT_BYTE(pointer)),
sp_globals.c_act[constr_nr]))
{
pix = sp_globals.c_pix[constr_nr];
format1 = format;
for (l = 2; l > 0; l--)
{
format1 >>= 2;
if ((size = format1 & 0x03))
pointer += size - 1;
}
}
else
{
orus = (format & BIT2)?
NEXT_WORD(pointer):
(fix15)NEXT_BYTE(pointer);
if (format & BIT5)
{
off = (fix31)((format & BIT4)?
NEXT_WORD(pointer):
(fix7)NEXT_BYTE(pointer));
off = (off << (sp_globals.multshift - 6)) + sp_globals.multrnd;
}
else
{
off = sp_globals.multrnd;
}
pix = (fix15)(((fix31)orus * ppo + off) / (1 << sp_globals.mpshift)) & sp_globals.pixfix;
}
}
else
{
format1 = format;
for (l = 3; l > 0; l--)
{
if ((size = format1 & 0x03))
pointer += size - 1;
format1 >>= 2;
}
pix = 0;
}
if (format & 0xc0)
{
min = (format & BIT7)?
(fix15)NEXT_BYTE(pointer) << sp_globals.pixshift:
sp_globals.onepix;
}
else
{
min = 0;
}
sp_globals.c_pix[i] = (pix < min)? min: pix;
i++;
}
if (j) break;
constr_org = sp_globals.Y_constr_org = i;
n = no_Y_constr;
ppo = yppo;
}
#if DEBUG
printf("\nCONSTRAINT TABLE\n");
n = no_X_constr + 2;
for (i = 0; i < n; i++)
{
printf("%3d ", i);
if (sp_globals.c_act[i])
{
printf("T ");
}
else
{
printf("F ");
}
printf("%5.1f\n", ((real)sp_globals.c_pix[i] / (real)sp_globals.onepix));
}
printf("--------------\n");
n = no_Y_constr + 2;
for (i = 0; i < n; i++)
{
j = i + sp_globals.Y_constr_org;
printf("%3d ", i);
if (sp_globals.c_act[j])
{
printf("T ");
}
else
{
printf("F ");
}
printf("%5.1f\n", ((real)sp_globals.c_pix[j] / (real)sp_globals.onepix));
}
#endif
}
#endif
FUNCTION ufix8 FONTFAR *read_oru_table(
GDECL
ufix8 FONTFAR *pointer)
{
fix15 i, j, k, n;
boolean zero_not_in;
boolean zero_added;
fix15 oru;
#if INCL_RULES
fix15 pos;
#endif
i = 0;
n = sp_globals.no_X_orus;
#if INCL_RULES
pos = sp_globals.tcb.xpos;
#endif
for (j = 0; ; j++)
{
zero_not_in = TRUE;
zero_added = FALSE;
for (k = 0; k < n; k++)
{
oru = NEXT_WORD(pointer);
if (zero_not_in && (oru >= 0))
{
#if INCL_RULES
sp_plaid.pix[i] = pos;
#endif
if (oru != 0)
{
sp_plaid.orus[i++] = 0;
zero_added = TRUE;
}
zero_not_in = FALSE;
}
sp_plaid.orus[i++] = oru;
}
if (zero_not_in)
{
#if INCL_RULES
sp_plaid.pix[i] = pos;
#endif
sp_plaid.orus[i++] = 0;
zero_added = TRUE;
}
if (j)
break;
if (zero_added)
sp_globals.no_X_orus++;
n = sp_globals.no_Y_orus;
#if INCL_RULES
pos = sp_globals.tcb.ypos;
#endif
}
if (zero_added)
sp_globals.no_Y_orus++;
#if DEBUG
printf("\nX ORUS\n");
n = sp_globals.no_X_orus;
for (i = 0; i < n; i++)
{
printf("%2d %4d\n", i, sp_plaid.orus[i]);
}
printf("\nY ORUS\n");
n = sp_globals.no_Y_orus;
for (i = 0; i < n; i++)
{
printf("%2d %4d\n", i, sp_plaid.orus[i + sp_globals.no_X_orus]);
}
#endif
return pointer;
}
#if INCL_SQUEEZING || INCL_ISW
FUNCTION static void calculate_x_pix(
GDECL
ufix8 start_edge, ufix8 end_edge,
ufix16 constr_nr,
fix31 x_scale,
fix31 x_offset,
fix31 ppo,
fix15 setwidth_pix)
{
fix15 zone_pix;
fix15 start_oru, end_oru;
start_oru= (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[start_edge], x_scale, x_offset));
end_oru = (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[end_edge], x_scale, x_offset));
if (!sp_globals.c_act[constr_nr])
{
zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo) /
(1<<sp_globals.mpshift)) + sp_globals.pixrnd) & sp_globals.pixfix;
if (((end_oru-start_oru) > 0) && (zone_pix < 0))
zone_pix = 0x7ffff;
if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
goto Lx;
}
zone_pix = (fix15)(((SQUEEZE_MULT(x_scale,sp_globals.c_pix[constr_nr]))
+ sp_globals.pixrnd) & sp_globals.pixfix);
if ((sp_globals.c_pix[constr_nr] > 0) && (zone_pix < 0))
zone_pix = 0x7fff;
if (start_edge > end_edge)
{
zone_pix = -zone_pix;
}
Lx:
sp_plaid.pix[end_edge]=sp_plaid.pix[start_edge] + zone_pix;
if (((sp_plaid.pix[start_edge] >0) && (zone_pix >0)) &&
(sp_plaid.pix[end_edge] < 0))
sp_plaid.pix[end_edge] = 0x7fff;
#if INCL_ISW
if (!sp_globals.import_setwidth_act)
#endif
if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) && (sp_plaid.pix[end_edge] < 0))
sp_plaid.pix[end_edge] = 0;
if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) &&
(sp_plaid.pix[end_edge] > setwidth_pix))
sp_plaid.pix[end_edge] = setwidth_pix;
}
#endif
#if INCL_SQUEEZING
FUNCTION static void calculate_y_pix(
GDECL
ufix8 start_edge, ufix8 end_edge,
ufix16 constr_nr,
fix31 top_scale, fix31 bottom_scale,
fix31 ppo,
fix15 em_top_pix, fix15 em_bot_pix)
{
fix15 zone_pix;
fix15 start_oru, end_oru;
fix31 zone_width, above_base, below_base;
if (sp_plaid.orus[start_edge] < 0)
start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], bottom_scale));
else
start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], top_scale));
if (sp_plaid.orus[end_edge] < 0)
end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], bottom_scale));
else
end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], top_scale));
if (!sp_globals.c_act[constr_nr])
{
zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo)
>> sp_globals.mpshift)+ sp_globals.pixrnd) & sp_globals.pixfix;
if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
goto Ly;
}
if ((end_oru >= 0) && (start_oru >=0))
zone_pix = (fix15)(SQUEEZE_MULT(top_scale, sp_globals.c_pix[constr_nr]));
else if ((end_oru <= 0) && (start_oru <=0))
zone_pix = (fix15)(SQUEEZE_MULT(bottom_scale, sp_globals.c_pix[constr_nr]));
else
{
if (start_oru > 0)
{
zone_width = start_oru - end_oru;
above_base = (((fix31)start_oru) << 16) /
((fix31)zone_width) ;
below_base = (((fix31)-end_oru) << 16) /
((fix31)zone_width) ;
}
else
{
zone_width = end_oru - start_oru;
above_base = (((fix31)-start_oru) << 16) /
((fix31)zone_width) ;
below_base = (((fix31)end_oru) << 16) /
((fix31)zone_width) ;
}
zone_pix = ((((above_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) *
top_scale) +
(((below_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) *
bottom_scale)) >> 16;
}
zone_pix = (zone_pix + sp_globals.pixrnd) & sp_globals.pixfix;
if ((sp_globals.c_pix[constr_nr] != 0) && (zone_pix < sp_globals.onepix))
zone_pix = sp_globals.onepix;
if (start_edge > end_edge)
{
zone_pix = -zone_pix;
}
Ly:
sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix;
if ((sp_globals.pspecs->flags & SQUEEZE_TOP) &&
(sp_plaid.pix[end_edge] > em_top_pix))
sp_plaid.pix[end_edge] = em_top_pix;
if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) &&
(sp_plaid.pix[end_edge] < em_bot_pix))
sp_plaid.pix[end_edge] = em_bot_pix;
}
FUNCTION boolean calculate_x_scale(x_factor, x_offset, no_X_ctrl_zones)
GDECL
fix31 *x_factor,
fix31 *x_offset,
fix15 no_X_ctrl_zones)
{
boolean squeeze_left, squeeze_right;
boolean out_on_right, out_on_left;
fix15 bbox_width,set_width;
fix15 bbox_xmin, bbox_xmax;
fix15 x_offset_pix;
fix15 i;
#if INCL_ISW
fix31 isw_scale;
fix15 shift;
#endif
squeeze_left = (sp_globals.pspecs->flags & SQUEEZE_LEFT)? TRUE:FALSE;
squeeze_right = (sp_globals.pspecs->flags & SQUEEZE_RIGHT)? TRUE:FALSE;
bbox_xmin = sp_globals.bbox_xmin_orus;
bbox_xmax = sp_globals.bbox_xmax_orus;
set_width = sp_globals.setwidth_orus;
if (bbox_xmax > set_width)
out_on_right = TRUE;
else
out_on_right = FALSE;
if (bbox_xmin < 0)
out_on_left = TRUE;
else
out_on_left = FALSE;
bbox_width =bbox_xmax - bbox_xmin;
if ((!squeeze_left && !squeeze_right) ||
(!out_on_right && !out_on_left) ||
(squeeze_left && !squeeze_right && !out_on_left) ||
(squeeze_right && !squeeze_left && !out_on_right))
return FALSE;
#if INCL_ISW
if (sp_globals.import_setwidth_act)
{
isw_scale = compute_isw_scale();
}
else
isw_scale = 0x10000L;
#endif
if (squeeze_left && squeeze_right)
{
if (bbox_width < set_width)
*x_factor = 0x10000L;
else
*x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
#if INCL_ISW
IMPORT_FACTOR
#endif
if (out_on_left)
*x_offset = -(fix31)*x_factor * (fix31)bbox_xmin;
else if (out_on_right && (*x_factor == 0x10000L))
*x_offset = -(fix31)*x_factor * (fix31)(bbox_xmax - set_width);
else
*x_offset = 0x0L;
}
else if (squeeze_left)
{
if (bbox_width < set_width)
*x_factor = 0x10000L;
else if (out_on_right)
*x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
else
*x_factor = ((fix31)set_width<<16)/
(fix31)(bbox_width - (bbox_xmax-set_width));
#if INCL_ISW
IMPORT_FACTOR
#endif
*x_offset = (fix31)-*x_factor * (fix31)bbox_xmin;
}
else
{
if (bbox_width < set_width)
{
*x_factor = 0x10000L;
#if INCL_ISW
IMPORT_FACTOR
#endif
*x_offset = (fix31)-*x_factor * (fix31)bbox_xmin;
}
else if (out_on_left)
{
*x_factor = ((fix31)set_width<<16)/(fix31)bbox_width;
#if INCL_ISW
IMPORT_FACTOR
#endif
*x_offset = 0x0L;
}
else
{
*x_factor = ((fix31)set_width<<16)/(fix31)bbox_xmax;
#if INCL_ISW
IMPORT_FACTOR
#endif
*x_offset = 0x0L;
}
}
x_offset_pix = (fix15)(((*x_offset >> 16) * sp_globals.tcb0.xppo)
/ (1<<sp_globals.mpshift));
if ((x_offset_pix >0) && (x_offset_pix < sp_globals.onepix))
x_offset_pix = sp_globals.onepix;
for (i=0; i < (no_X_ctrl_zones+1); i++)
if (sp_plaid.orus[i] >= 0)
{
sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *x_factor)
+sp_globals.pixrnd + x_offset_pix) & sp_globals.pixfix;
break;
}
return TRUE;
}
FUNCTION boolean calculate_y_scale(
GDECL
fix31 *top_scale, fix31 *bottom_scale,
fix15 first_Y_zone,
fix15 no_Y_ctrl_zones)
{
boolean squeeze_top, squeeze_bottom;
boolean out_on_top, out_on_bottom;
fix15 bbox_top, bbox_bottom;
fix15 bbox_height;
fix15 i;
squeeze_top = (sp_globals.pspecs->flags & SQUEEZE_TOP)? TRUE:FALSE;
squeeze_bottom = (sp_globals.pspecs->flags & SQUEEZE_BOTTOM)? TRUE:FALSE;
bbox_top = sp_globals.bbox_ymax_orus;
bbox_bottom = sp_globals.bbox_ymin_orus;
bbox_height = bbox_top - bbox_bottom;
if (bbox_top > EM_TOP)
out_on_top = TRUE;
else
out_on_top = FALSE;
if (bbox_bottom < EM_BOT)
out_on_bottom = TRUE;
else
out_on_bottom = FALSE;
if ((!squeeze_top && !squeeze_bottom) ||
(!out_on_top && !out_on_bottom) ||
(squeeze_top && !squeeze_bottom && !out_on_top) ||
(squeeze_bottom && !squeeze_top && !out_on_bottom))
return FALSE;
if (squeeze_top && (bbox_top > EM_TOP))
*top_scale = ((fix31)EM_TOP << 16)/(fix31)(bbox_top);
else
*top_scale = 0x10000L;
if (squeeze_bottom && (bbox_bottom < EM_BOT))
*bottom_scale = ((fix31)-(EM_BOT) << 16)/(fix31)-bbox_bottom;
else
*bottom_scale = 0x10000L;
if (sp_globals.squeezing_compound)
{
for (i=first_Y_zone; i < (first_Y_zone + no_Y_ctrl_zones + 1); i++)
{
if (sp_plaid.orus[i] >= 0)
sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *top_scale)
+sp_globals.pixrnd) & sp_globals.pixfix;
else
sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *bottom_scale)
+sp_globals.pixrnd) & sp_globals.pixfix;
}
}
return TRUE;
}
#endif
#if INCL_RULES
FUNCTION static ufix8 FONTFAR *sp_setup_pix_table(
GDECL
ufix8 FONTFAR *pointer,
boolean short_form,
fix15 no_X_ctrl_zones,
fix15 no_Y_ctrl_zones)
{
fix15 i, j, n;
fix31 ppo;
#if INCL_SQUEEZING || INCL_ISW
fix31 xppo0;
fix31 yppo0;
#endif
ufix8 edge_org;
ufix8 edge;
ufix8 start_edge;
ufix8 end_edge;
ufix16 constr_org;
fix15 constr_nr;
fix15 zone_pix;
fix31 whole_zone;
ufix16 tmpufix16;
#if INCL_SQUEEZING
fix31 x_scale;
fix31 y_top_scale, y_bottom_scale;
fix31 x_offset;
boolean squeezed_y;
fix15 setwidth_pix, em_top_pix, em_bot_pix;
#endif
#if INCL_ISW
boolean imported_width;
fix31 isw_scale;
fix15 isw_setwidth_pix;
#endif
#if INCL_ISW || INCL_SQUEEZING
boolean squeezed_x;
#endif
#if INCL_PLAID_OUT
begin_ctrl_zones(no_X_ctrl_zones, no_Y_ctrl_zones);
#endif
edge_org = 0;
constr_org = 0;
sp_globals.rnd_xmin = 0;
n = no_X_ctrl_zones;
ppo = sp_globals.tcb.xppo;
#if INCL_SQUEEZING || INCL_ISW
xppo0 = sp_globals.tcb0.xppo;
yppo0 = sp_globals.tcb0.yppo;
squeezed_x = FALSE;
#endif
#if INCL_SQUEEZING
squeezed_x = calculate_x_scale (&x_scale, &x_offset, no_X_ctrl_zones);
squeezed_y = calculate_y_scale(&y_top_scale,&y_bottom_scale,(n+1),
no_Y_ctrl_zones);
#if INCL_ISW
if (sp_globals.import_setwidth_act == TRUE)
setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >>
sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
else
#endif
setwidth_pix = ((fix15)(((fix31)sp_globals.setwidth_orus * xppo0) >>
sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
if (setwidth_pix < 0)
setwidth_pix = 0x7fff;
em_bot_pix = ((fix15)(((fix31)EM_BOT * yppo0) >>
sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
em_top_pix = ((fix15)(((fix31)EM_TOP * yppo0) >>
sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
#endif
#if INCL_ISW
isw_setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >>
sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix;
if (isw_setwidth_pix < 0)
isw_setwidth_pix = 0x7fff;
if (!squeezed_x && ((imported_width = sp_globals.import_setwidth_act) == TRUE))
{
isw_scale = compute_isw_scale();
for (i=0; i < (no_X_ctrl_zones+1); i++)
if (sp_plaid.orus[i] >= 0)
{
sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], isw_scale)
+sp_globals.pixrnd) & sp_globals.pixfix;
break;
}
}
#endif
for (i = 0; ; i++)
{
for (j = 0; j < n; j++)
{
if (short_form)
{
edge = NEXT_BYTE(pointer);
start_edge = edge_org + (edge & 0x0f);
end_edge = edge_org + (edge >> 4);
}
else
{
start_edge = edge_org + NEXT_BYTE(pointer);
end_edge = edge_org + NEXT_BYTE(pointer);
}
constr_nr = constr_org +
NEXT_BYTES(pointer, tmpufix16);
#if INCL_SQUEEZING
if (i == 0 && squeezed_x)
calculate_x_pix(start_edge, end_edge, constr_nr,
x_scale, x_offset, ppo, setwidth_pix);
else if (i == 1 && squeezed_y)
calculate_y_pix(start_edge, end_edge,constr_nr,
y_top_scale, y_bottom_scale, ppo, em_top_pix, em_bot_pix);
else
{
#endif
#if INCL_ISW
if (i==0 && imported_width)
calculate_x_pix(start_edge, end_edge, constr_nr,
isw_scale, 0, ppo, isw_setwidth_pix);
else
{
#endif
if (!sp_globals.c_act[constr_nr])
{
zone_pix = ((fix15)((((fix31)sp_plaid.orus[end_edge] -
(fix31)sp_plaid.orus[start_edge]) * ppo) /
(1<<sp_globals.mpshift)) + sp_globals.pixrnd) &
sp_globals.pixfix;
if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr])
goto L1;
}
zone_pix = sp_globals.c_pix[constr_nr];
if (start_edge > end_edge)
{
zone_pix = -zone_pix;
}
L1:
if ((j == 0) && (i == 0))
{
whole_zone = (((fix31)sp_plaid.orus[end_edge] -
(fix31)sp_plaid.orus[start_edge]) *
ppo) / (1<<sp_globals.mpshift);
sp_globals.rnd_xmin = whole_zone - zone_pix;
}
sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix;
#if INCL_SQUEEZING
if (i == 0)
{
if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) &&
(sp_plaid.pix[end_edge] < 0))
sp_plaid.pix[end_edge] = 0;
if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) &&
(sp_plaid.pix[end_edge] > setwidth_pix))
sp_plaid.pix[end_edge] = setwidth_pix;
}
if (i == 1)
{
if ((sp_globals.pspecs->flags & SQUEEZE_TOP) &&
(sp_plaid.pix[end_edge] > em_top_pix))
sp_plaid.pix[end_edge] = em_top_pix;
if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) &&
(sp_plaid.pix[end_edge] < em_bot_pix))
sp_plaid.pix[end_edge] = em_bot_pix;
}
#endif
#if INCL_SQUEEZING
}
#endif
#if INCL_ISW
}
#endif
#if INCL_PLAID_OUT
record_ctrl_zone(
(fix31)sp_plaid.pix[start_edge] << (16 - sp_globals.pixshift),
(fix31)sp_plaid.pix[end_edge] << (16 - sp_globals.pixshift),
(fix15)(constr_nr - constr_org));
#endif
}
if (i)
break;
edge_org = sp_globals.Y_edge_org;
constr_org = sp_globals.Y_constr_org;
n = no_Y_ctrl_zones;
ppo = sp_globals.tcb.yppo;
}
#if DEBUG
printf("\nX PIX TABLE\n");
n = no_X_ctrl_zones + 1;
for (i = 0; i < n; i++)
printf("%2d %6.1f\n", i, (real)sp_plaid.pix[i] / (real)sp_globals.onepix);
printf("\nY PIX TABLE\n");
n = no_Y_ctrl_zones + 1;
for (i = 0; i < n; i++)
{
j = i + no_X_ctrl_zones + 1;
printf("%2d %6.1f\n", i, (real)sp_plaid.pix[j] / (real)sp_globals.onepix);
}
#endif
return pointer;
}
#endif
#if INCL_RULES
FUNCTION static ufix8 FONTFAR *sp_setup_int_table(
GDECL
ufix8 FONTFAR *pointer,
fix15 no_X_int_zones,
fix15 no_Y_int_zones)
{
fix15 i, j, k, l, n;
ufix8 format;
ufix8 format_copy;
ufix8 tmpufix8;
fix15 start_orus = 0;
ufix8 edge_org;
ufix8 edge;
ufix16 adj_factor;
fix15 adj_orus;
fix15 end_orus = 0;
fix31 zone_orus;
fix15 start_pix = 0;
fix15 end_pix = 0;
#if INCL_PLAID_OUT
begin_int_zones(no_X_int_zones, no_Y_int_zones);
#endif
i = 0;
edge_org = 0;
n = no_X_int_zones;
for (j = 0; ; j++)
{
for (k = 0; k < n; k++)
{
format = NEXT_BYTE(pointer);
if (format & BIT7)
{
tmpufix8 = NEXT_BYTE(pointer);
edge = edge_org + (tmpufix8 & 0xf);
start_orus = sp_plaid.orus[edge];
start_pix = sp_plaid.pix[edge];
edge = edge_org + (tmpufix8 >> 4);
end_orus = sp_plaid.orus[edge];
end_pix = sp_plaid.pix[edge];
}
else
{
format_copy = format;
for (l = 0; ; l++)
{
switch (format_copy & 0x7)
{
case 0:
edge = edge_org + NEXT_BYTE(pointer);
end_orus = sp_plaid.orus[edge];
end_pix = sp_plaid.pix[edge];
break;
case 1:
adj_factor = 0xffff & NEXT_BYTE(pointer) << 8;
goto L1;
case 2:
adj_factor = 0xffff & NEXT_WORD(pointer);
L1: edge = edge_org + NEXT_BYTE(pointer);
end_orus = sp_plaid.orus[edge] +
((((fix31)sp_plaid.orus[edge + 1] - (fix31)sp_plaid.orus[edge]) *
(ufix32)adj_factor + (fix31)32768) >> 16);
end_pix = sp_plaid.pix[edge] +
((((fix31)sp_plaid.pix[edge + 1] - (fix31)sp_plaid.pix[edge]) *
(ufix32)adj_factor + (fix31)32768) >> 16);
break;
case 3:
adj_orus = -(fix15)NEXT_BYTE(pointer);
goto L2;
case 4:
adj_orus = -NEXT_WORD(pointer);
L2: edge = edge_org;
goto L4;
case 5:
adj_orus = (fix15)NEXT_BYTE(pointer);
goto L3;
case 6:
adj_orus = NEXT_WORD(pointer);
L3: edge = j? sp_globals.Y_edge_org + sp_globals.no_Y_orus - 1: sp_globals.no_X_orus - 1;
L4: end_orus = sp_plaid.orus[edge] + adj_orus;
end_pix = sp_plaid.pix[edge] +
(((fix31)adj_orus * (fix31)(j? sp_globals.tcb.yppo: sp_globals.tcb.xppo) +
sp_globals.mprnd) / (1<<sp_globals.mpshift));
break;
}
if (l)
break;
format_copy >>= 3;
start_orus = end_orus;
start_pix = end_pix;
}
}
#if INCL_PLAID_OUT
record_int_zone(
(fix31)start_pix << (16 - sp_globals.pixshift),
(fix31)end_pix << (16 - sp_globals.pixshift));
#endif
zone_orus = (fix31)end_orus - (fix31)start_orus;
sp_plaid.mult[i] = ((((fix31)end_pix - (fix31)start_pix) << sp_globals.mpshift) +
(zone_orus / 2)) / zone_orus;
sp_plaid.offset[i] =
(((((fix31)start_pix + (fix31)end_pix) << sp_globals.mpshift) -
((fix31)sp_plaid.mult[i] * ((fix31)start_orus + (fix31)end_orus))) / 2) +
sp_globals.mprnd;
i++;
}
if (j)
break;
edge_org = sp_globals.Y_edge_org;
n = no_Y_int_zones;
}
#if DEBUG
printf("\nX INT TABLE\n");
n = no_X_int_zones;
for (i = 0; i < n; i++)
{
printf("%2d %7.4f %7.4f\n", i,
(real)sp_plaid.mult[i] / (real)(1 << sp_globals.multshift),
(real)sp_plaid.offset[i] / (real)(1 << sp_globals.multshift));
}
printf("\nY INT TABLE\n");
n = no_Y_int_zones;
for (i = 0; i < n; i++)
{
j = i + no_X_int_zones;
printf("%2d %7.4f %7.4f\n", i,
(real)sp_plaid.mult[j] / (real)(1 << sp_globals.multshift),
(real)sp_plaid.offset[j] / (real)(1 << sp_globals.multshift));
}
#endif
return pointer;
}
#endif
#if INCL_ISW
FUNCTION fix31 compute_isw_scale()
GDECL
{
fix31 isw_scale;
if (sp_globals.setwidth_orus == 0)
isw_scale = 0x00010000;
else
isw_scale = ((fix31)sp_globals.imported_width << 16)/
(fix31)sp_globals.setwidth_orus;
return isw_scale;
}
#endif