Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/vfontdata_freetype.c
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| /* Read the char */ | /* Read the char */ | ||||
| che = freetypechar_to_vchar(face, charcode, vfont->data); | che = freetypechar_to_vchar(face, charcode, vfont->data); | ||||
| /* And everything went ok */ | /* And everything went ok */ | ||||
| return che; | return che; | ||||
| } | } | ||||
| static VFontData *objfnt_to_ftvfontdata(PackedFile *pf) | static FT_Face vfont_face(PackedFile *pf) | ||||
campbellbarton: Prefer a more descriptive name `vfont_face_load_from_packed_file`. | |||||
| { | { | ||||
| /* Variables */ | if (!pf) { | ||||
campbellbartonUnsubmitted Done Inline ActionsThe NULL check doesn't seem necessary (it's not in the previous code, and if it _is_ null, FT_Init_FreeType/FT_Done_FreeType is unnecessary overhead). Think it's fine to simply not check for NULL. campbellbarton: The NULL check doesn't seem necessary (it's not in the previous code, and if it _is_ null… | |||||
| FT_Face face; | |||||
| VFontData *vfd; | |||||
| /* load the freetype font */ | |||||
| err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); | |||||
| if (err) { | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* allocate blender font */ | FT_Face face = NULL; | ||||
| vfd = MEM_callocN(sizeof(*vfd), "FTVFontData"); | FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); | ||||
| if (!face) { | |||||
| return NULL; | |||||
| } | |||||
| /* Get the name. */ | /* Font must contain vectors, not bitmaps. */ | ||||
| if (face->family_name) { | if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) { | ||||
| BLI_snprintf(vfd->name, sizeof(vfd->name), "%s %s", face->family_name, face->style_name); | FT_Done_Face(face); | ||||
| BLI_str_utf8_invalid_strip(vfd->name, strlen(vfd->name)); | return NULL; | ||||
| } | } | ||||
| /* Select a character map. */ | /* Select a character map. */ | ||||
| err = FT_Select_Charmap(face, FT_ENCODING_UNICODE); | FT_Error err = FT_Select_Charmap(face, FT_ENCODING_UNICODE); | ||||
| if (err) { | if (err) { | ||||
| err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN); | err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN); | ||||
| } | } | ||||
| if (err && face->num_charmaps > 0) { | if (err && face->num_charmaps > 0) { | ||||
| err = FT_Select_Charmap(face, face->charmaps[0]->encoding); | err = FT_Select_Charmap(face, face->charmaps[0]->encoding); | ||||
| } | } | ||||
| if (err) { | if (err) { | ||||
| FT_Done_Face(face); | FT_Done_Face(face); | ||||
| MEM_freeN(vfd); | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* Test that we can load glyphs from this font. */ | |||||
| FT_UInt glyph_index = 0; | |||||
| FT_Get_First_Char(face, &glyph_index); | |||||
| if (!glyph_index || | |||||
| FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP) != FT_Err_Ok) { | |||||
| FT_Done_Face(face); | |||||
| return NULL; | |||||
| } | |||||
| return face; | |||||
| } | |||||
| VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf) | |||||
| { | |||||
| if (FT_Init_FreeType(&library) != FT_Err_Ok) { | |||||
| return NULL; | |||||
| } | |||||
| FT_Face face = vfont_face(pf); | |||||
| if (!face) { | |||||
| FT_Done_FreeType(library); | |||||
| return NULL; | |||||
| } | |||||
| /* allocate blender font */ | |||||
| VFontData *vfd = MEM_callocN(sizeof(*vfd), "FTVFontData"); | |||||
| /* Get the name. */ | |||||
| if (face->family_name) { | |||||
| BLI_snprintf(vfd->name, sizeof(vfd->name), "%s %s", face->family_name, face->style_name); | |||||
| BLI_str_utf8_invalid_strip(vfd->name, strlen(vfd->name)); | |||||
| } | |||||
| /* Blender default BFont is not "complete". */ | /* Blender default BFont is not "complete". */ | ||||
| const bool complete_font = (face->ascender != 0) && (face->descender != 0) && | const bool complete_font = (face->ascender != 0) && (face->descender != 0) && | ||||
| (face->ascender != face->descender); | (face->ascender != face->descender); | ||||
| if (complete_font) { | if (complete_font) { | ||||
| /* We can get descender as well, but we simple store descender in relation to the ascender. | /* We can get descender as well, but we simple store descender in relation to the ascender. | ||||
| * Also note that descender is stored as a negative number. */ | * Also note that descender is stored as a negative number. */ | ||||
| vfd->ascender = (float)face->ascender / (face->ascender - face->descender); | vfd->ascender = (float)face->ascender / (face->ascender - face->descender); | ||||
| Show All 26 Lines | |||||
| for (int i = 0; i < preload_count; i++) { | for (int i = 0; i < preload_count; i++) { | ||||
| charcode = FT_Get_Next_Char(face, charcode, &glyph_index); | charcode = FT_Get_Next_Char(face, charcode, &glyph_index); | ||||
| if (!charcode || !glyph_index) { | if (!charcode || !glyph_index) { | ||||
| break; | break; | ||||
| } | } | ||||
| freetypechar_to_vchar(face, charcode, vfd); | freetypechar_to_vchar(face, charcode, vfd); | ||||
| } | } | ||||
| return vfd; | |||||
| } | |||||
| static bool check_freetypefont(PackedFile *pf) | |||||
| { | |||||
| FT_Face face = NULL; | |||||
| FT_UInt glyph_index = 0; | |||||
| bool success = false; | |||||
| err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); | |||||
| if (err) { | |||||
| return false; | |||||
| // XXX error("This is not a valid font"); | |||||
| } | |||||
| FT_Get_First_Char(face, &glyph_index); | |||||
| if (glyph_index) { | |||||
| err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP); | |||||
| if (!err) { | |||||
| success = (face->glyph->format == ft_glyph_format_outline); | |||||
| } | |||||
| } | |||||
| FT_Done_Face(face); | |||||
| return success; | |||||
| } | |||||
| VFontData *BKE_vfontdata_from_freetypefont(PackedFile *pf) | |||||
| { | |||||
| VFontData *vfd = NULL; | |||||
| /* init Freetype */ | |||||
| err = FT_Init_FreeType(&library); | |||||
| if (err) { | |||||
| /* XXX error("Failed to load the Freetype font library"); */ | |||||
| return NULL; | |||||
| } | |||||
| if (check_freetypefont(pf)) { | |||||
| vfd = objfnt_to_ftvfontdata(pf); | |||||
| } | |||||
| /* free Freetype */ | |||||
| FT_Done_FreeType(library); | FT_Done_FreeType(library); | ||||
| return vfd; | return vfd; | ||||
| } | } | ||||
| static void *vfontdata_copy_characters_value_cb(const void *src) | static void *vfontdata_copy_characters_value_cb(const void *src) | ||||
| { | { | ||||
| return BKE_vfontdata_char_copy(src); | return BKE_vfontdata_char_copy(src); | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||
Prefer a more descriptive name vfont_face_load_from_packed_file.