Big TTF fonts and al_draw_text

I started developing small application which primary aim was displaying big texts. Nothing special. While having some previous (small though) experience with allegro, I decided to make use of it.
Now, I can use much sleep because of it (or my lack of knowledge, in which case I beg on my tired knees for yours apologies).

Consider following example. Nothing special, initialization, displaying one letter in common ttf font (verdana, times, doesn't matter, something popular enough). Where the problem start? Try increasing the font's size to 300 while displaying the magical "j" letter or set it to 400 and print any character.
On my computer it ends with spectacular crash with fireworks (about 2GB of RAM consumed) ended by the OS. Not what I was expecting.
I don't consider 400px (-400 gives the same effect) to be font big enough for my computer.

I would appreciate any possible help a lot, as I lost lots of hair trying figure out what was crashing (and I do not think of myself as programmer as bad as 2GB leaker). I really hope, that it is only my fault, but extracting this example from my application makes my possible mistake even bigger.

Some useful information:
MSVC 2010
Allegro 5.0.7, monolithic, MD, debug
STATIC LINKING of the Allegro

Debugging leads into:
or (if aligning text not to the left, when al_draw_ustr calls ttf_text_length before render which result in calling cache_glyph anyway)

1#define ALLEGRO_STATICLINK 2 3#include <allegro5/allegro.h> 4#include <allegro5/allegro_image.h> 5#include <allegro5/allegro_font.h> 6#include <allegro5/allegro_ttf.h> 7#include <iostream> 8using namespace std; 9 10int main(int argc, _TCHAR* argv[]) 11 { 12 try 13 { 14 if(!al_install_system(ALLEGRO_VERSION_INT, NULL)) 15 throw 1; 16 if(!al_init_image_addon()) 17 throw 2; 18 al_init_font_addon(); 19 if(!al_init_ttf_addon()) 20 throw 3; 21 22 23 ALLEGRO_DISPLAY *display_ = al_create_display(640, 640); 24 if(!display_) 25 4; 26 27 { // msvc workaround for easier loading 28 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); 29 al_change_directory(al_path_cstr(path, '/')); 30 al_destroy_path(path); 31 } 32 33 int size = 100; // the SIZE 34 ALLEGRO_FONT *font_ = al_load_ttf_font("verdana.ttf", size, 0); 35 al_clear_to_color(al_map_rgb(0, 0, 0)); 36 al_draw_text(font_, al_map_rgb(0, 0, 255), 10, 10, ALLEGRO_ALIGN_LEFT, "j"); // the "j" or another beautiful string 37 al_flip_display(); 38 39 { // just present the result 40 int z = 0; 41 cin >> z; 42 } 43 44 al_destroy_font(font_); 45 al_destroy_display(display_); 46 al_shutdown_ttf_addon(); 47 al_shutdown_font_addon(); 48 al_shutdown_image_addon(); 49 al_uninstall_system(); 50 } 51 catch(int i) 52 { 53 cout <<i << endl; 54 } 55 catch(...) 56 { 57 cout << "Doesn't working" << endl; 58 } 59 60 61 int i; 62 cin >> i; 63 return 0; 64 }

Trent Gamblin

I believe the ttf addon creates 256x256 "pages" to store the font glyphs. Obviously that's not going to work with a 400px font. Not sure what to do in this case :/.


Would it be hard to use 512x512 pages if the requested size is above 256?

Trent Gamblin

Probably not very hard. Someone just has to write the code.


Thanks for fast response.
Sadly for me, it didn't sound good. As I conclude, there is no hope to fix it (improve?) quickly? I am asking, because I'm running out of schedule and it is crucial to pick up the proper tool and Allegro seemed appropriate until now.

Is it Allegro issue or FreeType's?
And probably, imho, it should be handled automatically in some way, dynamic page sizes or something like that? It seems to be somewhat overlooked to have fixed "max" size of fonts and additionaly not documented anywhere.

Trent Gamblin

It should be a dynamic size. It's a pretty easy fix... I could do it I suppose, I don't suspect any problems but you never know. But you have to realize: you'll have to compile Allegro yourself no matter what or who fixes it. So if you want this fix, fastest way is to go into the ttf addon and set it to 1024x1024 (supported by anything, even 1st gen ipod touch) and compile.


Thanks, I'll give it a shot. TTF FullHD should be sufficient.
However, it would be nice challenge to compile Allegro again, spent lots of time doing it last time ;) Occasion to compile MT version.
Just be in spite of this little bug in future releases, thanks for your help.

Really appreciate your work guys, cheers.

Btw. last thing. So who i sresponsible Allegro or TrueType? ;>

EDIT: second last:

1// FIXME: Add a special case for when a single glyph rendering won't fit 2// into 256x256 pixels.

; )

Trent Gamblin

Hm, well I believe Allegro is at fault. But in light of that comment, I'm not sure what the problem is anymore, unless that special case doesn't work.


Allegro. Only need to adjust this line:

I guess a better algorithm would be to start with a w x h bitmap where w and h is the size of the first glyph. Then keep doubling the width until you hit the maximum texture width. So for example... 32x32 -> 64x32 -> 128x32 -> ... -> 8192x32. The old bitmap would be copied over to the new page and then discarded each time. Once the bitmap has reached the maximum width, start doubling the height. And only once width and height is maxed out use the current algorithm.

The advantages compared to the current one would be:

- No size limit (except a single glyph has to fit into the maximum texture size).
- Faster because a lot more glyphs are kept in a single texture.

The disadvantage is that generating the initial cache would be slightly slower due to the extra blit before discarding the previous bitmap - but by always doubling the size it won't happen very often.

Anyway, I have this on my TODO for like 2 years, I believe the very first version of ttf.c already had it as a FIXME. So I won't promise anything... :/ [edit: as you discovered :)]


Wanted to report the effect - workaround did the job, after 2h of recompiling the sources all works great, Changing 256 to 512 runs smoothly and I can see my fonts from the other room ; )
Great, thank guys. While it is not done by default, I would really suggest to write something about it, I was going crazy about not knowing what's going on.
Dynamic would be perfect, but for 1080p 512 is sufficient enough I think. And while I am not aware of performance issues, I think it would be ok to switch to 512x512 by default, but it is only my suggestion.

Thanks again, time to sleep, in my time zone.

Thread #610908. Printed from