diff options
-rw-r--r-- | source/blender/blenkernel/intern/vfontdata_freetype.c | 104 |
1 files changed, 42 insertions, 62 deletions
diff --git a/source/blender/blenkernel/intern/vfontdata_freetype.c b/source/blender/blenkernel/intern/vfontdata_freetype.c index 91ca3100f8c..37e85e70bdb 100644 --- a/source/blender/blenkernel/intern/vfontdata_freetype.c +++ b/source/blender/blenkernel/intern/vfontdata_freetype.c @@ -266,30 +266,22 @@ static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) return che; } -static VFontData *objfnt_to_ftvfontdata(PackedFile *pf) +static FT_Face vfont_face_load_from_packed_file(PackedFile *pf) { - /* Variables */ - FT_Face face; - VFontData *vfd; - - /* load the freetype font */ - err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); - - if (err) { + FT_Face face = NULL; + FT_New_Memory_Face(library, pf->data, pf->size, 0, &face); + if (!face) { return NULL; } - /* allocate blender font */ - 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)); + /* Font must contain vectors, not bitmaps. */ + if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) { + FT_Done_Face(face); + return NULL; } /* Select a character map. */ - err = FT_Select_Charmap(face, FT_ENCODING_UNICODE); + FT_Error err = FT_Select_Charmap(face, FT_ENCODING_UNICODE); if (err) { err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN); } @@ -298,10 +290,42 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf) } if (err) { FT_Done_Face(face); - MEM_freeN(vfd); 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_load_from_packed_file(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". */ const bool complete_font = (face->ascender != 0) && (face->descender != 0) && (face->ascender != face->descender); @@ -344,50 +368,6 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf) 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); return vfd; |