static void FTC_Manager_Check( FTC_Manager manager ) { FTC_Node node, first; first = manager->nodes_list; /* check node weights */ if ( first ) { FT_ULong weight = 0; node = first; do { FTC_Cache cache = manager->caches[node->cache_index]; if ( (FT_UInt)node->cache_index >= manager->num_caches ) FT_TRACE0(( "FTC_Manager_Check: invalid node (cache index = %ld\n", node->cache_index )); else weight += cache->clazz.node_weight( node, cache ); node = FTC_NODE__NEXT( node ); } while ( node != first ); if ( weight != manager->cur_weight ) FT_TRACE0(( "FTC_Manager_Check: invalid weight %ld instead of %ld\n", manager->cur_weight, weight )); } /* check circular list */ if ( first ) { FT_UFast count = 0; node = first; do { count++; node = FTC_NODE__NEXT( node ); } while ( node != first ); if ( count != manager->num_nodes ) FT_TRACE0(( "FTC_Manager_Check:" " invalid cache node count %d instead of %d\n", manager->num_nodes, count )); } }
/* * PROPERTY SERVICE * */ static FT_Error tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; if ( !ft_strcmp( property_name, "interpreter-version" ) ) { FT_UInt* interpreter_version = (FT_UInt*)value; #ifndef TT_CONFIG_OPTION_SUBPIXEL_HINTING if ( *interpreter_version != TT_INTERPRETER_VERSION_35 ) error = FT_ERR( Unimplemented_Feature ); else #endif driver->interpreter_version = *interpreter_version; return error; } FT_TRACE0(( "tt_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
FT_Add_Default_Modules( FT_Library library ) { FT_Error error; const FT_Module_Class* const* cur; /* FT_DEFAULT_MODULES_GET dereferences `library' in PIC mode */ #ifdef FT_CONFIG_OPTION_PIC if ( !library ) return; #endif /* GCC 4.6 warns the type difference: * FT_Module_Class** != const FT_Module_Class* const* */ cur = (const FT_Module_Class* const*)FT_DEFAULT_MODULES_GET; /* test for valid `library' delayed to FT_Add_Module() */ while ( *cur ) { error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) FT_TRACE0(( "FT_Add_Default_Module:" " Cannot install `%s', error = 0x%x\n", (*cur)->module_name, error )); cur++; } }
FT_Error af_property_set( FT_Module ft_module, const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* fallback_script = (FT_UInt*)value; module->fallback_script = *fallback_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) globals->increase_x_height = prop->limit; return error; } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_UInt sfnt_get_name_index( TT_Face face, FT_String* glyph_name ) { FT_Face root = &face->root; FT_UInt i, max_gid = FT_UINT_MAX; if ( root->num_glyphs < 0 ) return 0; else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX ) max_gid = ( FT_UInt ) root->num_glyphs; else FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n", FT_UINT_MAX, root->num_glyphs )); for ( i = 0; i < max_gid; i++ ) { FT_String* gname; FT_Error error = tt_face_get_ps_name( face, i, &gname ); if ( error ) continue; if ( !ft_strcmp( glyph_name, gname ) ) return i; } return 0; }
static FT_Error cff_property_get( FT_Module module, /* CFF_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; FT_UInt hinting_engine = driver->hinting_engine; FT_Bool no_stem_darkening = driver->no_stem_darkening; if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt* val = (FT_UInt*)value; *val = hinting_engine; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { FT_Bool* val = (FT_Bool*)value; *val = no_stem_darkening; return error; } FT_TRACE0(( "cff_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error tt_property_get( FT_Module module, /* TT_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; FT_UInt interpreter_version = driver->interpreter_version; if ( !ft_strcmp( property_name, "interpreter-version" ) ) { FT_UInt* val = (FT_UInt*)value; *val = interpreter_version; return error; } FT_TRACE0(( "tt_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
/* * PROPERTY SERVICE * */ static FT_Error tt_property_set( FT_Module module, /* TT_Driver */ const char* property_name, const void* value, FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; TT_Driver driver = (TT_Driver)module; #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES FT_UNUSED( value_is_string ); #endif if ( !ft_strcmp( property_name, "interpreter-version" ) ) { FT_UInt interpreter_version; #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) { const char* s = (const char*)value; interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); } else #endif { FT_UInt* iv = (FT_UInt*)value; interpreter_version = *iv; } if ( interpreter_version == TT_INTERPRETER_VERSION_35 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || interpreter_version == TT_INTERPRETER_VERSION_38 #endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL || interpreter_version == TT_INTERPRETER_VERSION_40 #endif ) driver->interpreter_version = interpreter_version; else error = FT_ERR( Unimplemented_Feature ); return error; } FT_TRACE0(( "tt_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error cff_property_get( FT_Module module, /* CFF_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params = driver->darken_params; FT_Int* val = (FT_Int*)value; val[0] = darken_params[0]; val[1] = darken_params[1]; val[2] = darken_params[2]; val[3] = darken_params[3]; val[4] = darken_params[4]; val[5] = darken_params[5]; val[6] = darken_params[6]; val[7] = darken_params[7]; return error; } else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt hinting_engine = driver->hinting_engine; FT_UInt* val = (FT_UInt*)value; *val = hinting_engine; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { FT_Bool no_stem_darkening = driver->no_stem_darkening; FT_Bool* val = (FT_Bool*)value; *val = no_stem_darkening; return error; } FT_TRACE0(( "cff_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error CFF_Load_FD_Select( CFF_FDSelect fdselect, FT_UInt num_glyphs, FT_Stream stream, FT_ULong offset ) { FT_Error error; FT_Byte format; FT_UInt num_ranges; /* read format */ if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) ) goto Exit; fdselect->format = format; fdselect->cache_count = 0; /* clear cache */ switch ( format ) { case 0: /* format 0, that's simple */ fdselect->data_size = num_glyphs; goto Load_Data; case 3: /* format 3, a tad more complex */ if ( FT_READ_USHORT( num_ranges ) ) goto Exit; if ( !num_ranges ) { FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } fdselect->data_size = num_ranges * 3 + 2; Load_Data: if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) ) goto Exit; break; default: /* hmm... that's wrong */ error = FT_THROW( Invalid_File_Format ); } Exit: return error; }
FT_Error af_property_get( FT_Module ft_module, const char* property_name, void* value ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; FT_UInt fallback_script = module->fallback_script; if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) { FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) prop->map = globals->glyph_scripts; return error; } else if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* val = (FT_UInt*)value; *val = fallback_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) prop->limit = globals->increase_x_height; return error; } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
FT_Add_Default_Modules( FT_Library library ) { FT_Error error; const FT_Module_Class* const* cur; /* test for valid `library' delayed to FT_Add_Module() */ cur = FT_DEFAULT_MODULES_GET; while ( *cur ) { error = FT_Add_Module( library, *cur ); /* notify errors, but don't stop */ if ( error ) FT_TRACE0(( "FT_Add_Default_Module:" " Cannot install `%s', error = 0x%x\n", (*cur)->module_name, error )); cur++; } }
FTC_Manager_Compress( FTC_Manager manager ) { FTC_Node node, first; if ( !manager ) return; first = manager->nodes_list; #ifdef FT_DEBUG_ERROR FTC_Manager_Check( manager ); FT_TRACE0(( "compressing, weight = %ld, max = %ld, nodes = %d\n", manager->cur_weight, manager->max_weight, manager->num_nodes )); #endif if ( manager->cur_weight < manager->max_weight || first == NULL ) return; /* go to last node -- it's a circular list */ node = FTC_NODE__PREV( first ); do { FTC_Node prev; prev = ( node == first ) ? NULL : FTC_NODE__PREV( node ); if ( node->ref_count <= 0 ) ftc_node_destroy( node, manager ); node = prev; } while ( node && manager->cur_weight > manager->max_weight ); }
/* * PROPERTY SERVICE * */ static FT_Error cff_property_set( FT_Module module, /* CFF_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt* hinting_engine = (FT_UInt*)value; #ifndef CFF_CONFIG_OPTION_OLD_ENGINE if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) error = FT_ERR( Unimplemented_Feature ); else #endif driver->hinting_engine = *hinting_engine; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { FT_Bool* no_stem_darkening = (FT_Bool*)value; driver->no_stem_darkening = *no_stem_darkening; return error; } FT_TRACE0(( "cff_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
cid_load_glyph( T1_Decoder decoder, FT_UInt glyph_index ) { CID_Face face = (CID_Face)decoder->builder.face; CID_FaceInfo cid = &face->cid; FT_Byte* p; FT_ULong fd_select; FT_Stream stream = face->cid_stream; FT_Error error = FT_Err_Ok; FT_Byte* charstring = NULL; FT_Memory memory = face->root.memory; FT_ULong glyph_length = 0; PSAux_Service psaux = (PSAux_Service)face->psaux; #ifdef FT_CONFIG_OPTION_INCREMENTAL FT_Incremental_InterfaceRec *inc = face->root.internal->incremental_interface; #endif FT_TRACE1(( "cid_load_glyph: glyph index %d\n", glyph_index )); #ifdef FT_CONFIG_OPTION_INCREMENTAL /* For incremental fonts get the character data using */ /* the callback function. */ if ( inc ) { FT_Data glyph_data; error = inc->funcs->get_glyph_data( inc->object, glyph_index, &glyph_data ); if ( error ) goto Exit; p = (FT_Byte*)glyph_data.pointer; fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); if ( glyph_data.length != 0 ) { glyph_length = (FT_ULong)( glyph_data.length - cid->fd_bytes ); (void)FT_ALLOC( charstring, glyph_length ); if ( !error ) ft_memcpy( charstring, glyph_data.pointer + cid->fd_bytes, glyph_length ); } inc->funcs->free_glyph_data( inc->object, &glyph_data ); if ( error ) goto Exit; } else #endif /* FT_CONFIG_OPTION_INCREMENTAL */ /* For ordinary fonts read the CID font dictionary index */ /* and charstring offset from the CIDMap. */ { FT_UInt entry_len = (FT_UInt)( cid->fd_bytes + cid->gd_bytes ); FT_ULong off1, off2; if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset + glyph_index * entry_len ) || FT_FRAME_ENTER( 2 * entry_len ) ) goto Exit; p = (FT_Byte*)stream->cursor; fd_select = cid_get_offset( &p, (FT_Byte)cid->fd_bytes ); off1 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); p += cid->fd_bytes; off2 = cid_get_offset( &p, (FT_Byte)cid->gd_bytes ); FT_FRAME_EXIT(); if ( fd_select >= (FT_ULong)cid->num_dicts || off2 > stream->size || off1 > off2 ) { FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } glyph_length = off2 - off1; if ( glyph_length == 0 ) goto Exit; if ( FT_ALLOC( charstring, glyph_length ) ) goto Exit; if ( FT_STREAM_READ_AT( cid->data_offset + off1, charstring, glyph_length ) ) goto Exit; } /* Now set up the subrs array and parse the charstrings. */ { CID_FaceDict dict; CID_Subrs cid_subrs = face->subrs + fd_select; FT_UInt cs_offset; /* Set up subrs */ decoder->num_subrs = cid_subrs->num_subrs; decoder->subrs = cid_subrs->code; decoder->subrs_len = 0; /* Set up font matrix */ dict = cid->font_dicts + fd_select; decoder->font_matrix = dict->font_matrix; decoder->font_offset = dict->font_offset; decoder->lenIV = dict->private_dict.lenIV; /* Decode the charstring. */ /* Adjustment for seed bytes. */ cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0; if ( cs_offset > glyph_length ) { FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" )); error = FT_THROW( Invalid_Offset ); goto Exit; } /* Decrypt only if lenIV >= 0. */ if ( decoder->lenIV >= 0 ) psaux->t1_decrypt( charstring, glyph_length, 4330 ); error = decoder->funcs.parse_charstrings( decoder, charstring + cs_offset, glyph_length - cs_offset ); } #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts can optionally override the metrics. */ if ( !error && inc && inc->funcs->get_glyph_metrics ) { FT_Incremental_MetricsRec metrics; metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x ); metrics.bearing_y = 0; metrics.advance = FIXED_TO_INT( decoder->builder.advance.x ); metrics.advance_v = FIXED_TO_INT( decoder->builder.advance.y ); error = inc->funcs->get_glyph_metrics( inc->object, glyph_index, FALSE, &metrics ); decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x ); decoder->builder.advance.x = INT_TO_FIXED( metrics.advance ); decoder->builder.advance.y = INT_TO_FIXED( metrics.advance_v ); } #endif /* FT_CONFIG_OPTION_INCREMENTAL */ Exit: FT_FREE( charstring ); return error; }
static FT_Error af_property_set( FT_Module ft_module, const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* fallback_script = (FT_UInt*)value; FT_UInt ss; /* We translate the fallback script to a fallback style that uses */ /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ /* coverage value. */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; if ( (FT_UInt)style_class->script == *fallback_script && style_class->coverage == AF_COVERAGE_DEFAULT ) { module->fallback_style = ss; break; } } if ( !AF_STYLE_CLASSES_GET[ss] ) { FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", fallback_script, property_name )); return FT_THROW( Invalid_Argument ); } return error; } else if ( !ft_strcmp( property_name, "default-script" ) ) { FT_UInt* default_script = (FT_UInt*)value; module->default_script = *default_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) globals->increase_x_height = prop->limit; return error; } #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { FT_Bool* warping = (FT_Bool*)value; module->warping = *warping; return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
tt_face_load_maxp( TT_Face face, FT_Stream stream ) { FT_Error error; TT_MaxProfile* maxProfile = &face->max_profile; const FT_Frame_Field maxp_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE TT_MaxProfile FT_FRAME_START( 6 ), FT_FRAME_LONG ( version ), FT_FRAME_USHORT( numGlyphs ), FT_FRAME_END }; const FT_Frame_Field maxp_fields_extra[] = { FT_FRAME_START( 26 ), FT_FRAME_USHORT( maxPoints ), FT_FRAME_USHORT( maxContours ), FT_FRAME_USHORT( maxCompositePoints ), FT_FRAME_USHORT( maxCompositeContours ), FT_FRAME_USHORT( maxZones ), FT_FRAME_USHORT( maxTwilightPoints ), FT_FRAME_USHORT( maxStorage ), FT_FRAME_USHORT( maxFunctionDefs ), FT_FRAME_USHORT( maxInstructionDefs ), FT_FRAME_USHORT( maxStackElements ), FT_FRAME_USHORT( maxSizeOfInstructions ), FT_FRAME_USHORT( maxComponentElements ), FT_FRAME_USHORT( maxComponentDepth ), FT_FRAME_END }; error = face->goto_table( face, TTAG_maxp, stream, 0 ); if ( error ) goto Exit; if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) goto Exit; maxProfile->maxPoints = 0; maxProfile->maxContours = 0; maxProfile->maxCompositePoints = 0; maxProfile->maxCompositeContours = 0; maxProfile->maxZones = 0; maxProfile->maxTwilightPoints = 0; maxProfile->maxStorage = 0; maxProfile->maxFunctionDefs = 0; maxProfile->maxInstructionDefs = 0; maxProfile->maxStackElements = 0; maxProfile->maxSizeOfInstructions = 0; maxProfile->maxComponentElements = 0; maxProfile->maxComponentDepth = 0; if ( maxProfile->version >= 0x10000L ) { if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) goto Exit; /* XXX: an adjustment that is necessary to load certain */ /* broken fonts like `Keystrokes MT' :-( */ /* */ /* We allocate 64 function entries by default when */ /* the maxFunctionDefs field is null. */ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; /* we add 4 phantom points later */ if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) ) { FT_TRACE0(( "tt_face_load_maxp:" " too much twilight points in `maxp' table;\n" " " " some glyphs might be rendered incorrectly\n" )); maxProfile->maxTwilightPoints = 0xFFFFU - 4; } } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); Exit: return error; }
static FT_Error af_property_set( FT_Module ft_module, const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* fallback_script = (FT_UInt*)value; FT_UInt ss; /* We translate the fallback script to a fallback style that uses */ /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ /* coverage value. */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; if ( (FT_UInt)style_class->script == *fallback_script && style_class->coverage == AF_COVERAGE_DEFAULT ) { module->fallback_style = ss; break; } } if ( !AF_STYLE_CLASSES_GET[ss] ) { FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", fallback_script, property_name )); return FT_THROW( Invalid_Argument ); } return error; } else if ( !ft_strcmp( property_name, "default-script" ) ) { FT_UInt* default_script = (FT_UInt*)value; module->default_script = *default_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) globals->increase_x_height = prop->limit; return error; } #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { FT_Bool* warping = (FT_Bool*)value; module->warping = *warping; return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params = (FT_Int*)value; FT_Int x1 = darken_params[0]; FT_Int y1 = darken_params[1]; FT_Int x2 = darken_params[2]; FT_Int y2 = darken_params[3]; FT_Int x3 = darken_params[4]; FT_Int y3 = darken_params[5]; FT_Int x4 = darken_params[6]; FT_Int y4 = darken_params[7]; if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || x1 > x2 || x2 > x3 || x3 > x4 || y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) return FT_THROW( Invalid_Argument ); module->darken_params[0] = x1; module->darken_params[1] = y1; module->darken_params[2] = x2; module->darken_params[3] = y2; module->darken_params[4] = x3; module->darken_params[5] = y3; module->darken_params[6] = x4; module->darken_params[7] = y4; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { FT_Bool* no_stem_darkening = (FT_Bool*)value; module->no_stem_darkening = *no_stem_darkening; return error; } FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error pcf_get_metrics( FT_Stream stream, PCF_Face face ) { FT_Error error; FT_Memory memory = FT_FACE( face )->memory; FT_ULong format, size; PCF_Metric metrics = 0; FT_ULong nmetrics, i; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, PCF_METRICS, &format, &size ); if ( error ) return error; if ( FT_READ_ULONG_LE( format ) ) goto Bail; if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) && !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) ) return FT_THROW( Invalid_File_Format ); if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_ULONG( nmetrics ); else (void)FT_READ_ULONG_LE( nmetrics ); } else { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_USHORT( nmetrics ); else (void)FT_READ_USHORT_LE( nmetrics ); } if ( error ) return FT_THROW( Invalid_File_Format ); face->nmetrics = nmetrics; if ( !nmetrics ) return FT_THROW( Invalid_Table ); FT_TRACE4(( "pcf_get_metrics:\n" )); FT_TRACE4(( " number of metrics: %d\n", nmetrics )); /* rough estimate */ if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) { if ( nmetrics > size / PCF_METRIC_SIZE ) return FT_THROW( Invalid_Table ); } else { if ( nmetrics > size / PCF_COMPRESSED_METRIC_SIZE ) return FT_THROW( Invalid_Table ); } if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) return FT_THROW( Out_Of_Memory ); metrics = face->metrics; for ( i = 0; i < nmetrics; i++, metrics++ ) { error = pcf_get_metric( stream, format, metrics ); metrics->bits = 0; FT_TRACE5(( " idx %d: width=%d, " "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n", i, metrics->characterWidth, metrics->leftSideBearing, metrics->rightSideBearing, metrics->ascent, metrics->descent, metrics->attributes )); if ( error ) break; /* sanity checks -- those values are used in `PCF_Glyph_Load' to */ /* compute a glyph's bitmap dimensions, thus setting them to zero in */ /* case of an error disables this particular glyph only */ if ( metrics->rightSideBearing < metrics->leftSideBearing || metrics->ascent + metrics->descent < 0 ) { metrics->characterWidth = 0; metrics->leftSideBearing = 0; metrics->rightSideBearing = 0; metrics->ascent = 0; metrics->descent = 0; FT_TRACE0(( "pcf_get_metrics:" " invalid metrics for glyph %d\n", i )); } } if ( error ) FT_FREE( face->metrics ); Bail: return error; }
/* * This function tries to load a small bitmap within a given FTC_SNode. * Note that it returns a non-zero error code _only_ in the case of * out-of-memory condition. For all other errors (e.g., corresponding * to a bad font file), this function will mark the sbit as `unavailable' * and return a value of 0. * * You should also read the comment within the @ftc_snode_compare * function below to see how out-of-memory is handled during a lookup. */ static FT_Error ftc_snode_load( FTC_SNode snode, FTC_Manager manager, FT_UInt gindex, FT_ULong *asize ) { FT_Error error; FTC_GNode gnode = FTC_GNODE( snode ); FTC_Family family = gnode->family; FT_Memory memory = manager->memory; FT_Face face; FTC_SBit sbit; FTC_SFamilyClass clazz; if ( (FT_UInt)(gindex - gnode->gindex) >= snode->count ) { FT_ERROR(( "ftc_snode_load: invalid glyph index" )); return FT_THROW( Invalid_Argument ); } sbit = snode->sbits + ( gindex - gnode->gindex ); clazz = (FTC_SFamilyClass)family->clazz; sbit->buffer = 0; error = clazz->family_load_glyph( family, gindex, manager, &face ); if ( error ) goto BadGlyph; { FT_Int temp; FT_GlyphSlot slot = face->glyph; FT_Bitmap* bitmap = &slot->bitmap; FT_Pos xadvance, yadvance; /* FT_GlyphSlot->advance.{x|y} */ if ( slot->format != FT_GLYPH_FORMAT_BITMAP ) { FT_TRACE0(( "ftc_snode_load:" " glyph loaded didn't return a bitmap\n" )); goto BadGlyph; } /* Check whether our values fit into 8-bit containers! */ /* If this is not the case, our bitmap is too large */ /* and we will leave it as `missing' with sbit.buffer = 0 */ #define CHECK_CHAR( d ) ( temp = (FT_Char)d, (FT_Int) temp == (FT_Int) d ) #define CHECK_BYTE( d ) ( temp = (FT_Byte)d, (FT_UInt)temp == (FT_UInt)d ) /* horizontal advance in pixels */ xadvance = ( slot->advance.x + 32 ) >> 6; yadvance = ( slot->advance.y + 32 ) >> 6; if ( !CHECK_BYTE( bitmap->rows ) || !CHECK_BYTE( bitmap->width ) || !CHECK_CHAR( bitmap->pitch ) || !CHECK_CHAR( slot->bitmap_left ) || !CHECK_CHAR( slot->bitmap_top ) || !CHECK_CHAR( xadvance ) || !CHECK_CHAR( yadvance ) ) { FT_TRACE2(( "ftc_snode_load:" " glyph too large for small bitmap cache\n")); goto BadGlyph; } sbit->width = (FT_Byte)bitmap->width; sbit->height = (FT_Byte)bitmap->rows; sbit->pitch = (FT_Char)bitmap->pitch; sbit->left = (FT_Char)slot->bitmap_left; sbit->top = (FT_Char)slot->bitmap_top; sbit->xadvance = (FT_Char)xadvance; sbit->yadvance = (FT_Char)yadvance; sbit->format = (FT_Byte)bitmap->pixel_mode; sbit->max_grays = (FT_Byte)(bitmap->num_grays - 1); /* copy the bitmap into a new buffer -- ignore error */ error = ftc_sbit_copy_bitmap( sbit, bitmap, memory ); /* now, compute size */ if ( asize ) *asize = (FT_ULong)FT_ABS( sbit->pitch ) * sbit->height; } /* glyph loading successful */ /* ignore the errors that might have occurred -- */ /* we mark unloaded glyphs with `sbit.buffer == 0' */ /* and `width == 255', `height == 0' */ /* */ if ( error && FT_ERR_NEQ( error, Out_Of_Memory ) ) { BadGlyph: sbit->width = 255; sbit->height = 0; sbit->buffer = NULL; error = FT_Err_Ok; if ( asize ) *asize = 0; } return error; }
/* entries to C-style strings (this is, NULL-terminated). */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, FT_Byte** pool ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; *table = NULL; if ( idx->offsets == NULL ) { error = cff_index_load_offsets( idx ); if ( error ) goto Exit; } if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) && ( !pool || !FT_ALLOC( new_bytes, idx->data_size + idx->count ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; FT_Byte* org_bytes = idx->bytes; /* at this point, `idx->offsets' can't be NULL */ cur_offset = idx->offsets[0] - 1; /* sanity check */ if ( cur_offset != 0 ) { FT_TRACE0(( "cff_index_get_pointers:" " invalid first offset value %d set to zero\n", cur_offset )); cur_offset = 0; } if ( !pool ) t[0] = org_bytes + cur_offset; else t[0] = new_bytes + cur_offset; for ( n = 1; n <= idx->count; n++ ) { FT_ULong next_offset = idx->offsets[n] - 1; /* two sanity checks for invalid offset tables */ if ( next_offset < cur_offset ) next_offset = cur_offset; else if ( next_offset > idx->data_size ) next_offset = idx->data_size; if ( !pool ) t[n] = org_bytes + next_offset; else { t[n] = new_bytes + next_offset + extra; if ( next_offset != cur_offset ) { FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); t[n][0] = '\0'; t[n] += 1; extra++; } } cur_offset = next_offset; } *table = t; if ( pool ) *pool = new_bytes; } Exit: return error; }
cff_font_load( FT_Library library, FT_Stream stream, FT_Int face_index, CFF_Font font, FT_Bool pure_cff ) { static const FT_Frame_Field cff_header_fields[] = { #undef FT_STRUCTURE #define FT_STRUCTURE CFF_FontRec FT_FRAME_START( 4 ), FT_FRAME_BYTE( version_major ), FT_FRAME_BYTE( version_minor ), FT_FRAME_BYTE( header_size ), FT_FRAME_BYTE( absolute_offsize ), FT_FRAME_END }; FT_Error error; FT_Memory memory = stream->memory; FT_ULong base_offset; CFF_FontRecDict dict; CFF_IndexRec string_index; FT_Int subfont_index; FT_ZERO( font ); FT_ZERO( &string_index ); font->stream = stream; font->memory = memory; dict = &font->top_font.font_dict; base_offset = FT_STREAM_POS(); /* read CFF font header */ if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) ) goto Exit; /* check format */ if ( font->version_major != 1 || font->header_size < 4 || font->absolute_offsize > 4 ) { FT_TRACE2(( " not a CFF font header\n" )); error = FT_THROW( Unknown_File_Format ); goto Exit; } /* skip the rest of the header */ if ( FT_STREAM_SKIP( font->header_size - 4 ) ) goto Exit; /* read the name, top dict, string and global subrs index */ if ( FT_SET_ERROR( cff_index_init( &font->name_index, stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &font->font_dict_index, stream, 0 ) ) || FT_SET_ERROR( cff_index_init( &string_index, stream, 1 ) ) || FT_SET_ERROR( cff_index_init( &font->global_subrs_index, stream, 1 ) ) || FT_SET_ERROR( cff_index_get_pointers( &string_index, &font->strings, &font->string_pool ) ) ) goto Exit; font->num_strings = string_index.count; if ( pure_cff ) { /* well, we don't really forget the `disabled' fonts... */ subfont_index = face_index; if ( subfont_index >= (FT_Int)font->name_index.count ) { FT_ERROR(( "cff_font_load:" " invalid subfont index for pure CFF font (%d)\n", subfont_index )); error = FT_THROW( Invalid_Argument ); goto Exit; } font->num_faces = font->name_index.count; } else { subfont_index = 0; if ( font->name_index.count > 1 ) { FT_ERROR(( "cff_font_load:" " invalid CFF font with multiple subfonts\n" " " " in SFNT wrapper\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } } /* in case of a font format check, simply exit now */ if ( face_index < 0 ) goto Exit; /* now, parse the top-level font dictionary */ FT_TRACE4(( "parsing top-level\n" )); error = cff_subfont_load( &font->top_font, &font->font_dict_index, subfont_index, stream, base_offset, library ); if ( error ) goto Exit; if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) ) goto Exit; error = cff_index_init( &font->charstrings_index, stream, 0 ); if ( error ) goto Exit; /* now, check for a CID font */ if ( dict->cid_registry != 0xFFFFU ) { CFF_IndexRec fd_index; CFF_SubFont sub = NULL; FT_UInt idx; /* this is a CID-keyed font, we must now allocate a table of */ /* sub-fonts, then load each of them separately */ if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) ) goto Exit; error = cff_index_init( &fd_index, stream, 0 ); if ( error ) goto Exit; if ( fd_index.count > CFF_MAX_CID_FONTS ) { FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" )); goto Fail_CID; } /* allocate & read each font dict independently */ font->num_subfonts = fd_index.count; if ( FT_NEW_ARRAY( sub, fd_index.count ) ) goto Fail_CID; /* set up pointer table */ for ( idx = 0; idx < fd_index.count; idx++ ) font->subfonts[idx] = sub + idx; /* now load each subfont independently */ for ( idx = 0; idx < fd_index.count; idx++ ) { sub = font->subfonts[idx]; FT_TRACE4(( "parsing subfont %u\n", idx )); error = cff_subfont_load( sub, &fd_index, idx, stream, base_offset, library ); if ( error ) goto Fail_CID; } /* now load the FD Select array */ error = CFF_Load_FD_Select( &font->fd_select, font->charstrings_index.count, stream, base_offset + dict->cid_fd_select_offset ); Fail_CID: cff_index_done( &fd_index ); if ( error ) goto Exit; } else font->num_subfonts = 0; /* read the charstrings index now */ if ( dict->charstrings_offset == 0 ) { FT_ERROR(( "cff_font_load: no charstrings offset\n" )); error = FT_THROW( Invalid_File_Format ); goto Exit; } font->num_glyphs = font->charstrings_index.count; error = cff_index_get_pointers( &font->global_subrs_index, &font->global_subrs, NULL ); if ( error ) goto Exit; /* read the Charset and Encoding tables if available */ if ( font->num_glyphs > 0 ) { FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff ); error = cff_charset_load( &font->charset, font->num_glyphs, stream, base_offset, dict->charset_offset, invert ); if ( error ) goto Exit; /* CID-keyed CFFs don't have an encoding */ if ( dict->cid_registry == 0xFFFFU ) { error = cff_encoding_load( &font->encoding, &font->charset, font->num_glyphs, stream, base_offset, dict->encoding_offset ); if ( error ) goto Exit; } } /* get the font name (/CIDFontName for CID-keyed fonts, */ /* /FontName otherwise) */ font->font_name = cff_index_get_name( font, subfont_index ); Exit: cff_index_done( &string_index ); return error; }
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ) { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_Offset hash; FT_Int no_cmap_change = 0; if ( cmap_index < 0 ) { /* Treat a negative cmap index as a special value, meaning that you */ /* don't want to change the FT_Face's character map through this */ /* call. This can be useful if the face requester callback already */ /* sets the face's charmap to the appropriate value. */ no_cmap_change = 1; cmap_index = 0; } if ( !cache ) { FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; hash = FTC_CMAP_HASH( face_id, (FT_UInt)cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX ) ) return 0; /* XXX: should return appropriate error */ gindex = FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; gindex = 0; error = FTC_Manager_LookupFace( cache->manager, FTC_CMAP_NODE( node )->face_id, &face ); if ( error ) goto Exit; if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; old = face->charmap; cmap = face->charmaps[cmap_index]; if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first] = (FT_UShort)gindex; } Exit: return gindex; }
FTC_CMapCache_Lookup( FTC_CMapCache cmap_cache, FTC_FaceID face_id, FT_Int cmap_index, FT_UInt32 char_code ) { FTC_Cache cache = FTC_CACHE( cmap_cache ); FTC_CMapQueryRec query; FTC_Node node; FT_Error error; FT_UInt gindex = 0; FT_PtrDist hash; FT_Int no_cmap_change = 0; if ( cmap_index < 0 ) { /* Treat a negative cmap index as a special value, meaning that you */ /* don't want to change the FT_Face's character map through this */ /* call. This can be useful if the face requester callback already */ /* sets the face's charmap to the appropriate value. */ no_cmap_change = 1; cmap_index = 0; } if ( !cache ) { FT_TRACE0(( "FTC_CMapCache_Lookup: bad arguments, returning 0\n" )); return 0; } #ifdef FT_CONFIG_OPTION_OLD_INTERNALS /* * If cmap_index is greater than the maximum number of cachable * charmaps, we assume the request is from a legacy rogue client * using old internal header. See include/config/ftoption.h. */ if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE && !no_cmap_change ) { FTC_OldCMapDesc desc = (FTC_OldCMapDesc) face_id; char_code = (FT_UInt32)cmap_index; query.face_id = desc->face_id; switch ( desc->type ) { case FTC_OLD_CMAP_BY_INDEX: query.cmap_index = desc->u.index; query.char_code = (FT_UInt32)cmap_index; break; case FTC_OLD_CMAP_BY_ENCODING: { FT_Face face; error = FTC_Manager_LookupFace( cache->manager, desc->face_id, &face ); if ( error ) return 0; FT_Select_Charmap( face, desc->u.encoding ); return FT_Get_Char_Index( face, char_code ); } default: return 0; } } else #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ { query.face_id = face_id; query.cmap_index = (FT_UInt)cmap_index; query.char_code = char_code; } hash = FTC_CMAP_HASH( face_id, cmap_index, char_code ); #if 1 FTC_CACHE_LOOKUP_CMP( cache, ftc_cmap_node_compare, hash, &query, node, error ); #else error = FTC_Cache_Lookup( cache, hash, &query, &node ); #endif if ( error ) goto Exit; FT_ASSERT( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first ) < FTC_CMAP_INDICES_MAX ); /* something rotten can happen with rogue clients */ if ( (FT_UInt)( char_code - FTC_CMAP_NODE( node )->first >= FTC_CMAP_INDICES_MAX ) ) return 0; /* XXX: should return appropriate error */ gindex = FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first]; if ( gindex == FTC_CMAP_UNKNOWN ) { FT_Face face; gindex = 0; error = FTC_Manager_LookupFace( cache->manager, FTC_CMAP_NODE( node )->face_id, &face ); if ( error ) goto Exit; #ifdef FT_MAX_CHARMAP_CACHEABLE /* something rotten can happen with rogue clients */ if ( cmap_index > FT_MAX_CHARMAP_CACHEABLE ) return 0; /* XXX: should return appropriate error */ #endif if ( (FT_UInt)cmap_index < (FT_UInt)face->num_charmaps ) { FT_CharMap old, cmap = NULL; old = face->charmap; cmap = face->charmaps[cmap_index]; if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, cmap ); gindex = FT_Get_Char_Index( face, char_code ); if ( old != cmap && !no_cmap_change ) FT_Set_Charmap( face, old ); } FTC_CMAP_NODE( node )->indices[char_code - FTC_CMAP_NODE( node )->first] = (FT_UShort)gindex; } Exit: return gindex; }
static FT_Error af_property_set( FT_Module ft_module, const char* property_name, const void* value, FT_Bool value_is_string ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES FT_UNUSED( value_is_string ); #endif if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* fallback_script; FT_UInt ss; #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) return FT_THROW( Invalid_Argument ); #endif fallback_script = (FT_UInt*)value; /* We translate the fallback script to a fallback style that uses */ /* `fallback-script' as its script and `AF_COVERAGE_NONE' as its */ /* coverage value. */ for ( ss = 0; AF_STYLE_CLASSES_GET[ss]; ss++ ) { AF_StyleClass style_class = AF_STYLE_CLASSES_GET[ss]; if ( (FT_UInt)style_class->script == *fallback_script && style_class->coverage == AF_COVERAGE_DEFAULT ) { module->fallback_style = ss; break; } } if ( !AF_STYLE_CLASSES_GET[ss] ) { FT_TRACE0(( "af_property_set: Invalid value %d for property `%s'\n", fallback_script, property_name )); return FT_THROW( Invalid_Argument ); } return error; } else if ( !ft_strcmp( property_name, "default-script" ) ) { FT_UInt* default_script; #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) return FT_THROW( Invalid_Argument ); #endif default_script = (FT_UInt*)value; module->default_script = *default_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop; AF_FaceGlobals globals; #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) return FT_THROW( Invalid_Argument ); #endif prop = (FT_Prop_IncreaseXHeight*)value; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) globals->increase_x_height = prop->limit; return error; } #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) { const char* s = (const char*)value; long w = ft_strtol( s, NULL, 10 ); if ( w == 0 ) module->warping = 0; else if ( w == 1 ) module->warping = 1; else return FT_THROW( Invalid_Argument ); } else #endif { FT_Bool* warping = (FT_Bool*)value; module->warping = *warping; } return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params; FT_Int x1, y1, x2, y2, x3, y3, x4, y4; #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES FT_Int dp[8]; if ( value_is_string ) { const char* s = (const char*)value; char* ep; int i; /* eight comma-separated numbers */ for ( i = 0; i < 7; i++ ) { dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); if ( *ep != ',' || s == ep ) return FT_THROW( Invalid_Argument ); s = ep + 1; } dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) return FT_THROW( Invalid_Argument ); darken_params = dp; } else #endif darken_params = (FT_Int*)value; x1 = darken_params[0]; y1 = darken_params[1]; x2 = darken_params[2]; y2 = darken_params[3]; x3 = darken_params[4]; y3 = darken_params[5]; x4 = darken_params[6]; y4 = darken_params[7]; if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || x1 > x2 || x2 > x3 || x3 > x4 || y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) return FT_THROW( Invalid_Argument ); module->darken_params[0] = x1; module->darken_params[1] = y1; module->darken_params[2] = x2; module->darken_params[3] = y2; module->darken_params[4] = x3; module->darken_params[5] = y3; module->darken_params[6] = x4; module->darken_params[7] = y4; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES if ( value_is_string ) { const char* s = (const char*)value; long nsd = ft_strtol( s, NULL, 10 ); if ( nsd == 0 ) module->no_stem_darkening = 0; else if ( nsd == 1 ) module->no_stem_darkening = 1; else return FT_THROW( Invalid_Argument ); } else #endif { FT_Bool* no_stem_darkening = (FT_Bool*)value; module->no_stem_darkening = *no_stem_darkening; } return error; } FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error af_property_get( FT_Module ft_module, const char* property_name, void* value ) { FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; FT_UInt fallback_style = module->fallback_style; FT_UInt default_script = module->default_script; #ifdef AF_CONFIG_OPTION_USE_WARPER FT_Bool warping = module->warping; #endif if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) { FT_Prop_GlyphToScriptMap* prop = (FT_Prop_GlyphToScriptMap*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) prop->map = globals->glyph_styles; return error; } else if ( !ft_strcmp( property_name, "fallback-script" ) ) { FT_UInt* val = (FT_UInt*)value; AF_StyleClass style_class = AF_STYLE_CLASSES_GET[fallback_style]; *val = style_class->script; return error; } else if ( !ft_strcmp( property_name, "default-script" ) ) { FT_UInt* val = (FT_UInt*)value; *val = default_script; return error; } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; AF_FaceGlobals globals; error = af_property_get_face_globals( prop->face, &globals, module ); if ( !error ) prop->limit = globals->increase_x_height; return error; } #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { FT_Bool* val = (FT_Bool*)value; *val = warping; return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }
static FT_Error pcf_get_bitmaps( FT_Stream stream, PCF_Face face ) { FT_Error error = PCF_Err_Ok; FT_Memory memory = FT_FACE(face)->memory; FT_Long* offsets; FT_Long bitmapSizes[GLYPHPADOPTIONS]; FT_ULong format, size; FT_ULong nbitmaps, i, sizebitmaps = 0; error = pcf_seek_to_table_type( stream, face->toc.tables, face->toc.count, PCF_BITMAPS, &format, &size ); if ( error ) return error; error = FT_Stream_EnterFrame( stream, 8 ); if ( error ) return error; format = FT_GET_ULONG_LE(); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) nbitmaps = FT_GET_ULONG(); else nbitmaps = FT_GET_ULONG_LE(); FT_Stream_ExitFrame( stream ); if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) ) return PCF_Err_Invalid_File_Format; FT_TRACE4(( "pcf_get_bitmaps:\n" )); FT_TRACE4(( " number of bitmaps: %d\n", nbitmaps )); /* XXX: PCF_Face->nmetrics is singed FT_Long, see pcf.h */ if ( face->nmetrics < 0 || nbitmaps != ( FT_ULong )face->nmetrics ) return PCF_Err_Invalid_File_Format; if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) return error; for ( i = 0; i < nbitmaps; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_LONG( offsets[i] ); else (void)FT_READ_LONG_LE( offsets[i] ); FT_TRACE5(( " bitmap %d: offset %ld (0x%lX)\n", i, offsets[i], offsets[i] )); } if ( error ) goto Bail; for ( i = 0; i < GLYPHPADOPTIONS; i++ ) { if ( PCF_BYTE_ORDER( format ) == MSBFirst ) (void)FT_READ_LONG( bitmapSizes[i] ); else (void)FT_READ_LONG_LE( bitmapSizes[i] ); if ( error ) goto Bail; sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )]; FT_TRACE4(( " padding %d implies a size of %ld\n", i, bitmapSizes[i] )); } FT_TRACE4(( " %d bitmaps, padding index %ld\n", nbitmaps, PCF_GLYPH_PAD_INDEX( format ) )); FT_TRACE4(( " bitmap size = %d\n", sizebitmaps )); FT_UNUSED( sizebitmaps ); /* only used for debugging */ for ( i = 0; i < nbitmaps; i++ ) { /* rough estimate */ if ( ( offsets[i] < 0 ) || ( (FT_ULong)offsets[i] > size ) ) { FT_TRACE0(( "pcf_get_bitmaps:" " invalid offset to bitmap data of glyph %d\n", i )); } else face->metrics[i].bits = stream->pos + offsets[i]; } face->bitmapsFormat = format; Bail: FT_FREE( offsets ); return error; }
tt_face_load_hmtx( TT_Face face, FT_Stream stream, FT_Bool vertical ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong table_len; FT_Long num_shorts, num_longs, num_shorts_checked; TT_LongMetrics* longs; TT_ShortMetrics** shorts; FT_Byte* p; if ( vertical ) { void* lm = &face->vertical.long_metrics; void** sm = &face->vertical.short_metrics; error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); if ( error ) goto Fail; num_longs = face->vertical.number_Of_VMetrics; if ( (FT_ULong)num_longs > table_len / 4 ) num_longs = (FT_Long)( table_len / 4 ); face->vertical.number_Of_VMetrics = 0; longs = (TT_LongMetrics*)lm; shorts = (TT_ShortMetrics**)sm; } else { void* lm = &face->horizontal.long_metrics; void** sm = &face->horizontal.short_metrics; error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); if ( error ) goto Fail; num_longs = face->horizontal.number_Of_HMetrics; if ( (FT_ULong)num_longs > table_len / 4 ) num_longs = (FT_Long)( table_len / 4 ); face->horizontal.number_Of_HMetrics = 0; longs = (TT_LongMetrics*)lm; shorts = (TT_ShortMetrics**)sm; } /* never trust derived values */ num_shorts = face->max_profile.numGlyphs - num_longs; num_shorts_checked = ( table_len - num_longs * 4L ) / 2; if ( num_shorts < 0 ) { FT_TRACE0(( "tt_face_load_hmtx:" " %cmtx has more metrics than glyphs.\n", vertical ? 'v' : 'h' )); /* Adobe simply ignores this problem. So we shall do the same. */ #if 0 error = vertical ? SFNT_Err_Invalid_Vert_Metrics : SFNT_Err_Invalid_Horiz_Metrics; goto Exit; #else num_shorts = 0; #endif } if ( FT_QNEW_ARRAY( *longs, num_longs ) || FT_QNEW_ARRAY( *shorts, num_shorts ) ) goto Fail; if ( FT_FRAME_ENTER( table_len ) ) goto Fail; p = stream->cursor; { TT_LongMetrics cur = *longs; TT_LongMetrics limit = cur + num_longs; for ( ; cur < limit; cur++ ) { cur->advance = FT_NEXT_USHORT( p ); cur->bearing = FT_NEXT_SHORT( p ); } } /* do we have an inconsistent number of metric values? */ { TT_ShortMetrics* cur = *shorts; TT_ShortMetrics* limit = cur + FT_MIN( num_shorts, num_shorts_checked ); for ( ; cur < limit; cur++ ) *cur = FT_NEXT_SHORT( p ); /* We fill up the missing left side bearings with the */ /* last valid value. Since this will occur for buggy CJK */ /* fonts usually only, nothing serious will happen. */ if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) { FT_Short val = (*shorts)[num_shorts_checked - 1]; limit = *shorts + num_shorts; for ( ; cur < limit; cur++ ) *cur = val; } } FT_FRAME_EXIT(); if ( vertical ) face->vertical.number_Of_VMetrics = (FT_UShort)num_longs; else face->horizontal.number_Of_HMetrics = (FT_UShort)num_longs; Fail: return error; }
/* * PROPERTY SERVICE * */ static FT_Error cff_property_set( FT_Module module, /* CFF_Driver */ const char* property_name, const void* value ) { FT_Error error = FT_Err_Ok; CFF_Driver driver = (CFF_Driver)module; if ( !ft_strcmp( property_name, "darkening-parameters" ) ) { FT_Int* darken_params = (FT_Int*)value; FT_Int x1 = darken_params[0]; FT_Int y1 = darken_params[1]; FT_Int x2 = darken_params[2]; FT_Int y2 = darken_params[3]; FT_Int x3 = darken_params[4]; FT_Int y3 = darken_params[5]; FT_Int x4 = darken_params[6]; FT_Int y4 = darken_params[7]; if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || x1 > x2 || x2 > x3 || x3 > x4 || y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) return FT_THROW( Invalid_Argument ); driver->darken_params[0] = x1; driver->darken_params[1] = y1; driver->darken_params[2] = x2; driver->darken_params[3] = y2; driver->darken_params[4] = x3; driver->darken_params[5] = y3; driver->darken_params[6] = x4; driver->darken_params[7] = y4; return error; } else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { FT_UInt* hinting_engine = (FT_UInt*)value; #ifndef CFF_CONFIG_OPTION_OLD_ENGINE if ( *hinting_engine != FT_CFF_HINTING_ADOBE ) error = FT_ERR( Unimplemented_Feature ); else #endif driver->hinting_engine = *hinting_engine; return error; } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { FT_Bool* no_stem_darkening = (FT_Bool*)value; driver->no_stem_darkening = *no_stem_darkening; return error; } FT_TRACE0(( "cff_property_set: missing property `%s'\n", property_name )); return FT_THROW( Missing_Property ); }