mirror of https://github.com/freetype/freetype
[vf] Add DVI interpreter functions.
This commit is contained in:
parent
7305227c8c
commit
30679ffae9
|
@ -38,6 +38,14 @@ FT_BEGIN_HEADER
|
|||
} VF_BitmapRec, *VF_Bitmap;
|
||||
|
||||
|
||||
/* Bitmap list */
|
||||
struct vf_s_bitmaplist {
|
||||
FT_Long off_x, off_y;
|
||||
VF_Bitmap bitmap;
|
||||
struct vf_s_bitmaplist *next;
|
||||
};
|
||||
typedef struct vf_s_bitmaplist *VF_BITMAPLIST;
|
||||
|
||||
typedef struct TFM_Rec_
|
||||
{
|
||||
/* Font Info */
|
||||
|
|
316
src/vf/vflib.c
316
src/vf/vflib.c
|
@ -381,6 +381,52 @@
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* BMPLIST FUNCTIONS */
|
||||
|
||||
vf_bitmaplist_finish(VF_BITMAPLIST bmlist)
|
||||
{
|
||||
VF_BITMAPLIST elem, elem_next;
|
||||
|
||||
elem = bmlist->next;
|
||||
while (elem != NULL)
|
||||
{
|
||||
elem_next = elem->next;
|
||||
VF_FreeBitmap(elem->bitmap);/* To Define */
|
||||
FT_FREE(elem);
|
||||
elem = elem_next;
|
||||
}
|
||||
|
||||
bmlist->next = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vf_bitmaplist_init(VF_BITMAPLIST bmlist)
|
||||
{
|
||||
bmlist->next = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
vf_bitmaplist_finish(VF_BITMAPLIST bmlist)
|
||||
{
|
||||
VF_BITMAPLIST elem, elem_next;
|
||||
|
||||
elem = bmlist->next;
|
||||
while (elem != NULL)
|
||||
{
|
||||
elem_next = elem->next;
|
||||
VF_FreeBitmap(elem->bitmap);
|
||||
vf_free(elem);
|
||||
elem = elem_next;
|
||||
}
|
||||
|
||||
bmlist->next = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
|
@ -388,4 +434,274 @@
|
|||
*
|
||||
*/
|
||||
|
||||
void
|
||||
vf_dvi_interp_font_select(VF vf, VF_DVI_STACK dvi_stack, long f,
|
||||
FT_ULong *fmag_p)
|
||||
{
|
||||
VF_SUBFONT sf;
|
||||
|
||||
STACK(f) = f;
|
||||
STACK(font_id) = -1;
|
||||
for (sf = vf->subfonts; sf != NULL; sf = sf->next)
|
||||
{
|
||||
if (sf->k == f)
|
||||
{
|
||||
STACK(font_id) = sf->font_id;
|
||||
if (fmag_p != NULL)
|
||||
*fmag_p = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vf_dvi_interp_put_rule(VF_BITMAPLIST bmlist, VF vf, VF_DVI_STACK dvi_stack,
|
||||
long w, long h, double mag_x, double mag_y)
|
||||
{
|
||||
VF_Bitmap bm;
|
||||
FT_ULong rx, ry, ds;
|
||||
int bm_w, bm_h;
|
||||
long off_x, off_y;
|
||||
|
||||
ds = vf->design_size / (FT_ULong)(1<<20);
|
||||
rx = vf->mag_x * mag_x * vf->dpi_x/72.27 * ds;
|
||||
ry = vf->mag_y * mag_y * vf->dpi_y/72.27 * ds;
|
||||
|
||||
bm_w = rx * w;
|
||||
bm_h = ry * h;
|
||||
if (bm_w <= 0)
|
||||
bm_w = 1;
|
||||
if (bm_h <= 0)
|
||||
bm_h = 1;
|
||||
|
||||
bm = vf_alloc_bitmap(bm_w, bm_h);
|
||||
if (bm == NULL)
|
||||
return;
|
||||
VF_FillBitmap(bm);
|
||||
|
||||
bm->off_x = 0;
|
||||
bm->off_y = bm_h - 1;
|
||||
off_x = rx * (double)STACK(h);
|
||||
off_y = -ry * (double)STACK(v);
|
||||
|
||||
vf_bitmaplist_put(bmlist, bm, off_x, off_y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vf_dvi_interp_put_char(VF_BITMAPLIST bmlist, VF vf, VF_DVI_STACK dvi_stack,
|
||||
long code_point, int mode, double mag_x, double mag_y)
|
||||
{
|
||||
VF_BITMAP bm;
|
||||
double rx, ry, ds;
|
||||
long off_x, off_y;
|
||||
|
||||
if (STACK(font_id) < 0)
|
||||
return;
|
||||
if (mode == 1)
|
||||
{
|
||||
bm = VF_GetBitmap1(STACK(font_id), code_point, mag_x, mag_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
bm = VF_GetBitmap2(STACK(font_id), code_point, mag_x, mag_y);
|
||||
}
|
||||
if (bm == NULL)
|
||||
return;
|
||||
|
||||
ds = vf->design_size / (double)(1<<20);
|
||||
#if 1 /*XXX*/
|
||||
rx = vf->mag_x * mag_x * (vf->dpi_x/72.27) * ds;
|
||||
ry = vf->mag_y * mag_y * (vf->dpi_y/72.27) * ds;
|
||||
#else
|
||||
rx = (vf->dpi_x/72.27) * ds;
|
||||
ry = (vf->dpi_y/72.27) * ds;
|
||||
#endif
|
||||
off_x = rx * (double)STACK(h);
|
||||
off_y = -ry * (double)STACK(v);
|
||||
|
||||
vf_bitmaplist_put(bmlist, bm, off_x, off_y);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
vf_dvi_interp(VF_BITMAPLIST bmlist, VF vf,
|
||||
int mode, double mag_x, double mag_y,
|
||||
long cc, unsigned char *dvi_prog, int prog_len)
|
||||
{
|
||||
int pc, instr, n, ret;
|
||||
long code_point, h, w, f, length;
|
||||
double fmag;
|
||||
double r_mv_x, r_mv_y;
|
||||
struct vf_s_metric1 met, *m;
|
||||
struct s_vf_dvi_stack the_dvi_stack, *dvi_stack;
|
||||
|
||||
fmag = 1.0;
|
||||
dvi_stack = &the_dvi_stack;
|
||||
vf_dvi_stack_init(vf, dvi_stack);
|
||||
|
||||
pc = 0;
|
||||
ret = 0;
|
||||
while (pc < prog_len)
|
||||
{
|
||||
if (vf_debug('d'))
|
||||
{
|
||||
printf("VFlib Virtual Font\n ");
|
||||
printf("DVI CODE PC=0x%04x: INSTR=0x%02x (%d) H=0x%08x V=0x%08x\n",
|
||||
pc, (int)dvi_prog[pc], (int)dvi_prog[pc],
|
||||
(int)STACK(h), (int)STACK(v));
|
||||
}
|
||||
instr = (int)dvi_prog[pc++];
|
||||
if (instr <= VFINST_SET4)
|
||||
{ /* SETCHAR0 ... SETCHAR127, SET1, ... ,SET4 */
|
||||
if ((code_point = instr) > VFINST_SETCHAR127)
|
||||
{
|
||||
n = instr - VFINST_SET1 + 1;
|
||||
code_point = GET_UINTN(&dvi_prog[pc], n);
|
||||
pc += n;
|
||||
}
|
||||
vf_dvi_interp_put_char(bmlist, vf, dvi_stack, code_point,
|
||||
mode, fmag * mag_x, fmag * mag_y);
|
||||
m = VF_GetMetric1(STACK(font_id), code_point, &met,
|
||||
fmag * mag_x, fmag * mag_y);
|
||||
if (m == NULL)
|
||||
continue;
|
||||
r_mv_x = (met.mv_x / vf->design_size) * (double)(1<<20);
|
||||
r_mv_y = (met.mv_y / vf->design_size) * (double)(1<<20);
|
||||
STACK(h) = STACK(h) + toint(r_mv_x);
|
||||
STACK(v) = STACK(v) + toint(r_mv_y);
|
||||
}
|
||||
else if ((VFINST_FNTNUM0 <= instr) && (instr <= (VFINST_FNTNUM63)))
|
||||
{
|
||||
f = instr - VFINST_FNTNUM0;
|
||||
vf_dvi_interp_font_select(vf, dvi_stack, f, &fmag);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (instr)
|
||||
{
|
||||
case VFINST_PUT1:
|
||||
case VFINST_PUT2:
|
||||
case VFINST_PUT3:
|
||||
case VFINST_PUT4:
|
||||
n = instr - VFINST_SET1 + 1;
|
||||
code_point = (UINT4)GET_UINTN(&dvi_prog[pc], n); pc += n;
|
||||
vf_dvi_interp_put_char(bmlist, vf, dvi_stack, code_point,
|
||||
mode, fmag * mag_x, fmag * mag_y);
|
||||
break;
|
||||
case VFINST_SETRULE:
|
||||
h = (long)GET_INT4(&dvi_prog[pc]); pc += 4;
|
||||
w = (long)GET_INT4(&dvi_prog[pc]); pc += 4;
|
||||
vf_dvi_interp_put_rule(bmlist, vf, dvi_stack, w, h, mag_x, mag_y);
|
||||
STACK(h) += w;
|
||||
break;
|
||||
case VFINST_PUTRULE:
|
||||
h = (long)GET_INT4(&dvi_prog[pc]); pc += 4;
|
||||
w = (long)GET_INT4(&dvi_prog[pc]); pc += 4;
|
||||
vf_dvi_interp_put_rule(bmlist, vf, dvi_stack, w, h, mag_x, mag_y);
|
||||
break;
|
||||
case VFINST_RIGHT1:
|
||||
case VFINST_RIGHT2:
|
||||
case VFINST_RIGHT3:
|
||||
case VFINST_RIGHT4:
|
||||
n = instr - VFINST_RIGHT1 + 1;
|
||||
STACK(h) += (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
break;
|
||||
case VFINST_X1:
|
||||
case VFINST_X2:
|
||||
case VFINST_X3:
|
||||
case VFINST_X4:
|
||||
n = instr - VFINST_X0;
|
||||
STACK(x) = (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
case VFINST_X0:
|
||||
STACK(h) += STACK(x);
|
||||
break;
|
||||
case VFINST_W1:
|
||||
case VFINST_W2:
|
||||
case VFINST_W3:
|
||||
case VFINST_W4:
|
||||
n = instr - VFINST_W0;
|
||||
STACK(w) = (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
case VFINST_W0:
|
||||
STACK(h) += STACK(w);
|
||||
break;
|
||||
case VFINST_Y1:
|
||||
case VFINST_Y2:
|
||||
case VFINST_Y3:
|
||||
case VFINST_Y4:
|
||||
n = instr - VFINST_Y0;
|
||||
STACK(y) = (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
case VFINST_Y0:
|
||||
STACK(v) += STACK(y);
|
||||
break;
|
||||
case VFINST_Z1:
|
||||
case VFINST_Z2:
|
||||
case VFINST_Z3:
|
||||
case VFINST_Z4:
|
||||
n = instr - VFINST_Z0;
|
||||
STACK(z) = (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
case VFINST_Z0:
|
||||
STACK(v) += STACK(z);
|
||||
break;
|
||||
case VFINST_DOWN1:
|
||||
case VFINST_DOWN2:
|
||||
case VFINST_DOWN3:
|
||||
case VFINST_DOWN4:
|
||||
n = instr - VFINST_DOWN1 + 1;
|
||||
STACK(v) += (long)GET_INTN(&dvi_prog[pc], n);
|
||||
break;
|
||||
case VFINST_XXX1:
|
||||
case VFINST_XXX2:
|
||||
case VFINST_XXX3:
|
||||
case VFINST_XXX4:
|
||||
n = instr - VFINST_XXX1 + 1;
|
||||
length = (long)GET_INTN(&dvi_prog[pc], n); pc += n;
|
||||
pc += length;
|
||||
break;
|
||||
case VFINST_FNT1:
|
||||
case VFINST_FNT2:
|
||||
case VFINST_FNT3:
|
||||
case VFINST_FNT4:
|
||||
n = instr - VFINST_FNT1 + 1;
|
||||
f = GET_UINTN(&dvi_prog[pc], n); pc += n;
|
||||
vf_dvi_interp_font_select(vf, dvi_stack, f, &fmag);
|
||||
break;
|
||||
case VFINST_PUSH:
|
||||
vf_dvi_stack_push(vf, dvi_stack);
|
||||
break;
|
||||
case VFINST_POP:
|
||||
vf_dvi_stack_pop(vf, dvi_stack);
|
||||
break;
|
||||
case VFINST_NOP:
|
||||
break;
|
||||
default:
|
||||
vf_error = VF_ERR_ILL_FONT_FILE;
|
||||
ret = -1;
|
||||
goto ExitInterp;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExitInterp:
|
||||
vf_dvi_stack_deinit(vf, dvi_stack);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
VF_Bitmap
|
||||
vf_run_dvi_program(VF vf, VF_CHAR_PACKET packet,
|
||||
int mode, double mag_x, double mag_y)
|
||||
{
|
||||
struct vf_s_bitmaplist the_bmlist;
|
||||
VF_Bitmap bm;
|
||||
|
||||
vf_bitmaplist_init(&the_bmlist);
|
||||
vf_dvi_interp(&the_bmlist, vf, mode, mag_x, mag_y,
|
||||
packet->cc, packet->dvi, packet->pl);
|
||||
bm = vf_bitmaplist_compose(&the_bmlist);
|
||||
vf_bitmaplist_finish(&the_bmlist);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
/* END */
|
||||
|
|
Loading…
Reference in New Issue