I have a program that utilizes the Freetype library to draw glyphs on screen. For some reason, FT_LOAD_GLYPH is returning a value of 140 when the Brush Script MT font file is loaded and the code is run on MacOS. The 140 error is described as "too many function definitions" in the Freetype documentation. This is not an issue on Windows and, as far as I'm aware, no other font causes this error.
As a result, none of the Brush Script MT font characters are rendered onscreen. For now, there is a temporary fix that uses a placeholder font (Lucida Grande) as a fallback.
I have written a minimal, reproducible example that uses FreeType 2 to open the "Brush Script.ttf" font file and fetch a glyph from the font face. When stepping through the code, FT_Load_Glyph will return error 140 on MacOS.
Here is the code:
// INITIALIZE FREETYPE LIBRARY
dim freetype_library_ptr as ptr
soft declare function FT_Init_FreeType lib freetype (byRef alibrary as ptr) as int32
dim err as int32 = FT_Init_FreeType(freetype_library_ptr)
// CREATE BRUSH SCRIPT MT FACE
dim face_index as integer = 0
dim p as ptr
dim brush_script_file as new folderitem("/System/Library/Fonts/Supplemental/Brush Script.ttf")
dim path as string = brush_script_file.shellpath
#if targetMacOS
path=replaceall(path,"\","")
#endif
soft declare function FT_New_Face lib freetype (library as ptr,filepathname as cstring,face_index as int32,byref aface as ptr) as int32
err=FT_New_Face(freetype_library_ptr,path,face_index,p)
// SET CHARACTER SIZE FOR GLYPH
dim char_width as int32 = 0
dim char_height as int32 = 262144
dim horz_resolution as uint32 = 72
dim vert_resolution as uint32 = 72
soft declare function FT_Set_Char_Size lib freetype (face as ptr,char_width as int32,char_height as int32,horz_resolution as uint32,vert_resolution as uint32) as int32
err=FT_Set_Char_Size(p,char_width,char_height,horz_resolution,vert_resolution)
// RETRIEVE A GLYPH FROM THE FACE
dim glyph_index as integer = 75 // Index for K character
dim load_flags as integer = 0
soft declare function FT_Load_Glyph lib freetype (face as ptr,glyph_index as uint32,load_flags as int32) as int32
err=FT_Load_Glyph(p,glyph_index,load_flags) // ERROR 140 on MacOS: too many function definitions
// FINISHED USING BRUSH SCRIPT MT FACE
soft declare function FT_Done_Face lib freetype (face as ptr) as int32
err=FT_Done_Face(p)
// FINISHED USING FREETYPE LIBRARY
soft declare function FT_Done_FreeType lib freetype (library as ptr) as int32
err=FT_Done_FreeType(freetype_library_ptr)
This code is written in Xojo which is syntactically similar to Visual Basic. I have tried to make the code as readable as possible but please let me know if anything is unclear.
Important Details:
I have tried rebuilding the freetype library in debug mode and observing the logs produced when typing a glyph character from Brush Script MT. Upon calling FT_Load_Glyph, "NPUSHB" is printed once and "FDEF" is printed 11 times in the output logs.
I have found that one of the dependancies "ttinterp.c" has the code:
if ( CUR.numFDefs >= CUR.maxFDefs )
{
CUR.error = TT_Err_Too_Many_Function_Defs;
return;
}
CUR.numFDefs++;
It looks like the number of maxFDefs is being exceeded so the error is thrown. I'm not sure why this would be happening in the case of Brush Script however.
What makes the Brush Script MT font potentially a special case is that it's not a default system font included with MacOS - it comes with an install of Microsoft Word. Additionally, the Brush Script MT font family only has an italic font.
Upon further investigation, it looks like this problem has been brought up before on GitLabs: https://gitlab.freedesktop.org/freetype/freetype/-/issues/281
The Brush Script MT font is somehow broken on MacOS hence the maxFunctionDefs being too small.
Fortunately the handling of broken fonts has been improved in version 2.4.3 according to the FreeType change logs.
For reference, the exact fix can be found in commit 3987b15 of the FreeType repo. I implemented the code in this commit, rebuilt the libfreetype.6.dylib for MacOS, and Brush Script MT font glyphs are now correctly loaded and displayed in my program.