As you may know, releasing an SDL_ttf font face twice (either calling TTF_CloseFont twice, or calling TTF_CloseFont after TTF_Quit) will cause an access violation. I find this behavior odd because virtually every other API I know of simply does nothing when told to release a resource that has already been released.
The reason is in FT_Done_Face in the freetype library.
FT_EXPORT_DEF( FT_Error )
FT_Done_Face( FT_Face face )
{
FT_Error error;
FT_Driver driver;
FT_Memory memory;
FT_ListNode node;
error = FT_ERR( Invalid_Face_Handle );
if ( face && face->driver )
{
face->internal->refcount--;
if ( face->internal->refcount > 0 )
error = FT_Err_Ok;
else
{
driver = face->driver;
memory = driver->root.memory;
/* find face in driver's list */
node = FT_List_Find( &driver->faces_list, face );
if ( node )
{
/* remove face object from the driver's list */
FT_List_Remove( &driver->faces_list, node );
FT_FREE( node );
/* now destroy the object proper */
destroy_face( memory, face, driver );
error = FT_Err_Ok;
}
}
}
return error;
}
This function is also indirectly called from FT_Done_FreeType (which is called from TTF_Quit). It only checks if driver
is valid, but not if internal
is valid and the freetype developers decided not to set driver
to null when releasing the face, but set internal
to null. This causes an access violation when trying to dereference internal->refcount
.
This whole thing is particular problematic if SDL_ttf is being used in a garbage collected environment where TTF_Quit might be called before the garbage collector releases some forgotten font faces. Arguably that’s a bug in the application and shouldn’t happen in the first place, and it could be fixed by adding a check via TTF_WasInit, but IMO a resource cleanup function causing access violations because they’re being called twice is very unusual and annoying. If nothing else, I think this should be explicitly mentioned in the documentation of TTF_CloseFont.
Is the behavior as it currently is intended? Is this maybe being considered a freetype bug and therefore not changed in SDL_ttf?