[vf] Add DVI interpreter functions.

This commit is contained in:
Parth Wazurkar 2018-12-18 16:28:35 +05:30
parent 7305227c8c
commit 30679ffae9
2 changed files with 324 additions and 0 deletions

View File

@ -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 */

View File

@ -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 */