SWFFONT* swf_LoadT1Font(const char*filename) { SWFFONT * font; int nr; float angle,underline; char*fontname,*fullname,*familyname; BBox bbox; int s,num; char**charnames; char**charname; char*encoding[256]; int c; int t; if(!t1lib_initialized) { T1_SetBitmapPad(16); if ((T1_InitLib(NO_LOGFILE)==NULL)){ fprintf(stderr, "Initialization of t1lib failed\n"); return 0; } t1lib_initialized = 1; } nr = T1_AddFont(filename); T1_LoadFont(nr); charnames = T1_GetAllCharNames(nr); if(!charnames) { fprintf(stderr, "No Charnames record- not a Type1 Font?\n"); return 0; } angle = T1_GetItalicAngle(nr); fontname = T1_GetFontName(nr); fullname = T1_GetFullName(nr); familyname = T1_GetFamilyName(nr); underline = T1_GetUnderlinePosition(nr); bbox = T1_GetFontBBox(nr); font = (SWFFONT*)rfx_calloc(sizeof(SWFFONT)); font->version = 2; if(fontname) font->name = (U8*)strdup(fontname); else font->name = 0; font->layout = (SWFLAYOUT*)rfx_calloc(sizeof(SWFLAYOUT)); num = 0; charname = charnames; while(*charname) { charname++; if(num<256) { if(*charname) encoding[num] = strdup(*charname); else encoding[num] = strdup(".notdef"); } num++; } for(t=num;t<256;t++) encoding[t] = strdup(".notdef"); //T1_ReencodeFont(nr, encoding); font->maxascii = num; font->numchars = num; font->style = (/*bold*/0?FONT_STYLE_BOLD:0) + (angle>0.05?FONT_STYLE_ITALIC:0); font->glyph = (SWFGLYPH*)rfx_calloc(num*sizeof(SWFGLYPH)); font->glyph2ascii = (U16*)rfx_calloc(num*sizeof(U16)); font->ascii2glyph = (int*)rfx_calloc(font->maxascii*sizeof(int)); font->layout->ascent = (U16)(underline - bbox.lly); font->layout->descent = (U16)(bbox.ury - underline); font->layout->leading = (U16)(font->layout->ascent - font->layout->descent - (bbox.lly - bbox.ury)); font->layout->bounds = (SRECT*)rfx_calloc(sizeof(SRECT)*num); font->layout->kerningcount = 0; font->layout->kerning = 0; font->glyphnames = rfx_calloc(num*sizeof(char*)); num = 0; charname = charnames; for(c=0;c<font->numchars;c++) { drawer_t draw; SRECT bbox; T1_OUTLINE * outline; FPOINT pos,last; int firstx; outline = T1_GetCharOutline(nr, c, 100.0, 0); firstx = outline->dest.x/0xffff; pos.x = 0; pos.y = 0; last = pos; font->glyphnames[c] = strdup(*charname); if(c<font->maxascii) font->ascii2glyph[c] = c; font->glyph2ascii[c] = c; swf_Shape01DrawerInit(&draw, 0); while(outline) { pos.x += (outline->dest.x/(float)0xffff); pos.y += (outline->dest.y/(float)0xffff); if(outline->type == T1_PATHTYPE_MOVE) { draw.moveTo(&draw,&pos); } else if(outline->type == T1_PATHTYPE_LINE) { draw.lineTo(&draw,&pos); } else if(outline->type == T1_PATHTYPE_BEZIER) { T1_BEZIERSEGMENT*o2 = (T1_BEZIERSEGMENT*)outline; FPOINT b,c; b.x = o2->B.x/(float)0xffff+last.x; b.y = o2->B.y/(float)0xffff+last.y; c.x = o2->C.x/(float)0xffff+last.x; c.y = o2->C.y/(float)0xffff+last.y; draw_cubicTo(&draw,&b,&c,&pos); } else { fprintf(stderr, "loadT1Font: unknown outline type:%d\n", outline->type); } last = pos; outline = outline->link; } draw.finish(&draw); font->glyph[c].shape = swf_ShapeDrawerToShape(&draw); bbox = swf_ShapeDrawerGetBBox(&draw); draw.dealloc(&draw); font->layout->bounds[c] = bbox; font->glyph[c].advance = bbox.xmax; if(!font->glyph[c].advance) { font->glyph[c].advance = firstx; } charname++; } T1_DeleteFont(nr); for(t=0;t<256;t++) rfx_free(encoding[t]); return font; }
int i_t1_bbox(i_t1_font_t font, double points,const char *str,size_t len, i_img_dim cords[6], int utf8,char const *flags) { BBox bbox; BBox gbbox; int mod_flags = t1_get_flags(flags); i_img_dim advance; int fontnum = font->font_id; int space_position; i_clear_error(); i_mutex_lock(mutex); space_position = T1_GetEncodingIndex(fontnum, "space"); mm_log((1,"i_t1_bbox(font %p (%d),points %.2f,str '%.*s', len %u)\n", font, fontnum,points,(int)len,str,(unsigned)len)); if (T1_LoadFont(fontnum) == -1) { t1_push_error(); i_mutex_unlock(mutex); return 0; } if (len == 0) { /* len == 0 has special meaning to T1lib, but it means there's nothing to draw, so return that */ bbox.llx = bbox.lly = bbox.urx = bbox.ury = 0; advance = 0; } else { if (utf8) { int worklen; char *work = t1_from_utf8(str, len, &worklen); if (!work) { i_mutex_unlock(mutex); return 0; } advance = T1_GetStringWidth(fontnum, work, worklen, 0, mod_flags); bbox = T1_GetStringBBox(fontnum,work,worklen,0,mod_flags); t1_fix_bbox(&bbox, work, worklen, advance, space_position); myfree(work); } else { advance = T1_GetStringWidth(fontnum, (char *)str, len, 0, mod_flags); bbox = T1_GetStringBBox(fontnum,(char *)str,len,0,mod_flags); t1_fix_bbox(&bbox, str, len, advance, space_position); } } gbbox = T1_GetFontBBox(fontnum); mm_log((1,"bbox: (%d, %d, %d, %d, %d, %d)\n", (int)(bbox.llx*points/1000), (int)(gbbox.lly*points/1000), (int)(bbox.urx*points/1000), (int)(gbbox.ury*points/1000), (int)(bbox.lly*points/1000), (int)(bbox.ury*points/1000) )); cords[BBOX_NEG_WIDTH]=((double)bbox.llx*points)/1000; cords[BBOX_POS_WIDTH]=((double)bbox.urx*points)/1000; cords[BBOX_GLOBAL_DESCENT]=((double)gbbox.lly*points)/1000; cords[BBOX_GLOBAL_ASCENT]=((double)gbbox.ury*points)/1000; cords[BBOX_DESCENT]=((double)bbox.lly*points)/1000; cords[BBOX_ASCENT]=((double)bbox.ury*points)/1000; cords[BBOX_ADVANCE_WIDTH] = ((double)advance * points)/1000; cords[BBOX_RIGHT_BEARING] = cords[BBOX_ADVANCE_WIDTH] - cords[BBOX_POS_WIDTH]; i_mutex_unlock(mutex); return BBOX_RIGHT_BEARING+1; }