Allegro 5 fails to load TTF font
Addison Elliott

So i've been using Allegro 5 to create a client and I just recently got to the font part. I started off by trying to load the arial TTF font. It failed. The odd thing about this is I had made another program using the exact same font(it was identical code) and it worked on my other computer. But it fails here. I am quite confused right now why this could be.
The order that I initialize the addons. Not sure if it matters.

The peice of code where I try to retrieve the font.
ALLEGRO_FONT *font = al_load_font("arial.ttf", 12, 0);

If there is any additional information you need to know then you're welcome to ask me. I would just like to solve this problem so I can continue on.

jmasterx

Have you tried:

The logic here is that you are trying to turn on the radio without first putting the key in the ignition ;)

Addison Elliott

I just tried replacing it with my old code and it didn't seem to fix anything.

Edit: I do get your logic now :P
Another thing I might need to add is that i'm using 4.9.22. Not sure if there was a bug in it that was solved in another version or something.

jmasterx

hmmm

maybe you can check if anything is not initing...

if(!al_init())
{
   //uh ohs
}
...
if(!font)
{
  //uh ohs
}

Although I doubt this is the problem, maybe font is being mangled with something else since it is a common name. Maybe try arialFont instead.

I used 4.9.22 for a while with no problems,

Here is my cheezy, messy, testbed for my gui api,
maybe you can find your answer somewhere it it ;)

#SelectExpand
1/*====================================== 2ALLEGRO 5 TEMPLATE 3======================================== */ 4 5#include "Agui/Agui.hpp" 6#include "Agui/Widgets/Label/AguiLabel.hpp" 7#include "Agui/Widgets/Button/AguiButton.hpp" 8#include "Agui/Widgets/CheckBox/AguiCheckBox.hpp" 9#include "Agui/Widgets/RadioButton/AguiRadioButton.hpp" 10#include "agui/Widgets/RadioButton/AguiRadioButtonGroup.hpp" 11#include "Agui/Widgets/ScrollBar/AguiVScrollBar.hpp" 12#include "Agui/Widgets/ScrollBar/AguiHScrollBar.hpp" 13#include "Agui/Backends/Allegro5/AguiAllegro5.hpp" 14 15#include <stdlib.h> //Standard library 16#include <string.h> //String functions 17#include <sstream> //More string functions 18 19#include <allegro5/allegro.h> 20#include <allegro5/allegro5.h> 21#include <allegro5/allegro_image.h> 22#include <allegro5/allegro_primitives.h> 23#include <allegro5/allegro_audio.h> 24#include <allegro5/allegro_font.h> 25#include <allegro5/allegro_ttf.h> 26#include <allegro5/allegro_acodec.h> 27#include <allegro5/allegro_opengl.h> 28//#include <allegro5/allegro_physfs.h> 29//#include <physfs.h> 30 31#include <vector> //Dynamic array data structure 32#include <math.h> // C99 Math functions 33#include <ctime> // C Time functions 34#include <iostream> 35bool yes = true; 36 37#define FRAME_RATE 60 38 39//Declarations 40ALLEGRO_DISPLAY *display; 41ALLEGRO_MONITOR_INFO info; 42ALLEGRO_TIMER *timer; 43ALLEGRO_EVENT event; 44ALLEGRO_EVENT_QUEUE *queue; 45ALLEGRO_BITMAP *flow; 46bool done; 47AguiBitmap glass; 48AguiButton *myButton; 49AguiButton *mySecondButton; 50AguiWidgetManager *con; 51AguiEventManager* Eman; 52AguiAllegro5GraphicsManager* Gman; 53AguiTextAreaManager TextAreaMan; 54 AguiBitmap button; 55 AguiFont segoe; 56ALLEGRO_BITMAP* rawww; 57AguiRectangle test; 58AguiBitmap buttPic[3]; 59AguiRadioButton *checkbox[9][9]; 60AguiVScrollBar *vscroll; 61AguiHScrollBar *hscroll; 62std::vector<std::string> testVec; 63std::vector<std::string> lineTestVec; 64 65 66AguiLabel *label; 67 68ALLEGRO_COLOR BLACK = al_map_rgb(0,0,0); 69int ret; 70bool key[256]; 71 72//Mouse 73int mX = 0; 74int mY = 0; 75 76 77void init() { 78 //Install event handlers 79 al_init(); 80 al_init_image_addon(); 81 al_init_font_addon(); 82 al_init_primitives_addon(); 83 al_init_ttf_addon(); 84 al_install_mouse(); 85 al_install_keyboard(); 86 al_install_joystick(); 87 al_install_audio(); 88 al_init_acodec_addon(); 89 90 //For PhysFS 91 //PHYSFS_init(0); 92 //PHYSFS_addToSearchPath("",1); 93 94 // Start a timer to regulate speed 95 96 97 timer = al_create_timer(1.0/FRAME_RATE); 98 al_start_timer(timer); 99 100 //for audio.... 101 //al_reserve_samples(64); 102 103 //for keyboard... 104 memset(key,0,sizeof(bool) * 256); 105 106 107 //make the random function randomer 108 srand(time(NULL)); 109 110 111 //show screen 112 //al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE); 113 //al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_REQUIRE); 114 115 al_set_new_display_flags(ALLEGRO_RESIZABLE | ALLEGRO_OPENGL_3_0); 116 117 display = al_create_display(640, 480); 118 119 if(!display) 120 { 121 done = true; 122 } 123 //show the mouse 124 al_show_mouse_cursor(display); 125 126 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP); 127 128 //For PhysFS 129 //al_set_physfs_file_interface(); 130 131 //Window Title 132 al_set_window_title(display,"Allegro 5 Template"); 133 134 queue = al_create_event_queue(); 135 136 AguiBitmap::setBitmapManager(new AguiAllegro5BitmapManager); 137 AguiFont::setFontManager(new AguiAllegro5FontManager); 138 139 Eman = new AguiAllegro5EventManager(&event,queue); 140 Gman = new AguiAllegro5GraphicsManager(); 141 142 con = new AguiWidgetManager(Eman,Gman); 143 144 segoe = AguiFont(std::string("test.ttf"),18); 145 AguiWidget::setGlobalFont(segoe); 146 147 if(!display) 148 { 149 std::cerr << " EPIC display fail \n"; 150 done = true; 151 } 152 153 154 155} 156AguiRectangle r; 157 158 159//Mouse_Down 160void mousedown(ALLEGRO_MOUSE_EVENT *mouse) { 161 162 (void)mouse; 163 } 164//Mouse Up 165void mouseup(ALLEGRO_MOUSE_EVENT *mouse) { 166 (void)mouse; 167 } 168// If a key is pressed down, add it to the key array 169void keydown(ALLEGRO_KEYBOARD_EVENT *kb) { 170 key[kb->keycode] = true; 171 172 if(kb->keycode == ALLEGRO_KEY_ESCAPE) { 173 174 done = true; 175 } 176 177} 178 179// If a key is released, mark it as unpressed 180void keyup(ALLEGRO_KEYBOARD_EVENT *kb) { 181 key[kb->keycode] = false; 182} 183 184// If an operating system repeat event comes in, set the flag 185void keyrepeat(ALLEGRO_KEYBOARD_EVENT *kb) { 186(void)kb; 187} 188 189//Mouse Move 190 191//texty 192AguiRectangle re = AguiRectangle(0,0,300,300); 193void mouseaxes(ALLEGRO_MOUSE_EVENT *mouse) { 194 mX = mouse->x; 195 mY = mouse->y; 196 197 } 198 void render() 199 { 200 //draw to the screen 201 202 //code goes here 203 al_clear_to_color(BLACK); 204 205 con->handleRender(); 206 207 al_flip_display(); 208 209 } 210 211int main(int argc, char *argv[]) 212 213{ 214 (void)argc; 215 (void)argv; 216 //initialize game 217 init(); 218 bool need_redraw = true; 219 220 //Main Loop 221 222//***** Start Main Code Here ***** 223 224 // Start the event queue to handle keyboard input and our timer 225 226 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)al_get_keyboard_event_source()); 227 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)al_get_mouse_event_source()); 228 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)timer); 229 al_register_event_source(queue, (ALLEGRO_EVENT_SOURCE*)display); 230 231 232 233 234 while(!done) { 235 236 // Block until an event enters the queue 237 if (need_redraw && al_event_queue_is_empty(queue)) { 238 render(); 239 240 need_redraw = false; 241 } 242 al_wait_for_event(queue, &event); 243 con->handleEvent(); 244 245 //We only get here if there is an event in the queue 246 switch(event.type) { 247 case ALLEGRO_EVENT_MOUSE_AXES: 248 mouseaxes(&event.mouse); 249 break; 250 251 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 252 mousedown(&event.mouse); 253 break; 254 255 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 256 mouseup(&event.mouse); 257 break; 258 259 case ALLEGRO_EVENT_KEY_DOWN: 260 keydown(&event.keyboard); 261 break; 262 263 case ALLEGRO_EVENT_KEY_UP: 264 keyup(&event.keyboard); 265 break; 266 267 268 case ALLEGRO_EVENT_TIMER: 269 if(event.timer.source == timer) 270 { 271 272 need_redraw = true; 273 } 274 275 break; 276 case ALLEGRO_EVENT_DISPLAY_RESIZE: 277 al_acknowledge_resize(event.display.source); 278 279 break; 280 case ALLEGRO_EVENT_DISPLAY_CLOSE: 281 return 0; 282 break; 283 } 284 285 286 } 287//***** End Main Code Here ***** 288 289 return 0; 290}

If you want to post your code, I'll look and see if I see something fishy

Addison Elliott

I tried checking if it fails initializing but it doesn't. Then I copied the arial font into the folder and tried that, nothing. Then I renamed the arial font to arialFont.ttf and still nothing. Not sure what else it could be.

Edit: I'm really bad at reading text after code. I saw the code then skipped over that last message of me showing you that code. Anyways, I don't want to throw it all at you so i'll just give you the file that it is in. If you think it could be anything else tell me.

Note: I do use a A5 wrapper class that a friend of mine has made. It pretty much is the same as any others code. And so you know, when something doesn't work I try to comment it out and make it more simple. I remove it all once I fix it :P

#SelectExpand
1#include "../renderer.hpp" 2#include "../../client.hpp" 3 4static void ButtonClick(void *sender) 5{ 6 printf("the button was clicked\n"); 7} 8 9static void LoadMainMenu(Renderer *renderer) 10{ 11 renderer->gui->background = renderer->bitmapLoader->Get("gui/background.png"); 12 13 //GUIControls::Icon *icon = new GUIControls::Icon(renderer->bitmapLoader->Get("gui/icon.png")); 14 //renderer->gui->AddChild(icon, a5::Rectangle(100, 300, 0, 0)); 15 16 //GUIControls::Button *button = new GUIControls::Button(renderer->bitmapLoader->Get("gui/regular.png"), renderer->bitmapLoader->Get("gui/hover.png"), 8); 17 //button->OnClick({ButtonClick, renderer}); 18 //renderer->gui->AddChild(button, a5::Rectangle(300, 300, 0, 0)); 19 20 GUIControls::Primitive *primitive = new GUIControls::Primitive(GUIControls::Primitive::FilledRectangle, a5::RGB(255, 201, 14)); 21 renderer->gui->AddChild(primitive, a5::Rectangle(100, 100, 400, 112)); 22 23 std::string fontDirectory = renderer->client->settings["FontDirectory"]; 24 //printf("grr: %s\n", (std::string(fontDirectory + "arial.ttf").c_str())); 25 //a5::Font *font = new a5::Font(std::string(fontDirectory + "arial.ttf").c_str(), 12); 26 //a5::Font *font = new a5::Font("arialFont.ttf", 15); 27 ALLEGRO_FONT *font = al_load_ttf_font("./arialFont.ttf", -12, 0); 28 if (!font) 29 { 30 printf("Failure to load font\n"); 31 } 32 //GUIControls::Textbox *textbox = new GUIControls::Textbox(); 33}

jmasterx

what I meant was your ALLEGRO_FONT *font to become ALLEGRO_FONT *arialFont

Addison Elliott

Just tried that as well. Didn't affect anything.

William Labbett

did you check the return value of al_init_ttf_font_addon() ?

jmasterx

Then the best I can do is ask you to post some code so I can look through it for errors :)

Peter Wang

Does ex_ttf work, with the supplied font or arial.ttf?

Addison Elliott

Yes William I did and it is fine. I'll post the code, it'll have to be a few files of coding.

Note: I do use a5ses(Allegro 5 Sepples Edition, just a C++ wrapper). I am quite sure that it is not the problem because the creator has gotten the font to work before. If you would like to research it just in case, this is the link: a5ses.

#SelectExpand
1//This is main.cpp 2#include <a5ses/a5ses.hpp> // This includes allegro_font, allegro_image on its own. 3 4#include "client.hpp" 5 6int main(int argc, char *argv[0]) 7{ 8 try 9 { 10 if (!al_init()) 11 { 12 printf("Failed to initialize allegro.\n"); 13 return 1; 14 } 15 16 if (!al_init_image_addon()) 17 { 18 printf("Failed to initialize allegro image addon.\n"); 19 return 1; 20 } 21 22 al_init_font_addon(); 23 24 if (!al_init_ttf_addon()) 25 { 26 printf("Failed to initialize allegro TTF addon.\n"); 27 return 1; 28 } 29 30 if (!al_init_primitives_addon()) 31 { 32 printf("Failed to initialize allegro primitives addon.\n"); 33 return 1; 34 } 35 printf("Checked them all\n"); 36 37 38 Client *client = new Client(); 39 client->LoadState(Client::MainMenu); // This is just a simple function that calls LoadMainMenu 40 client->Main(); // This does not matter since it doesn't get here 41 } 42 catch (std::runtime_error &e) 43 { 44 printf(e.what()); 45 return 1; 46 } 47 return 0; 48}

Now, the next file is in "renderer/States/MainMenu.cpp". Most of this code I don't believe is relevant until you get to the part where it loads the font. So you know, I started with a5::Font, moved to al_load_font, and finally al_load_ttf_font. They all had failed.

#SelectExpand
1#include "../renderer.hpp" 2#include "../../client.hpp" 3 4static void ButtonClick(void *sender) 5{ 6 printf("the button was clicked\n"); 7} 8 9static void LoadMainMenu(Renderer *renderer) 10{ 11 renderer->gui->background = renderer->bitmapLoader->Get("gui/background.png"); 12 13 //GUIControls::Icon *icon = new GUIControls::Icon(renderer->bitmapLoader->Get("gui/icon.png")); 14 //renderer->gui->AddChild(icon, a5::Rectangle(100, 300, 0, 0)); 15 16 //GUIControls::Button *button = new GUIControls::Button(renderer->bitmapLoader->Get("gui/regular.png"), renderer->bitmapLoader->Get("gui/hover.png"), 8); 17 //button->OnClick({ButtonClick, renderer}); 18 //renderer->gui->AddChild(button, a5::Rectangle(300, 300, 0, 0)); 19 20 GUIControls::Primitive *primitive = new GUIControls::Primitive(GUIControls::Primitive::FilledRectangle, a5::RGB(255, 201, 14)); 21 renderer->gui->AddChild(primitive, a5::Rectangle(100, 100, 400, 112)); 22 23 std::string fontDirectory = renderer->client->settings["FontDirectory"]; 24 //printf("grr: %s\n", (std::string(fontDirectory + "arial.ttf").c_str())); 25 //a5::Font *font = new a5::Font(std::string(fontDirectory + "arial.ttf").c_str(), 12); 26 //a5::Font *font = new a5::Font("arialFont.ttf", 15); 27 ALLEGRO_FONT *arialFont = al_load_ttf_font("./arialFont.ttf", -12, 0); 28 if (!arialFont) 29 { 30 printf("Failure to load font\n"); 31 } 32 //GUIControls::Textbox *textbox = new GUIControls::Textbox(); 33}

If there is any other peices of code that you'd like to see(I decided not to show the client class or the gui class) then just ask.

jmasterx

Geez, i'm really sorry, I've looked through several times and see nothing wrong with your code :(, I really wish I could do more to help but I don't know at this point, hopefully someone else will know :)

I saw the A5 wrapper is called 4.9.21.2 and you use 4.9.22, I don't know if that could be it, just putting it out there.

Addison Elliott

Yeah the creator is lazy :P I manually updated to 4.9.22 and made sure everything is the same. Another friend of mine uses 4.9.22 and also uses the wrapper and said font loading worked fine.

To answer Peter's question, I just tried to compile ex_ttf.c and it worked fine. Maybe I should analyze my code with the example and see if I see anything different.

Edit: I have an idea. I will use the debug version of the .ttf and see where exactly it fails. I will edit this post to show my results.

A weird thing I noticed while just screwing around with the code is that it loads the font fine when it's in the main function, but when it goes to LoadMainMenu it fails there.

jmasterx

If the main menu executes on a different thread than it will fail. I don't know if that is your case.

Addison Elliott

Alright, I think we're getting closer and closer to solving this. I found another peice of interesting information. It seems that it loads the font fine only if it's before this line of code in main "Client *client = new Client();" and after it it will always fail. Here is what the constructor contains. Any ideas on how to fix it or what might be causing it?

#SelectExpand
1Client::Client() : running(true) 2{ 3 queue.Register(keyboard); 4 queue.Register(mouse); 5 6 settings.Read(".\\config\\settings.ini"); 7 renderer = new Renderer(this); 8}

Matthew Leverton

Check what settings.read() and new Renderer() do. Maybe the the file interface gets changed or bitmap flags are set.

Addison Elliott

settings.Read is just opening a file to read line by line. I doubt it's the problem. But I do think it may be new Renderer. Here is the constructor. This is where the screen is created, so that may be the problem.

#SelectExpand
1Renderer::Renderer(Client *client_) : client(client_), screen(640, 480, a5::Display::Windowed), fps(0), redraw(true) 2{ 3 screen.SetTitle("Chronos Online"); 4 screen.Target(); 5 6 client->queue.Register(screen); 7 8 a5::Timer *fpsTimer = new a5::Timer(1.0); 9 fpsTimer->Start(); 10 client->timers.insert(std::pair<a5::Timer *, InputCallbackData>(fpsTimer, {FpsTimer, this})); 11 client->queue.Register(*fpsTimer); 12 13 bitmapLoader = new BitmapLoader(client->settings["ImageCacheLimit"]); 14 fontLoader = new FontLoader(client->settings["FontDirectory"]); 15 gui = new GUI(this); 16}

jmasterx

What does the font loader do? Why do array brackets [] take in a cstring?

Addison Elliott

Don't worry about that. settings is a Config class. The Config classes base is a map. So if this is the config file:
Test = 0
Rawr = no
The Config class would have this in the array:
Test => 0
Rawr => "no"

I'm almost positive of the problem now. I was using PHYSFS for loading bitmaps and it was calling al_set_physfs_interface inside the BitmapLoader interface. So I decided to call it in the main function instead but it's still having problems.

Edit: Finally solved it. God, it was so simple, but that's how most of my errors go. The problem was that I was using PHYSFS and whenever it was searching for the font, it was looking in the search paths. Thank you all for the help.

Thread #605931. Printed from Allegro.cc