Exemplo n.º 1
0
/* load a font from a ttf file with the given fontindex and pointsize as font font_id */
int vultures_load_font (int font_id, const char * ttf_filename, int fontindex, int pointsize)
{
    TTF_Font * newfont;
    if(!TTF_WasInit())
    {
        if(TTF_Init()==-1)
            return FALSE;

        if (!vultures_fonts)
            vultures_fonts = (struct vultures_font *)calloc(VULTURES_MAX_FONTS, sizeof(struct vultures_font));
    }

    /* font_id should always be passed as a #define, which is always <  VULTURES_MAX_FONTS */
    if (font_id >= VULTURES_MAX_FONTS)
        return FALSE;

    newfont = TTF_OpenFontIndex(ttf_filename, pointsize, fontindex);

    if (!newfont)
        return FALSE;

    if (vultures_fonts[font_id].fontptr)
        TTF_CloseFont(vultures_fonts[font_id].fontptr);

    vultures_fonts[font_id].fontptr = newfont;
    vultures_fonts[font_id].lineheight = TTF_FontAscent(newfont) + 2;

    return TRUE;
}
Exemplo n.º 2
0
bool TextSupervisor::LoadFont(const std::string &filename, const std::string &font_name, uint32 size)
{
    // Make sure that the font name is not already taken
    if(IsFontValid(font_name) == true) {
        IF_PRINT_WARNING(VIDEO_DEBUG) << "a font with the desired reference name already existed: " << font_name << std::endl;
        return false;
    }

    if(size == 0) {
        IF_PRINT_WARNING(VIDEO_DEBUG) << "attempted to load a font of point size zero" << font_name << std::endl;
        return false;
    }

    // Attempt to load the font
    TTF_Font *font = TTF_OpenFont(filename.c_str(), size);
    if(font == NULL) {
        IF_PRINT_WARNING(VIDEO_DEBUG) << "call to TTF_OpenFont() failed to load the font file: " << filename << std::endl;
        return false;
    }

    // Create a new FontProperties object for this font and set all of the properties according to SDL_ttf
    FontProperties *fp = new FontProperties;
    fp->ttf_font = font;
    fp->height = TTF_FontHeight(font);
    fp->line_skip = TTF_FontLineSkip(font);
    fp->ascent = TTF_FontAscent(font);
    fp->descent = TTF_FontDescent(font);

    // Create the glyph cache for the font and add it to the font map
    fp->glyph_cache = new std::vector<FontGlyph *>;
    _font_map[font_name] = fp;
    return true;
} // bool TextSupervisor::LoadFont(...)
Exemplo n.º 3
0
Font::Font(const char *aaddress, int alength, int apointSize, int astyle,
		float afgRed, float afgGreen, float afgBlue, float abgRed, float abgGreen,
		float abgBlue) :
		height(), ascent(), descent(), lineSkip(), address(
				aaddress), length(alength), pointSize(apointSize), style(astyle), fgRed(
				afgRed), fgGreen(afgGreen), fgBlue(afgBlue), bgRed(abgRed), bgGreen(
				abgGreen), bgBlue(abgBlue), ttfFont(), foreground(), background() {
	int i;

	ttfFont = open_font(address, pointSize);

	TTF_SetFontStyle(ttfFont, style);

	foreground.r = (Uint8) (255 * fgRed);
	foreground.g = (Uint8) (255 * fgGreen);
	foreground.b = (Uint8) (255 * fgBlue);

	background.r = (Uint8) (255 * bgRed);
	background.g = (Uint8) (255 * bgGreen);
	background.b = (Uint8) (255 * bgBlue);

	height = TTF_FontHeight(ttfFont);
	ascent = TTF_FontAscent(ttfFont);
	descent = TTF_FontDescent(ttfFont);
	lineSkip = TTF_FontLineSkip(ttfFont);

	for (i = minGlyph; i <= maxGlyph; i++) {
		glyphs[i].pic = NULL;
		glyphs[i].tex = 0;
	}
}
Exemplo n.º 4
0
  Font_FT::Glyph::Glyph(TTF_Font *font_, const unsigned char &c,
                        SDL_Surface *source,
                        SDL_Surface *render_target, const SDL_Rect &dstrect,
                        const int &total_width, const int &total_height,
                        const float &vratio)
    : m_glyph_width(0)
  {
    int minx, maxy, glyph_width;
    TTF_GlyphMetrics(font_, c, &minx, 0, 0, &maxy, &glyph_width);

    m_glyph_width = glyph_width / vratio;
    m_upper_left_point.x = float(minx) / vratio;
    m_upper_left_point.y = float(TTF_FontAscent(font_) - maxy) / vratio;
    m_lower_right_point.x = m_upper_left_point.x + source->w / vratio;
    m_lower_right_point.y = m_upper_left_point.y + source->h / vratio;

    SDL_Rect dstrect2 = {dstrect.x, dstrect.y, Uint16(source->w), Uint16(source->h)};

    m_upper_left_texel.x = float(dstrect2.x) / float(total_width);
    m_upper_left_texel.y = float(dstrect2.y) / float(total_height);
    m_lower_right_texel.x = float(dstrect2.x + source->w) / float(total_width);
    m_lower_right_texel.y = float(dstrect2.y + source->h) / float(total_height);

    SDL_BlitSurface(source, 0, render_target, &dstrect2);
    SDL_FreeSurface(source);
  }
Exemplo n.º 5
0
static void cache_glyphs()
{
    int top=999, bottom=-999;

    start_color();

    for(int ch=0; ch<128; ch++)
    {
        for(int color=0; color<16; color++)
        {
            SDL_Surface * glyph = glyph_cache[ch][color] = (fontblending?TTF_RenderGlyph_Blended:TTF_RenderGlyph_Solid)(font, ch, windowsPalette[color]);
            int minx, maxx, miny, maxy, advance;
            if(glyph!=NULL && color==0 && 0==TTF_GlyphMetrics(font, ch, &minx, &maxx, &miny, &maxy, &advance) )
            {
               int t = TTF_FontAscent(font)-maxy;
               int b = t + glyph->h;
               if(t<top) top = t;
               if(b>bottom) bottom = b;
            }
        }
    }

    int height = bottom - top;
    int delta = (fontheight-height)/2;

    ttf_height_hack =  delta - top;
}
Exemplo n.º 6
0
void Font::InitFont( void )
{
	Initialized = false;
	
	if( TTFont )
		TTF_CloseFont( TTFont );
	
	TTFont = TTF_OpenFont( Name.c_str(), PointSize );
	if( ! TTFont )
	{
		// FIXME: Use TTF_Error output?
		fprintf( stderr, "Can't open font file: %s\n", Name.c_str() );
		return;
	}
	
	Height = TTF_FontHeight( TTFont );
	Ascent = TTF_FontAscent( TTFont );
	Descent = TTF_FontDescent( TTFont );
	LineSkip = TTF_FontLineSkip( TTFont );
	
	for( int i = 0; i < 256; i ++ )
	{
		Glyphs[ i ].Pic = NULL;
		Glyphs[ i ].Tex = 0;
	}
	
	LoadedTime.Reset();
	
	Initialized = true;
}
Exemplo n.º 7
0
static void cache_glyphs()
{
    int top = 999;
    int bottom = -999;
    start_color();

    for(int ch = 0; ch < 128; ch++) {
        for(int color = 0; color < 16; color++) {
            //I hate this kind of ternary use
            SDL_Surface * sglyph = (fontblending ? TTF_RenderGlyph_Blended : TTF_RenderGlyph_Solid)(font, ch, windowsPalette[color]);

            if(sglyph != NULL) {
                int minx, maxx, miny, maxy, advance;
                if(color==0 && 0 == TTF_GlyphMetrics(font, ch, &minx, &maxx, &miny, &maxy, &advance) ) {
                    int t = TTF_FontAscent(font)-maxy;
                    int b = t + sglyph->h;
                    if(t < top) top = t;
                    if(b > bottom) bottom = b;
                }
                glyph_height[ch] = sglyph->h;
                glyph_cache[ch][color] = SDL_CreateTextureFromSurface(renderer,sglyph);
            }

            SDL_FreeSurface(sglyph);
        }
    }

    int height = bottom - top;
    int delta = (fontheight - height) / 2;

    ttf_height_hack =  delta - top;
}
	void GlyphFont::InitFont()
	{
		mTtfFont = TTF_OpenFont(mFilename, mPointSize);

		if(mTtfFont == NULL)
			printf("Can't open font file\n");

		// 0 = TTF_STYLE_NORMAL
		// 1 = TTF_STYLE_BOLD
		// 2 = TTF_STYLE_ITALIC
		// 4 = TTF_STYLE_UNDERLINE
		// 8 = TTF_STYLE_STRIKETHROUGH
		TTF_SetFontStyle(mTtfFont, mStyle);

		mColor.r = (Uint8)(mRed * 255);
		mColor.g  = (Uint8)(mGreen * 255);
		mColor.b = (Uint8)(mBlue * 255);

		mHeight = TTF_FontHeight(mTtfFont);
		mAscent = TTF_FontAscent(mTtfFont);
		mDescent = TTF_FontDescent(mTtfFont);
		mLineSkip = TTF_FontLineSkip(mTtfFont);

		for(int i = sMinGlyph; i <= sMaxGlyph; i++)
		{
			mGlyphs[i].Surface = NULL;
			mGlyphs[i].Texture = 0;
		}
	}
Exemplo n.º 9
0
Bool renderText(GPU_Target* renderTarget, GC gc, int x, int y, const char* string) {
    LOG("Rendering text: '%s'\n", string);
    if (string == NULL || string[0] == '\0') { return True; }
    GraphicContext* gContext = GET_GC(gc);
    SDL_Color color = {
            GET_RED_FROM_COLOR(gContext->foreground),
            GET_GREEN_FROM_COLOR(gContext->foreground),
            GET_BLUE_FROM_COLOR(gContext->foreground),
            GET_ALPHA_FROM_COLOR(gContext->foreground),
    };
    SDL_Surface* fontSurface = TTF_RenderUTF8_Blended(GET_FONT(gContext->font), string, color);
    if (fontSurface == NULL) {
        return False;
    }
    GPU_Image* fontImage = GPU_CopyImageFromSurface(fontSurface);
    SDL_FreeSurface(fontSurface);
    if (fontImage == NULL) {
        return False;
    }
    y -= TTF_FontAscent(GET_FONT(gContext->font));
    GPU_Blit(fontImage, NULL, renderTarget, x + fontImage->w / 2, y + fontImage->h / 2);
    GPU_FreeImage(fontImage);
    GPU_Flip(renderTarget);
    return True;
}
Exemplo n.º 10
0
SDL_Rect FontInfo::calcUpdatedArea(int start_xy[2])
{
    SDL_Rect rect;
    
    if (tateyoko_mode == YOKO_MODE){
        if (start_xy[1] == xy[1]){
            rect.x = top_xy[0] + pitch_xy[0]*start_xy[0]/2;
            rect.w = pitch_xy[0]*(xy[0]-start_xy[0])/2+1;
        }
        else{
            rect.x = top_xy[0];
            rect.w = pitch_xy[0]*num_xy[0];
        }
        rect.y = top_xy[1] + start_xy[1]*pitch_xy[1]/2;
        rect.h = pitch_xy[1]*(xy[1]-start_xy[1]+2)/2;
        if (ttf_font) rect.h += font_size_xy[1] - TTF_FontAscent((TTF_Font*)ttf_font);
        if (rubyon_flag) rect.h += pitch_xy[1] - font_size_xy[1];
    }
    else{
        rect.x = top_xy[0] + pitch_xy[0]*xy[0]/2;
        rect.w = pitch_xy[0]*(start_xy[0]-xy[0]+2)/2;
        if (rubyon_flag) rect.w += font_size_xy[0]-pitch_xy[0];
        if (start_xy[0] == xy[0]){
            rect.y = top_xy[1] + pitch_xy[1]*start_xy[1]/2;
            rect.h = pitch_xy[1]*(xy[1]-start_xy[1])/2+1;
        }
        else{
            rect.y = top_xy[1];
            rect.h = pitch_xy[1]*num_xy[1];
        }
        num_xy[0] = (xy[0]-start_xy[0])/2+1;
    }

    return rect;
}
Exemplo n.º 11
0
void ONScripterLabel::drawGlyph( SDL_Surface *dst_surface, FontInfo *info, SDL_Color &color, char* text, int xy[2], bool shadow_flag, AnimationInfo *cache_info, SDL_Rect *clip, SDL_Rect &dst_rect )
{
    unsigned short unicode;
    if (IS_TWO_BYTE(text[0])){
        unsigned index = ((unsigned char*)text)[0];
        index = index << 8 | ((unsigned char*)text)[1];
        unicode = onsLocaleConv( index );
    }
    else{
        if ((text[0] & 0xe0) == 0xa0 || (text[0] & 0xe0) == 0xc0) unicode = ((unsigned char*)text)[0] - 0xa0 + 0xff60;
        else unicode = text[0];
    }

    int minx, maxx, miny, maxy, advanced;
#if 0
    if (TTF_GetFontStyle( (TTF_Font*)info->ttf_font ) !=
        (info->is_bold?TTF_STYLE_BOLD:TTF_STYLE_NORMAL) )
        TTF_SetFontStyle( (TTF_Font*)info->ttf_font, (info->is_bold?TTF_STYLE_BOLD:TTF_STYLE_NORMAL));
#endif    
    TTF_GlyphMetrics( (TTF_Font*)info->ttf_font, unicode,
                      &minx, &maxx, &miny, &maxy, &advanced );
    //printf("min %d %d %d %d %d %d\n", minx, maxx, miny, maxy, advanced,TTF_FontAscent((TTF_Font*)info->ttf_font)  );
    
    SDL_Surface *tmp_surface = renderGlyph( (TTF_Font*)info->ttf_font, unicode );

    bool rotate_flag = false;
    if ( info->getTateyokoMode() == FontInfo::TATE_MODE && IS_ROTATION_REQUIRED(text) ) rotate_flag = true;
    
    dst_rect.x = xy[0] + minx;
    dst_rect.y = xy[1] + TTF_FontAscent((TTF_Font*)info->ttf_font) - maxy;
    if ( rotate_flag ) dst_rect.x += miny - minx;
        
    if ( info->getTateyokoMode() == FontInfo::TATE_MODE && IS_TRANSLATION_REQUIRED(text) ){
        dst_rect.x += info->font_size_xy[0]/2;
        dst_rect.y -= info->font_size_xy[0]/2;
    }

    if ( shadow_flag ){
        dst_rect.x += shade_distance[0];
        dst_rect.y += shade_distance[1];
    }

    if ( tmp_surface ){
        if (rotate_flag){
            dst_rect.w = tmp_surface->h;
            dst_rect.h = tmp_surface->w;
        }
        else{
            dst_rect.w = tmp_surface->w;
            dst_rect.h = tmp_surface->h;
        }

        if (cache_info)
            cache_info->blendBySurface( tmp_surface, dst_rect.x, dst_rect.y, color, clip, rotate_flag );
        
        if (dst_surface)
            alphaBlend32( dst_surface, dst_rect, tmp_surface, color, clip, rotate_flag );
    }
}
Exemplo n.º 12
0
void load_font(char *fname, int size)
{
    char *p;

    free_font();
    font=TTF_OpenFont(fname, size);
    if(!font)
    {
        printf("TTF_OpenFont: %s\n", TTF_GetError());
        exit(3);
    }

    /* print some metrics and attributes */
    printf("size                    : %d\n",size);
    printf("TTF_FontHeight          : %d\n",TTF_FontHeight(font));
    printf("TTF_FontAscent          : %d\n",TTF_FontAscent(font));
    printf("TTF_FontDescent         : %d\n",TTF_FontDescent(font));
    printf("TTF_FontLineSkip        : %d\n",TTF_FontLineSkip(font));
    printf("TTF_FontFaceIsFixedWidth: %d\n",TTF_FontFaceIsFixedWidth(font));
    {
        char *str=TTF_FontFaceFamilyName(font);
        if(!str)
            str="(null)";
        printf("TTF_FontFaceFamilyName  : \"%s\"\n",str);
    }
    {
        char *str=TTF_FontFaceStyleName(font);
        if(!str)
            str="(null)";
        printf("TTF_FontFaceStyleName   : \"%s\"\n",str);
    }
    if(TTF_GlyphIsProvided(font,'g'))
    {
        int minx, maxx, miny, maxy, advance;
        TTF_GlyphMetrics(font,'g', &minx, &maxx, &miny, &maxy, &advance);
        printf("TTF_GlyphMetrics('g'):\n\tminx=%d\n\tmaxx=%d\n\tminy=%d\n\tmaxy=%d\n\tadvance=%d\n",
            minx, maxx, miny, maxy, advance);
    }
    else
        printf("TTF_GlyphMetrics('g'): unavailable in font!\n");

    /* set window title and icon name, using filename and stuff */
    p=strrchr(fname,'/');
    if(!p)
        p=strrchr(fname,'\\');
    if(!p)
        p=strrchr(fname,':');
    if(!p)
        p=fname;
    else
        p++;

    /* cache new glyphs */
    cache_glyphs();
}
Exemplo n.º 13
0
float CText::GetAscent(FontType font, float size)
{
    assert(font != FONT_BUTTON);

    CachedFont* cf = GetOrOpenFont(font, size);
    assert(cf != nullptr);
    Math::IntPoint wndSize;
    wndSize.y = TTF_FontAscent(cf->font);
    Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize);
    return ifSize.y;
}
Exemplo n.º 14
0
void
Font::CalculateHeights()
{
  height = TTF_FontHeight(font);
  ascent_height = TTF_FontAscent(font);

  int miny, maxy;
  TTF_GlyphMetrics(font, 'M', NULL, NULL, &miny, &maxy, NULL);

  capital_height = maxy - miny + 1;
}
Exemplo n.º 15
0
JNIEXPORT jint JNICALL Java_sdljava_x_swig_SWIG_1SDLTTFJNI_TTF_1FontAscent(JNIEnv *jenv, jclass jcls, jlong jarg1) {
    jint jresult = 0 ;
    TTF_Font *arg1 = (TTF_Font *) 0 ;
    int result;
    
    (void)jenv;
    (void)jcls;
    arg1 = *(TTF_Font **)&jarg1; 
    result = (int)TTF_FontAscent(arg1);
    
    jresult = (jint)result; 
    return jresult;
}
Exemplo n.º 16
0
// Get real text dimensions -- the textshape will completely contain the 
// rendered text but won't match its size.  This function can be used to
// get the true position and dimensions of the rendered text.
//
// The fifth argument, b, is the baseline of the text
void TextShape::getTextDimensions(int *x, int *y, int *w, int *h, int *b,
        int *yOff)
{
    if (textShapeFont[fontSize] == NULL)
    {
        textShapeFont[fontSize] = FONT_LoadTTF("FreeSans.ttf", fontSize);
    }
    assert(textShapeFont[fontSize] != NULL);

    int realH = 0;
    Uint16 *ch = unicodeStr;
    int overallMaxY = 0;
    while (*ch != '\0')
    {
        int minx, maxx, miny, maxy, advance;

        int err = TTF_GlyphMetrics(textShapeFont[fontSize], *ch, &minx,
                &maxx, &miny, &maxy, &advance);
        if (!err)
        {
            realH = std::max(realH, maxy - miny + 1);
            overallMaxY = std::max(overallMaxY, maxy);
        }
        else
        {
            printf("warning: TTF_GlyphMetrics returned an error\n");
        }
        ch++;
    }
    int ascent = TTF_FontAscent(textShapeFont[fontSize]);
    int realYOffset = ascent - overallMaxY;

    // Can't get width from the individual glyphs due to kerning issues, 
    // just call TTF_SizeUNICODE
    int textw, dummy;
    // Get text size:
    TTF_SizeUNICODE(textShapeFont[fontSize], unicodeStr, &textw, &dummy);

    if (x)  *x = xpos + cxoff;
    if (y)  *y = ypos + cyoff;
    if (w)  *w = textw;
    if (h)  *h = realH;
    if (b)  *b = ypos + overallMaxY + cxoff;

    if (yOff) *yOff = realYOffset;
}
Exemplo n.º 17
0
KFontProperties::KFontProperties(const TTF_Font *_Font, const KFile *file, int ptSize) :
fontPath(file->getAbsolutePath().c_str()),
familyName(TTF_FontFaceFamilyName(_Font)),
styleName(TTF_FontFaceStyleName(_Font)),
ttf_Style(TTF_GetFontStyle(_Font)),
height(TTF_FontHeight(_Font)),
ascent(TTF_FontAscent(_Font)),
descent(TTF_FontDescent(_Font)),
lineSkip(TTF_FontLineSkip(_Font)),
faces(TTF_FontFaces(_Font)),
monospace(TTF_FontFaceIsFixedWidth(_Font)),
firstGlyph(getFirstGlyph(_Font)),
lastGlyph(getLastGlyph(_Font)),
totalGlyphs(getTotalGlyphs(_Font)),
glyphRanges(getRanges(_Font)),
pointSize(ptSize) {

}
Exemplo n.º 18
0
static void OutputChar(Uint16 t, int x, int y, unsigned char color)
{
    color &= 0xf;

    SDL_Surface * glyph = t<0x80?glyph_cache[t][color]:(fontblending?TTF_RenderGlyph_Blended:TTF_RenderGlyph_Solid)(font, t, windowsPalette[color]);

    if(glyph)
    {
		int minx=0, maxy=0, dx=0, dy = 0;
		if( 0==TTF_GlyphMetrics(font, t, &minx, NULL, NULL, &maxy, NULL))
		{
			dx = minx;
			dy = TTF_FontAscent(font)-maxy+ttf_height_hack;
			SDL_Rect rect;
			rect.x = x+dx; rect.y = y+dy; rect.w = fontwidth; rect.h = fontheight;
			SDL_BlitSurface(glyph, NULL, screen, &rect);
		}
		if(t>=0x80) SDL_FreeSurface(glyph);
    }
}
Exemplo n.º 19
0
bool FontTTF::load(std::string fileName, int size)
{
	cleanUp();
	_font = TTF_OpenFont( fileName.c_str(), size );
	if (NULL == _font)
		std::cerr << "Failed to load font " << fileName << ". Cannot start." << std::endl;
	else
//		_height = size;	//calc_text_metrics("X")._y;
//		_height = calc_text_metrics("A")._max._y;
//		_height = TTF_FontHeight(_font);
		_height = TTF_FontAscent(_font);
	/*
		int minx,maxx,miny,maxy,advance;
		if(TTF_GlyphMetrics(_font,'A',&minx,&maxx,&miny,&maxy,&advance)==-1)
			return 0;
		_height =  maxy;// - miny;
	*/
	_init = (_font != NULL);
	return _init;
}
Exemplo n.º 20
0
static void OutputChar(char t, int x, int y, int n, unsigned char color)
{
    unsigned char ch = t & 0x7f;
    color &= 0xf;

    SDL_Surface * glyph = glyph_cache[ch][color];

    if(glyph)
    {
		int minx=0, maxy=0, dx=0, dy = 0;
		if( 0==TTF_GlyphMetrics(font, ch, &minx, NULL, NULL, &maxy, NULL))
		{
			dx = minx;
			dy = TTF_FontAscent(font)-maxy+ttf_height_hack;
			SDL_Rect rect;
			rect.x = x+dx; rect.y = y+dy; rect.w = fontwidth; rect.h = fontheight;
			SDL_BlitSurface(glyph, NULL, screen, &rect);
		}
    }
}
Exemplo n.º 21
0
static void OutputFontChar(Uint16 t, int x, int y, unsigned char color)
{
    color &= 0xf;

    bool created = false;
    SDL_Texture * glyph;
    int height = 0;
    if(t < 0x80) {
        glyph = glyph_cache[t][color];
        height = glyph_height[t];
    } else {
        //create the texture instead
        SDL_Surface *sglyph = (fontblending ? TTF_RenderGlyph_Blended
            : TTF_RenderGlyph_Solid) (font, t, windowsPalette[color]);
        glyph = SDL_CreateTextureFromSurface(renderer,sglyph);
        height = sglyph->h;
        SDL_FreeSurface(sglyph);
        created = true;
    }

    if(glyph) {
        int minx = 0, miny = 0, maxy = 0, dx = 0, dy = 0;
        if( 0 == TTF_GlyphMetrics(font, t, &minx, NULL, &miny, &maxy, NULL))
        {
            dx = minx;
            dy = TTF_FontAscent(font) - maxy + ttf_height_hack;
            SDL_Rect rect;
            rect.x = x + dx;
            rect.y = y + dy;
            //these are not fontwidth/fontheight...
            rect.w = fontwidth;
            rect.h = height;
            SDL_RenderCopy(renderer,glyph,NULL,&rect);
        }
        if(created) {
            SDL_DestroyTexture(glyph);
        }
    }
}
Exemplo n.º 22
0
        font_impl::font_impl(const string & face, int size, const color & fg)
            : face(face), size(size), ttf_font_ptr(0), fg(fg)
        {
            gsgl::log(string::format(L"font_impl: creating %ls %d (%f, %f, %f)", face.w_string(), size, fg[color::COMPONENT_RED], fg[color::COMPONENT_GREEN], fg[color::COMPONENT_BLUE]));

            if (FONT_DIR.is_empty())
                get_font_dir();

            // common font names
            string fname = FONT_DIR;

#ifdef WIN32
            if (face == L"Mono")
            {
                fname += L"cour.ttf";
            }
            else if (face == L"Sans")
            {
                fname += L"arial.ttf";
            }
            else
            {
                throw runtime_exception(L"Unable to determine font file name for '%ls'", face.w_string());
            }
#else
#error Font name lookup unimplemented!
#endif

            //
            ttf_font_ptr = TTF_OpenFont(fname.c_string(), size);

            if (!ttf_font_ptr)
                throw runtime_exception(L"Unable to load font '%ls': %hs", face.w_string(), TTF_GetError());

            //
            font_height = TTF_FontHeight(static_cast<TTF_Font *>(ttf_font_ptr));
            font_ascent = TTF_FontAscent(static_cast<TTF_Font *>(ttf_font_ptr));
            texture_height = nearest_power_2(font_height);
        } // font_impl::font_impl()
Exemplo n.º 23
0
//
// Load a new font and create textures for each glyph
//
font *ttf_new (const char *name, int pointSize, int style)
{
    uint8 c;
    font *f;
    
    f = (fontp)zalloc(sizeof(*f));
    if (!f) {
        return (NULL);
    }

    f->name = strdup(name);
    f->ttf = TTF_OpenFont(name, pointSize);
    if (!f->ttf) {
        DIE("cannot open font file %s", name);
    }

    f->foreground.r = 255;
    f->foreground.g = 255;
    f->foreground.b = 255;
    f->background.r = 0;
    f->background.g = 0;
    f->background.b = 0;

    TTF_SetFontStyle(f->ttf, style);
    TTF_SetFontOutline(f->ttf, 0.5);
    f->height = TTF_FontHeight(f->ttf);
    f->ascent = TTF_FontAscent(f->ttf);
    f->descent = TTF_FontDescent(f->ttf);
    f->lineSkip = TTF_FontLineSkip(f->ttf);

    for (c = TTF_GLYPH_MIN; c < TTF_GLYPH_MAX; c++) {
        ttf_create_tex_from_char(f, c);
    }

    return (f);
}
Exemplo n.º 24
0
void FontTTF::loadMetrics(TTF_Font *font) {
    _cellHeight = TTF_FontHeight(font);
    _cellWidth = 0;
    
    int x1, x2, y1, y2, advance;
    for( int i = 0; i < 256; ++i ) {
        TTF_GlyphMetrics(font, static_cast<Uint16>(i), &x1, &x2, &y1, &y2, &advance);

        // Only handle visible characters (>32) and the 'space' character (32).
        _fontWidth[i] = i >= 32 ? advance : 0;

        if(_fontWidth[i] > _cellWidth) {
            _cellWidth = advance;
        }
    }

    // Set a tab to be the width of 4 spaces.
    _fontWidth[9] = _fontWidth[32] * 4;
    
    _fontAscent = TTF_FontAscent(font);
    _fontDescent = TTF_FontDescent(font);
    _fontHeight = _fontAscent - _fontDescent;
    _lineSkip = TTF_FontLineSkip(font);
}
Exemplo n.º 25
0
Font::Font(const std::string& path, int size)
{
    TTF_Font* font = TTF_OpenFont(path.c_str(), size);
    if (!font)
    {
        fatalError("Failed to open font '" + path + "'.");
    }
    SDL_Color color {255, 255, 255, 255};
    SDL_Surface* surfaces [NUM_GLYPHS];
    for (int i = 0; i < NUM_GLYPHS; i++)
    {
        char c = FIRST_CHAR + i;
        TTF_GlyphMetrics(
                font, c, 
                &glyph_metrics_map_[i].min_x,
                &glyph_metrics_map_[i].max_x,
                &glyph_metrics_map_[i].min_y,
                &glyph_metrics_map_[i].max_y,
                &glyph_metrics_map_[i].advance);
        surfaces[i] = TTF_RenderGlyph_Blended(font, c, color);
    }
    int font_height = TTF_FontHeight(font);
    int font_offset = font_height - TTF_FontAscent(font);
    int num_glyphs_per_row = 16;
    int num_rows = (NUM_GLYPHS - 1) / num_glyphs_per_row + 1;
    int max_row_width = 0;
    for (int i = 0; i < num_rows; i++)
    {
        int row_width = 0;
        for (int j = 0; j < num_glyphs_per_row; j++)
        {
            int index = i * num_glyphs_per_row + j;
            if (index >= NUM_GLYPHS)
                break;
            row_width += surfaces[index]->w;
        }
        if (row_width > max_row_width)
            max_row_width = row_width;
    }
    int atlas_height = num_rows * font_height;
    int atlas_width =  max_row_width;
    int cursor_x = 0;
    int cursor_y = 0;
    int bytes_per_pixel = 4;
    std::vector<uint8_t> atlas_pixels (bytes_per_pixel * atlas_height * atlas_width);
    for (int i = 0; i < num_rows; i++)
    {
        for (int j = 0; j < num_glyphs_per_row; j++)
        {
            int index = i * num_glyphs_per_row + j;
            if (index >= NUM_GLYPHS)
                break;
            SDL_Surface* surface = surfaces[index];
            for (int k = 0; k < font_height; k++)
            {
                for (int l = 0; l < surface->w; l++)
                {
                    int atlas_index = bytes_per_pixel * ((cursor_y + k) * atlas_width + cursor_x + l);
                    int surface_index = bytes_per_pixel * ((surface->h - k - 1) * surface->w + l);
                    for (int m = 0; m < bytes_per_pixel; m++)
                    {
                        atlas_pixels[atlas_index + m] = reinterpret_cast<uint8_t*>(surface->pixels)[surface_index + m];
                    }
                }
            }
            GlyphMetrics& metrics = glyph_metrics_map_[index];
            GlyphBound& bound = glyph_bound_map_[index];
            bound.min_s = double(cursor_x + metrics.min_x) / atlas_width;
            bound.max_s = double(cursor_x + metrics.max_x) / atlas_width;
            bound.min_t = double(cursor_y + font_offset + metrics.min_y) / atlas_height;
            bound.max_t = double(cursor_y + font_offset + metrics.max_y) / atlas_height;
            cursor_x += surface->w;
        }
        cursor_x = 0;
        cursor_y += font_height;
    }
    for (int i = 0; i < NUM_GLYPHS; i++)
    {
        SDL_FreeSurface(surfaces[i]);
    }
    TTF_CloseFont(font);
    glGenTextures(1, &atlas_);
    glBindTexture(GL_TEXTURE_2D, atlas_);
    glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_RGBA,
            atlas_width,
            atlas_height,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            atlas_pixels.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
Exemplo n.º 26
0
void GM_Debug::renderScene()
{
	if(background)
		background->Blit(0,0,0,0,background->getBasicWidth(),background->getBasicHeight(),glictGlobals.w, glictGlobals.h);
	if(spr)
		spr->Blit(50,50);
 	if(thing)
		thing->Blit(100,50);

	if(background)
		background->Blit(150,50,125,51,85,136,32,48);

/*
    int xs = px - mapw/2;
    int ys = py - maph/2;
    int xe = px + mapw/2;
    int ye = py + maph/2;

    if (map[0]) map[0]->Blit(0,0, xs%256, ys%256, 256-(xs%256), 256-(ys%256));
    if (map[1]) map[1]->Blit(256-(xs%256),0, 0, ys%256, mapw-(256-(xs%256)), 256-(ys%256));
    if (map[2]) map[2]->Blit(0,256-(ys%256), xs%256, 0, 256-(xs%256), maph-(256-(ys%256)));
    if (map[3]) map[3]->Blit(256-(xs%256),256-(ys%256), 0, 0, mapw-(256-(xs%256)), maph-(256-(ys%256)));
*/
	GM_Debug *gd = (GM_Debug*)g_game;
    a.renderSelf(700,0,256,256,Position(gd->px, gd->py, gd->pz));

/*
    std::stringstream testchar;
    testchar << (char)('u'+32);

    for(int i = 0; i < 255; i++) {
        g_engine->drawText(testchar.str().c_str(), "system", 0+(i%8)*12,300+(i/8)*12, i);
    }
*/


	//desktop.RememberTransformations();
	desktop.Paint();

#ifdef SDLTTF_EXPERIMENT
    if (font) 
	{

        SDL_Surface* glyph = NULL;
        SDL_Color forecol, backcol;

        forecol.r = 255;
        forecol.g = 255;
        forecol.b = 255;

        backcol.r = 0;
        backcol.g = 0;
        backcol.b = 0;


        SDL_SetClipRect(g_engine->m_screen, NULL);

        int YOffset = TTF_FontAscent(font);  // Actually a baseline


        for (int i = 32; i < 256; i++)
        {

            int minx, maxx, miny, maxy, advance;


            glyph = TTF_RenderGlyph_Solid( font, i, forecol);//backcol ); // solid or shaded; shaded uses backcol, solid doesnt


            TTF_GlyphMetrics(font, i, &minx, &maxx, &miny, &maxy, &advance);


            SDL_Rect src = {0, 0, glyph->w, glyph->h};
            SDL_Rect dest = {((i - 32) % 32)*8 + minx,
                             ((i - 32) / 32)*16 + YOffset-maxy,
                             glyph->w,
                             glyph->h};





            SDL_BlitSurface(glyph, &src, g_engine->m_screen, &dest);


            SDL_FreeSurface(glyph);
        }
    }
#endif

}
Exemplo n.º 27
0
XFontStruct* XLoadQueryFont(Display* display, _Xconst char* name) {
    // https://tronche.com/gui/x/xlib/graphics/font-metrics/XLoadQueryFont.html
    Font fontId = XLoadFont(display, name);
    if (fontId == None) {
        return NULL;
    }
    TTF_Font* font = GET_FONT(fontId);
    SET_X_SERVER_REQUEST(display, X_QueryFont);
    XFontStruct* fontStruct = malloc(sizeof(XFontStruct));
    if (fontStruct == NULL) {
        handleOutOfMemory(0, display, 0, 0);
        TTF_CloseFont(font);
        return NULL;
    }
    fontStruct->fid = fontId;
    fontStruct->ascent = TTF_FontAscent(font);
    fontStruct->descent = abs(TTF_FontDescent(font));
    fontStruct->per_char = NULL;
    unsigned int numChars = 0;
    unsigned int i;
    for (i = 0; i < 65536 /* 2^16 */; i++) {
        if (TTF_GlyphIsProvided(font, (Uint16) i)) {
            if (numChars == 0) {
                fontStruct->min_char_or_byte2 = i;
            }
            fontStruct->max_char_or_byte2 = i;
            numChars++;
        }
    }
//    if (numChars >= 256) {
//        fontStruct->min_byte1 = fontStruct->min_char_or_byte2 / 256;
//        fontStruct->max_byte1 = fontStruct->max_char_or_byte2 / 256;
//        fontStruct->min_char_or_byte2 = 0;
//    } else {
        fontStruct->min_byte1 = 0;
        fontStruct->max_byte1 = 0;
//    }
    // TODO: This is debugging
    fontStruct->max_char_or_byte2 = 255;
    // Build per_char
    int monospace = TTF_FontFaceIsFixedWidth(font);
    XCharStruct charStruct;
    if (!monospace) {
        fontStruct->per_char = malloc(sizeof(XCharStruct) * numChars);
        if (fontStruct->per_char == NULL) {
            handleOutOfMemory(0, display, 0, 0);
            XFreeFont(display, fontStruct);
            return NULL;
        }
        charStruct = fontStruct->per_char[0];
    }
    if (fillXCharStruct(font, fontStruct->min_char_or_byte2, &charStruct) == False) {
        XFreeFont(display, fontStruct);
        return NULL;
    }
    fontStruct->max_bounds = charStruct;
    fontStruct->min_bounds = charStruct;
    if (monospace) {
        fontStruct->per_char = NULL;
    } else {
        int counter = 1;
        for (i = fontStruct->min_char_or_byte2 + 1; i < 65536 /* 2^16 */; ++i) {
            if (TTF_GlyphIsProvided(font, (Uint16) i)) {
                charStruct = fontStruct->per_char[counter];
                if (fillXCharStruct(font, i, &charStruct) == False) {
                    XFreeFont(display, fontStruct);
                    return NULL;
                }
                // I think rbearing (aka. advance) is the value that matters here
                if (fontStruct->max_bounds.rbearing < charStruct.rbearing) {
                    fontStruct->max_bounds = charStruct;
                } else if (fontStruct->min_bounds.rbearing > charStruct.rbearing) {
                    fontStruct->max_bounds = charStruct;
                }
                counter++;
            }
        }
    }
    return fontStruct;
}
Exemplo n.º 28
0
Arquivo: main.cpp Projeto: newobj/taz
int main(int argc, char* argv[])
{
	if ( argc < 4 )
	{
		fprintf(stderr, "usage: tool_font filename.ttf chars.txt ptsize <style> <supersample>\n");
		return -1;
	}

	char szFont[256];
	strcpy(szFont, argv[1]);
	*strstr(szFont, ".ttf") = 0;
	int nFontSize = atol(argv[3]);

	int nStyle = TTF_STYLE_NORMAL;

	if ( argc > 3 )
	{
		for ( int i = 0 ; argv[4][i] != 0 ; i++ )
		{
			switch ( argv[4][i] )
			{
				case 'b':
					nStyle |= TTF_STYLE_BOLD;
					break;
				case 'i':
					nStyle |= TTF_STYLE_ITALIC;
					break;
				case 'u':
					nStyle |= TTF_STYLE_UNDERLINE;
					break;
			}
		}
	}

	float fScale = 1.0f;
	if ( argc > 5 )
	{
		fScale = 1.0f/atof(argv[6]);
	}

	SDL_Init(SDL_INIT_VIDEO);
	TTF_Init();
	TTF_Font* pFont = TTF_OpenFont(argv[1], nFontSize/fScale);
	if ( !pFont )
	{
		fprintf(stderr, "could not open %s @ %d points\n", argv[1], nFontSize);
		return -1;
	}

	int nAscent = TTF_FontAscent(pFont);
	int nDescent = TTF_FontDescent(pFont);
	int nHeight = TTF_FontHeight(pFont);

	char szStyle[4] = { 0 };
	char* pchStyle = szStyle;
	if ( nStyle & TTF_STYLE_BOLD ) *pchStyle++ = 'b';
	if ( nStyle & TTF_STYLE_ITALIC ) *pchStyle++ = 'i';
	if ( nStyle & TTF_STYLE_UNDERLINE ) *pchStyle++ = 'u';

	TTF_SetFontStyle(pFont, nStyle);

	char achGlyphs[1024];
	int cGlyphs = 0;
	FILE* fpChars = fopen(argv[2], "r");
	while ( EOF != (achGlyphs[cGlyphs++] = fgetc(fpChars)) );
	fclose(fpChars);
	cGlyphs--;
		
	SDL_Rect* aRects = new SDL_Rect[cGlyphs];
	SDL_Surface** apSurfaces = new SDL_Surface*[cGlyphs];

	for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph )
	{
		SDL_Color color = { 255, 255, 255, 0 };
		char szGlyph[2] = { 0 };
		szGlyph[0] = achGlyphs[iGlyph];
		apSurfaces[iGlyph] = TTF_RenderText_Blended(pFont, szGlyph, color);
//		char szFile[128];
//		sprintf(szFile, "textures/fonts/%s/%d.raw", argv[1], szGlyph[0]);
//		FILE* fp = fopen(szFile, "wb");
//		fwrite(apSurfaces[iGlyph]->pixels, apSurfaces[iGlyph]->pitch*apSurfaces[iGlyph]->h, 1, fp);
//		fclose(fp);
	}

	struct DIMS
	{
		int w, h;
	};

	DIMS aDims[] = 
	{	
		64, 64,
		64, 128,
		64, 256,
		128, 64,
		128, 128,
		128, 256,
		256, 64,
		256, 128,
		256, 256,
		64, 512,
		128, 512,
		256, 512,
		512, 64,
		512, 128,
		512, 256,
		512, 512,
		64, 1024,
		128, 1024,
		256, 1024,
		256, 1024,
		512, 1024,
		1024, 64,
		1024, 128,
		1024, 256,
		1024, 512,
		1024, 1024,
		64, 2048,
		128, 2048,
		256, 2048,
		512, 2048,
		1024, 2048,
		2048, 64,
		2048, 128,
		2048, 256,
		2048, 512,
		2048, 1024,
		2048, 2048,
/*		512, 64,
		512, 128,
		512, 256,
		512, 512,
		64, 512,
		128, 512,
		256, 512,
		1024, 64,
		1024, 128,
		1024, 256,
		1024, 512,
		64,	1024,
		128, 1024,
		256, 1024,
		512, 1024, 
		2048, 64,
		2048, 128,
		2048, 256,
		2048, 1024,
		2048, 2048,
		64,	2048,
		128, 2048,
		256, 2048,
		512, 2048,
		1024, 2048
*/	};

	int cDims = sizeof(aDims)/sizeof(DIMS);

	for ( int iDims = 0 ; iDims < cDims ; ++iDims )
	{
		int nWidth = aDims[iDims].w;
		int nHeight = aDims[iDims].h;

		SDL_Surface* pSurfaceGeneric = SDL_CreateRGBSurface(SDL_SWSURFACE, nWidth, nHeight, 32, 0, 0, 0, 0);
		SDL_Surface* pSurface = SDL_ConvertSurface(pSurfaceGeneric, apSurfaces[0]->format, 0);
		SDL_FillRect(pSurface, NULL, SDL_MapRGBA(pSurface->format, 0,0,0,0));
		bool* aabyUsage = new bool[nHeight*nWidth];
		memset(aabyUsage, 0, nHeight*nWidth*sizeof(bool));
		bool bFit = true;

		for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph )
		{
			if ( !Fit(aabyUsage, pSurface, apSurfaces[iGlyph], &aRects[iGlyph], fScale) )
			{
				bFit = false;
				break;
			}
		}

		if ( bFit )
		{
			fprintf(stderr, "glyphs fit into %d x %d texture\n", nWidth, nHeight);
			char szFile[256];
			sprintf(szFile, "textures/fonts/%s%d%s.png", szFont, nFontSize, szStyle);

			for ( int y = 0 ; y < pSurface->h ; ++y )
			{
				for ( int x = 0 ; x < pSurface->w ; ++x )
				{
					unsigned char r = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0];
					unsigned char g = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1];
					unsigned char b = ((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2];

					unsigned char a = (r+g+b)/3;
					r = g = b = 255;

					((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 0] = r;
					((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 1] = g;
					((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 2] = b;
					((unsigned char*)pSurface->pixels)[x*4 + y*pSurface->w*4 + 3] = a;
				}
			}

			ILuint iImage = 0;
			ilInit();
			ilGenImages(1, &iImage);
			ilBindImage(iImage);
			ilTexImage(pSurface->w, pSurface->h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, pSurface->pixels);
//			ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
			iluFlipImage();
			iluImageParameter(ILU_FILTER, ILU_SCALE_LANCZOS3);
			iluScale(pSurface->w*fScale, pSurface->h*fScale, 1);
			ilSaveImage(szFile);

			int nDescent = TTF_FontDescent(pFont);

			char szFontFile[256];
			sprintf(szFontFile, "fonts/%s%d%s.font", szFont, nFontSize, szStyle);
			FILE* fp = fopen(szFontFile, "w");
			fprintf(fp, "<font name=\"%s\" height=\"%d\" lineskip=\"%d\" shader=\"%s,srcalpha,invsrcalpha\">\n", szFont, int(TTF_FontHeight(pFont)*fScale), int(TTF_FontLineSkip(pFont)*fScale), szFile);
			for ( int iGlyph = 0 ; iGlyph < cGlyphs ; ++iGlyph )
			{
				int xmin, xmax, ymin, ymax, adv;
				TTF_GlyphMetrics(pFont, achGlyphs[iGlyph], &xmin, &xmax, &ymin, &ymax, &adv);
				fprintf(fp, "%c<glyph ascii=\"%d\" adv=\"%d\" dims=\"%d,%d\" origin=\"%d,%d\" u0=\"%f\" v0=\"%f\" u1=\"%f\" v1=\"%f\"/>\n",
					9,
					achGlyphs[iGlyph],
					int(adv*fScale),
					int(aRects[iGlyph].w*fScale), int(aRects[iGlyph].h*fScale),
					int(xmin*fScale),
					int(-nDescent*fScale),
					float(aRects[iGlyph].x)/float(pSurface->w),
					float(aRects[iGlyph].y)/float(pSurface->h),
					float(aRects[iGlyph].x+aRects[iGlyph].w)/float(pSurface->w),
					float(aRects[iGlyph].y+aRects[iGlyph].h)/float(pSurface->h));
			}
			fprintf(fp, "</font>\n");
			fclose(fp);
//				FILE* fp = fopen("textures/fonts/blockup.raw", "wb");
//				fwrite(pSurface->pixels, pSurface->pitch*pSurface->h, 1, fp);
//				fclose(fp);
			return 0;
		}
			
		delete [] aabyUsage;
		SDL_FreeSurface(pSurface);
		SDL_FreeSurface(pSurfaceGeneric);
	}

	return 0;
}
Exemplo n.º 29
0
static void track_baseline(const struct rect *rect, const TTF_Font *a,
                           struct rect *aligned, const TTF_Font *b)
{
    split(*rect, pixels(from_top(TTF_FontAscent(a)  - TTF_FontAscent(b), 0)),
          NULL, aligned);
}
Exemplo n.º 30
0
/*
 * create_font
 */
int create_font(char *filename,
                FONT **font,
                int size,
                int style,
                SDL_Color color)
{
  TTF_Font* ttffont;
  SDL_Surface* character_surface;
  int ret_code = BUILD_FONT_OK;
  int rc;
  Uint16 ii;

  /*
   * Allocate the memory required for the font object.
   */
  (*font) = (FONT *) DT_MALLOC(sizeof(FONT));

  /*
   * Set the font attributes.
   */
  memcpy(&((*font)->color), &color, sizeof(SDL_Color));
  (*font)->pointsize = size;
  (*font)->style = style;

  /*
   * The font loading may fail if the file does not exist or permissions are
   * incorrect etc.
   */
  ttffont = TTF_OpenFont(filename, (*font)->pointsize);
  if (ttffont == NULL)
  {
    DT_DEBUG_LOG("Error opening font (%s): %s\n", filename, TTF_GetError());
    ret_code = BUILD_FONT_LOAD_FAIL;
    goto EXIT_LABEL;
  }

  /*
   * Set the style of the font to whatever we passed in.
   */
  TTF_SetFontStyle(ttffont, (*font)->style);

  /*
   * Retrieve the font information to store in our font structure.
   */
  (*font)->ascent = TTF_FontAscent(ttffont);
  (*font)->descent = TTF_FontDescent(ttffont);
  (*font)->height = TTF_FontHeight(ttffont);
  (*font)->lineskip = TTF_FontLineSkip(ttffont);

  /*
   * For each possible glyph, attempt to load the font character and create a
   * texture for it. If any of these fail we attempt to close down gracefully
   * and exit the function.
   */
  for (ii = ' '; ii <= '~'; ii++)
  {
    character_surface = TTF_RenderGlyph_Blended(ttffont, ii, (*font)->color);
    if (NULL == character_surface)
    {
      DT_DEBUG_LOG("Error rendering glyph %c whilst creating font (%s): %s\n",
                   (char) ii,
                   filename,
                   TTF_GetError());
      ret_code = BUILD_FONT_RENDER_FAIL;
      goto EXIT_LABEL;
    }

    /*
     * Retrieve the metric info from the font object and store it in our local
     * structure.
     */
    TTF_GlyphMetrics(ttffont,
                     ii,
                     &((*font)->glyphs[ii].minx),
                     &((*font)->glyphs[ii].maxx),
                     &((*font)->glyphs[ii].miny),
                     &((*font)->glyphs[ii].maxy),
                     &((*font)->glyphs[ii].advance));

    /*
     * This function can fail if opengl cannot allocate any more memory for
     * textures.
     */
    rc = SDL_GL_LoadTexture(character_surface, &((*font)->glyphs[ii].texid), false);
    if (LOAD_TEXTURE_OK != rc)
    {
      DT_DEBUG_LOG("Failed creating texture for glyph %c from font %s\n",
                   (char) ii,
                   TTF_GetError());
      SDL_FreeSurface(character_surface);
      ret_code = BUILD_FONT_CREATE_TEXTURE_FAIL;
      goto EXIT_LABEL;
    }

    /*
     * Set the texture coordinates for the glyph (note this is the same for all
     * glyphs).
     */
    (*font)->glyphs[ii].texcoord[0] = 0.0f;
    (*font)->glyphs[ii].texcoord[1] = 0.0f;
    (*font)->glyphs[ii].texcoord[2] = 1.0f;
    (*font)->glyphs[ii].texcoord[3] = 1.0f;

    /*
     * The surface used for that character is no longer required.
     */
    SDL_FreeSurface(character_surface);
  }

EXIT_LABEL:

  if (NULL != ttffont)
  {
    TTF_CloseFont(ttffont);
  }

  return ret_code;
}