📄 font_freetype.c
字号:
/* Kerning point syndrome avoidance */ if (pf->last_pen_pos > x) x = pf->last_pen_pos; pf->last_pen_pos = x; } pf->last_glyph_code = curchar; } if (pf->fontattr & MWTF_UNDERLINE) GdLine(psd, startx, starty, x, y, FALSE);}/* * Return information about a specified font. */static MWBOOLfreetype_getfontinfo(PMWFONT pfont, PMWFONTINFO pfontinfo){ int i; PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_UShort last_glyph_index; TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); /* Fill up the fields */ pfontinfo->height = (((properties.horizontal->Ascender * \ imetrics.y_scale)/ 0x10000) >> 6) - (((properties.horizontal->Descender * \ imetrics.y_scale)/ 0x10000) >> 6); pfontinfo->maxwidth = ((properties.horizontal->xMax_Extent * \ imetrics.x_scale)/ 0x10000) >> 6; pfontinfo->baseline = ((properties.horizontal->Ascender * \ imetrics.y_scale)/ 0x10000) >> 6; pfontinfo->firstchar = TT_CharMap_First(pf->char_map, NULL); pfontinfo->lastchar = TT_CharMap_Last(pf->char_map, NULL); pfontinfo->fixed = properties.postscript->isFixedPitch; /* FIXME: Wild guesses - should be possible to get these properly * from the library. */ pfontinfo->linespacing = pfontinfo->height + 2; pfontinfo->descent = pfontinfo->height - pfontinfo->baseline; pfontinfo->maxascent = pfontinfo->baseline; pfontinfo->maxdescent = pfontinfo->descent; last_glyph_index = properties.num_Glyphs > 255 ? 255: properties.num_Glyphs-1; /* Doesn't work ... don't know why ....*/#if 0 if (TT_Get_Face_Widths( pf->face, 0, last_glyph_index, widths, NULL ) != TT_Err_Ok) { return TRUE; } for(i=0; i<=last_glyph_index; i++) DPRINTF("widths[%d]: %d\n", i, widths[i]);#endif /* Get glyphs widths */ for(i=0; i<=last_glyph_index; i++) pfontinfo->widths[i] = Get_Glyph_Width(pf, i);#if 0 DPRINTF("x_ppem: %d\ny_ppem: %d\nx_scale: %d\ny_scale: %d\n\ x_resolution: %d\ny_resolution: %d\n", imetrics.x_ppem, imetrics.y_ppem, imetrics.x_scale, \ imetrics.y_scale, imetrics.x_resolution, imetrics.y_resolution); DPRINTF("Ascender: %d\nDescender: %d\nxMax_Extent: %d\n\ Mac Style Say Italic?: %d\nMac Style Say Bold?: %d\n\ sTypoAscender: %d\nsTypoDescender: %d\nusWinAscent: %d\n\ usWinDescent: %d\nusFirstCharIndex: %d\nusLastCharIndex: %d\n\ OS2 Say Italic?: %d\nOS2 Say Bold?: %d\nOS2 Say monospaced?: %d\n\ Postscript Say monospaced?: %d\n",\ properties.horizontal->Ascender, properties.horizontal->Descender, properties.horizontal->xMax_Extent, (properties.header->Mac_Style & 0x2)?1:0, (properties.header->Mac_Style & 0x1)?1:0, properties.os2->sTypoAscender, properties.os2->sTypoDescender, properties.os2->usWinAscent, properties.os2->usWinDescent, properties.os2->usFirstCharIndex, properties.os2->usLastCharIndex, (properties.os2->fsSelection & 0x1)?1:0, (properties.os2->fsSelection & 0x20)?1:0, properties.postscript->isFixedPitch, (properties.os2->panose[3] == 9)?1:0);#endif return TRUE;}static voidfreetype_gettextsize(PMWFONT pfont, const void *text, int cc, MWTEXTFLAGS flags, MWCOORD *pwidth, MWCOORD *pheight, MWCOORD *pbase){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; const unsigned short * str = text; TT_F26Dot6 x = 0; int i; TT_UShort curchar; TT_Glyph_Metrics metrics; TT_Face_Properties properties; TT_Instance_Metrics imetrics; TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); pf->last_glyph_code = -1; /* reset kerning*/ pf->last_pen_pos = -32767; for (i = 0; i < cc; i++) { curchar = TT_Char_Index (pf->char_map, str[i]); if (TT_Load_Glyph (pf->instance, pf->glyph, curchar, TTLOAD_SCALE_GLYPH|TTLOAD_HINT_GLYPH) != TT_Err_Ok) continue; TT_Get_Glyph_Metrics (pf->glyph, &metrics); if ((pf->fontattr&MWTF_KERNING) && pf->can_kern) { x += compute_kernval(pf, curchar) / 64; } x += metrics.advance / 64; /* Kerning point syndrome avoidance */ if (pf->last_pen_pos > x) x = pf->last_pen_pos; pf->last_pen_pos = x; pf->last_glyph_code = curchar; } *pwidth = x; *pheight = (((properties.horizontal->Ascender * imetrics.y_scale)/ 0x10000) >> 6) - (((properties.horizontal->Descender * imetrics.y_scale)/ 0x10000) >> 6); /* FIXME: is it what's required ?? */ *pbase = (((-properties.horizontal->Descender) * imetrics.y_scale)/ 0x10000) >> 6;}static voidfreetype_destroyfont(PMWFONT pfont){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; TT_Close_Face(pf->face); free(pf);}static voidfreetype_setfontsize(PMWFONT pfont, MWCOORD fontsize){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; pf->fontsize = fontsize; /* allow create font with height=0*/ if (!fontsize) return; /* We want real pixel sizes ... not points ...*/ TT_Set_Instance_PixelSizes( pf->instance, pf->fontsize, pf->fontsize, pf->fontsize * 64 );#if 0 /* set charsize (convert to points for freetype)*/ TT_Set_Instance_CharSize (pf->instance, ((pf->fontsize * 72 + 96/2) / 96) * 64);#endif}static voidfreetype_setfontrotation(PMWFONT pfont, int tenthdegrees){ PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; float angle; pf->fontrotation = tenthdegrees; /* Build the rotation matrix with the given angle */ TT_Set_Instance_Transform_Flags (pf->instance, TRUE, FALSE); angle = pf->fontrotation * M_PI / 1800; pf->matrix.yy = (TT_Fixed) (cos (angle) * (1 << 16)); pf->matrix.yx = (TT_Fixed) (sin (angle) * (1 << 16)); pf->matrix.xx = pf->matrix.yy; pf->matrix.xy = -pf->matrix.yx;}/* FIXME: this routine should work for all font renderers...*/intGdGetTextSizeEx(PMWFONT pfont, const void *str, int cc,int nMaxExtent, int* lpnFit, int* alpDx,MWCOORD *pwidth,MWCOORD *pheight, MWCOORD *pbase, MWTEXTFLAGS flags){ unsigned short buf[256]; unsigned short* text; PMWFREETYPEFONT pf = (PMWFREETYPEFONT)pfont; MWTEXTFLAGS defencoding = pf->fontprocs->encoding; int x = 0; int i; TT_UShort curchar; TT_Glyph_Metrics metrics; TT_Face_Properties properties; TT_Instance_Metrics imetrics; if ((cc<0)||(!str)) { *pwidth = *pheight = *pbase = 0; return 0; } /* convert encoding if required*/ if((flags & (MWTF_PACKMASK|MWTF_DBCSMASK)) != defencoding) { cc = GdConvertEncoding(str, flags, cc, buf, defencoding); flags &= ~(MWTF_PACKMASK|MWTF_DBCSMASK); flags |= defencoding; text=buf; } else text =(unsigned short*)str; if(cc <= 0) { *pwidth = *pheight = *pbase = 0; return 0; } TT_Get_Face_Properties (pf->face, &properties); TT_Get_Instance_Metrics(pf->instance, &imetrics); pf->last_glyph_code = -1; /* reset kerning*/ pf->last_pen_pos = -32767; if (lpnFit) *lpnFit=-1; for (i = 0; i < cc; i++) { curchar = TT_Char_Index (pf->char_map,text[i]); if (TT_Load_Glyph (pf->instance, pf->glyph, curchar, TTLOAD_SCALE_GLYPH|TTLOAD_HINT_GLYPH) != TT_Err_Ok) { printf("Unable to load glyph with index=%d\n",curchar); return 0; } TT_Get_Glyph_Metrics (pf->glyph, &metrics); if ((pf->fontattr&MWTF_KERNING) && pf->can_kern) { x += compute_kernval(pf, curchar) / 64; } x += metrics.advance / 64; if((lpnFit)&&(alpDx)) { if (x<=nMaxExtent) alpDx[i]=x; else if (*lpnFit==-1) (*lpnFit)=i; } /* Kerning point syndrome avoidance */ if (pf->last_pen_pos > x) x = pf->last_pen_pos; pf->last_pen_pos = x; pf->last_glyph_code = curchar; } if ((lpnFit)&&(*lpnFit==-1)) *lpnFit=cc; *pwidth = x; *pheight = (((properties.horizontal->Ascender * imetrics.y_scale)/ 0x10000) >> 6) - (((properties.horizontal->Descender * imetrics.y_scale)/ 0x10000) >> 6); /* FIXME: is it what's required ??*/ if (pbase) *pbase = (((-properties.horizontal->Descender) * imetrics.y_scale)/ 0x10000) >> 6; return 1;}/* * This function is taken almost verbatim from ftdump.c from * the freetype library (version 1.3.1) */static char *tt_lookup_name(TT_Face face){ TT_Face_Properties prop; unsigned short i, n; unsigned short platform, encoding, language, id; char *string; char *name_buffer; unsigned short string_len; int j, found; int index = 4; /* I dont know why as yet.. */ int name_len; TT_Get_Face_Properties(face, &prop); n = prop.num_Names; for ( i = 0; i < n; i++ ) { TT_Get_Name_ID( face, i, &platform, &encoding, &language, &id ); TT_Get_Name_String( face, i, &string, &string_len ); if (id == index ) { /* The following code was inspired from Mark Leisher's */ /* ttf2bdf package */ found = 0; /* Try to find a Microsoft English name */ if ( platform == 3 ) for ( j = 1; j >= 0; j-- ) if ( encoding == j ) /* Microsoft ? */ if ( (language & 0x3FF) == 0x009 ) { /* English language */ found = 1; break; } if ( !found && platform == 0 && language == 0 ) found = 1; /* Found a Unicode Name. */ if ( found ) { if ( string_len > 512 ) string_len = 512; name_len = 0; name_buffer = (char*)malloc((string_len / 2) + 1); for ( i = 1; i < string_len; i += 2 ) name_buffer[name_len++] = string[i]; name_buffer[name_len] = '\0'; return name_buffer; } } } /* Not found */ return NULL;}static char *get_tt_name(char *p){ TT_Face face; char *ret; /*printf("Trying to open: %s!\n",p);*/ if (TT_Open_Face(engine, p, &face) != TT_Err_Ok) { printf("Error opening font: %s\n", p); return NULL; } ret = tt_lookup_name(face); TT_Close_Face(face); return ret;}voidGdFreeFontList(MWFONTLIST ***fonts, int n){ int i; MWFONTLIST *g, **list = *fonts; for (i = 0; i < n; i++) { g = list[i]; if(g) { if(g->mwname) free(g->mwname); if(g->ttname) free(g->ttname); free(g); } } free(list); *fonts = 0;}voidGdGetFontList(MWFONTLIST ***fonts, int *numfonts){ DIR *dir; struct dirent *dent; char *p, *ftmp; int pl, idx = 0; MWFONTLIST **list; if (TT_Err_Ok != TT_Init_FreeType(&engine)) { printf("Unable to initialize freetype\n"); *numfonts = -1; return ; } dir = opendir(FREETYPE_FONT_DIR); if (dir <= 0) { printf("Error opening font directory\n"); *numfonts = -1; return ; } /* get the number of strings we need to allocate */ while ((dent = readdir(dir)) != NULL) { p = strrchr(dent->d_name, '.'); if (strcasecmp(p, ".ttf") == 0) idx++; } *numfonts = idx; rewinddir(dir); /* allocate strings */ list = (MWFONTLIST**)malloc(idx * sizeof(MWFONTLIST*)); for (pl = 0; pl < idx; pl++) list[pl] = (MWFONTLIST*)malloc(sizeof(MWFONTLIST)); *fonts = list; idx = 0; while ((dent = readdir(dir)) != NULL) { /* check extension */ p = strrchr(dent->d_name, '.'); if (strcasecmp(p, ".ttf") == 0) { /* get full path */ p = 0; pl = strlen(FREETYPE_FONT_DIR) + strlen(dent->d_name) * sizeof(char) + 2; p = (char*)malloc(pl); p = (char*)memset(p, '\0', pl); p = (char*)strcat(p, FREETYPE_FONT_DIR); p = (char*)strcat(p, "/"); p = (char*)strcat(p, dent->d_name); if((ftmp = get_tt_name(p)) != NULL) { list[idx]->ttname = ftmp; list[idx]->mwname = malloc(strlen(dent->d_name) + 1); list[idx]->mwname = strcpy(list[idx]->mwname, dent->d_name); idx++; } free(p); } } closedir(dir);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -