SDL_ttf "Couldn't load font file" with SDL2 in c++ - c++

I have the following code to draw some text in an SDL2 application. When I build and run, I'm consistently seeing an error of TTF_OpenFont() Failed: Couldn't load font file. I've tried the following:
Ensured the font file is in the current directory of running program. In fact, I've put the font in almost any directory the program could be running from and have tried with an absolute path.
Setting different permissions and owning the file
Opening the file separately with SDL_RWFromFile as described here: http://www.gamedev.net/topic/275525-sdl_ttf-weirdness/
Downloaded and recompiled a newer version of SDL_ttf (2.0.14)
Here's my code:
void SDLRenderer::drawText(
const Vector2d& pos,
string message,
const Color& color)
{
if(!TTF_WasInit()) {
cerr << "TTF_Init failed " << TTF_GetError() << endl;
exit(1);
}
TTF_Font* fixed = TTF_OpenFont("./DejaVuSansMono.ttf", 16);
if (fixed == NULL) {
cerr << "TTF_OpenFont() Failed: " << TTF_GetError() << endl;
TTF_Quit();
SDL_Quit();
exit(1);
}
...
I'm also calling TTF_Init() from the constructor of this code's class. I'm also a little unsure how to debug further because gdb doesn't even give a backtrace after the error and doesn't seem to let me step into the TTF_OpenFont function.

I ran into this issue and it was caused by linking against the incorrect version of the SDL_ttf library. I was using SDL 2.0, but I was linking against libSDL_ttf.so instead of libSDL2_ttf.so. libSDL_ttf.so is for SDL 1.2, and is not compatible with SDK 2.0.
My original command line was:
$ gcc -o showfont showfont.c `sdl2-config --cflags --libs` -lSDL_ttf
$ ./showfont /usr/share/fonts/truetype/freefont/FreeSans.ttf
Couldn't load 18 pt font from /usr/share/fonts/truetype/freefont/FreeSans.ttf: Couldn't load font file
I fixed it by linking against libSDL2_ttf.so instead:
$ gcc -o showfont showfont.c `sdl2-config --cflags --libs` -lSDL2_ttf
$ ./showfont /usr/share/fonts/truetype/freefont/FreeSans.ttf
Font is generally 21 big, and string is 21 big
The showfont.c program is an example included with SDL_ttf.

My thoughts probably belong in a comment but I don't have enough reputation. You can make sure you're in the right directory by explicitly setting the current working directory (chdir in unistd.h on Linux, or SetCurrentDirectory in windows.h on Windows). I don't think you need to include ./ in the file name.
I recall having problems with SDL_ttf when calling TTF_Init, TTF_Quit, and then TTF_Init again. This may not be causing your problem but I would recommend doing your TTF_Init just once at the beginning of the program and TTF_Quit once at the end, not every time your constructor runs.
If this doesn't work look into building a debug version of SDL_ttf that will play nicer with GDB.

I've had your same problem and managed to fix it by entering the full path to the font.
Instead of just passing the string "./font.ttf"
I used: "/User/MyUsername/Projects/MyProject/font.tff"
Hope this helps!

Related

SDL2_image not initializing

Im trying to load a .png file with SDL2 and SDL2_image. SDL2 initializes properly while SDL2_image just fails for no apparent reason, please help.
IMG_Init() returns 0
IMG_GetError() returns nothing
I'm using SDL2 2.0.10 and SDL2_image 2.0.5 (latest versions afaik)
I do have all needed dll files in the same folder as my executable (SDL2.dll, SDL2_image.dll, libpng16-16.dll, zlib1.dll as I'm only using png files right now)
I have no idea why this isn't working and I have been trying to find an answer for at least 2 hours now
My code:
if(IMG_Init(IMG_INIT_PNG) != 0) {
std::cout << "Failed to init sdl_image"<<IMG_GetError()<<std::endl;
return 0;
}
As HolyBlackCat pointed out, it should be IMG_INIT(IMG_INIT_PNG) != IMG_INIT_PNG instead of IMG_INIT(IMG_INIT_PNG) != 0

OpenCV program compiles but doesn't run

I am working on Windows 8 with OpenCV 2.4.13 and MinGW 4.9.
I wrote a simple and small opencv program to check if everything was installed properly. Following is the code:
#include <opencv2/highgui/highgui.hpp>
int main () {
printf("in main\n");
for (int i = 0; i<10; i++) {
printf("here\n");
IplImage * image = cvLoadImage("C:/{...}/test.jpg");
cvReleaseImage(&image);
}
return 0;
}
I compiled it with the following command at the command prompt:
g++ -o test test.cpp -LC:\{...}\opencv\build\x64\vc11\lib -lopencv_core2413 -lopencv_highgui2413 -IC:\{...}\opencv\build\include
{...} is the path to the specified folder/file.
This command runs properly and compilation is successful without any errors. However, when I run it with:
test
in main and one here gets printed after which I get the error message as 'test.exe has stopped working. Windows is looking for a solution.'
What all I have tried:
For installation of OpenCV, ran the downloaded opencv executable file (which extracts all files) and added the system variable OPENCV_DIR and edited the system PATH for location of DLLs (which reside in %OPENCV_DIR%\bin) as per:
http://docs.opencv.org/2.4/doc/tutorials/introduction/windows_install/windows_install.html#installation-by-using-the-pre-built-libraries
Tried adding the required DLLs in the same directory as the .exe.
Tried doing the whole thing from vc12 directory.
After the error message appears, it gives an option of debugging. On pressing that, the Just In Time Debugger opens up and says 'An unhandled win32 exception occurred in test.exe'. I googled this and tried inspecting the registry key as directed here
https://support.microsoft.com/en-us/kb/811191
but it was already properly set. So, there was nothing for me to change in that.
Nothing is working for me at all. Please let me know if any more information is required. I'm desperately looking for a solution to this.
For those who might be encountering the same problem, I compiled the program with OpenCV dynamic (.dll) libraries instead of the .lib files and it ran just fine at runtime for some reason.

SDL - TTF - font not loading

I am having Problem loading SDL_TTF font.
my program is so big, so there's a piece of code which is creating problem.
TTF_Font *font = NULL;
SDL_Color textColor = {255, 255, 255};
if(SDL_Init() == -1 || TTF_Init() == -1)
return 0;
font = TTF_OpenFont("calibri.ttf", 28);
if(font == NULL)
return 0;
Now please tell me why the funtion TTF_OpenFont is not working.
font remains NULL after the funtion and the program exits...
EDIT:
I cannot cout or printf TTF_GetError() but i used breakpoints to see which function is not working correctly and found the function TTF_OpenFont() returning null every time.
(BTW if there any way to print the Erroe on screen the tell please).
TTF_Init() is working correctly.
FOR PEOPLE WHO ARE ASKING TO INSTALL SDL_TTF SEPARATELY:
I have written the link below from which i am learning SDL in first tutorial it guides how to install SDL and integrate it which project, In 3rd lesson comes the SDL_IMAGE extension library which is to be needed to install separately (which i did and used all image functions easily), In 7th lesson it didn't teach how to install SDL_TFF rather says to do the same steps as for SDL_IMAGE but this time for SDL_TTf so i downloaded SDL_TTF and intalled and you know the rest after....
Windows 8.1, CodeBlocks, MinGW32, SDL1
Here's the link i am learning SDL from
SDL Tutorials
This is how i installed the Extension Library(SDL_TTF)
Setting Up Extention Library
If font is NULL you should use TTF_GetError to know what went wrong.
If the error message is opaque you may want then to take a look at TTF_OpenFont source.
Suggestions:
1) substitute this code for TTF_Init():
if(TTF_Init()==-1) {
printf("TTF_Init: %s\n", TTF_GetError());
exit(2);
}
2) Make sure you call it before any other SDL_ttf functions.
If you're still having problems, please specify
your platform (Windows? Linux?)
how you installed your TTF fonts.
3) See also: https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html
===================================================================
I'm sorry you're still having problems displaying fonts. A few additional suggestions:
1) I'm sure the tutorial you're using is very good. But you can't assume that just because you followed all the steps, you didn't inadvertantly miss something. To resolve the problem, you're going to have to "look beyond" the tutorial.
2) For starters, we need to confirm whether or not TTF_Init() succeeded. We must be able to see TTF_Init() return status, and TTF_GetError() messages.
Q: What is the return value of TTF_Init?
There are several ways you can display "TTF_GetError":
Start your program from a command prompt ("cmd"):printf("TTF_Init: %s\n", TTF_GetError());
Copy the error to a string and look at it under a debugger: char[80] msg; strcpy (msg, TTF_GetError());
Use a Win32 MessageBox to display the error in a pop-up: MSDN - MessageBox function
3) Make sure you have these .dll's on your filesystem:
libfreetype*.dll
SDL2_ttf*.dll
zlib*.dll
4) Look at the fonts you have installed on your filesystem, for example: C:\Windows\Fonts\*.ttf
See also SDL_ttf - Font directory/Where do fonts go?
PROBLEM SOLVED.
Thanks EveryOne for giving your time...
the problem was program was not recognizing font(candara )
so it copy pasted in my project folder.
I know this was already answerd but i ran into a similar problem with SDL2_ttf under Visual Studio 2015 and want to share my solution to help maybe others in the future.
My problem was that when i started my SDLe application that used SDLe_ttf it could not load the font that was placed in the same directory. But when i executed the the build executable manualy from the command line everything was fine.
I think the problem is that Visual Studio 2015 executes the build executable from a different directory and since i used only the font file name(Sans.ttf) it could not load the font because it treats it as a relative path.
My soultion was to just prefix the font file name with the execution directory which can be optained by calling SDL_GetBasePath.

Improper use of system() call?

I have a particle system program that generates a .dat file with particle coordinates in every iteration. The end goal is to run the program multiple times via a script with different parameters. So, I am trying to setup my program in a way that, for every run, all relevant data are going to be stored in a folder.
What I do is to generate PNGs from the .dat files with Gnuplot, call ffmpeg to create a video out of the PNGs, use WinRAR to compress the .dat files and finally clean up, by deleting all the intermediate files. This works, when I do it in the working directory.
Now I try to create a new directory and do the same stuff in there. My code:
// Load the proper library to use chdir() function
#ifdef _WIN32
#include <direct.h>
#elif defined __linux__ || defined __APPLE__&&__MACH__
#include <unistd.h>
#endif
// Make output directory and change working directory to new directory
ostringstream dirCommand;
dirCommand << "mkdir " << folderName_str;
system(dirCommand.str().c_str());
const char* test = folderName_str.c_str();
#ifdef _WIN32
if(_chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#elif defined __linux__ || defined __APPLE__&&__MACH__
if(chdir(test))
{
printf( "Unable to locate the directory: %s\n",test);
return;
}
#endif
else
printf("Created output directory...\n");
Already for this part, I know that there are going to be objections. I have looked extensively on SO and many people favor SetCurrentDirectory() for Windows, or they are skeptical about using system(). In my defense, I am a novice programmer and my knowledge is really limited...
Now, when I try to make the video with FFMpeg and then rar/tar my files:
// Make video
std::cout << "Generating Video..." << endl;
ostringstream command;
command << "ffmpeg -f image2 -r 1/0.1 -i output_%01d.png -vcodec mpeg4 " << videoName_str << ".avi -loglevel quiet";
std::system(command.str().c_str());
// Clean Up!
std::cout << "Cleaning up!" << endl;
ostringstream command2;
#ifdef _WIN32
command2 << "rar -inul a " << videoName_str << ".rar *.dat settings.gp loadfile.gp";
#elif defined __linux__ || defined __APPLE__&&__MACH__
command2 << "tar cf " << videoName_str << ".tar *.dat settings.gp loadfile.gp";
#endif
std::system(command2.str().c_str());
I get very different behaviors in Win/ Linux.
Win 7 x64, Visual Studio 2010/12
In windows, the folder is created. The .dat files are generated correctly and gnuplot plots the PNGs as well. When ffmpeg is called, nothing happens. No error message from FFMpeg or anything. The same goes for WinRAR. Maybe, for the last thing, I can use the command line utility of 7z which is free!
Linux Mint 14 x64, Qt 4.8.1
Strangely enough, the behavior is inverted from that of Windows. As soon as the dir is changed, only the first .dat file is generated. It is as if every subsequent call I make to fprintf() for my file generation does not work, or gets lost somewhere. Gnuplot works, as do ffmpeg and tar!!
I am really perplexed. Any help, would be really appreciated.
A few points that might be helpful:
Make sure to check the result of every system call, including system() and fprintf().
It's been a while since I last touched Windows; I remember that depending on how binaries were linked, they would not always print out to the same console. So ffmpeg/winrar could be throwing the error messages away, or just allocating a new, short-lived console to print.
I would use mkdir/_mkdir instead of calling system().
With popen()/_popen() you can get more control over the error output.
Consider using a shell script or bat file.

Error when running OpenNI 2 class ( gcc 4.7.2 / ubuntu 12.10 )

I'm trying to compile an run a very basic program given below (test.cpp) which calls the OpenNI class. You can see the files and dirs they're in here. Sorry that some characters screws up a little bit in the browser's encoding. I'm using the linux command: tree, if you know a better command tell me and I will update it.
File Structure
I'm following the guide here, see "GCC / GNU Make".
#include < stdio.h >
#include < OpenNI.h >
using namespace openni;
int
main ( void )
{
Status rc = OpenNI::initialize();
if (rc != STATUS_OK)
{
printf("\nInitialize failed\n%s\n", OpenNI::getExtendedError());
return 1;
}
printf("Hello, world!\n");
return 0;
}
Here is what I'm running in the command line to compile it (gcc 4.7.2):
gcc test.cpp -I../OpenNI-2.0.0/Include -L/home/evan/Code/OpenNi/Init -l OpenNI2 -o test
This works fine but when I run ./test I get the following error:
Initialize failed
DeviceDriver: library handle is invalid for file libOniFile.so
Couldn't understand file 'libOniFile.so' as a device driver
DeviceDriver: library handle is invalid for file libPS1080.so
Couldn't understand file 'libPS1080.so' as a device driver
Found no valid drivers in './OpenNI2/Drivers'
Thanks, any help would be much appreciated.
Instructions from your guide says, that
It is highly suggested to also add the "-Wl,-rpath ./" to your linkage command. Otherwise, the runtime linker will not find the libOpenNI.so file when you run your application. (default Linux behavior is to look for shared objects only in /lib and /usr/lib).
It seems you have exactly this problem -- it can not find some libraries. Try to add proper rpath (seems to be /home/evan/Code/OpenNi/Init/OpenNI2/Drivers in your case) to your compilation string.
I had the same issue after compiling this little "Hello World" with Eclipse and trying to run it in the command line.
The "Wl,-rpath=./" thing did not work for me.
As also discussed here it worked for me after setting some env. variables before execution:
export LD_LIBRARY_PATH="/path/to/OpenNI2:$LD_LIBRARY_PATH"
export OPENNI2_DRIVERS_PATH="/path/to/OpenNI2/Drivers"
export LD_LIBRARY_PATH="/path/to/OpenNI2/Drivers:$LD_LIBRARY_PATH"
Somewhere I got the info that the first two lines should be enough but it was the third line which is important. I does also work just with the third line.