#include "speedo.h"
#ifndef FONTMODULE
#include <math.h>
#else
#include "xf86_ansic.h"
#endif
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define SHOW(X) printf("X = %d\n", X)
#else
#define SHOW(X)
#endif
#define PI 3.1415926536
#define PTPERINCH 72.2892
#define BIT8 0x0100
#define BIT9 0x0200
#define BIT10 0x0400
#define BIT11 0x0800
#define BIT12 0x1000
#define BIT13 0x2000
#define BIT14 0x4000
#define BIT15 0x8000
#define READ 0
typedef short bool16;
typedef int bool;
typedef
struct
{
bool16 left;
bool16 right;
bool16 top;
bool16 bottom;
} lrtb;
typedef
struct
{
buff_t *pfont;
ufix16 mode;
real point_size_x;
real point_size_y;
real res_hor;
real res_ver;
real rot_angle;
real obl_angle;
bool16 whitewrite;
fix15 thresh;
bool16 import_widths;
lrtb clip;
lrtb squeeze;
bool16 bogus_mode;
} comp_char_desc;
fw_reset();
fw_set_specs();
bool fw_make_char();
void _open_bitmap();
void _close_bitmap();
void _set_bitmap_bits();
void _open_outline();
void _open_outline();
void _start_new_char();
void _start_curve();
void _line_to();
void _close_curve();
void _close_outline();
static specs_t *pspecs;
static buff_t *pfont;
static buff_t char_data;
static fix15 set_width_x;
static specs_t specsarg;
static fix31 make_mult();
FUNCTION fw_reset()
{
sp_reset();
}
FUNCTION fw_set_specs(pspecs)
comp_char_desc *pspecs;
{
fix15 irot;
fix15 iobl;
fix15 x_trans_type;
fix15 y_trans_type;
fix31 xx_mult;
fix31 xy_mult;
fix31 yx_mult;
fix31 yy_mult;
real sinrot, cosrot, tanobl;
real x_distortion;
real pixperem_h;
real pixperem_v;
real point_size_x;
real point_size_y;
real res_hor;
real res_ver;
fix15 mode;
specsarg.pfont = pspecs->pfont;
irot = floor(pspecs->rot_angle + 0.5);
iobl = floor(pspecs->obl_angle + 0.5);
if (iobl > 85)
iobl = 85;
if (iobl < -85)
iobl = -85;
if ((irot % 90) == 0)
{
x_trans_type = y_trans_type = irot / 90 & 0x0003;
if (iobl != 0)
{
if (x_trans_type & 0x01)
y_trans_type = 4;
else
x_trans_type = 4;
}
}
else if (((irot + iobl) % 90) == 0)
{
x_trans_type = y_trans_type = (irot + iobl) / 90 & 0x0003;
if (iobl != 0)
{
if (x_trans_type & 0x01)
x_trans_type = 4;
else
y_trans_type = 4;
}
}
else
{
x_trans_type = y_trans_type = 4;
}
point_size_x = pspecs->point_size_x;
point_size_y = pspecs->point_size_y;
res_hor = pspecs->res_hor;
res_ver = pspecs->res_ver;
switch (x_trans_type)
{
case 0:
xx_mult = make_mult(point_size_x, res_hor);
xy_mult = 0;
break;
case 1:
xx_mult = 0;
xy_mult = make_mult(point_size_y, res_hor);
break;
case 2:
xx_mult = -make_mult(point_size_x, res_hor);
xy_mult = 0;
break;
case 3:
xx_mult = 0;
xy_mult = -make_mult(point_size_y, res_hor);
break;
default:
sinrot = sin((real)irot * PI / 180.);
cosrot = cos((real)irot * PI / 180.);
tanobl = tan((real)iobl * PI / 180.);
x_distortion = point_size_x / point_size_y;
pixperem_h = point_size_y * res_hor / (real)PTPERINCH;
xx_mult = floor(cosrot * x_distortion * pixperem_h * 65536.0 + 0.5);
xy_mult = floor((sinrot + cosrot * tanobl) * pixperem_h * 65536.0 + 0.5);
break;
}
switch (y_trans_type)
{
case 0:
yx_mult = 0;
yy_mult = make_mult(point_size_y, res_ver);
break;
case 1:
yx_mult = -make_mult(point_size_x, res_hor);
yy_mult = 0;
break;
case 2:
yx_mult = 0;
yy_mult = -make_mult(point_size_y, res_ver);
break;
case 3:
yx_mult = make_mult(point_size_x, res_ver);
yy_mult = 0;
break;
default:
sinrot = sin((real)irot * PI / 180.);
cosrot = cos((real)irot * PI / 180.);
tanobl = tan((real)iobl * PI / 180.);
x_distortion = point_size_x / point_size_y;
pixperem_v = point_size_y * res_ver / (real)PTPERINCH;
yx_mult = floor(-sinrot * x_distortion * pixperem_v * 65536.0 + 0.5);
yy_mult = floor((cosrot - sinrot * tanobl) * pixperem_v * 65536.0 + 0.5);
break;
}
specsarg.xxmult = xx_mult;
specsarg.xymult = xy_mult;
specsarg.xoffset = 0;
specsarg.yxmult = yx_mult;
specsarg.yymult = yy_mult;
specsarg.yoffset = 0;
specsarg.out_info = 0;
switch (pspecs->mode)
{
case 1:
if (pspecs->whitewrite)
{
mode = 1;
}
else
{
mode = 0;
}
break;
case 2:
mode = 2;
break;
default:
mode = pspecs->mode;
break;
}
if (pspecs->bogus_mode)
{
mode |= BIT4;
}
if (pspecs->import_widths)
{
mode |= BIT6;
}
if (pspecs->clip.left)
{
mode |= BIT8;
}
if (pspecs->clip.right)
{
mode |= BIT9;
}
if (pspecs->clip.top)
{
mode |= BIT10;
}
if (pspecs->clip.bottom)
{
mode |= BIT11;
}
if (pspecs->squeeze.left)
{
mode |= BIT12;
}
if (pspecs->squeeze.right)
{
mode |= BIT13;
}
if (pspecs->squeeze.top)
{
mode |= BIT14;
}
if (pspecs->squeeze.bottom)
{
mode |= BIT15;
}
specsarg.flags = mode;
sp_set_specs(&specsarg);
}
FUNCTION static fix31 make_mult(point_size, resolution)
real point_size;
real resolution;
{
real ms_factor;
return (fix31)floor((point_size * resolution * 65536.0) / (real)PTPERINCH + 0.5);
}
FUNCTION bool fw_make_char(char_index)
ufix16 char_index;
{
return sp_make_char(char_index);
}
FUNCTION buff_t *sp_load_char_data(file_offset, no_bytes, cb_offset)
fix31 file_offset;
fix15 no_bytes;
fix15 cb_offset;
{
#if DEBUG
printf("load_char_data(%d, %d, %d)\n", file_offset, no_bytes, char_offset);
#endif
char_data.org = pfont->org + file_offset;
char_data.no_bytes = no_bytes;
return &char_data;
}
FUNCTION void sp_report_error(n)
fix15 n;
{
switch(n)
{
case 1:
printf("Insufficient font data loaded\n");
break;
case 3:
printf("Transformation matrix out of range\n");
break;
case 4:
printf("Font format error\n");
break;
case 5:
printf("Requested specs not compatible with output module\n");
break;
case 7:
printf("Intelligent transformation requested but not supported\n");
break;
case 8:
printf("Unsupported output mode requested\n");
break;
case 9:
printf("Extended font loaded but only compact fonts supported\n");
break;
case 10:
printf("Font specs not set prior to use of font\n");
break;
case 12:
printf("Character data not available()\n");
break;
case 13:
printf("Track kerning data not available()\n");
break;
case 14:
printf("Pair kerning data not available()\n");
break;
default:
printf("report_error(%d)\n", n);
break;
}
}
FUNCTION void sp_open_bitmap(sw_x, sw_y, xorg, yorg, xsize, ysize)
fix31 sw_x;
fix31 sw_y;
fix31 xorg;
fix31 yorg;
fix15 xsize;
fix15 ysize;
{
fix15 xmin,xmax,ymin,ymax;
#if DEBUG
printf("sp_open_bitmap:\n");
printf(" X component of set width vector = %3.1f\n", (real)sw_x / 65536.0);
printf(" Y component of set width vector = %3.1f\n", (real)sw_y / 65536.0);
printf(" Bounding box is (%d, %d, %d, %d)\n", xmin, ymin, xmax, ymax);
#endif
xmin = xorg >> 16;
ymin = yorg >> 16;
xmax = xmin + xsize;
ymax = ymin + ysize;
set_width_x = ((sw_x >> 15) + 1) >> 1;
open_bitmap(set_width_x, xmin, xmax, ymin, ymax);
}
FUNCTION void sp_set_bitmap_bits(y, x1, x2)
fix15 y, x1, x2;
{
#if DEBUG
printf("set_bitmap_bits(%d, %d, %d)\n", y, x1, x2);
#endif
set_bitmap_bits(y, x1, x2);
}
FUNCTION void sp_close_bitmap()
{
#if DEBUG
printf("close_bitmap()\n");
#endif
close_bitmap();
}
FUNCTION void sp_open_outline(sw_x, sw_y, xmin, xmax, ymin, ymax)
fix31 sw_x;
fix31 sw_y;
fix31 xmin;
fix31 xmax;
fix31 ymin;
fix31 ymax;
{
#if DEBUG
printf("open_outline(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
(real)sw_x / 65536.0, (real)sw_y / 65536.0,
(real)xmin / 65536.0, (real)xmax / 65536.0, (real)ymin / 65536.0, (real)ymax / 65536.0);
#endif
set_width_x = ((sw_x >> 15) + 1) >> 1;
open_outline(set_width_x);
}
FUNCTION void sp_start_new_char()
{
#if DEBUG
printf("start_new_char()\n");
#endif
start_new_char();
}
FUNCTION void sp_start_contour(x, y, outside)
fix31 x;
fix31 y;
boolean outside;
{
real realx, realy;
realx = (real)x / 65536.0;
realy = (real)y / 65536.0;
#if DEBUG
printf("start_curve(%3.1f, %3.1f, %s)\n",
realx, realy,
outside? "outside": "inside");
#endif
start_curve(realx, realy, outside);
}
FUNCTION void sp_curve_to(x1, y1, x2, y2, x3, y3)
fix31 x1;
fix31 y1;
fix31 x2;
fix31 y2;
fix31 x3;
fix31 y3;
{
#if DEBUG
printf("curve_to(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
(real)x1 / 65536.0, (real)y1 / 65536.0,
(real)x2 / 65536.0, (real)y2 / 65536.0,
(real)x3 / 65536.0, (real)y3 / 65536.0);
#endif
}
FUNCTION void sp_line_to(x, y)
fix31 x;
fix31 y;
{
real realx, realy;
realx = (real)x / 65536.0;
realy = (real)y / 65536.0;
#if DEBUG
printf("line_to(%3.1f, %3.1f)\n",
realx, realy);
#endif
line_to(realx, realy);
}
FUNCTION void sp_close_contour()
{
#if DEBUG
printf("close_curve()\n");
#endif
close_curve();
}
FUNCTION void sp_close_outline()
{
#if DEBUG
printf("close_outline()\n");
#endif
close_outline(set_width_x);
}