The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Simple truetype font library for SDL2
wboe


Joined: 09 Jan 2012
Posts: 41
Location: Amsterdam, Netherlands
Hi,

SDL uses the SDL_ttf library for font rendering. The engine of this lib is the freetype lib, which is fine until you have to cross-compile for Android. This freetype lib consists of a huge number of C files, that must be compiled apart from the Android NDK environment because no Android.mk files are provided.

There is an alternative. A clever guy called Sean Barrett has written a parser and renderer for truetype fonts. It consists of one file (http://nothings.org/stb/stb_truetype.h), containing everything you need: a manual, examples, header file and C code.

From the examples I created a small demo program, listed hereunder.
If you call it test-stbtt.c it can be compiled as follows:
gcc test-stbtt.c -o test-stbtt $(sdl2-config --cflags) $(sdl2-config --libs) -lm

It can be run with 0, 1, 2 or 3 options, and will display a black text in a white window. Notice that there is a hard-coded path to a ttf spec file, modify this as needed.

I did'nt use all provided refinements in this demo program. Notice that the SDL.h file is included after the stb_truetype.h, that's because some big- and small endian magic occurs, which might get disturbed by #define statements in SDL.h. The characters that are displayed are not cached, so a big speed-up would still be possible.

wboe

Code:
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

#include <SDL.h>

int main(int argc, char **argv) {
   if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("Init problem: %s\n",SDL_GetError()); exit(1); }
   SDL_Window *window = SDL_CreateWindow("test-stbtt", 100,100,200,100, SDL_WINDOW_SHOWN);
   if (!window) { printf("%s\n",SDL_GetError()); SDL_Quit(); }
   SDL_Renderer *renderer=SDL_CreateRenderer(window, -1,SDL_RENDERER_ACCELERATED);
   SDL_SetRenderDrawColor(renderer,0xff,0xff,0xff,0xff);
   SDL_RenderClear(renderer);
   SDL_RenderPresent(renderer);
   SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

   stbtt_fontinfo font;
   unsigned char *bitmap=0;
   const char *text=(argc > 1 ? argv[1] : "Hallo!");
   int s = (argc > 2 ? atoi(argv[2]) : 20);

   FILE *ff=fopen(argc > 3 ? argv[3] : "/usr/share/fonts/google-droid/DroidSans.ttf","rb");
   if (!ff) { puts("font file not found"); exit(1); }
   fseek(ff,0,SEEK_END);
   int fsize=ftell(ff);
   rewind(ff);
   char ttf_buffer[fsize];
   fread(ttf_buffer, 1,fsize,ff);

   stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
   float scale=stbtt_ScaleForPixelHeight(&font, s);
   int ascent,
       descent;
   stbtt_GetFontVMetrics(&font,&ascent,&descent,0);

   int ind,
       advance,
       x0,y0,
       h,w,
       xpos=10,
       ypos=10+scale*ascent;
   printf("ascent=%d descent=%d linedist=%d\n",(int)(scale*ascent),(int)(scale*descent),(int)(scale * (ascent-descent)));
   for (ind=0;text[ind];++ind) {
      bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), text[ind], &w, &h, 0,0);
      stbtt_GetCodepointHMetrics(&font, text[ind], &advance, 0);
      stbtt_GetCodepointBitmapBox(&font, text[ind], scale, scale, &x0, &y0, 0, 0);

      int i,j,
          x=xpos,
          y=ypos;
      for (j=0; j < h; ++j) {
         for (i=0; i < w; ++i) {
            if (bitmap[j*w+i]) {
              SDL_SetRenderDrawColor(renderer,0,0,0,bitmap[j*w+i]);
              SDL_RenderDrawPoint(renderer,x+x0,y+y0);
            }
            ++x;
         }
         x=xpos;
         ++y;
      }
      stbtt_FreeBitmap(bitmap,0);
      if (!text[ind+1]) break;
      xpos += scale*advance;
   }
   SDL_RenderPresent(renderer);
   SDL_Event event;
   while (1)
     while(SDL_PollEvent(&event))
       if (event.type==SDL_QUIT) { SDL_Quit(); exit(0); }
   return 0;
}
Simple truetype font library for SDL2
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
Because of the open nature of the license, what I'd recommend (and this is something that I may do myself anyway) is to add some code to support SDL_RWops, and write an official SDL port of the library.  Once that's done, the community will have a chance to see it in action with SDL.  I don't think this needs to be a replacement for SDL_ttf, either - if it works, it's just another option.

The more I read through the code, the more I get this impression that I've looked at this before, and maybe it was on this mailing list a few years ago?  Anyway, good find, and nice example of it alongside SDL Smile

-Alex

On Mon, Oct 15, 2012 at 4:35 AM, wboe wrote:
Quote:
Hi,

SDL uses the SDL_ttf library for font rendering. The engine of this lib is the freetype lib, which is fine until you have to cross-compile for Android. This freetype lib consists of a huge number of C files, that must be compiled apart from the Android NDK environment because no Android.mk files are provided.

There is an alternative. A clever guy called Sean Barrett has written a parser and renderer for truetype fonts. It consists of one file (http://nothings.org/stb/stb_truetype.h), containing everything you need: a manual, examples, header file and C code.

From the examples I created a small demo program, listed hereunder.
If you call it test-stbtt.c it can be compiled as follows:
gcc test-stbtt.c -o test-stbtt $(sdl2-config --cflags) $(sdl2-config --libs) -lm

It can be run with 0, 1, 2 or 3 options, and will display a black text in a white window. Notice that there is a hard-coded path to a ttf spec file, modify this as needed.

I did'nt use all provided refinements in this demo program. Notice that the SDL.h file is included after the stb_truetype.h, that's because some big- and small endian magic occurs, which might get disturbed by #define statements in SDL.h. The characters that are displayed are not cached, so a big speed-up would still be possible.

wboe




Code:

#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

#include

int main(int argc, char **argv) {
   if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("Init problem: %s\n",SDL_GetError()); exit(1); }
   SDL_Window *window = SDL_CreateWindow("test-stbtt", 100,100,200,100, SDL_WINDOW_SHOWN);
   if (!window) { printf("%s\n",SDL_GetError()); SDL_Quit(); }
   SDL_Renderer *renderer=SDL_CreateRenderer(window, -1,SDL_RENDERER_ACCELERATED);
   SDL_SetRenderDrawColor(renderer,0xff,0xff,0xff,0xff);
   SDL_RenderClear(renderer);
   SDL_RenderPresent(renderer);
   SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

   stbtt_fontinfo font;
   unsigned char *bitmap=0;
   const char *text=(argc > 1 ? argv[1] : "Hallo!");
   int s = (argc > 2 ? atoi(argv[2]) : 20);

   FILE *ff=fopen(argc > 3 ? argv[3] : "/usr/share/fonts/google-droid/DroidSans.ttf","rb");
   if (!ff) { puts("font file not found"); exit(1); }
   fseek(ff,0,SEEK_END);
   int fsize=ftell(ff);
   rewind(ff);
   char ttf_buffer[fsize];
   fread(ttf_buffer, 1,fsize,ff);

   stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
   float scale=stbtt_ScaleForPixelHeight(&font, s);
   int ascent,
       descent;
   stbtt_GetFontVMetrics(&font,&ascent,&descent,0);

   int ind,
       advance,
       x0,y0,
       h,w,
       xpos=10,
       ypos=10+scale*ascent;
   printf("ascent=%d descent=%d linedist=%d\n",(int)(scale*ascent),(int)(scale*descent),(int)(scale * (ascent-descent)));
   for (ind=0;text[ind];++ind) {
      bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), text[ind], &w, &h, 0,0);
      stbtt_GetCodepointHMetrics(&font, text[ind], &advance, 0);
      stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ind], scale,scale,0,0, &x0,&y0,0,0);

      int i,j,
          x=xpos,
          y=ypos;
      for (j=0; j < h; ++j) {
         for (i=0; i < w; ++i) {
            if (bitmap[j*w+i]) {
              SDL_SetRenderDrawColor(renderer,0,0,0,bitmap[j*w+i]);
              SDL_RenderDrawPoint(renderer,x+x0,y+y0);
            }
            ++x;
         }
         x=xpos;
         ++y;
      }
      stbtt_FreeBitmap(bitmap,0);
      if (!text[ind+1]) break;
      xpos += scale*advance;
   }
   SDL_RenderPresent(renderer);
   SDL_Event event;
   while (1)
     while(SDL_PollEvent(&event))
       if (event.type==SDL_QUIT) { SDL_Quit(); exit(0); }
   return 0;
}






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Simple truetype font library for SDL2
wahono


Joined: 18 Aug 2012
Posts: 37
SFML has internal font rendering, if this truetype rendering added in SDL, I think it would very usefull, we don't need freetype again, especially for iOS and Android.

regards
Simple truetype font library for SDL2
Vittorio Giovara
Guest

Afaik there is no problem in compiling Freetype for Android.
You can find the Android.mk we use every day here: https://code.google.com/p/hedgewars/source/browse/#hg%2Fmisc%2Flibfreetype

Vittorio

On Mon, Oct 15, 2012 at 10:35 AM, wboe wrote:
Quote:
Hi,

SDL uses the SDL_ttf library for font rendering. The engine of this lib is the freetype lib, which is fine until you have to cross-compile for Android. This freetype lib consists of a huge number of C files, that must be compiled apart from the Android NDK environment because no Android.mk files are provided.

There is an alternative. A clever guy called Sean Barrett has written a parser and renderer for truetype fonts. It consists of one file (http://nothings.org/stb/stb_truetype.h), containing everything you need: a manual, examples, header file and C code.

From the examples I created a small demo program, listed hereunder.
If you call it test-stbtt.c it can be compiled as follows:
gcc test-stbtt.c -o test-stbtt $(sdl2-config --cflags) $(sdl2-config --libs) -lm

It can be run with 0, 1, 2 or 3 options, and will display a black text in a white window. Notice that there is a hard-coded path to a ttf spec file, modify this as needed.

I did'nt use all provided refinements in this demo program. Notice that the SDL.h file is included after the stb_truetype.h, that's because some big- and small endian magic occurs, which might get disturbed by #define statements in SDL.h. The characters that are displayed are not cached, so a big speed-up would still be possible.

wboe




Code:

#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"

#include

int main(int argc, char **argv) {
   if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("Init problem: %s\n",SDL_GetError()); exit(1); }
   SDL_Window *window = SDL_CreateWindow("test-stbtt", 100,100,200,100, SDL_WINDOW_SHOWN);
   if (!window) { printf("%s\n",SDL_GetError()); SDL_Quit(); }
   SDL_Renderer *renderer=SDL_CreateRenderer(window, -1,SDL_RENDERER_ACCELERATED);
   SDL_SetRenderDrawColor(renderer,0xff,0xff,0xff,0xff);
   SDL_RenderClear(renderer);
   SDL_RenderPresent(renderer);
   SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);

   stbtt_fontinfo font;
   unsigned char *bitmap=0;
   const char *text=(argc > 1 ? argv[1] : "Hallo!");
   int s = (argc > 2 ? atoi(argv[2]) : 20);

   FILE *ff=fopen(argc > 3 ? argv[3] : "/usr/share/fonts/google-droid/DroidSans.ttf","rb");
   if (!ff) { puts("font file not found"); exit(1); }
   fseek(ff,0,SEEK_END);
   int fsize=ftell(ff);
   rewind(ff);
   char ttf_buffer[fsize];
   fread(ttf_buffer, 1,fsize,ff);

   stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0));
   float scale=stbtt_ScaleForPixelHeight(&font, s);
   int ascent,
       descent;
   stbtt_GetFontVMetrics(&font,&ascent,&descent,0);

   int ind,
       advance,
       x0,y0,
       h,w,
       xpos=10,
       ypos=10+scale*ascent;
   printf("ascent=%d descent=%d linedist=%d\n",(int)(scale*ascent),(int)(scale*descent),(int)(scale * (ascent-descent)));
   for (ind=0;text[ind];++ind) {
      bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), text[ind], &w, &h, 0,0);
      stbtt_GetCodepointHMetrics(&font, text[ind], &advance, 0);
      stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ind], scale,scale,0,0, &x0,&y0,0,0);

      int i,j,
          x=xpos,
          y=ypos;
      for (j=0; j < h; ++j) {
         for (i=0; i < w; ++i) {
            if (bitmap[j*w+i]) {
              SDL_SetRenderDrawColor(renderer,0,0,0,bitmap[j*w+i]);
              SDL_RenderDrawPoint(renderer,x+x0,y+y0);
            }
            ++x;
         }
         x=xpos;
         ++y;
      }
      stbtt_FreeBitmap(bitmap,0);
      if (!text[ind+1]) break;
      xpos += scale*advance;
   }
   SDL_RenderPresent(renderer);
   SDL_Event event;
   while (1)
     while(SDL_PollEvent(&event))
       if (event.type==SDL_QUIT) { SDL_Quit(); exit(0); }
   return 0;
}






_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org