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