FT_Error tt_driver_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; TTModulePIC* container = NULL; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->truetype = container; /* initialize pointer table - this is how the module usually */ /* expects this data */ error = FT_Create_Class_tt_services( library, &container->tt_services ); if ( error ) goto Exit; #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT FT_Init_Class_tt_service_gx_multi_masters( &container->tt_service_gx_multi_masters ); #endif FT_Init_Class_tt_service_truetype_glyf( &container->tt_service_truetype_glyf ); Exit: if ( error ) tt_driver_class_pic_free( library ); return error; }
FT_Error cff_driver_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; CffModulePIC* container; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof(*container) ); pic_container->cff = container; /* initialize pointer table - this is how the module usually expects this data */ error = FT_Create_Class_cff_services(library, &container->cff_services); if(error) goto Exit; error = FT_Create_Class_cff_field_handlers(library, &container->cff_field_handlers); if(error) goto Exit; FT_Init_Class_cff_service_ps_info(library, &container->cff_service_ps_info); FT_Init_Class_cff_service_glyph_dict(library, &container->cff_service_glyph_dict); FT_Init_Class_cff_service_ps_name(library, &container->cff_service_ps_name); FT_Init_Class_cff_service_get_cmap_info(library, &container->cff_service_get_cmap_info); FT_Init_Class_cff_service_cid_info(library, &container->cff_service_cid_info); FT_Init_Class_cff_cmap_encoding_class_rec(library, &container->cff_cmap_encoding_class_rec); FT_Init_Class_cff_cmap_unicode_class_rec(library, &container->cff_cmap_unicode_class_rec); Exit: if(error) cff_driver_class_pic_free(library); return error; }
FT_Error ft_raster1_renderer_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; RasterPIC* container = NULL; FT_Memory memory = library->memory; /* XXX: since this function also served the no longer available */ /* raster5 renderer it uses reference counting, which could */ /* be removed now */ if ( pic_container->raster ) { ((RasterPIC*)pic_container->raster)->ref_count++; return error; } /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->raster = container; container->ref_count = 1; /* initialize pointer table - */ /* this is how the module usually expects this data */ FT_Init_Class_ft_standard_raster( &container->ft_standard_raster ); return error; }
FT_Error ft_smooth_renderer_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; SmoothPIC* container = NULL; FT_Memory memory = library->memory; /* since this function also serve smooth_lcd and smooth_lcdv renderers, it implements reference counting */ if ( pic_container->smooth ) { ((SmoothPIC*)pic_container->smooth)->ref_count++; return error; } /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->smooth = container; container->ref_count = 1; /* initialize pointer table - */ /* this is how the module usually expects this data */ FT_Init_Class_ft_grays_raster( &container->ft_grays_raster ); return error; }
FT_Error psnames_module_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = PSnames_Err_Ok; PSModulePIC* container; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof(*container) ); pic_container->psnames = container; /* initialize pointer table - this is how the module usually expects this data */ error = FT_Create_Class_pscmaps_services(library, &container->pscmaps_services); if(error) goto Exit; FT_Init_Class_pscmaps_interface(library, &container->pscmaps_interface); Exit: if(error) psnames_module_class_pic_free(library); return error; }
FT_Alloc( FT_Memory memory, FT_Long size, void* *P ) { FT_ASSERT( P != 0 ); if ( size > 0 ) { *P = memory->alloc( memory, size ); if ( !*P ) { FT_ERROR(( "FT_Alloc:" )); FT_ERROR(( " Out of memory? (%ld requested)\n", size )); return FT_Err_Out_Of_Memory; } FT_MEM_SET( *P, 0, size ); } else *P = NULL; FT_TRACE7(( "FT_Alloc:" )); FT_TRACE7(( " size = %ld, block = 0x%08p, ref = 0x%08p\n", size, *P, P )); return FT_Err_Ok; }
FT_Error sfnt_module_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; sfntModulePIC* container; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof(*container) ); pic_container->sfnt = container; /* initialize pointer table - this is how the module usually expects this data */ error = FT_Create_Class_sfnt_services(library, &container->sfnt_services); if(error) goto Exit; error = FT_Create_Class_tt_cmap_classes(library, &container->tt_cmap_classes); if(error) goto Exit; FT_Init_Class_sfnt_service_glyph_dict(library, &container->sfnt_service_glyph_dict); FT_Init_Class_sfnt_service_ps_name(library, &container->sfnt_service_ps_name); FT_Init_Class_tt_service_get_cmap_info(library, &container->tt_service_get_cmap_info); FT_Init_Class_sfnt_service_sfnt_table(&container->sfnt_service_sfnt_table); #ifdef TT_CONFIG_OPTION_BDF FT_Init_Class_sfnt_service_bdf(&container->sfnt_service_bdf); #endif FT_Init_Class_sfnt_interface(library, &container->sfnt_interface); Exit: if(error) sfnt_module_class_pic_free(library); return error; }
FT_Error ft_raster1_renderer_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = Raster_Err_Ok; RasterPIC* container; FT_Memory memory = library->memory; /* since this function also serve raster5 renderer, it implements reference counting */ if ( pic_container->raster ) { ((RasterPIC*)pic_container->raster)->ref_count++; return error; } /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->raster = container; container->ref_count = 1; /* initialize pointer table - this is how the module usually expects this data */ FT_Init_Class_ft_standard_raster( &container->ft_standard_raster ); /*Exit:*/ if( error ) ft_raster1_renderer_class_pic_free( library ); return error; }
/* return the glyph's control box */ static void ft_smooth_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox ) { FT_MEM_SET( cbox, 0, sizeof ( *cbox ) ); if ( slot->format == render->glyph_format ) FT_Outline_Get_CBox( &slot->outline, cbox ); }
ft_pic_container_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; FT_MEM_SET( pic_container, 0, sizeof ( *pic_container ) ); error = ft_base_pic_init( library ); if ( error ) return error; return FT_Err_Ok; }
static FT_MemTable ft_mem_table_new( FT_Memory memory ) { FT_MemTable table; table = (FT_MemTable)memory->alloc( memory, sizeof ( *table ) ); if ( table == NULL ) goto Exit; FT_MEM_SET( table, 0, sizeof ( *table ) ); table->size = FT_MEM_SIZE_MIN; table->nodes = 0; table->memory = memory; table->memory_user = memory->user; table->alloc = memory->alloc; table->realloc = memory->realloc; table->free = memory->free; table->buckets = (FT_MemNode *) memory->alloc( memory, table->size * sizeof ( FT_MemNode ) ); if ( table->buckets ) FT_MEM_SET( table->buckets, 0, sizeof ( FT_MemNode ) * table->size ); else { memory->free( memory, table ); table = NULL; } Exit: return table; }
FT_Error autofit_module_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_UInt ss; FT_Error error = AF_Err_Ok; AFModulePIC* container; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->autofit = container; /* initialize pointer table - */ /* this is how the module usually expects this data */ for ( ss = 0 ; ss < AF_SCRIPT_CLASSES_REC_COUNT ; ss++ ) { container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; } container->af_script_classes[AF_SCRIPT_CLASSES_COUNT - 1] = NULL; /* add call to initialization function when you add new scripts */ ss = 0; FT_Init_Class_af_dummy_script_class( &container->af_script_classes_rec[ss++] ); #ifdef FT_OPTION_AUTOFIT2 FT_Init_Class_af_latin2_script_class( &container->af_script_classes_rec[ss++] ); #endif FT_Init_Class_af_latin_script_class( &container->af_script_classes_rec[ss++] ); FT_Init_Class_af_cjk_script_class( &container->af_script_classes_rec[ss++] ); FT_Init_Class_af_indic_script_class( &container->af_script_classes_rec[ss++] ); FT_Init_Class_af_autofitter_service( library, &container->af_autofitter_service ); /* Exit: */ if ( error ) autofit_module_class_pic_free( library ); return error; }
static void ft_mem_table_resize( FT_MemTable table ) { FT_ULong new_size; new_size = ft_mem_closest_prime( table->nodes ); if ( new_size != table->size ) { FT_MemNode* new_buckets ; FT_ULong i; new_buckets = (FT_MemNode *) ft_mem_table_alloc( table, new_size * sizeof ( FT_MemNode ) ); if ( new_buckets == NULL ) return; FT_MEM_SET( new_buckets, 0, sizeof ( FT_MemNode ) * new_size ); for ( i = 0; i < table->size; i++ ) { FT_MemNode node, next, *pnode; FT_ULong hash; node = table->buckets[i]; while ( node ) { next = node->link; hash = FT_MEM_VAL( node->address ) % new_size; pnode = new_buckets + hash; node->link = pnode[0]; pnode[0] = node; node = next; } } if ( table->buckets ) ft_mem_table_free( table, table->buckets ); table->buckets = new_buckets; table->size = new_size; } }
FT_Error pshinter_module_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; PSHinterPIC* container; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof(*container) ); pic_container->pshinter = container; /* add call to initialization function when you add new scripts */ FT_Init_Class_pshinter_interface(library, &container->pshinter_interface); /*Exit:*/ if(error) pshinter_module_class_pic_free(library); return error; }
T1_Decoder_Init( T1_Decoder decoder, FT_Face face, FT_Size size, FT_GlyphSlot slot, FT_Byte** glyph_names, PS_Blend blend, FT_Bool hinting, T1_Decoder_Callback parse_callback ) { FT_MEM_SET( decoder, 0, sizeof ( *decoder ) ); /* retrieve PSNames interface from list of current modules */ { PSNames_Service psnames = 0; psnames = (PSNames_Service)FT_Get_Module_Interface( FT_FACE_LIBRARY(face), "psnames" ); if ( !psnames ) { FT_ERROR(( "T1_Decoder_Init: " )); FT_ERROR(( "the `psnames' module is not available\n" )); return PSaux_Err_Unimplemented_Feature; } decoder->psnames = psnames; } T1_Builder_Init( &decoder->builder, face, size, slot, hinting ); decoder->num_glyphs = face->num_glyphs; decoder->glyph_names = glyph_names; decoder->blend = blend; decoder->parse_callback = parse_callback; decoder->funcs = t1_decoder_funcs; return 0; }
static void ft_mem_table_remove( FT_MemTable table, FT_Byte* address ) { if ( table ) { FT_MemNode *pnode, node; pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { if ( node->size < 0 ) ft_mem_debug_panic( "freeing memory block at %p more than once at (%s:%ld)\n" "block allocated at (%s:%ld) and released at (%s:%ld)", address, FT_FILENAME( table->file_name ), table->line_no, FT_FILENAME( node->alloc_file_name ), node->alloc_line_no, FT_FILENAME( node->free_file_name ), node->free_line_no ); /* we simply invert the node's size to indicate that the node */ /* was freed. We also change its contents. */ FT_MEM_SET( address, 0xF3, node->size ); table->alloc_current -= node->size; node->size = -node->size; node->free_file_name = table->file_name; node->free_line_no = table->line_no; } else ft_mem_debug_panic( "trying to free unknown block at %p in (%s:%ld)\n", address, FT_FILENAME( table->file_name ), table->line_no ); } }
static OSErr FT_FSpMakePath( const FSSpec* spec_p, UInt8* path, UInt32 maxPathSize ) { OSErr err; FSSpec spec = *spec_p; short vRefNum; long dirID; Str255 parDir_name; FT_MEM_SET( path, 0, maxPathSize ); while ( 1 ) { int child_namelen = ft_strlen( (char *)path ); unsigned char node_namelen = spec.name[0]; unsigned char* node_name = spec.name + 1; if ( node_namelen + child_namelen > maxPathSize ) return errFSNameTooLong; FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen ); FT_MEM_COPY( path, node_name, node_namelen ); if ( child_namelen > 0 ) path[node_namelen] = ':'; vRefNum = spec.vRefNum; dirID = spec.parID; parDir_name[0] = '\0'; err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec ); if ( noErr != err || dirID == spec.parID ) break; } return noErr; }
FT_Realloc( FT_Memory memory, FT_Long current, FT_Long size, void** P ) { void* Q; FT_ASSERT( P != 0 ); /* if the original pointer is NULL, call FT_Alloc() */ if ( !*P ) return FT_Alloc( memory, size, P ); /* if the new block if zero-sized, clear the current one */ if ( size <= 0 ) { FT_Free( memory, P ); return FT_Err_Ok; } Q = memory->realloc( memory, current, size, *P ); if ( !Q ) goto Fail; if ( size > current ) FT_MEM_SET( (char*)Q + current, 0, size - current ); *P = Q; return FT_Err_Ok; Fail: FT_ERROR(( "FT_Realloc:" )); FT_ERROR(( " Failed (current %ld, requested %ld)\n", current, size )); return FT_Err_Out_Of_Memory; }
FT_Error ft_base_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_Error error = FT_Err_Ok; BasePIC* container = NULL; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->base = container; /* initialize default modules list and pointers */ error = ft_create_default_module_classes( library ); if ( error ) goto Exit; /* initialize pointer table - */ /* this is how the module usually expects this data */ FT_Init_Class_ft_outline_glyph_class( &container->ft_outline_glyph_class ); FT_Init_Class_ft_bitmap_glyph_class( &container->ft_bitmap_glyph_class ); #ifdef FT_CONFIG_OPTION_MAC_FONTS FT_Init_Table_ft_raccess_guess_table( (ft_raccess_guess_rec*)&container->ft_raccess_guess_table ); #endif Exit: if ( error ) ft_base_pic_free( library ); return error; }
TT_New_GlyphZone( FT_Memory memory, FT_UShort maxPoints, FT_Short maxContours, TT_GlyphZone zone ) { FT_Error error; if ( maxPoints > 0 ) maxPoints += 2; FT_MEM_SET( zone, 0, sizeof ( *zone ) ); zone->memory = memory; if ( FT_NEW_ARRAY( zone->org, maxPoints * 2 ) || FT_NEW_ARRAY( zone->cur, maxPoints * 2 ) || FT_NEW_ARRAY( zone->tags, maxPoints ) || FT_NEW_ARRAY( zone->contours, maxContours ) ) { TT_Done_GlyphZone( zone ); } return error; }
ah_outline_compute_segments( AH_Outline* outline ) { int dimension; AH_Segment* segments; FT_Int* p_num_segments; AH_Direction segment_dir; AH_Direction major_dir; segments = outline->horz_segments; p_num_segments = &outline->num_hsegments; major_dir = ah_dir_right; /* This value must be positive! */ segment_dir = major_dir; /* set up (u,v) in each point */ ah_setup_uv( outline, ah_uv_fyx ); for ( dimension = 1; dimension >= 0; dimension-- ) { AH_Point** contour = outline->contours; AH_Point** contour_limit = contour + outline->num_contours; AH_Segment* segment = segments; FT_Int num_segments = 0; #ifdef AH_HINT_METRICS AH_Point* min_point = 0; AH_Point* max_point = 0; FT_Pos min_coord = 32000; FT_Pos max_coord = -32000; #endif /* do each contour separately */ for ( ; contour < contour_limit; contour++ ) { AH_Point* point = contour[0]; AH_Point* last = point->prev; int on_edge = 0; FT_Pos min_pos = +32000; /* minimum segment pos != min_coord */ FT_Pos max_pos = -32000; /* maximum segment pos != max_coord */ FT_Bool passed; #ifdef AH_HINT_METRICS if ( point->u < min_coord ) { min_coord = point->u; min_point = point; } if ( point->u > max_coord ) { max_coord = point->u; max_point = point; } #endif if ( point == last ) /* skip singletons -- just in case? */ continue; if ( ABS( last->out_dir ) == major_dir && ABS( point->out_dir ) == major_dir ) { /* we are already on an edge, try to locate its start */ last = point; for (;;) { point = point->prev; if ( ABS( point->out_dir ) != major_dir ) { point = point->next; break; } if ( point == last ) break; } } last = point; passed = 0; for (;;) { FT_Pos u, v; if ( on_edge ) { u = point->u; if ( u < min_pos ) min_pos = u; if ( u > max_pos ) max_pos = u; if ( point->out_dir != segment_dir || point == last ) { /* we are just leaving an edge; record a new segment! */ segment->last = point; segment->pos = ( min_pos + max_pos ) >> 1; /* a segment is round if either its first or last point */ /* is a control point */ if ( ( segment->first->flags | point->flags ) & ah_flag_control ) segment->flags |= ah_edge_round; /* compute segment size */ min_pos = max_pos = point->v; v = segment->first->v; if ( v < min_pos ) min_pos = v; if ( v > max_pos ) max_pos = v; segment->min_coord = min_pos; segment->max_coord = max_pos; on_edge = 0; num_segments++; segment++; /* fallthrough */ } } /* now exit if we are at the start/end point */ if ( point == last ) { if ( passed ) break; passed = 1; } if ( !on_edge && ABS( point->out_dir ) == major_dir ) { /* this is the start of a new segment! */ segment_dir = point->out_dir; /* clear all segment fields */ FT_MEM_SET( segment, 0, sizeof ( *segment ) ); segment->dir = segment_dir; segment->flags = ah_edge_normal; min_pos = max_pos = point->u; segment->first = point; segment->last = point; segment->contour = contour; on_edge = 1; #ifdef AH_HINT_METRICS if ( point == max_point ) max_point = 0; if ( point == min_point ) min_point = 0; #endif } point = point->next; } } /* contours */ #ifdef AH_HINT_METRICS /* we need to ensure that there are edges on the left-most and */ /* right-most points of the glyph in order to hint the metrics; */ /* we do this by inserting fake segments when needed */ if ( dimension == 0 ) { AH_Point* point = outline->points; AH_Point* point_limit = point + outline->num_points; FT_Pos min_pos = 32000; FT_Pos max_pos = -32000; min_point = 0; max_point = 0; /* compute minimum and maximum points */ for ( ; point < point_limit; point++ ) { FT_Pos x = point->fx; if ( x < min_pos ) { min_pos = x; min_point = point; } if ( x > max_pos ) { max_pos = x; max_point = point; } } /* insert minimum segment */ if ( min_point ) { /* clear all segment fields */ FT_MEM_SET( segment, 0, sizeof ( *segment ) ); segment->dir = segment_dir; segment->flags = ah_edge_normal; segment->first = min_point; segment->last = min_point; segment->pos = min_pos; num_segments++; segment++; } /* insert maximum segment */ if ( max_point ) { /* clear all segment fields */ FT_MEM_SET( segment, 0, sizeof ( *segment ) ); segment->dir = segment_dir; segment->flags = ah_edge_normal; segment->first = max_point; segment->last = max_point; segment->pos = max_pos; num_segments++; segment++; } } #endif /* AH_HINT_METRICS */ *p_num_segments = num_segments; segments = outline->vert_segments; major_dir = ah_dir_up; p_num_segments = &outline->num_vsegments; ah_setup_uv( outline, ah_uv_fxy ); }
CFF_Size_Init( CFF_Size size ) { FT_Error error = 0; PSH_Globals_Funcs funcs = CFF_Size_Get_Globals_Funcs( size ); if ( funcs ) { PSH_Globals globals; CFF_Face face = (CFF_Face)size->face; CFF_Font font = (CFF_FontRec *)face->extra.data; CFF_SubFont subfont = &font->top_font; CFF_Private cpriv = &subfont->private_dict; PS_PrivateRec priv; /* IMPORTANT: The CFF and Type1 private dictionaries have */ /* slightly different structures; we need to */ /* synthetize a type1 dictionary on the fly here. */ { FT_UInt n, count; FT_MEM_SET( &priv, 0, sizeof ( priv ) ); count = priv.num_blue_values = cpriv->num_blue_values; for ( n = 0; n < count; n++ ) priv.blue_values[n] = (FT_Short)cpriv->blue_values[n]; count = priv.num_other_blues = cpriv->num_other_blues; for ( n = 0; n < count; n++ ) priv.other_blues[n] = (FT_Short)cpriv->other_blues[n]; count = priv.num_family_blues = cpriv->num_family_blues; for ( n = 0; n < count; n++ ) priv.family_blues[n] = (FT_Short)cpriv->family_blues[n]; count = priv.num_family_other_blues = cpriv->num_family_other_blues; for ( n = 0; n < count; n++ ) priv.family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n]; priv.blue_scale = cpriv->blue_scale; priv.blue_shift = cpriv->blue_shift; priv.blue_fuzz = cpriv->blue_fuzz; priv.standard_width[0] = (FT_UShort)cpriv->standard_width; priv.standard_height[0] = (FT_UShort)cpriv->standard_height; count = priv.num_snap_widths = cpriv->num_snap_widths; for ( n = 0; n < count; n++ ) priv.snap_widths[n] = (FT_Short)cpriv->snap_widths[n]; count = priv.num_snap_heights = cpriv->num_snap_heights; for ( n = 0; n < count; n++ ) priv.snap_heights[n] = (FT_Short)cpriv->snap_heights[n]; priv.force_bold = cpriv->force_bold; priv.language_group = cpriv->language_group; priv.lenIV = cpriv->lenIV; } error = funcs->create( size->face->memory, &priv, &globals ); if ( !error ) size->internal = (FT_Size_Internal)(void*)globals; } return error; }
FT_Error autofit_module_class_pic_init( FT_Library library ) { FT_PIC_Container* pic_container = &library->pic_container; FT_UInt ss; FT_Error error = FT_Err_Ok; AFModulePIC* container = NULL; FT_Memory memory = library->memory; /* allocate pointer, clear and set global container pointer */ if ( FT_ALLOC ( container, sizeof ( *container ) ) ) return error; FT_MEM_SET( container, 0, sizeof ( *container ) ); pic_container->autofit = container; /* initialize pointer table - */ /* this is how the module usually expects this data */ error = FT_Create_Class_af_services( library, &container->af_services ); if ( error ) goto Exit; FT_Init_Class_af_service_properties( &container->af_service_properties ); for ( ss = 0; ss < AF_WRITING_SYSTEM_MAX; ss++ ) container->af_writing_system_classes[ss] = &container->af_writing_system_classes_rec[ss]; container->af_writing_system_classes[AF_WRITING_SYSTEM_MAX] = NULL; for ( ss = 0; ss < AF_SCRIPT_MAX; ss++ ) container->af_script_classes[ss] = &container->af_script_classes_rec[ss]; container->af_script_classes[AF_SCRIPT_MAX] = NULL; for ( ss = 0; ss < AF_STYLE_MAX; ss++ ) container->af_style_classes[ss] = &container->af_style_classes_rec[ss]; container->af_style_classes[AF_STYLE_MAX] = NULL; #undef WRITING_SYSTEM #define WRITING_SYSTEM( ws, WS ) \ FT_Init_Class_af_ ## ws ## _writing_system_class( \ &container->af_writing_system_classes_rec[ss++] ); ss = 0; #include "afwrtsys.h" #undef SCRIPT #define SCRIPT( s, S, d, h, H, sss ) \ FT_Init_Class_af_ ## s ## _script_class( \ &container->af_script_classes_rec[ss++] ); ss = 0; #include "afscript.h" #undef STYLE #define STYLE( s, S, d, ws, sc, bss, c ) \ FT_Init_Class_af_ ## s ## _style_class( \ &container->af_style_classes_rec[ss++] ); ss = 0; #include "afstyles.h" FT_Init_Class_af_autofitter_interface( library, &container->af_autofitter_interface ); Exit: if ( error ) autofit_module_class_pic_free( library ); return error; }
/* this function is used to compute the script index of each glyph * within a given face */ static FT_Error af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) { FT_Error error = 0; FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; FT_UInt ss; /* the value 255 means "uncovered glyph" */ FT_MEM_SET( globals->glyph_scripts, AF_SCRIPT_LIST_NONE, globals->glyph_count ); error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); if ( error ) { /* ignore this error, we'll simply use Latin as the standard * script. XXX: Shouldn't we rather disable hinting ?? */ error = 0; goto Exit; } /* scan each script in a Unicode charmap */ for ( ss = 0; af_script_classes[ss]; ss++ ) { AF_ScriptClass clazz = af_script_classes[ss]; AF_Script_UniRange range; if ( clazz->script_uni_ranges == NULL ) continue; /* scan all unicode points in the range, and set the corresponding * glyph script index */ for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) { FT_ULong charcode = range->first; FT_UInt gindex; gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && gindex < globals->glyph_count && gscripts[ gindex ] == AF_SCRIPT_LIST_NONE ) { gscripts[ gindex ] = (FT_Byte) ss; } for (;;) { charcode = FT_Get_Next_Char( face, charcode, &gindex ); if ( gindex == 0 || charcode > range->last ) break; if ( gindex < globals->glyph_count && gscripts[ gindex ] == AF_SCRIPT_LIST_NONE ) { gscripts[ gindex ] = (FT_Byte) ss; } } } } Exit: /* by default, all uncovered glyphs are set to the latin script * XXX: shouldnt' we disable hinting or do something similar ? */ { FT_UInt nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) { if ( gscripts[ nn ] == AF_SCRIPT_LIST_NONE ) gscripts[ nn ] = AF_SCRIPT_LIST_DEFAULT; } } FT_Set_Charmap( face, old_charmap ); return error; }
CID_New_Parser( CID_Parser* parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux ) { FT_Error error; FT_ULong base_offset, offset, ps_len; FT_Byte buffer[256 + 10]; FT_Int buff_len; FT_MEM_SET( parser, 0, sizeof ( *parser ) ); psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); parser->stream = stream; base_offset = FT_STREAM_POS(); /* first of all, check the font format in the header */ if ( FT_FRAME_ENTER( 31 ) ) goto Exit; if ( ft_strncmp( (char *)stream->cursor, "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) { FT_TRACE2(( "[not a valid CID-keyed font]\n" )); error = CID_Err_Unknown_File_Format; } FT_FRAME_EXIT(); if ( error ) goto Exit; /* now, read the rest of the file, until we find a `StartData' */ buff_len = 256; for (;;) { FT_Byte *p, *limit = buffer + 256; FT_ULong top_position; /* fill input buffer */ buff_len -= 256; if ( buff_len > 0 ) FT_MEM_MOVE( buffer, limit, buff_len ); p = buffer + buff_len; if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) ) goto Exit; top_position = FT_STREAM_POS() - buff_len; buff_len = 256 + 10; /* look for `StartData' */ for ( p = buffer; p < limit; p++ ) { if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) { /* save offset of binary data after `StartData' */ offset = (FT_ULong)( top_position - ( limit - p ) + 10 ); goto Found; } } } Found: /* we have found the start of the binary data. We will now */ /* rewind and extract the frame of corresponding to the Postscript */ /* section */ ps_len = offset - base_offset; if ( FT_STREAM_SEEK( base_offset ) || FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) goto Exit; parser->data_offset = offset; parser->postscript_len = ps_len; parser->root.base = parser->postscript; parser->root.cursor = parser->postscript; parser->root.limit = parser->root.cursor + ps_len; parser->num_dict = -1; Exit: return error; }
static void ft_mem_table_remove( FT_MemTable table, FT_Byte* address, FT_Long delta ) { if ( table ) { FT_MemNode *pnode, node; pnode = ft_mem_table_get_nodep( table, address ); node = *pnode; if ( node ) { FT_MemSource source; if ( node->size < 0 ) ft_mem_debug_panic( "freeing memory block at %p more than once at (%s:%ld)\n" "block allocated at (%s:%ld) and released at (%s:%ld)", address, FT_FILENAME( _ft_debug_file ), _ft_debug_lineno, FT_FILENAME( node->source->file_name ), node->source->line_no, FT_FILENAME( node->free_file_name ), node->free_line_no ); /* scramble the node's content for additional safety */ FT_MEM_SET( address, 0xF3, node->size ); if ( delta == 0 ) { source = node->source; source->cur_blocks--; source->cur_size -= node->size; table->alloc_current -= node->size; } if ( table->keep_alive ) { /* we simply invert the node's size to indicate that the node */ /* was freed. */ node->size = -node->size; node->free_file_name = _ft_debug_file; node->free_line_no = _ft_debug_lineno; } else { table->nodes--; *pnode = node->link; node->size = 0; node->source = NULL; ft_mem_table_free( table, node ); if ( table->nodes * 3 < table->size || table->size * 3 < table->nodes ) ft_mem_table_resize( table ); } } else ft_mem_debug_panic( "trying to free unknown block at %p in (%s:%ld)\n", address, FT_FILENAME( _ft_debug_file ), _ft_debug_lineno ); } }
static FT_Error af_face_globals_compute_style_coverage( AF_FaceGlobals globals ) { FT_Error error; FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gstyles = globals->glyph_styles; FT_UInt ss; FT_UInt i; FT_UInt dflt = -1; /* the value AF_STYLE_UNASSIGNED means `uncovered glyph' */ FT_MEM_SET( globals->glyph_styles, AF_STYLE_UNASSIGNED, globals->glyph_count ); error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); if ( error ) { /* * Ignore this error; we simply use the fallback style. * XXX: Shouldn't we rather disable hinting? */ error = FT_Err_Ok; goto Exit; } /* scan each style in a Unicode charmap */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET[style_class->script]; AF_Script_UniRange range; if ( script_class->script_uni_ranges == NULL ) continue; /* * Scan all Unicode points in the range and set the corresponding * glyph style index. */ if ( style_class->coverage == AF_COVERAGE_DEFAULT ) { if ( style_class->script == globals->module->default_script ) dflt = ss; for ( range = script_class->script_uni_ranges; range->first != 0; range++ ) { FT_ULong charcode = range->first; FT_UInt gindex; gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count && gstyles[gindex] == AF_STYLE_UNASSIGNED ) gstyles[gindex] = (FT_Byte)ss; for (;;) { charcode = FT_Get_Next_Char( face, charcode, &gindex ); if ( gindex == 0 || charcode > range->last ) break; if ( gindex < (FT_ULong)globals->glyph_count && gstyles[gindex] == AF_STYLE_UNASSIGNED ) gstyles[gindex] = (FT_Byte)ss; } } } else { /* get glyphs not directly addressable by cmap */ af_get_coverage( globals, style_class, gstyles ); } } /* handle the default OpenType features of the default script ... */ af_get_coverage( globals, AF_STYLE_CLASSES_GET[dflt], gstyles ); /* ... and the remaining default OpenType features */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; if ( ss != dflt && style_class->coverage == AF_COVERAGE_DEFAULT ) af_get_coverage( globals, style_class, gstyles ); } /* mark ASCII digits */ for ( i = 0x30; i <= 0x39; i++ ) { FT_UInt gindex = FT_Get_Char_Index( face, i ); if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) gstyles[gindex] |= AF_DIGIT; } Exit: /* * By default, all uncovered glyphs are set to the fallback style. * XXX: Shouldn't we disable hinting or do something similar? */ if ( globals->module->fallback_style != AF_STYLE_UNASSIGNED ) { FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) { if ( ( gstyles[nn] & ~AF_DIGIT ) == AF_STYLE_UNASSIGNED ) { gstyles[nn] &= ~AF_STYLE_UNASSIGNED; gstyles[nn] |= globals->module->fallback_style; } } } #ifdef FT_DEBUG_LEVEL_TRACE FT_TRACE4(( "\n" "style coverage\n" "==============\n" "\n" )); for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; FT_UInt count = 0; FT_Long idx; FT_TRACE4(( "%s:\n", af_style_names[style_class->style] )); for ( idx = 0; idx < globals->glyph_count; idx++ ) { if ( ( gstyles[idx] & ~AF_DIGIT ) == style_class->style ) { if ( !( count % 10 ) ) FT_TRACE4(( " " )); FT_TRACE4(( " %d", idx )); count++; if ( !( count % 10 ) ) FT_TRACE4(( "\n" )); } } if ( !count ) FT_TRACE4(( " (none)\n" )); if ( count % 10 ) FT_TRACE4(( "\n" )); } #endif /* FT_DEBUG_LEVEL_TRACE */ FT_Set_Charmap( face, old_charmap ); return error; }
static FT_Bool tt_check_trickyness_sfnt_ids( TT_Face face ) { #define TRICK_SFNT_IDS_PER_FACE 3 #define TRICK_SFNT_IDS_NUM_FACES 18 static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES] [TRICK_SFNT_IDS_PER_FACE] = { #define TRICK_SFNT_ID_cvt 0 #define TRICK_SFNT_ID_fpgm 1 #define TRICK_SFNT_ID_prep 2 { /* MingLiU 1995 */ { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ { 0xA344A1EAUL, 0x000001E1UL } /* prep */ }, { /* MingLiU 1996- */ { 0x05BCF058UL, 0x000002E4UL }, /* cvt */ { 0x28233BF1UL, 0x000087C4UL }, /* fpgm */ { 0xA344A1EBUL, 0x000001E1UL } /* prep */ }, { /* DFKaiShu */ { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ { 0x5A30CA3BUL, 0x00009063UL }, /* fpgm */ { 0x13A42602UL, 0x0000007EUL } /* prep */ }, { /* DFKaiShu2 */ { 0x11E5EAD4UL, 0x00000350UL }, /* cvt */ { 0xA6E78C01UL, 0x00008998UL }, /* fpgm */ { 0x13A42602UL, 0x0000007EUL } /* prep */ }, { /* HuaTianKaiTi */ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ { 0x9C9E48B8UL, 0x0000BEA2UL }, /* fpgm */ { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* HuaTianSongTi */ { 0xFFFBFFFCUL, 0x00000008UL }, /* cvt */ { 0x0A5A0483UL, 0x00017C39UL }, /* fpgm */ { 0x70020112UL, 0x00000008UL } /* prep */ }, { /* NEC fadpop7.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ { 0xA39B58E3UL, 0x0000117CUL } /* prep */ }, { /* NEC fadrei5.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x33C41652UL, 0x000000E5UL }, /* fpgm */ { 0x26D6C52AUL, 0x00000F6AUL } /* prep */ }, { /* NEC fangot7.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x6DB1651DUL, 0x0000019DUL }, /* fpgm */ { 0x6C6E4B03UL, 0x00002492UL } /* prep */ }, { /* NEC fangyo5.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x40C92555UL, 0x000000E5UL }, /* fpgm */ { 0xDE51FAD0UL, 0x0000117CUL } /* prep */ }, { /* NEC fankyo5.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x85E47664UL, 0x000000E5UL }, /* fpgm */ { 0xA6C62831UL, 0x00001CAAUL } /* prep */ }, { /* NEC fanrgo5.ttf */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x2D891CFDUL, 0x0000019DUL }, /* fpgm */ { 0xA0604633UL, 0x00001DE8UL } /* prep */ }, { /* NEC fangot5.ttc */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x40AA774CUL, 0x000001CBUL }, /* fpgm */ { 0x9B5CAA96UL, 0x00001F9AUL } /* prep */ }, { /* NEC fanmin3.ttc */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x0D3DE9CBUL, 0x00000141UL }, /* fpgm */ { 0xD4127766UL, 0x00002280UL } /* prep */ }, { /* NEC FA-Gothic, 1996 */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x4A692698UL, 0x000001F0UL }, /* fpgm */ { 0x340D4346UL, 0x00001FCAUL } /* prep */ }, { /* NEC FA-Minchou, 1996 */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0xCD34C604UL, 0x00000166UL }, /* fpgm */ { 0x6CF31046UL, 0x000022B0UL } /* prep */ }, { /* NEC FA-RoundGothicB, 1996 */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0x5DA75315UL, 0x0000019DUL }, /* fpgm */ { 0x40745A5FUL, 0x000022E0UL } /* prep */ }, { /* NEC FA-RoundGothicM, 1996 */ { 0x00000000UL, 0x00000000UL }, /* cvt */ { 0xF055FC48UL, 0x000001C2UL }, /* fpgm */ { 0x3900DED3UL, 0x00001E18UL } /* prep */ } }; FT_ULong checksum; int num_matched_ids[TRICK_SFNT_IDS_NUM_FACES]; FT_Bool has_cvt, has_fpgm, has_prep; FT_UShort i; int j, k; FT_MEM_SET( num_matched_ids, 0, sizeof ( int ) * TRICK_SFNT_IDS_NUM_FACES ); has_cvt = FALSE; has_fpgm = FALSE; has_prep = FALSE; for ( i = 0; i < face->num_tables; i++ ) { checksum = 0; switch( face->dir_tables[i].Tag ) { case TTAG_cvt: k = TRICK_SFNT_ID_cvt; has_cvt = TRUE; break; case TTAG_fpgm: k = TRICK_SFNT_ID_fpgm; has_fpgm = TRUE; break; case TTAG_prep: k = TRICK_SFNT_ID_prep; has_prep = TRUE; break; default: continue; } for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) if ( face->dir_tables[i].Length == sfnt_id[j][k].Length ) { if ( !checksum ) checksum = tt_get_sfnt_checksum( face, i ); if ( sfnt_id[j][k].CheckSum == checksum ) num_matched_ids[j]++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } } for ( j = 0; j < TRICK_SFNT_IDS_NUM_FACES; j++ ) { if ( !has_cvt && !sfnt_id[j][TRICK_SFNT_ID_cvt].Length ) num_matched_ids[j] ++; if ( !has_fpgm && !sfnt_id[j][TRICK_SFNT_ID_fpgm].Length ) num_matched_ids[j] ++; if ( !has_prep && !sfnt_id[j][TRICK_SFNT_ID_prep].Length ) num_matched_ids[j] ++; if ( num_matched_ids[j] == TRICK_SFNT_IDS_PER_FACE ) return TRUE; } return FALSE; }
static FT_Error af_face_globals_compute_script_coverage( AF_FaceGlobals globals ) { FT_Error error = AF_Err_Ok; FT_Face face = globals->face; FT_CharMap old_charmap = face->charmap; FT_Byte* gscripts = globals->glyph_scripts; FT_UInt ss, i; /* the value 255 means `uncovered glyph' */ FT_MEM_SET( globals->glyph_scripts, AF_SCRIPT_LIST_NONE, globals->glyph_count ); error = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); if ( error ) { /* * Ignore this error; we simply use the default script. * XXX: Shouldn't we rather disable hinting? */ error = AF_Err_Ok; goto Exit; } /* scan each script in a Unicode charmap */ for ( ss = 0; AF_SCRIPT_CLASSES_GET[ss]; ss++ ) { AF_ScriptClass clazz = AF_SCRIPT_CLASSES_GET[ss]; AF_Script_UniRange range; if ( clazz->script_uni_ranges == NULL ) continue; /* * Scan all unicode points in the range and set the corresponding * glyph script index. */ for ( range = clazz->script_uni_ranges; range->first != 0; range++ ) { FT_ULong charcode = range->first; FT_UInt gindex; gindex = FT_Get_Char_Index( face, charcode ); if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; } for (;;) { charcode = FT_Get_Next_Char( face, charcode, &gindex ); if ( gindex == 0 || charcode > range->last ) break; if ( gindex < (FT_ULong)globals->glyph_count && gscripts[gindex] == AF_SCRIPT_LIST_NONE ) { gscripts[gindex] = (FT_Byte)ss; } } } } /* mark ASCII digits */ for ( i = 0x30; i <= 0x39; i++ ) { FT_UInt gindex = FT_Get_Char_Index( face, i ); if ( gindex != 0 && gindex < (FT_ULong)globals->glyph_count ) gscripts[gindex] |= AF_DIGIT; } Exit: /* * By default, all uncovered glyphs are set to the latin script. * XXX: Shouldn't we disable hinting or do something similar? */ { FT_Long nn; for ( nn = 0; nn < globals->glyph_count; nn++ ) { if ( ( gscripts[nn] & ~AF_DIGIT ) == AF_SCRIPT_LIST_NONE ) { gscripts[nn] &= ~AF_SCRIPT_LIST_NONE; gscripts[nn] |= AF_SCRIPT_LIST_DEFAULT; } } } FT_Set_Charmap( face, old_charmap ); return error; }
FT_New_Face_From_FOND( FT_Library library, Handle fond, FT_Long face_index, FT_Face* aface ) { short have_sfnt, have_lwfn = 0; ResID sfnt_id, fond_id; OSType fond_type; Str255 fond_name; Str255 lwfn_file_name; UInt8 path_lwfn[PATH_MAX]; OSErr err; FT_Error error = FT_Err_Ok; /* test for valid `aface' and `library' delayed to */ /* `FT_New_Face_From_XXX' */ GetResInfo( fond, &fond_id, &fond_type, fond_name ); if ( ResError() != noErr || fond_type != TTAG_FOND ) return FT_THROW( Invalid_File_Format ); HLock( fond ); parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name, face_index ); HUnlock( fond ); if ( lwfn_file_name[0] ) { ResFileRefNum res; res = HomeResFile( fond ); if ( noErr != ResError() ) goto found_no_lwfn_file; #if HAVE_FSREF { UInt8 path_fond[PATH_MAX]; FSRef ref; err = FSGetForkCBInfo( res, kFSInvalidVolumeRefNum, NULL, NULL, NULL, &ref, NULL ); if ( noErr != err ) goto found_no_lwfn_file; err = FSRefMakePath( &ref, path_fond, sizeof ( path_fond ) ); if ( noErr != err ) goto found_no_lwfn_file; error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, path_lwfn, sizeof ( path_lwfn ) ); if ( !error ) have_lwfn = 1; } #elif HAVE_FSSPEC { UInt8 path_fond[PATH_MAX]; FCBPBRec pb; Str255 fond_file_name; FSSpec spec; FT_MEM_SET( &spec, 0, sizeof ( FSSpec ) ); FT_MEM_SET( &pb, 0, sizeof ( FCBPBRec ) ); pb.ioNamePtr = fond_file_name; pb.ioVRefNum = 0; pb.ioRefNum = res; pb.ioFCBIndx = 0; err = PBGetFCBInfoSync( &pb ); if ( noErr != err ) goto found_no_lwfn_file; err = FSMakeFSSpec( pb.ioFCBVRefNum, pb.ioFCBParID, fond_file_name, &spec ); if ( noErr != err ) goto found_no_lwfn_file; err = FT_FSpMakePath( &spec, path_fond, sizeof ( path_fond ) ); if ( noErr != err ) goto found_no_lwfn_file; error = lookup_lwfn_by_fond( path_fond, lwfn_file_name, path_lwfn, sizeof ( path_lwfn ) ); if ( !error ) have_lwfn = 1; } #endif /* HAVE_FSREF, HAVE_FSSPEC */ } if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) ) error = FT_New_Face_From_LWFN( library, path_lwfn, face_index, aface ); else error = FT_ERR( Unknown_File_Format ); found_no_lwfn_file: if ( have_sfnt && error ) error = FT_New_Face_From_SFNT( library, sfnt_id, face_index, aface ); return error; }