ftc_image_node_init( FTC_ImageNode inode, FTC_GlyphQuery gquery, FTC_Cache cache ) { FTC_ImageFamily ifam = FTC_IMAGE_FAMILY( gquery->query.family ); FT_Error error; FT_Face face; FT_Size size; /* initialize its inner fields */ ftc_glyph_node_init( FTC_GLYPH_NODE( inode ), gquery->gindex, FTC_GLYPH_FAMILY( ifam ) ); /* we will now load the glyph image */ error = FTC_Manager_Lookup_Size( FTC_FAMILY( ifam )->cache->manager, &ifam->type.font, &face, &size ); if ( !error ) { FT_UInt gindex = FTC_GLYPH_NODE_GINDEX( inode ); error = FT_Load_Glyph( face, gindex, ifam->type.flags ); if ( !error ) { if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP || face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ) { /* ok, copy it */ FT_Glyph glyph; error = FT_Get_Glyph( face->glyph, &glyph ); if ( !error ) { inode->glyph = glyph; goto Exit; } } else error = FTC_Err_Invalid_Argument; } } /* in case of error */ ftc_glyph_node_done( FTC_GLYPH_NODE(inode), cache ); Exit: return error; }
ftc_basic_family_init( FTC_MruNode ftcfamily, FT_Pointer ftcquery, FT_Pointer ftccache ) { FTC_BasicFamily family = (FTC_BasicFamily)ftcfamily; FTC_BasicQuery query = (FTC_BasicQuery)ftcquery; FTC_Cache cache = (FTC_Cache)ftccache; FTC_Family_Init( FTC_FAMILY( family ), cache ); family->attrs = query->attrs; return 0; }
ftc_cmap_family_compare( FTC_CMapFamily cfam, FTC_CMapQuery cquery ) { FT_Int result = 0; /* first, compare face id and type */ if ( cfam->desc.face_id != cquery->desc->face_id || cfam->desc.type != cquery->desc->type ) goto Exit; switch ( cfam->desc.type ) { case FTC_CMAP_BY_INDEX: result = ( cfam->desc.u.index == cquery->desc->u.index ); break; case FTC_CMAP_BY_ENCODING: result = ( cfam->desc.u.encoding == cquery->desc->u.encoding ); break; case FTC_CMAP_BY_ID: result = ( cfam->desc.u.id.platform == cquery->desc->u.id.platform && cfam->desc.u.id.encoding == cquery->desc->u.id.encoding ); break; default: ; } if ( result ) { /* when found, update the 'family' and 'hash' field of the query */ FTC_QUERY( cquery )->family = FTC_FAMILY( cfam ); FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); } Exit: return FT_BOOL( result ); }
ftc_glyph_family_init( FTC_GlyphFamily gfam, FT_UInt32 hash, FT_UInt item_count, FT_UInt item_total, FTC_GlyphQuery gquery, FTC_Cache cache ) { FT_Error error; error = ftc_family_init( FTC_FAMILY( gfam ), FTC_QUERY( gquery ), cache ); if ( !error ) { gfam->hash = hash; gfam->item_total = item_total; gfam->item_count = item_count; FTC_GLYPH_FAMILY_FOUND( gfam, gquery ); } return error; }
ftc_glyph_family_done( FTC_GlyphFamily gfam ) { ftc_family_done( FTC_FAMILY( gfam ) ); }
ftc_cmap_family_init( FTC_CMapFamily cfam, FTC_CMapQuery cquery, FTC_Cache cache ) { FTC_Manager manager = cache->manager; FTC_CMapDesc desc = cquery->desc; FT_UInt32 hash = 0; FT_Error error; FT_Face face; /* setup charmap descriptor */ cfam->desc = *desc; /* let's see whether the rest is correct too */ error = FTC_Manager_Lookup_Face( manager, desc->face_id, &face ); if ( !error ) { FT_UInt count = face->num_charmaps; FT_UInt idx = count; FT_CharMap* cur = face->charmaps; switch ( desc->type ) { case FTC_CMAP_BY_INDEX: idx = desc->u.index; hash = idx * 33; break; case FTC_CMAP_BY_ENCODING: for ( idx = 0; idx < count; idx++, cur++ ) if ( cur[0]->encoding == desc->u.encoding ) break; hash = idx * 67; break; case FTC_CMAP_BY_ID: for ( idx = 0; idx < count; idx++, cur++ ) { if ( (FT_UInt)cur[0]->platform_id == desc->u.id.platform && (FT_UInt)cur[0]->encoding_id == desc->u.id.encoding ) { hash = ( ( desc->u.id.platform << 8 ) | desc->u.id.encoding ) * 7; break; } } break; default: ; } if ( idx >= count ) goto Bad_Descriptor; /* compute hash value, both in family and query */ cfam->index = idx; cfam->hash = hash ^ FTC_FACE_ID_HASH( desc->face_id ); FTC_QUERY( cquery )->hash = FTC_CMAP_HASH( cfam, cquery ); error = ftc_family_init( FTC_FAMILY( cfam ), FTC_QUERY( cquery ), cache ); } return error; Bad_Descriptor: FT_ERROR(( "ftp_cmap_family_init: invalid charmap descriptor\n" )); return FTC_Err_Invalid_Argument; }