int i_t1_face_name(i_t1_font_t font, char *name_buf, size_t name_buf_size) { char *name; int font_num = font->font_id; i_mutex_lock(mutex); T1_errno = 0; if (T1_LoadFont(font_num)) { t1_push_error(); i_mutex_unlock(mutex); return 0; } name = T1_GetFontName(font_num); if (name) { size_t len = strlen(name); strncpy(name_buf, name, name_buf_size); name_buf[name_buf_size-1] = '\0'; i_mutex_unlock(mutex); return len + 1; } else { t1_push_error(); i_mutex_unlock(mutex); return 0; } }
int i_t1_has_chars(i_t1_font_t font, const char *text, size_t len, int utf8, char *out) { int count = 0; int font_num = font->font_id; i_mutex_lock(mutex); mm_log((1, "i_t1_has_chars(font_num %d, text %p, len %u, utf8 %d)\n", font_num, text, (unsigned)len, utf8)); i_clear_error(); if (T1_LoadFont(font_num)) { t1_push_error(); i_mutex_unlock(mutex); return 0; } while (len) { unsigned long c; if (utf8) { c = i_utf8_advance(&text, &len); if (c == ~0UL) { i_push_error(0, "invalid UTF8 character"); i_mutex_unlock(mutex); return 0; } } else { c = (unsigned char)*text++; --len; } if (c >= 0x100) { /* limit of 256 characters for T1 */ *out++ = 0; } else { char const * name = T1_GetCharName(font_num, (unsigned char)c); if (name) { *out++ = strcmp(name, ".notdef") != 0; } else { mm_log((2, " No name found for character %lx\n", c)); *out++ = 0; } } ++count; } i_mutex_unlock(mutex); return count; }
i_t1_font_t i_t1_new(char *pfb,char *afm) { int font_id; i_t1_font_t font; i_mutex_lock(mutex); i_clear_error(); if (!t1_initialized && i_init_t1_low(0)) { i_mutex_unlock(mutex); return NULL; } mm_log((1,"i_t1_new(pfb %s,afm %s)\n",pfb,(afm?afm:"NULL"))); font_id = T1_AddFont(pfb); if (font_id<0) { mm_log((1,"i_t1_new: Failed to load pfb file '%s' - return code %d.\n",pfb,font_id)); t1_push_error(); i_mutex_unlock(mutex); return NULL; } if (afm != NULL) { mm_log((1,"i_t1_new: requesting afm file '%s'.\n",afm)); if (T1_SetAfmFileName(font_id,afm)<0) mm_log((1,"i_t1_new: afm loading of '%s' failed.\n",afm)); } if (T1_LoadFont(font_id)) { mm_log((1, "i_t1_new() -> -1 - T1_LoadFont failed (%d)\n", T1_errno)); t1_push_error(); i_push_error(0, "loading font"); T1_DeleteFont(font_id); i_mutex_unlock(mutex); return NULL; } ++t1_active_fonts; i_mutex_unlock(mutex); font = mymalloc(sizeof(*font)); font->font_id = font_id; mm_log((1, "i_t1_new() -> %p (%d)\n", font, font_id)); return font; }
int i_t1_glyph_name(i_t1_font_t font, unsigned long ch, char *name_buf, size_t name_buf_size) { char *name; int font_num = font->font_id; i_clear_error(); if (ch > 0xFF) { return 0; } i_mutex_lock(mutex); if (T1_LoadFont(font_num)) { t1_push_error(); i_mutex_unlock(mutex); return 0; } name = T1_GetCharName(font_num, (unsigned char)ch); if (name) { if (strcmp(name, ".notdef")) { size_t len = strlen(name); strncpy(name_buf, name, name_buf_size); name_buf[name_buf_size-1] = '\0'; i_mutex_unlock(mutex); return len + 1; } else { i_mutex_unlock(mutex); return 0; } } else { t1_push_error(); i_mutex_unlock(mutex); return 0; } }
bool InitT1(struct font_entry * tfontp) { if (libt1==NULL) { if ((libt1=T1_InitLib( NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE | T1_NO_AFM)) == NULL) { Warning("an error occured during t1lib initialisation, disabling it"); option_flags &= ~USE_LIBT1; return(false); } # ifdef DEBUG else DEBUG_PRINT(DEBUG_T1,("\n T1LIB VERSION: %s", T1_GetLibIdent())); # endif } DEBUG_PRINT((DEBUG_DVI|DEBUG_T1),("\n OPEN T1 FONT:\t'%s'", tfontp->name)); tfontp->T1id = T1_AddFont( tfontp->name ); if (tfontp->T1id < 0) { Warning("t1lib could not open font file %s", tfontp->name); return(false); } if (T1_LoadFont(tfontp->T1id)) { Warning("t1lib could not load font file %s", tfontp->name); return(false); } Message(BE_VERBOSE,"<%s>", tfontp->name); if (tfontp->psfontmap!=NULL && tfontp->psfontmap->encoding != NULL) { DEBUG_PRINT(DEBUG_T1,("\n USE ENCODING:\t'%s'", tfontp->psfontmap->encoding->name)); if (T1_ReencodeFont(tfontp->T1id,tfontp->psfontmap->encoding->charname)) { Warning("unable to use font encoding '%s' for %s", tfontp->psfontmap->encoding->name,tfontp->name); return(false); } } tfontp->type = FONT_TYPE_T1; return(true); }
/* T1_SetChar(...): Generate the bitmap for a character */ T1_OUTLINE *T1_GetCharOutline( int FontID, char charcode, float size, T1_TMATRIX *transform) { int i; int mode; T1_PATHSEGMENT *charpath; struct XYspace *Current_S; unsigned char ucharcode; FONTSIZEDEPS *font_ptr; FONTPRIVATE *fontarrayP; /* We don't implement underlining for characters, but the rasterer implements it. Thus, we use a modflag of constant 0 */ int modflag=0; /* We return to this if something goes wrong deep in the rasterizer */ if ((i=setjmp( stck_state))!=0) { T1_errno=T1ERR_TYPE1_ABORT; sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", t1_get_abort_message( i)); T1_PrintLog( "T1_GetCharOutline()", err_warn_msg_buf, T1LOG_ERROR); return( NULL); } ucharcode=(unsigned char)charcode; /* First, check for a correct ID */ i=CheckForFontID(FontID); if (i==-1){ T1_errno=T1ERR_INVALID_FONTID; return(NULL); } /* if necessary load font into memory */ if (i==0) if (T1_LoadFont(FontID)) return(NULL); /* Check for valid size */ if (size<=0.0){ T1_errno=T1ERR_INVALID_PARAMETER; return(NULL); } fontarrayP=&(pFontBase->pFontArray[FontID]); /* font is now loaded into memory => Check for size: */ if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS); if (font_ptr==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } } /* Setup an appropriate charspace matrix. Note that the rasterizer assumes vertical values with inverted sign! Transformation should create a copy of the local charspace matrix which then still has to be made permanent. */ if (transform!=NULL) { Current_S=(struct XYspace *) Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, transform->cxx, - transform->cxy, transform->cyx, - transform->cyy), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } else{ Current_S=(struct XYspace *) Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, 1.0, 0.0, 0.0, -1.0), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } /* fnt_ptr now points to the correct FontSizeDeps-struct => lets now raster the character */ mode=0; charpath=(T1_PATHSEGMENT *)fontfcnB( FontID, modflag, Current_S, fontarrayP->pFontEnc, ucharcode, &mode, fontarrayP->pType1Data, DO_NOT_RASTER); KillSpace (Current_S); return((T1_OUTLINE *)charpath); }
/* T1_GetMoveOutline(...): Generate the "outline" for a movement */ T1_OUTLINE *T1_GetMoveOutline( int FontID, int deltax, int deltay, int modflag, float size, T1_TMATRIX *transform) { int i; FONTSIZEDEPS *font_ptr; struct segment *path, *tmppath; struct XYspace *Current_S; psfont *FontP; float length; /* We return to this if something goes wrong deep in the rasterizer */ if ((i=setjmp( stck_state))!=0) { T1_errno=T1ERR_TYPE1_ABORT; sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", t1_get_abort_message( i)); T1_PrintLog( "T1_GetMoveOutline()", err_warn_msg_buf, T1LOG_ERROR); return( NULL); } /* First, check for a correct ID */ i=CheckForFontID(FontID); if (i==-1){ T1_errno=T1ERR_INVALID_FONTID; return(NULL); } /* if necessary load font into memory */ if (i==0) if (T1_LoadFont(FontID)) return(NULL); /* Check for valid size */ if (size<=0.0){ T1_errno=T1ERR_INVALID_PARAMETER; return(NULL); } FontP=pFontBase->pFontArray[i].pType1Data; /* font is now loaded into memory => Check for size: */ if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS); if (font_ptr==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } } /* Setup an appropriate charspace matrix. Note that the rasterizer assumes vertical values with inverted sign! Transformation should create a copy of the local charspace matrix which then still has to be made permanent. */ if (transform!=NULL){ Current_S=(struct XYspace *) Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, transform->cxx, - transform->cxy, transform->cyx, - transform->cyy), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } else{ Current_S=(struct XYspace *) Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, 1.0, 0.0, 0.0, -1.0), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } path=(struct segment *)ILoc( Current_S, deltax, deltay); /* Take care for underlining and such */ length=(float) deltax; if (modflag & T1_UNDERLINE){ tmppath=(struct segment *)Type1Line(FontP,Current_S, pFontBase->pFontArray[FontID].UndrLnPos, pFontBase->pFontArray[FontID].UndrLnThick, length); path=(struct segment *)Join(path,tmppath); } if (modflag & T1_OVERLINE){ tmppath=(struct segment *)Type1Line(FontP,Current_S, pFontBase->pFontArray[FontID].OvrLnPos, pFontBase->pFontArray[FontID].OvrLnThick, length); path=(struct segment *)Join(path,tmppath); } if (modflag & T1_OVERSTRIKE){ tmppath=(struct segment *)Type1Line(FontP,Current_S, pFontBase->pFontArray[FontID].OvrStrkPos, pFontBase->pFontArray[FontID].OvrStrkThick, length); path=(struct segment *)Join(path,tmppath); } KillSpace( Current_S); return( (T1_OUTLINE *)path); }
/* T1_GetStringOutline(...): Generate the outline for a string of characters */ T1_OUTLINE *T1_GetStringOutline( int FontID, char *string, int len, long spaceoff, int modflag, float size, T1_TMATRIX *transform) { int i; int mode; /* initialize this to NULL just to be on the safe side */ T1_PATHSEGMENT *charpath = NULL; struct XYspace *Current_S; int *kern_pairs; /* use for accessing the kern pairs if kerning is requested */ int no_chars=0; /* The number of characters in the string */ static int lastno_chars=0; long spacewidth; /* This is given to fontfcnb_string() */ FONTSIZEDEPS *font_ptr; FONTPRIVATE *fontarrayP; static int *pixel_h_anchor_corr=NULL; static int *flags=NULL; unsigned char *ustring; /* We return to this if something goes wrong deep in the rasterizer */ if ((i=setjmp( stck_state))!=0) { T1_errno=T1ERR_TYPE1_ABORT; sprintf( err_warn_msg_buf, "t1_abort: Reason: %s", t1_get_abort_message( i)); T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, T1LOG_ERROR); return( NULL); } /* force string elements into unsigned */ ustring=(unsigned char*)string; /* First, check for a correct ID */ i=CheckForFontID(FontID); if (i==-1){ T1_errno=T1ERR_INVALID_FONTID; return(NULL); } /* if necessary load font into memory */ if (i==0) if (T1_LoadFont(FontID)) return(NULL); /* If no AFM info is present, we return an error */ if (pFontBase->pFontArray[FontID].pAFMData==NULL) { T1_errno=T1ERR_NO_AFM_DATA; return(NULL); } /* Check for valid size */ if (size<=0.0){ T1_errno=T1ERR_INVALID_PARAMETER; return(NULL); } fontarrayP=&(pFontBase->pFontArray[FontID]); /* font is now loaded into memory => Check for size: */ if ((font_ptr=QueryFontSize( FontID, size, NO_ANTIALIAS))==NULL){ font_ptr=CreateNewFontSize( FontID, size, NO_ANTIALIAS); if (font_ptr==NULL){ T1_errno=T1ERR_ALLOC_MEM; return(NULL); } } /* Now comes string specific stuff: Get length of string and create an array of integers where to store the bitmap positioning dimens: */ if (len<0){ /* invalid length */ T1_errno=T1ERR_INVALID_PARAMETER; return(NULL); } if (len==0) /* should be computed assuming "normal" 0-terminated string */ no_chars=strlen(string); else /* use value given on command line */ no_chars=len; /* If necessary, allocate memory */ if (no_chars>lastno_chars){ if (pixel_h_anchor_corr!=NULL){ free(pixel_h_anchor_corr); } if (flags!=NULL){ free(flags); } pixel_h_anchor_corr=(int *)calloc(no_chars, sizeof(int)); flags=(int *)calloc(no_chars, sizeof(int)); lastno_chars=no_chars; } else{ /* Reset flags and position array */ for (i=0; i<no_chars; i++){ flags[i]=0; pixel_h_anchor_corr[i]=0; } } /* Setup an appropriate charspace matrix. Note that the rasterizer assumes vertical values with inverted sign! Transformation should create a copy of the local charspace matrix which then still has to be made permanent. */ if (transform!=NULL){ Current_S=(struct XYspace *) Permanent(Scale(Transform (font_ptr->pCharSpaceLocal, transform->cxx, - transform->cxy, transform->cyx, - transform->cyy), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } else{ Current_S=(struct XYspace *) Permanent(Scale(Transform(font_ptr->pCharSpaceLocal, 1.0, 0.0, 0.0, -1.0), DeviceSpecifics.scale_x, DeviceSpecifics.scale_y)); } /* Compute the correct spacewidth value (in charspace units). The value supplied by the user is interpreted as an offset in char space units: */ spacewidth=T1_GetCharWidth(FontID,fontarrayP->space_position)+spaceoff; mode=0; kern_pairs=(int *)calloc(no_chars, sizeof(int)); if ((modflag & T1_KERNING)) for (i=0; i<no_chars -1; i++) kern_pairs[i]=T1_GetKerning( FontID, ustring[i], ustring[i+1]); charpath=(T1_PATHSEGMENT *) fontfcnB_string( FontID, modflag, Current_S, fontarrayP->pFontEnc, (unsigned char *)string, no_chars, &mode, fontarrayP->pType1Data, kern_pairs, spacewidth, DO_NOT_RASTER); KillSpace (Current_S); /* In all cases, free memory for kerning pairs */ free(kern_pairs); /* fill the string_glyph-structure */ if (mode != 0) { sprintf( err_warn_msg_buf, "fontfcnB_string() set mode=%d", mode); T1_PrintLog( "T1_GetStringOutline()", err_warn_msg_buf, T1LOG_WARNING); T1_errno=mode; /* make sure to get rid of path if it's there */ if (charpath){ KillRegion (charpath); } return(NULL); } if (charpath == NULL){ T1_PrintLog( "T1_GetStringOutline()", "path=NULL returned by fontfcnB_string()", T1LOG_WARNING); T1_errno=mode; return(NULL); } return( (T1_OUTLINE *)charpath); }
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; }