void Print_Charmaps( FT_Face face ) { int i, active = -1; if ( face->charmap ) active = FT_Get_Charmap_Index( face->charmap ); /* CharMaps */ printf( "charmaps\n" ); for( i = 0; i < face->num_charmaps; i++ ) { printf( " %d: platform %d, encoding %d", i, face->charmaps[i]->platform_id, face->charmaps[i]->encoding_id ); if ( i == active ) printf( " (active)" ); printf ( "\n" ); if ( verbose ) { FT_ULong charcode; FT_UInt gindex; FT_Set_Charmap( face, face->charmaps[i] ); charcode = FT_Get_First_Char( face, &gindex ); while ( gindex ) { printf( " 0x%04lx => %d\n", charcode, gindex ); charcode = FT_Get_Next_Char( face, charcode, &gindex ); } printf( "\n" ); } } }
void vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text) { FTC_FaceID face_id = (FTC_FaceID)font; FT_Face face; FTC_Manager_LookupFace(font->ftcmanager, face_id, &face); FT_Int charmap_index; charmap_index = FT_Get_Charmap_Index(face->charmap); FT_Glyph glyph; FT_Bool use_kerning = FT_HAS_KERNING(face); FT_UInt glyph_index, previous = 0; int pen_x = x; int pen_y = y + size; FTC_ScalerRec scaler; scaler.face_id = face_id; scaler.width = size; scaler.height = size; scaler.pixel = 1; FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; while (*text) { glyph_index = FTC_CMapCache_Lookup(font->cmapcache, (FTC_FaceID)font, charmap_index, *text); if (use_kerning && previous && glyph_index) { FT_Vector delta; FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); pen_x += delta.x >> 6; } if (!texture_atlas_exists(font->tex_atlas, glyph_index)) { FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL); if (!atlas_add_glyph(font->tex_atlas, glyph_index, (FT_BitmapGlyph)glyph, size)) { continue; } } bp2d_rectangle rect; int bitmap_left, bitmap_top; int advance_x, advance_y; int glyph_size; texture_atlas_get(font->tex_atlas, glyph_index, &rect, &bitmap_left, &bitmap_top, &advance_x, &advance_y, &glyph_size); const float draw_scale = size/(float)glyph_size; vita2d_draw_texture_tint_part_scale(font->tex_atlas->tex, pen_x + bitmap_left * draw_scale, pen_y - bitmap_top * draw_scale, rect.x, rect.y, rect.w, rect.h, draw_scale, draw_scale, color); pen_x += (advance_x >> 16) * draw_scale; pen_y += (advance_y >> 16) * draw_scale; previous = glyph_index; text++; }
FT_Error FTDemo_Install_Font( FTDemo_Handle* handle, const char* filepath ) { static char filename[1024 + 5]; int i, len, num_faces; FT_Face face; len = strlen( filepath ); if ( len > 1024 ) len = 1024; strncpy( filename, filepath, len ); filename[len] = 0; error = FT_New_Face( handle->library, filename, 0, &face ); if ( error ) return error; /* allocate new font object */ num_faces = face->num_faces; for ( i = 0; i < num_faces; i++ ) { PFont font; if ( i > 0 ) { error = FT_New_Face( handle->library, filename, i, &face ); if ( error ) continue; } if ( handle->encoding != FT_ENCODING_NONE ) { error = FT_Select_Charmap( face, handle->encoding ); if ( error ) { FT_Done_Face( face ); return error; } } font = (PFont)malloc( sizeof ( *font ) ); /* We allocate four more bytes since we want to attach an AFM */ /* or PFM file for Type 1 fonts (if available). Such fonts */ /* always have the extension `.afm' or `.pfm'. */ font->filepathname = (char*)malloc( strlen( filename ) + 4 + 1 ); strcpy( (char*)font->filepathname, filename ); font->face_index = i; font->cmap_index = face->charmap ? FT_Get_Charmap_Index( face->charmap ) : 0; if ( handle->preload ) { FILE* file = fopen( filename, "rb" ); size_t file_size; if ( file == NULL ) /* shouldn't happen */ { free( font ); return FT_Err_Invalid_Argument; } fseek( file, 0, SEEK_END ); file_size = ftell( file ); fseek( file, 0, SEEK_SET ); font->file_address = malloc( file_size ); fread( font->file_address, 1, file_size, file ); font->file_size = file_size; fclose( file ); } else { font->file_address = NULL; font->file_size = 0; } switch ( handle->encoding ) { case FT_ENCODING_NONE: font->num_indices = face->num_glyphs; break; case FT_ENCODING_UNICODE: font->num_indices = 0x110000L; break; case FT_ENCODING_ADOBE_LATIN_1: case FT_ENCODING_ADOBE_STANDARD: case FT_ENCODING_ADOBE_EXPERT: case FT_ENCODING_ADOBE_CUSTOM: case FT_ENCODING_APPLE_ROMAN: font->num_indices = 0x100L; break; /* some fonts use range 0x00-0x100, others have 0xF000-0xF0FF */ case FT_ENCODING_MS_SYMBOL: font->num_indices = 0x10000L; default: font->num_indices = 0x10000L; } FT_Done_Face( face ); face = NULL; if ( handle->max_fonts == 0 ) { handle->max_fonts = 16; handle->fonts = (PFont*)calloc( handle->max_fonts, sizeof ( PFont ) ); } else if ( handle->num_fonts >= handle->max_fonts ) { handle->max_fonts *= 2; handle->fonts = (PFont*)realloc( handle->fonts, handle->max_fonts * sizeof ( PFont ) ); memset( &handle->fonts[handle->num_fonts], 0, ( handle->max_fonts - handle->num_fonts ) * sizeof ( PFont ) ); } handle->fonts[handle->num_fonts++] = font; } return FT_Err_Ok; }