af_autofitter_load_glyph( AF_Module module, FT_GlyphSlot slot, FT_Size size, FT_UInt glyph_index, FT_Int32 load_flags ) { FT_Error error = FT_Err_Ok; FT_Memory memory = module->root.library->memory; #ifdef FT_DEBUG_AUTOFIT /* in debug mode, we use a global object that survives this routine */ AF_GlyphHints hints = _af_debug_hints_rec; AF_LoaderRec loader[1]; FT_UNUSED( size ); if ( hints->memory ) af_glyph_hints_done( hints ); af_glyph_hints_init( hints, memory ); af_loader_init( loader, hints ); error = af_loader_load_glyph( loader, module, slot->face, glyph_index, load_flags ); af_glyph_hints_dump_points( hints, 0 ); af_glyph_hints_dump_segments( hints, 0 ); af_glyph_hints_dump_edges( hints, 0 ); af_loader_done( loader ); return error; #else /* !FT_DEBUG_AUTOFIT */ AF_GlyphHintsRec hints[1]; AF_LoaderRec loader[1]; FT_UNUSED( size ); af_glyph_hints_init( hints, memory ); af_loader_init( loader, hints ); error = af_loader_load_glyph( loader, module, slot->face, glyph_index, load_flags ); af_loader_done( loader ); af_glyph_hints_done( hints ); return error; #endif /* !FT_DEBUG_AUTOFIT */ }
af_autofitter_done( FT_Module ft_module ) /* AF_Module */ { FT_UNUSED( ft_module ); #ifdef FT_DEBUG_AUTOFIT if ( _af_debug_hints_rec->memory ) af_glyph_hints_done( _af_debug_hints_rec ); #endif }
af_loader_done( AF_Loader loader ) { af_glyph_hints_done( &loader->hints ); loader->face = NULL; loader->globals = NULL; FT_GlyphLoader_Done( loader->gloader ); loader->gloader = NULL; }
af_loader_done( AF_Loader loader ) { af_glyph_hints_done( &loader->hints ); loader->face = NULL; loader->globals = NULL; #ifdef FT_DEBUG_AUTOFIT _af_debug_hints = NULL; #endif FT_GlyphLoader_Done( loader->gloader ); loader->gloader = NULL; }
af_latin_metrics_init_widths( AF_LatinMetrics metrics, FT_Face face, FT_ULong charcode ) { /* scan the array of segments in each direction */ AF_GlyphHintsRec hints[1]; af_glyph_hints_init( hints, face->memory ); metrics->axis[AF_DIMENSION_HORZ].width_count = 0; metrics->axis[AF_DIMENSION_VERT].width_count = 0; { FT_Error error; FT_UInt glyph_index; int dim; AF_LatinMetricsRec dummy[1]; AF_Scaler scaler = &dummy->root.scaler; glyph_index = FT_Get_Char_Index( face, charcode ); if ( glyph_index == 0 ) goto Exit; error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE ); if ( error || face->glyph->outline.n_points <= 0 ) goto Exit; FT_ZERO( dummy ); dummy->units_per_em = metrics->units_per_em; scaler->x_scale = scaler->y_scale = 0x10000L; scaler->x_delta = scaler->y_delta = 0; scaler->face = face; scaler->render_mode = FT_RENDER_MODE_NORMAL; scaler->flags = 0; af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy ); error = af_glyph_hints_reload( hints, &face->glyph->outline, 0 ); if ( error ) goto Exit; for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { AF_LatinAxis axis = &metrics->axis[dim]; AF_AxisHints axhints = &hints->axis[dim]; AF_Segment seg, limit, link; FT_UInt num_widths = 0; error = af_latin_hints_compute_segments( hints, (AF_Dimension)dim ); if ( error ) goto Exit; af_latin_hints_link_segments( hints, (AF_Dimension)dim ); seg = axhints->segments; limit = seg + axhints->num_segments; for ( ; seg < limit; seg++ ) { link = seg->link; /* we only consider stem segments there! */ if ( link && link->link == seg && link > seg ) { FT_Pos dist; dist = seg->pos - link->pos; if ( dist < 0 ) dist = -dist; if ( num_widths < AF_LATIN_MAX_WIDTHS ) axis->widths[ num_widths++ ].org = dist; } } af_sort_widths( num_widths, axis->widths ); axis->width_count = num_widths; } Exit: for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ ) { AF_LatinAxis axis = &metrics->axis[dim]; FT_Pos stdw; stdw = ( axis->width_count > 0 ) ? axis->widths[0].org : AF_LATIN_CONSTANT( metrics, 50 ); /* let's try 20% of the smallest width */ axis->edge_distance_threshold = stdw / 5; axis->standard_width = stdw; axis->extra_light = 0; } } af_glyph_hints_done( hints ); }