summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParth Wazurkar <parthwazurkar@gmail.com>2018-12-18 16:28:35 +0530
committerParth Wazurkar <parthwazurkar@gmail.com>2018-12-18 16:28:35 +0530
commit30679ffae9f7730799eda8aa9c44e1c00358e7c6 (patch)
treef6b829f55cd6916fa3ac0e0c16d46591ca86de17
parent7305227c8cf011b5e1c46ab81e4685de99f6df98 (diff)
downloadfreetype2-30679ffae9f7730799eda8aa9c44e1c00358e7c6.tar.gz
[vf] Add DVI interpreter functions.
-rw-r--r--src/vf/vfdrivr.h8
-rw-r--r--src/vf/vflib.c316
2 files changed, 324 insertions, 0 deletions
diff --git a/src/vf/vfdrivr.h b/src/vf/vfdrivr.h
index 78b318c2a..465ab91e6 100644
--- a/src/vf/vfdrivr.h
+++ b/src/vf/vfdrivr.h
@@ -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 */
diff --git a/src/vf/vflib.c b/src/vf/vflib.c
index c07707818..32c145297 100644
--- a/src/vf/vflib.c
+++ b/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 */