#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#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
static void sp_split_curve(PROTO_DECL2 point_t P1,point_t P2,point_t P3,fix15 depth);
static ufix8 FONTFAR *sp_get_args(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format,point_t STACKFAR *pP);
FUNCTION ufix8 FONTFAR *read_bbox(
GDECL
ufix8 FONTFAR *pointer,
point_t STACKFAR *pPmin,
point_t STACKFAR *pPmax,
boolean set_flag)
{
ufix8 format1;
ufix8 format = 0;
fix15 i;
point_t P;
sp_globals.x_int = 0;
sp_globals.y_int = sp_globals.Y_int_org;
sp_globals.x_orus = sp_globals.y_orus = 0;
format1 = NEXT_BYTE(pointer);
pointer = sp_get_args(pointer, format1, pPmin);
#if INCL_SQUEEZING || INCL_ISW
if (set_flag)
{
sp_globals.bbox_xmin_orus = sp_globals.x_orus;
sp_globals.bbox_ymin_orus = sp_globals.y_orus;
}
#endif
*pPmax = *pPmin;
for (i = 1; i < 4; i++)
{
switch(i)
{
case 1:
if (format1 & BIT6)
sp_globals.x_int++;
format = (format1 >> 4) | 0x0c;
break;
case 2:
if (format1 & BIT7)
sp_globals.y_int++;
format = NEXT_BYTE(pointer);
break;
case 3:
sp_globals.x_int = 0;
format >>= 4;
break;
default:
break;
}
pointer = sp_get_args(pointer, format, &P);
#if INCL_SQUEEZING || INCL_ISW
if (set_flag && (i==2))
{
sp_globals.bbox_xmax_orus = sp_globals.x_orus;
sp_globals.bbox_ymax_orus = sp_globals.y_orus;
}
#endif
if ((i == 2) || (!sp_globals.normal))
{
if (P.x < pPmin->x)
pPmin->x = P.x;
if (P.y < pPmin->y)
pPmin->y = P.y;
if (P.x > pPmax->x)
pPmax->x = P.x;
if (P.y > pPmax->y)
pPmax->y = P.y;
}
}
#if DEBUG
printf("BBOX %6.1f(Xint 0), %6.1f(Yint 0), %6.1f(Xint %d), %6.1f(Yint %d)\n",
(real)pPmin->x / (real)sp_globals.onepix,
(real)pPmin->y / (real)sp_globals.onepix,
(real)pPmax->x / (real)sp_globals.onepix,
(format1 >> 6) & 0x01,
(real)pPmax->y / (real)sp_globals.onepix,
(format1 >> 7) & 0x01);
#endif
return pointer;
}
FUNCTION void proc_outl_data(
GDECL
ufix8 FONTFAR *pointer)
{
ufix8 format1, format2;
point_t P0, P1, P2, P3;
fix15 depth;
fix15 curve_count;
sp_globals.x_int = 0;
sp_globals.y_int = sp_globals.Y_int_org;
#if INCL_PLAID_OUT
record_xint((fix15)sp_globals.x_int);
record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org));
#endif
sp_globals.x_orus = sp_globals.y_orus = 0;
curve_count = 0;
while(TRUE)
{
format1 = NEXT_BYTE(pointer);
switch(format1 >> 4)
{
case 0:
pointer = sp_get_args(pointer, format1, &P1);
#if DEBUG
printf("LINE %6.1f, %6.1f\n",
(real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix);
#endif
fn_line(P1);
sp_globals.P0 = P1;
continue;
case 1:
sp_globals.x_int = format1 & 0x0f;
#if DEBUG
printf("XINT %d\n", sp_globals.x_int);
#endif
#if INCL_PLAID_OUT
record_xint((fix15)sp_globals.x_int);
#endif
continue;
case 2:
sp_globals.y_int = sp_globals.Y_int_org + (format1 & 0x0f);
#if DEBUG
printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
#endif
#if INCL_PLAID_OUT
record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org));
#endif
continue;
case 3:
switch(format1 & 0x0f)
{
case 0:
if (curve_count)
{
fn_end_contour();
}
return;
case 1:
sp_globals.x_int = NEXT_BYTE(pointer);
#if DEBUG
printf("XINT %d\n", sp_globals.x_int);
#endif
#if INCL_PLAID_OUT
record_xint((fix15)sp_globals.x_int);
#endif
continue;
case 2:
sp_globals.y_int = sp_globals.Y_int_org + NEXT_BYTE(pointer);
#if DEBUG
printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
#endif
#if INCL_PLAID_OUT
record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org));
#endif
continue;
default:
continue;
}
case 4:
case 5:
if (curve_count++)
{
fn_end_contour();
}
pointer = sp_get_args(pointer, format1, &P0);
sp_globals.P0 = P0;
#if DEBUG
printf("MOVE %6.1f, %6.1f\n",
(real)sp_globals.P0.x / (real)sp_globals.onepix, (real)sp_globals.P0.y / (real)sp_globals.onepix);
#endif
fn_begin_contour(sp_globals.P0, (boolean)(format1 & BIT4));
continue;
case 6:
#if DEBUG
printf("*** Undefined instruction (Hex %4x)\n", format1);
#endif
continue;
case 7:
#if DEBUG
printf("*** Undefined instruction (Hex %4x)\n", format1);
#endif
continue;
default:
format2 = NEXT_BYTE(pointer);
pointer = sp_get_args(pointer, format1, &P1);
pointer = sp_get_args(pointer, format2, &P2);
pointer = sp_get_args(pointer, (ufix8)(format2 >> 4), &P3);
depth = (format1 >> 4) & 0x07;
#if DEBUG
printf("CRVE %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %d\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,
depth);
#endif
depth += sp_globals.depth_adj;
if (sp_globals.curves_out)
{
fn_curve(P1, P2, P3, depth);
sp_globals.P0 = P3;
continue;
}
if (depth <= 0)
{
fn_line(P3);
sp_globals.P0 = P3;
continue;
}
sp_split_curve(P1, P2, P3, depth);
continue;
}
}
}
FUNCTION static void sp_split_curve(
GDECL
point_t P1,
point_t P2,
point_t P3,
fix15 depth)
{
fix31 X0 = (fix31)sp_globals.P0.x;
fix31 Y0 = (fix31)sp_globals.P0.y;
fix31 X1 = (fix31)P1.x;
fix31 Y1 = (fix31)P1.y;
fix31 X2 = (fix31)P2.x;
fix31 Y2 = (fix31)P2.y;
fix31 X3 = (fix31)P3.x;
fix31 Y3 = (fix31)P3.y;
point_t Pmid;
point_t Pctrl1;
point_t Pctrl2;
#if DEBUG
printf("CRVE(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\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
Pmid.x = (X0 + (X1 + X2) * 3 + X3 + 4) >> 3;
Pmid.y = (Y0 + (Y1 + Y2) * 3 + Y3 + 4) >> 3;
if ((--depth) <= 0)
{
fn_line(Pmid);
sp_globals.P0 = Pmid;
fn_line(P3);
sp_globals.P0 = P3;
}
else
{
Pctrl1.x = (X0 + X1 + 1) >> 1;
Pctrl1.y = (Y0 + Y1 + 1) >> 1;
Pctrl2.x = (X0 + (X1 << 1) + X2 + 2) >> 2;
Pctrl2.y = (Y0 + (Y1 << 1) + Y2 + 2) >> 2;
sp_split_curve(Pctrl1, Pctrl2, Pmid, depth);
Pctrl1.x = (X1 + (X2 << 1) + X3 + 2) >> 2;
Pctrl1.y = (Y1 + (Y2 << 1) + Y3 + 2) >> 2;
Pctrl2.x = (X2 + X3 + 1) >> 1;
Pctrl2.y = (Y2 + Y3 + 1) >> 1;
sp_split_curve(Pctrl1, Pctrl2, P3, depth);
}
}
FUNCTION static ufix8 FONTFAR *sp_get_args(
GDECL
ufix8 FONTFAR *pointer,
ufix8 format,
point_t STACKFAR *pP)
{
ufix8 edge;
switch(format & 0x03)
{
case 0:
edge = NEXT_BYTE(pointer);
sp_globals.x_orus = sp_plaid.orus[edge];
sp_globals.x_pix = sp_plaid.pix[edge];
break;
case 1:
sp_globals.x_orus = NEXT_WORD(pointer);
goto L1;
case 2:
sp_globals.x_orus += (fix15)((fix7)NEXT_BYTE(pointer));
L1:
sp_globals.x_pix = TRANS(sp_globals.x_orus, sp_plaid.mult[sp_globals.x_int], sp_plaid.offset[sp_globals.x_int], sp_globals.mpshift);
break;
default:
break;
}
switch((format >> 2) & 0x03)
{
case 0:
edge = sp_globals.Y_edge_org + NEXT_BYTE(pointer);
sp_globals.y_orus = sp_plaid.orus[edge];
sp_globals.y_pix = sp_plaid.pix[edge];
break;
case 1:
sp_globals.y_orus = NEXT_WORD(pointer);
goto L2;
case 2:
sp_globals.y_orus += (fix15)((fix7)NEXT_BYTE(pointer));
L2:
sp_globals.y_pix = TRANS(sp_globals.y_orus, sp_plaid.mult[sp_globals.y_int], sp_plaid.offset[sp_globals.y_int], sp_globals.mpshift);
break;
default:
break;
}
switch(sp_globals.tcb.xmode)
{
case 0:
pP->x = sp_globals.x_pix;
break;
case 1:
pP->x = -sp_globals.x_pix;
break;
case 2:
pP->x = sp_globals.y_pix;
break;
case 3:
pP->x = -sp_globals.y_pix;
break;
default:
pP->x = (MULT16(sp_globals.x_orus, sp_globals.tcb.xxmult) +
MULT16(sp_globals.y_orus, sp_globals.tcb.xymult) +
sp_globals.tcb.xoffset) >> sp_globals.mpshift;
break;
}
switch(sp_globals.tcb.ymode)
{
case 0:
pP->y = sp_globals.y_pix;
break;
case 1:
pP->y = -sp_globals.y_pix;
break;
case 2:
pP->y = sp_globals.x_pix;
break;
case 3:
pP->y = -sp_globals.x_pix;
break;
default:
pP->y = (MULT16(sp_globals.x_orus, sp_globals.tcb.yxmult) +
MULT16(sp_globals.y_orus, sp_globals.tcb.yymult) +
sp_globals.tcb.yoffset) >> sp_globals.mpshift;
break;
}
return pointer;
}