22 #ifdef WITH_TRUETYPE_FONTS
31 static TT_Engine tt_handle;
34 typedef struct ftinfo {
54 static void tt_shrink_glyph
56 static void tt_font_remove
__PROTO((FTInfo *));
72 #define FT_HASH_SIZE 31
74 static ListHead ttfonts = {NULL, NULL, 0};
76 static int init_freetype(
void)
81 code = TT_Init_FreeType(&tt_handle);
83 DEBUG((
DBG_TT,
"(tt) Init_Freetype: error %d\n", code));
86 code = TT_Init_Post_Extension(tt_handle);
88 TT_Done_FreeType(tt_handle);
96 static void tt_encode_font(
DviFont *font, FTInfo *info)
98 TT_Face_Properties prop;
101 if(TT_Get_Face_Properties(info->face, &prop))
104 for(i = 0; i < prop.num_Glyphs; i++) {
108 if(TT_Get_PS_Name(info->face, i, &
string))
111 if(ndx < font->loc || ndx > font->
hic)
117 static int tt_really_load_font(
DviParams *params,
DviFont *font, FTInfo *info)
121 Int32 z, alpha, beta;
126 static int warned = 0;
128 TT_Face_Properties props;
131 DEBUG((
DBG_TT,
"(tt) really_load_font(%s)\n", info->fontname));
134 point_size = (double)font->
scale / (params->
tfm_conv * 0x100000);
135 point_size = 72.0 * point_size / 72.27;
138 TT_Set_Instance_Resolutions(info->instance,
140 TT_Set_Instance_CharSize(info->instance,
FROUND(point_size * 64));
142 info->hasmetrics = 1;
149 status = TT_Open_Face(tt_handle, font->
filename, &info->face);
152 info->fontname, TT_ErrToString18(status));
157 status = TT_New_Instance(info->face, &info->instance);
160 info->fontname, TT_ErrToString18(status));
161 TT_Close_Face(info->face);
166 status = TT_New_Glyph(info->face, &info->glyph);
169 info->fontname, TT_ErrToString18(status));
178 TT_Get_Face_Properties(info->face, &props);
181 for(i = 0; map_found < 0 && i < props.num_CharMaps; i++) {
184 TT_Get_CharMap_ID(info->face, i, &pid, &eid);
186 case TT_PLATFORM_APPLE_UNICODE:
189 case TT_PLATFORM_ISO:
190 if(eid == TT_ISO_ID_7BIT_ASCII ||
191 eid == TT_ISO_ID_8859_1)
194 case TT_PLATFORM_MICROSOFT:
195 if(eid == TT_MS_ID_UNICODE_CS)
201 mdvi_warning(
_(
"(tt) %s: no acceptable map found, using #0\n"),
206 info->fontname, map_found));
207 TT_Get_CharMap(info->face, map_found, &cmap);
209 DEBUG((
DBG_TT,
"(tt) %s: Set_Char_Size(%.2f, %d, %d)\n",
211 status = TT_Set_Instance_Resolutions(info->instance,
214 error(
_(
"(tt) %s: could not set resolution: %s\n"),
215 info->fontname, TT_ErrToString18(status));
218 status = TT_Set_Instance_CharSize(info->instance,
221 error(
_(
"(tt) %s: could not set point size: %s\n"),
222 info->fontname, TT_ErrToString18(status));
230 if(!status && info->mapinfo.encoding)
233 info->encoding = NULL;
235 if(info->encoding != NULL) {
238 status = TT_Load_PS_Names(info->face, &post);
243 info->encoding = NULL;
249 info->fmftype, info->fmfname);
251 if(info->tfminfo == NULL) {
252 mdvi_warning(
"(tt) %s: no metrics data, font ignored\n",
257 font->
design = info->tfminfo->design;
263 tt_encode_font(font, info);
265 mdvi_warning(
_(
"%s: no encoding vector found, expect bad output\n"),
268 for(i = font->
loc; i <= font->hic; i++)
269 font->
chars[i - font->
loc].
code = TT_Char_Index(cmap, i);
273 info->hasmetrics = 1;
277 tt_font_remove(info);
280 font->
loc = font->
hic = 0;
292 if(font->
in != NULL) {
303 info->hasmetrics = 0;
307 info->mapinfo.psname = NULL;
308 info->mapinfo.encoding = NULL;
309 info->mapinfo.fontfile = NULL;
310 info->mapinfo.extend = 0;
311 info->mapinfo.slant = 0;
317 for(i = 0; i < 256; i++) {
324 if(info->fmfname == NULL)
334 int code,
double xscale,
double yscale,
DviGlyph *glyph)
337 TT_Raster_Map raster;
339 TT_Glyph_Metrics metrics;
343 int have_outline = 0;
346 info = (FTInfo *)font->
private;
350 error = TT_Load_Glyph(info->instance, info->glyph,
351 code, TTLOAD_DEFAULT);
352 if(error)
goto tt_error;
353 error = TT_Get_Glyph_Outline(info->glyph, &outline);
354 if(error)
goto tt_error;
356 mat.xx =
FROUND(xscale * 65536);
357 mat.yy =
FROUND(yscale * 65536);
360 TT_Transform_Outline(&outline, &mat);
361 error = TT_Get_Outline_BBox(&outline, &bbox);
362 if(error)
goto tt_error;
365 bbox.xMax = (bbox.xMax + 63) & -64;
366 bbox.yMax = (bbox.yMax + 63) & -64;
367 w = (bbox.xMax - bbox.xMin) / 64;
368 h = (bbox.yMax - bbox.yMin) / 64;
372 glyph->
x = -bbox.xMin / 64;
373 glyph->
y = bbox.yMax / 64;
378 raster.cols =
ROUND(w, 8);
379 raster.size = h * raster.cols;
380 raster.flow = TT_Flow_Down;
383 TT_Translate_Outline(&outline, -bbox.xMin, -bbox.yMin);
384 TT_Get_Outline_Bitmap(tt_handle, &outline, &raster);
386 TT_Done_Outline(&outline);
392 TT_Done_Outline(&outline);
398 FTInfo *info = (FTInfo *)font->
private;
405 if(!info->hasmetrics && tt_really_load_font(params, font, info) < 0)
419 error = tt_get_bitmap(params, font, ch->
code,
420 (
double)font->
hdpi / dpi,
421 (
double)font->
vdpi / dpi,
443 tt_get_bitmap(&dvi->
params, font,
452 static void tt_reset_font(
DviFont *font)
454 FTInfo *info = (FTInfo *)font->
private;
458 info->hasmetrics = 0;
461 static void tt_font_remove(FTInfo *info)
467 TT_Done_Instance(info->instance);
468 TT_Close_Face(info->face);
482 static void tt_free_data(
DviFont *font)
487 tt_font_remove((FTInfo *)font->
private);
489 DEBUG((
DBG_TT,
"(tt) last font removed -- closing FreeType\n"));
490 TT_Done_FreeType(tt_handle);