Bitmap font toolkit

Member
Posts: 749
Joined: 2003.01
Post: #1
Based on Skorche's code to print ttf to bitmap, ( http://code.google.com/p/aerosol/source/...makefont.c ) I was thinking it could be cool to have a full kit for bitmap fonts in SDL/opengl.

The workflow could be:

-Use a program similar to Skorche's to output the ttf to a png and the metrics to a text file (or just as an array you can copy in your code).

-Apply a "style" or effect with photoshop. For stuff like vertical gradients it would be much much easier to have the whole font png on a single line, ending up with a pretty wide image... this shouldn't be a problem for SDL I hope.
Always for vertical gradients it would be good to have letters be drawn in the png with their vertical position as they would appear when actually written (not "standing" on the baseline).

-the applied style could make the fonts bigger, so you would have some parameter, to adjust this when loading back the png.

-A function to load back the fonts from the png and the metrics (in sdl surfaces?).

-A function to draw a string to a SDL surface (for use in a opengl texture)?
I'm not sure this is the way to go or it would be better to just make a texture for each character and then use multiple quads to write a string.

This could be a pretty cool and useful project if made as simple as possible, I'll see if I can write up something usable by the community. Of course if you've done this (or part of it) already and want to share feel free Wink

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Member
Posts: 241
Joined: 2008.07
Post: #2
I use a program from LMNOPC that generates a font sheet from any installed font. It takes a step of processing out of your app but adds a step to your pipeline. I prefer to just have that extra step in the pipeline for sake of simplicity. It's a Windows program but just to generate a few font sheets, it's easy enough to fire up Windows. It saves it as a BMP but you can convert it to whatever you like using your favorite program. It allows you to apply any color to the font and any color to the background. You can save it as any of a number of power-of-two sizes. It was created with bitmap font engines in mind. It's a great utility.
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #3
Yeah I'd mainly use bitmap fonts so you can style-color them with photoshop, so having a png or any other transparency enabled format would avoid you having to convert the white on black bmp to a transparency mask (not that it's much work) in photoshop (before applying the style), not a big deal. For that Skorche's code is just fine.

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #4
I've got a question, as for the font data to print out in order to subsequently recover the single glyphs from the full image, is it ok if I just make it printf "code" that will have to be copied by the user in a paricular function to load the font data i.e.

font->glyphs[32].xonsheet=40;
font->glyphs[32].yonsheet=150;
font->glyphs[32].width=0;
font->glyphs[32].height=0;
font->glyphs[32].minx=0;
font->glyphs[32].miny=0;
font->glyphs[32].advance=36;
font->glyphs[33].xonsheet=120;
font->glyphs[33].yonsheet=65;
font->glyphs[33].width=21;
font->glyphs[33].height=84;
font->glyphs[33].minx=6;
font->glyphs[33].miny=1;
font->glyphs[33].advance=31;
...

(for 126 glyphs)

or should I have the program output a file and then write a function to re-parse it?

(I mean they both work, but is the first "acceptable"?)

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
I wouldn't use the first. I probably wouldn't use the second either though Wink
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #6
Heh I'm sure there's an awesome Cocoa thing just for that Rasp

I've used IO a few times with C++ but I'm stuck with bare C for this one :/

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #7
The original printf format should be pretty trivially parseable with scanf.

For iPhone ScribBall I wrote a Ruby script that spit out a vertex array declaration from the metrics file. I will not be doing this again nor would I recommend generating code to copy paste. It ended being about as much work and made it very tedious to make tweaks to the font.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #8
I'm more or less done with this (some more testing wouldn't hurt), I'm thinking of releasing it with a BSD license.

@Skorche, there's not much left of your code though it certainly helped start, is it fine for you if I write "Copyright 2008 Matteo Guarnieri, portions based on code by Scott Lembcke"?

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #9
Sure go for it. It's not like any real thought other than computing the row max height was put into it on my part.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #10
Ok, here we go...

The *library* is called Simple Bitmap Font (SBF) Rasp
It's for use with SDL, but it's practical to use with OpenGL too (you just have to pass the SDL_Surface you draw the text on to an OpenGL texture).

Header:
Code:
/*file name: SBF.h

Simple Bitmap Font (SBF) Version 0.5, Copyright 2008 Matteo Guarnieri, portions based on code by Scott Lembcke.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

//If you use this please send me an email ( matteo@ragdollsoft.com )! It would be great to know someone is actually using this ;)

/*SBF is a tiny library for using bitmap fonts with SDL, SDL_image and SDL_ttf.
It currently supports only ASCII characters.

How to use:

1-OUTPUT THE TTF TO BMP: The SBF_output_font_data_and_bitmap(...) function, given a TTF_Font loaded with SDL_ttf, outputs the font sheet bitmap
( a long bitmap with all the fonts), along with a text file containing numerial data necessary to "recover" the font from
the bitmap and display it correctly.
Your truetype font and SDL_ttf are only needed for this part, once you have the BMP and the data file you dont those (or this function) anymore.

2-MODIFY THE FONT BMP: The main point of using a bitmap font is to apply cool effects to the font (you can do that with your favourite gfx application).
It is recommended  that you save the file in PNG with alpha mask (transparency) so that the letters are opaque and all the rest is transparent.

3-MAKE A SBF_font VARIABLE: SBF_font is a struct containing all the stuff you need for using a bitmap font. Just declare it as a normal struct ie. "SBF_font myfont;"
Be careful not to declare it as a pointer i.e. "SBF_font* myfont" as it will remain uninitialized.

4-LOAD THE BITMAP FONT DATA: In point 1 you had outputted a text file witH the font data: load this data back in your SBF_font with SBF_read_font_data(&myfont, "fontdata.txt");

5-ADJUST THE DATA: You can change the data at runtime in order to make up for the small size changes in the letters you may have done in point 2. See function SBF_adjust_font(...)

6-LOAD THE BITMAP FONT BITMAPS: Now you can load the actual bitmap glyphs (characters) from your PNG in your SBF_font with SBF_load_glyphs(...)

7-DRAW THE TEXT: use SBF_draw_text(...) or SBF_text_on_new_surface(...);

8-CLEAN UP: SBF_free_font(myfont) when finished with the font

FAQ:

Q:why is my BMP a long line of characters and not a grid?
A:this way you can apply vertical gradient effects in gimp or photoshop which otherwise would end up wrong (the letters on the bottom of the bmp would be of a different color from those on the top)
Vertical gradients are a pretty common effect for text.

Q:my characters get cropped!
A:Fix this with SBF_adjust_font(...) i.e. add some thickness or some "shadow".
*/

#ifndef _SBF_h
#define _SBF_h

#include "SDL_ttf/SDL_ttf.h"
#include "SDL_image/SDL_image.h"
#include "SDL/SDL.h"


/*bitmap glyph (character) type contains the bitmap of the character and other info about it.
see http://www.freetype.org/freetype2/docs/glyphs/glyphs-3.html for what variables mean*/
typedef struct SBF_glyph_
    {
        SDL_Surface *surface;
        int xonsheet;
        int yonsheet;
        int width;
        int height;
        int minx;
        int miny;
        int advance;
    }SBF_glyph;

/*the font "alphabet", contains the  glyphs, and some other info*/
typedef struct SBF_font_
    {
        SBF_glyph glyphs[256];
        int startnum;
        int endnum;        
        int ascent;
        int descent;
        int lineskip;
    }SBF_font;


/*outputs the font sheet bitmap, along with a text file containing numerial data necessary to "recover" the font from
the bitmap and display it correctly.
xpad and ypad are used to give some padding to the characters, needed if you have to apply effects to the font bitmap later.
Usually startnum should be 32, endnum 126 (those are the ascii codes for the first and last ascii characters)*/
void SBF_output_font_data_and_bitmap(TTF_Font *ttf_font, int xpad, int ypad, int startnum, int endnum, char* data_file_name, char* bitmap_file_name);

/*read the data outputted with SBF_output_font_data_and_bitmap(...) and put it in your SBF_font*/
void SBF_read_font_data(SBF_font* font, char* data_file_name);

/* The following function can be used after modifying the font bitmap sheet, in order to correct for changes in the sizes of the letters.
i.e. if you add a 2 pixel border around each letter put 2 as thickness, if you add a shadow that goes to the left for 3 pixels, put leftshadow=3 etc.
Notice that "thickness" also increases the distance between the letters, while the shadow values keep the distance unchanged
Call this function only after you have called SBF_read_font_data(...) */
void SBF_adjust_font(SBF_font* font, int thickness, int rightshadow, int leftshadow, int upshadow, int downshadow);

/*This function is used to load the bitmap font's glyphs (i.e. the characters) from the image specified (should be png in order to handle transparency)
Call this function only after you have called SBF_read_font_data(...) (and SBF_adjust_font(...) if needed)*/
void SBF_load_glyphs(SBF_font* font, char* image_name);

/*This function is used to draw a string on an existing (and already allocated) SDL_Surface. y is the baseline y you want to use to draw your text on*/
/*if you just want to write on a new surface for use in an OpenGL texture, SBF_text_on_new_surface(...) is easier*/
/*the "backwards" parameter if nonzero tells to draw the text from the last letter to the fist (use if you have a shadow on the left)*/
void SBF_draw_text(SBF_font* font, SDL_Surface *surface, char* text, int x, int y, int backwards);

/*this function creates a SDL_Surface with the minimum size required to hold the text, and writes the text inside it*/
/*Returns the pointer to the surface. Remebemer to free with SDL_FreeSurface() when done with it*/
/*the "backwards" parameter if nonzero tells to draw the text from the last letter to the fist (use if you have a shadow on the left)*/
SDL_Surface* SBF_text_on_new_surface(SBF_font* font, char* text, int backwards);

/*free the font memory when you're done*/
void SBF_free_font(SBF_font* font);

/*This function returns the length of a string (in pixels)*/
int SBF_text_length(SBF_font* font, char* text);

/*This function returns the height of a string (in pixels)*/
int SBF_text_height(SBF_font* font, char* text);

/*This function returns the maximum maxy of a string (in pixels)*/
int SBF_text_max_y(SBF_font* font, char* text);

/*This function is used to draw a char on an existing (and already allocated) SDL_Surface. y is the baseline y you want to use to draw your font on*/
/*you most likely want to use SBF_draw_text(...) or SBF_text_on_new_surface(...)*/
int SBF_draw_glyph(SBF_font* font, SDL_Surface *surface, char character,int x, int y);

/*used when ouputting the font bitmap*/
int SBF_chose_font_sheet_width(TTF_Font* ttf_font, int startnum, int endnum, int xpad);

#endif

Implementation:
Code:
/* file name: SBF.c
  
Simple Bitmap Font (SBF) Version 0.5, Copyright 2008 Matteo Guarnieri, portions based on code by Scott Lembcke.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

//FOR INSTRUCTIONS AND FUNCTION DESCRIPTION READ THE SBF.h FILE

#include "SBF.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL_ttf/SDL_ttf.h"
#include "SDL_image/SDL_image.h"
#include "SDL/SDL.h"



void SBF_output_font_data_and_bitmap(TTF_Font *ttf_font, int xpad, int ypad, int startnum, int endnum, char* data_file_name, char* bitmap_file_name)
{
    SDL_Color white = {0xFF, 0xFF, 0xFF, 0};
    SDL_Color black = {0x00, 0x00, 0x00, 0};
    SDL_Surface *output = SDL_CreateRGBSurface(SDL_SWSURFACE, SBF_chose_font_sheet_width(ttf_font, startnum,  endnum,  xpad), TTF_FontLineSkip(ttf_font)+ypad*2, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);    
    if(output == NULL) {
        fprintf(stderr, "SBF_output_font_data_and_bitmap: CreateRGBSurface failed: %s\n", SDL_GetError());
        exit(1);
    }        
    int y = ypad;
    int x = xpad;
    int i;
    FILE * pFile;
    pFile = fopen (data_file_name,"w");
    if (pFile==NULL)
    {
        fprintf(stderr, "SBF_output_font_data_and_bitmap: could not write data");
        exit(2);        
    }    
    fprintf(pFile,"%d\n", 1);
    fprintf(pFile,"%d %d %d %d %d\n", startnum, endnum, TTF_FontLineSkip(ttf_font), TTF_FontAscent(ttf_font), TTF_FontDescent(ttf_font));
    for(i = startnum; i <= endnum; i++ ) {
        SDL_Surface *glyph = TTF_RenderGlyph_Shaded( ttf_font, i, white, black);
        int minx, miny, advance;
        TTF_GlyphMetrics(ttf_font,i,&minx,NULL,&miny,NULL,&advance);
        int yonsheet=TTF_FontAscent(ttf_font) + y - glyph->h-miny;
        int xonsheet=x;
        SDL_Rect rect = (SDL_Rect){xonsheet, yonsheet, glyph->w, glyph->h};
        SDL_BlitSurface(glyph, NULL, output, &rect);
        fprintf(pFile,"%d %d %d %d %d %d %d\n", xonsheet, yonsheet, glyph->w, glyph->h, minx, miny, advance);
        x += glyph->w + xpad*2;
    }
    SDL_SaveBMP(output, bitmap_file_name);
    fclose (pFile);
}


void SBF_read_font_data(SBF_font* font, char* data_file_name)
{
    FILE * pFile;
    pFile = fopen (data_file_name,"r");
    if (pFile==NULL)
    {
        fprintf(stderr, "SBF_read_font_data: could not read data");
        exit(2);        
    }    
    int version;
    fscanf (pFile, "%d", &version);
    fscanf(pFile, "%d", &font->startnum);
    fscanf(pFile, "%d", &font->endnum);
    fscanf(pFile, "%d", &font->lineskip);
    fscanf(pFile, "%d", &font->ascent);
    fscanf(pFile, "%d", &font->descent);    
    int i;
    for (i=font->startnum;i<=font->endnum;i++)
    {
        fscanf(pFile, "%d", &font->glyphs[i].xonsheet);
        fscanf(pFile, "%d", &font->glyphs[i].yonsheet);
        fscanf(pFile, "%d", &font->glyphs[i].width);
        fscanf(pFile, "%d", &font->glyphs[i].height);
        fscanf(pFile, "%d", &font->glyphs[i].minx);
        fscanf(pFile, "%d", &font->glyphs[i].miny);
        fscanf(pFile, "%d", &font->glyphs[i].advance);
    }
    fclose (pFile);
}


void SBF_adjust_font(SBF_font* font, int thickness, int rightshadow, int leftshadow, int upshadow, int downshadow)
{    
    int i;
    for(i=font->startnum;i<=font->endnum ;i++)
    {
        font->glyphs[i].xonsheet-=thickness+leftshadow;
        font->glyphs[i].yonsheet-=thickness+upshadow;
        font->glyphs[i].width+=2*thickness+leftshadow+rightshadow;
        font->glyphs[i].height+=2*thickness+upshadow+downshadow;
        font->glyphs[i].advance+=2*thickness;
        font->glyphs[i].minx-=leftshadow;
        font->glyphs[i].miny-=thickness+downshadow;
    }
    font->lineskip+=2*thickness+upshadow+downshadow;
    font->ascent+=thickness+upshadow;
    font->descent-=thickness+downshadow;
}


void SBF_load_glyphs(SBF_font* font, char* image_name)
{
    SDL_Surface *fontsheet = IMG_Load(image_name);
    SDL_SetAlpha(fontsheet, 0, 0);
    if (fontsheet==NULL)
    {
        fprintf(stderr, "SBF_load_glyphs: Couldn't load image: %s\n",SDL_GetError());
        exit(2);        
    }
    int i;
    for(i=font->startnum;i<=font->endnum ;i++)
    {
        font->glyphs[i].surface=SDL_CreateRGBSurface(SDL_SWSURFACE, font->glyphs[i].width, font->glyphs[i].height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
        if(font->glyphs[i].surface == NULL) {
            fprintf(stderr, "SBF_load_glyphs: CreateRGBSurface failed: %s\n", SDL_GetError());
            exit(1);
        }
        SDL_Rect srcrect = (SDL_Rect){font->glyphs[i].xonsheet, font->glyphs[i].yonsheet, font->glyphs[i].width, font->glyphs[i].height};
        SDL_BlitSurface(fontsheet, &srcrect, font->glyphs[i].surface, NULL);
        SDL_SetAlpha(font->glyphs[i].surface, 0, 0);
    }
    SDL_FreeSurface(fontsheet);//new

}


void SBF_draw_text(SBF_font* font, SDL_Surface *surface, char* text, int x, int y, int backwards) //draws text on existing surface, y is baseline
{
    int i;
    if (!backwards)
    {
        for(i=0; i<strlen(text); i++)
        {
            if (i>0) x+=font->glyphs[text[i]].minx;
            int advance=SBF_draw_glyph(font, surface, text[i],x, y);
            x += advance-font->glyphs[text[i]].minx;
        }
    }
    else
    {
        x=SBF_text_length( font,  text);
        for(i=strlen(text)-1; i>=0; i--)
        {
            if (text[i]<font->startnum || text[i]>font->endnum)
            {
                fprintf(stderr, "SBF_text_length: character out of bounds");
            }
            else
            {        
                if (i==strlen(text)-1)
                {x-=font->glyphs[text[i]].width;}
                else
                {
                x-=font->glyphs[text[i]].advance;
                x+=font->glyphs[text[i]].minx;
                }
                SBF_draw_glyph(font, surface, text[i],x, y);
                x-=font->glyphs[text[i]].minx;
            }
        }
    }
}


SDL_Surface* SBF_text_on_new_surface(SBF_font* font, char* text, int backwards)
{
    int length=SBF_text_length(font, text);
    int height=SBF_text_height(font, text);
    int maxy=SBF_text_max_y(font, text);
    SDL_Surface* surface;
    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, length, height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
    if(surface == NULL) {
        fprintf(stderr, "SBF_text_on_new_surface: CreateRGBSurface failed: %s\n", SDL_GetError());
        exit(1);
    }    
    SDL_SetAlpha(surface, 0, 0);
    SBF_draw_text(font, surface, text,  0, maxy, backwards);    
    return surface;
}


void SBF_free_font(SBF_font* font)
{
    int i;
    for(i=font->startnum;i<=font->endnum ;i++)
    {
        SDL_FreeSurface(font->glyphs[i].surface);
    }
}


int SBF_draw_glyph(SBF_font* font, SDL_Surface *surface, char character,int x, int y)
{
    if (character<font->startnum || character>font->endnum)
    {
        fprintf(stderr, "SBF_draw_glyph: character out of bounds");
        return (0);
    }
    else
    {
        SBF_glyph* glyphtodraw=&( font ->glyphs[character]);
        SDL_Rect destrect= (SDL_Rect){x, y-glyphtodraw->miny-glyphtodraw->height, 0, 0};
        SDL_BlitSurface (glyphtodraw->surface, NULL, surface, &destrect);
        return glyphtodraw->advance;
    }
}

int SBF_text_length(SBF_font* font, char* text)
{
    int length=0;
    int i;
    for(i=0; i<strlen(text); i++)
    {
        if (text[i]<font->startnum || text[i]>font->endnum)
        {
            fprintf(stderr, "SBF_text_length: character out of bounds");
        }
        else
        {
            if (i==strlen(text)-1 && i==0) length+=font->glyphs[text[i]].width;
            else if (i==0) length+=font->glyphs[text[i]].advance-font->glyphs[text[i]].minx;
            else if (i==strlen(text)-1) length+=font->glyphs[text[i]].minx+font->glyphs[text[i]].width;
            else    length+=font->glyphs[text[i]].advance;
        }
    }
    return length;
}


int SBF_text_height(SBF_font* font, char* text)
{
    int totmaxy=0;
    int totminy=0;
    int i;
    for(i=0; i<strlen(text); i++)
    {
        if (text[i]<font->startnum || text[i]>font->endnum)
        {
            fprintf(stderr, "SBF_text_length: character out of bounds");
        }
        else
        {            
            int maxy=font->glyphs[text[i]].miny+font->glyphs[text[i]].height;
            int miny=font->glyphs[text[i]].miny;
            if (maxy>totmaxy) totmaxy=maxy;
            if (miny<totminy) totminy=miny;
        }
    }
    return totmaxy-totminy;
}


int SBF_text_max_y(SBF_font* font, char* text)
{
    int totmaxy=0;
    int i;
    for(i=0; i<strlen(text); i++)
    {
        if (text[i]<font->startnum || text[i]>font->endnum)
        {
            fprintf(stderr, "SBF_text_length: character out of bounds");
        }
        else
        {            
            int maxy=font->glyphs[text[i]].miny+font->glyphs[text[i]].height;
            if (maxy>totmaxy) totmaxy=maxy;
        }
    }
    return totmaxy;
}


int SBF_chose_font_sheet_width(TTF_Font* ttf_font, int startnum, int endnum, int xpad)
{
    int totadvance=0;
    int i;
    for(i = startnum; i <= endnum; i++ ) {
        int minx,maxx;
        TTF_GlyphMetrics(ttf_font, i, &minx, &maxx, NULL, NULL, NULL);
        totadvance+=maxx-minx;
    }
    return totadvance+(endnum-startnum+2)*xpad*2;
}

Example
Code:
/* file name: main.c

/*an example on how to use the Simple Bitmap Font library*/
/*you need to have a "font.ttf" font in the same folder as the executable for this to work*/

#include "SBF.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL_ttf/SDL_ttf.h"
#include "SDL_image/SDL_image.h"
#include "SDL/SDL.h"

int main(int argc, char *argv[])
{
    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
        fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
        exit(2);
    }
    if ( TTF_Init() < 0 ) {
        fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
        SDL_Quit();
        exit(2);
    }
    TTF_Font *ttf_font = TTF_OpenFont("font.ttf", 128);
    if ( ttf_font == NULL ) {
        fprintf(stderr, "Could not load font\n");
        exit(2);
    }
    SBF_output_font_data_and_bitmap(ttf_font,  30,  30, 32, 126, "fontdata.txt", "fontbit2.bmp");
    
/*After this you would usually want to open up your font bitmap with GIMP or Photoshop, convert it to a png with transparency mask (letters opaque, all the rest transparent),
then apply some cool  filter like emboss, textures, gradients, shadows etc. Then save as "retouched_font.png" or something*/
    
    SBF_font myfont;
    SBF_read_font_data(&myfont, "fontdata.txt");
    SBF_adjust_font(&myfont, 0, 0, 0, 0, 0); //if you modified your font bitmap you should use this function to correct the font and glyph parameters
    SBF_load_glyphs(&myfont, "fontbit2.bmp");//if you modified your font bitmap to a png (recommended) here you should load the png.
    SDL_Surface* test2= SBF_text_on_new_surface(&myfont, "HELLO WORLD",0);
    SDL_SaveBMP(test2, "test2.bmp");
    return 0;
}

I might not be ultra sexy smooth but it's reasonably well thought out and it works (at least for me Rasp)

I'm not a C wiz so if i'm doing something against usual conventions or something has bad style (or everything Rasp) please tell.

Let me know if you get to use it Smile and also if you have questions, suggestons, comments etc.

Also a question: it works if both (main and SBF) files are .c or both are .cpp, but not if one's cpp and the other' c (gives "symbols not found" for my functions when linking), why's that ?

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Bitmap fonts markhula 6 8,007 Feb 27, 2011 12:55 PM
Last Post: markhula
  Anyone experienced Performance ± with UILabels vs. Bitmap Font in OpenGL ES 1.1? Elphaba 3 4,349 Jul 28, 2009 10:40 AM
Last Post: AnotherJake
  CGContextFlush: invalid context with awt.Toolkit and awt.Graphics Tools10 1 3,664 Jun 10, 2007 04:07 PM
Last Post: Tools10
  opengl bitmap font question: switching to fullscreen moon_magic 2 3,000 Jul 8, 2006 03:39 PM
Last Post: OneSadCookie
  Bitmap Fonts in GL Joseph Duchesne 18 9,439 Feb 3, 2006 09:25 AM
Last Post: ThemsAllTook