LoadImageFont from TStream - possible bug?
BlitzMax Forums/BlitzMax Programming/LoadImageFont from TStream - possible bug?
| ||
I've been working on a a simple file packer which stores multiple data files in one external file. The app then extracts the required file(s) by loading them into a bank and then creating a BankStream. Ths works fine with images & sound, but does not seem to work with fonts. To break it down to it's simplest form, try the following (replace "myfont.ttf" with any font you have available): Strict Graphics 1024, 768, 0 SetBlend ALPHABLEND Local font1:TImageFont = LoadImageFont("myfont.ttf", 20) SetImageFont font1 DrawText "Normal font load", 10, 10 Local fontStream:TStream = ReadFile("myfont.ttf") Local font2:TImageFont = LoadImageFont(fontStream, 20) SetImageFont font2 DrawText "Stream font load", 10, 40 fontStream.Close Flip WaitKey End The first line is drawn in the correct font as expected, but the second line uses the default blitz font indicating that it did not load the front from the Stream (even though technically it is the same file). Is this a bug/limitation of Blitz Max, or is there a way of getting this to work? (e.g. loading a font from memory) I seem to recall a while ago that a similar problem occurred with incbining fonts - incbin fonts now work but I wonder if it is a related problem? I have tried doing it so the font is extracted to a temp file which is then loaded, however, the temp file can not be deleted (I think LoadImageFont does not release the file?). Even if I could get this method to work, I would still prefer to load directly from memory. |
| ||
The problem is BRL.FreeTypeFont .. its loader only takes strings. It should realy take streams/banks as the other stuff imho. But you can easily fix that by adding your own loader. I hacked this together for ya =) (ripped from BRL.FreeTypeLib) Btw, dont forget to put the "AddFontLoader" line before any font loading. Type TFreeTypeFontStream Extends TFreeTypeFont Function LoadStream:TFreeTypeFontStream( src:TStream,size,style ) Global ft_lib:Byte Ptr If Not ft_lib If FT_Init_FreeType( Varptr ft_lib ) Return EndIf Local buf:Byte Ptr,buf_size Local ft_face:Byte Ptr buf_size=src.Size() If Not buf_size Return buf=MemAlloc( buf_size ) src.ReadBytes( buf, buf_size) If FT_New_Memory_Face( ft_lib,buf,buf_size,0,Varptr ft_face ) MemFree buf Return EndIf While size If Not FT_Set_Pixel_Sizes( ft_face,0,size ) Exit size:-1 Wend If Not size FT_Done_Face ft_face Return EndIf Local face:FTFace=New FTFace MemCopy face,ft_face,SizeOf face Local metrics:FTMetrics=New FTMetrics MemCopy metrics,face.metrics,SizeOf metrics Local font:TFreeTypeFontStream=New TFreeTypeFontStream font._face=face font._ft_face=ft_face font._style=style font._height=metrics.height Sar 6 font._ascend=metrics.ascend Sar 6 font._descend=metrics.descend Sar 6 font._glyphs=New TFreeTypeGlyph[face.numglyphs] font._buf=buf font._buf_size=buf_size Return font End Function End Type Type TFreeTypeFontLoaderStream Extends TFontLoader Method LoadFont:TFreeTypeFont( url:Object,size,style ) If TStream(url) Then Return TFreeTypeFontStream.LoadStream( TStream(url), size, style) EndIf EndMethod EndType AddFontLoader New TFreeTypeFontLoaderStream EDIT: Oh, i forgot to mention this reads the WHOLE stream. If you want to read sections of a stream, use banks instead so you can limit the amount to read. |
| ||
Nice one, thank you very much :-) I am using banks, so no problem there. |