EXPORT_FUNC TT_Error TT_Load_Kerning_Table( TT_Face face, TT_UShort kern_index ) { TT_Error error; TT_Stream stream; TT_Kerning* kern; TT_Kern_Subtable* sub; PFace faze = HANDLE_Face( face ); if ( !faze ) return TT_Err_Invalid_Face_Handle; error = TT_Extension_Get( faze, KERNING_ID, (void**)&kern ); if ( error ) return error; if ( kern->nTables == 0 ) return TT_Err_Table_Missing; if ( kern_index >= kern->nTables ) return TT_Err_Invalid_Argument; sub = kern->tables + kern_index; if ( sub->format != 0 && sub->format != 2 ) return TT_Err_Invalid_Kerning_Table_Format; /* now access stream */ if ( USE_Stream( faze->stream, stream ) ) return error; if ( FILE_Seek( sub->offset ) ) goto Fail; if ( sub->format == 0 ) error = Subtable_Load_0( &sub->t.kern0, faze ); else if ( sub->format == 2 ) error = Subtable_Load_2( &sub->t.kern2, faze ); if ( !error ) sub->loaded = TRUE; Fail: /* release stream */ DONE_Stream( stream ); return error; }
TT_Get_Kerning_Directory( TT_Face face, TT_Kerning* directory ) { PFace faze = HANDLE_Face( face ); TT_Error error; TT_Kerning* kerning; if ( !faze ) return TT_Err_Invalid_Face_Handle; /* copy directory header */ error = TT_Extension_Get( faze, KERNING_ID, (void**)&kerning ); if ( !error ) *directory = *kerning; return error; }
EXPORT_FUNC TT_Error TT_Get_Face_Gasp_Flags( TT_Face face, TT_UShort point_size, TT_Bool* grid_fit, TT_Bool* smooth_font ) { PFace faze = HANDLE_Face( face ); UShort i, flag; if ( !faze ) return TT_Err_Invalid_Face_Handle; if ( faze->gasp.numRanges == 0 || !faze->gasp.gaspRanges ) return TT_Err_Table_Missing; for ( i = 0; i < faze->gasp.numRanges; i++ ) { if ( point_size <= faze->gasp.gaspRanges[i].maxPPEM ) { flag = faze->gasp.gaspRanges[i].gaspFlag; *grid_fit = ( (flag & GASP_GRIDFIT) != 0 ); *smooth_font = ( (flag & GASP_DOGRAY ) != 0 ); return TT_Err_Ok; } } /* for very large fonts we enable font smoothing and discard */ /* grid fitting */ *grid_fit = 0; *smooth_font = 1; return TT_Err_Ok; }
TT_Get_Face_Widths( TT_Face face, TT_UShort first_glyph, TT_UShort last_glyph, TT_UShort* widths, TT_UShort* heights ) { DEFINE_ALL_LOCALS; PFace faze = HANDLE_Face(face); UShort n; Long table; ULong glyf_offset; /* offset of glyph table in file */ UShort zero_width = 0; /* width of glyph 0 */ UShort zero_height = 0; /* height of glyph 0 */ Bool zero_loaded = 0; #ifndef TT_HUGE_PTR PStorage locations; #else Storage TT_HUGE_PTR * locations; #endif TT_BBox bbox; if ( !faze ) return TT_Err_Invalid_Face_Handle; if ( last_glyph >= faze->numGlyphs || first_glyph > last_glyph ) return TT_Err_Invalid_Argument; /* find "glyf" table */ table = TT_LookUp_Table( faze, TTAG_glyf ); if ( table < 0 ) { PERROR(( "ERROR: there is no glyph table in this font file!\n" )); return TT_Err_Glyf_Table_Missing; } glyf_offset = faze->dirTables[table].Offset; /* now access stream */ if ( USE_Stream( faze->stream, stream ) ) return error; locations = faze->glyphLocations + first_glyph; /* loop to load each glyph in the range */ for ( n = first_glyph; n <= last_glyph; n++ ) { if ( n + 1 < faze->numGlyphs && locations[0] == locations[1] ) { /* Note : Glyph 0 is always used to indicate a missing glyph */ /* in a range. We must thus return its width and height */ /* where appropriate when we find an undefined glyph. */ if ( zero_loaded == 0 ) { if ( FILE_Seek( glyf_offset + faze->glyphLocations[0] ) || ACCESS_Frame( 10L ) ) goto Fail; (void)GET_Short(); /* skip number of contours */ bbox.xMin = GET_Short(); bbox.yMin = GET_Short(); bbox.xMax = GET_Short(); bbox.yMax = GET_Short(); FORGET_Frame(); zero_width = (UShort)(bbox.xMax - bbox.xMin); zero_height = (UShort)(bbox.yMax - bbox.yMin); zero_loaded = 1; } if ( widths ) *widths++ = zero_width; if ( heights ) *heights++ = zero_height; } else { /* normal glyph, read header */ if ( FILE_Seek( glyf_offset + locations[0] ) || ACCESS_Frame( 10L ) ) goto Fail; (void)GET_Short(); /* skip number of contours */ bbox.xMin = GET_Short(); bbox.yMin = GET_Short(); bbox.xMax = GET_Short(); bbox.yMax = GET_Short(); FORGET_Frame(); if ( widths ) *widths++ = (UShort)(bbox.xMax - bbox.xMin); if ( heights ) *heights++ = (UShort)(bbox.yMax - bbox.yMin); } } Fail: DONE_Stream( stream ); return error; }