BCCでSDL TTF(トゥルータイプフォント)を使う


今回はSDLでTTFファイル読み込み、文字列を描画します。



先ず、SDLの拡張ライブラリSDL_ttfをダウンロードしましょう!!



http://www.libsdl.org/projects/SDL_ttf/:SDL_ttf



ライブラリのインストール方法はこちらのサイトを参考にしてください!



http://odenx.seesaa.net/article/98889384.html



ボーランドのフリーコンパイラーでSDLを導入される場合、上手くコンパイル出来ない場合があります。

対処法は自分の書いたブログに載っています。





SDL_ttfのいいところは、文字サイズを拡大、縮小しても文字が崩れない所。

逆に悪い所は、日本語に対応しておらず、描画する文字列がすべて英語に限定されます。

日本語を表示するにはSDL_kanji等を使えばよいと思います。

これについては後日使ってみたいと思います。



ソースコードです。適当にコンパイルしてください。


TrueTypeFont.cpp

#include "TrueTypeFont.h"

static SDL_Surface *Text;
static TTF_Font *fontType;

bool InitTTF(void){//TTFの初期化
    if( TTF_Init() == -1){
        printf("ttf_InitErr %s",SDL_GetError() );
        return false;
    }
    return true;
}

bool SetTTF(const char *path,int size){
    //SettingTTF_Font
    FreeTTF();
    
    //TTFを開く
    fontType=TTF_OpenFont(path,size);
    
    if(fontType == NULL){
        if(fopen(path,"r")==NULL){
            printf("TTF File is not Found %s",SDL_GetError());
            return false;
        }else{
            printf("TTF_File OpenError%s",SDL_GetError());
            return false;
        }
    }
    return true;
}

void 
TextPut(SDL_Surface *screen,const char *string,const char *color,Uint16 x,Uint16 y)
{
    SDL_Surface *textSurface;
    SDL_Color fontColor;//カラー構造体
    SDL_Rect dst = { x, y, 0, 0};
    
    if(fontType == NULL){
        //No InstanceTTF
        return;
    }
    //色をセット
    SetColor( &fontColor, color);
    
    //TTFから文字列を作成
    textSurface = TTF_RenderUTF8_Solid(fontType,string, fontColor);
    
    //TTFフォントの文字列を、ビデオスクリーンに高速転送
    SDL_BlitSurface( textSurface, NULL, screen, &dst );
    

    }
}

void SetColor(SDL_Color *color,const char *type){
    if(strcmp(type,"red")==0){
        color->r = 255;
        color->g = 0;
        color->b = 0;
    }else if(strcmp(type,"green")==0){
        color->r = 0;
        color->g = 255;
        color->b = 0;
    }else if(strcmp(type,"blue")==0){
        color->r = 0;
        color->g = 0;
        color->b = 255;
    }else if(strcmp(type,"white")==0){
        color->r = 255;
        color->g = 255;
        color->b = 255;
    }else if(strcmp(type,"black")==0){
        color->r = 0;
        color->g = 0;
        color->b = 0;
    }else{//default Color(Black)
        color->r = 0;
        color->g = 0;
        color->b = 0;
    }
}

void FreeTTF(void){
    if(fontType != NULL){
        TTF_CloseFont(fontType);
        fontType = NULL;
    }
}

TrueTypeFont.h

#ifndef _INCLUDE_TTF
#define _INCLUDE_TTF

#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>
#include <string.h>

bool InitTTF(void);
bool SetTTF(const char *path,int size);

void TextPut(SDL_Surface *screen,
    const char *string,
    const char *color,
Uint16 x,Uint16 y);
    
void SetColor(SDL_Color *color,const char *type);
void FreeTTF(void);

#endif


先ず、InitTTF()でライブラリを初期化してから、

SetTTF()にフォントデータのパスと、文字サイズを渡してやります。

この二つの関数を呼び出すのは一度で十分です。

SetTTF()に関しては、フォントデータを変えたいときや、

フォントのサイズを変えたいときに呼び出してください。



うまく文字列が描画されたでしょうか?







実はこのプログラムは重大な問題があります。

コンパイルして実行した後、タスクマネージャを立ち上げて

実行中のプログラムを観察してみてください。



メモリの使用量がドンドン増えてませんか?



これは関数のどこかでメモリが解放されず、

新しいメモリ領域を確保しているからでしょう。



TextPut()関数を見てください。

ここで、テキストイメージをメモリに転送するために

SDL_Surface *textSurface を宣言しています。



問題はこのサーフェースにテキストイメージのサーフェースを作って、

転送しているからです。



早い話、ここで新しく作ったサーフェースを解放しなければいけません。

そのためにTextPut()関数の最後に

if( textSurface != NULL){
    SDL_FreeSurface( textSurface );//CleanUp
}

として、サーフェースを解放してやりましょう。

結構見落としがちな部分でもあるので、皆さんも気をつけましょう!