SDL_TTFで日本語を表示する

今回はSDL_ttfで日本語を表示するため、SDL_ttfをJIS,SJIS

対応したライブラリに改造してみた。



SDL_ttfではUTF-8,Unicodeしか対応していなかったが、自分がそれらの不足した機能を補う形で改造してみた。

追加で作成した関数は、JISコード、SJISコードをレンダリングする処理など。



以下の関数を使う事で、日本語表示も可能です。

シフトJISの文字コードなら、..SJIS..()を使ってください。


extern DECLSPEC int SDLCALL TTF_SizeSJIS
    (TTF_Font *font, const Uint16 *text, int *w, int *h);
extern DECLSPEC int SDLCALL TTF_SizeJIS
    (TTF_Font *font, const Uint16 *text, int *w, int *h);

extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderSJIS_Solid
    (TTF_Font *font,const Uint16 *text, SDL_Color fg);
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderJIS_Solid
    (TTF_Font *font,const Uint16 *text, SDL_Color fg);

extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderSJIS_Shaded
    (TTF_Font *font,const Uint16 *text, SDL_Color fg, SDL_Color bg);
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderJIS_Shaded
    (TTF_Font *font,const Uint16 *text, SDL_Color fg, SDL_Color bg);

extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderSJIS_Blended
    (TTF_Font *font,const Uint16 *text, SDL_Color fg);
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderJIS_Blended
    (TTF_Font *font,const Uint16 *text, SDL_Color fg);

#define TTF_RenderSJIS(font, text, fg, bg)  \
    TTF_RenderSJIS_Shaded(font, text, fg, bg)
#define TTF_RenderJIS(font, text, fg, bg)   \
    TTF_RenderJIS_Shaded(font, text, fg, bg)


日本語表示可能なSDL_ttf

SDL_ttfを改造したソースコード




サンプル画像






今回の実装をするにあたってJISコード体系が大きな問題となりましたが、

根気よくググる事で何とか解決(´∀`)。

JISコードの2バイト文字は、2バイト目がAsciiコードや制御コードと重複するため

エスケープシーケンスを目印として、文字の切り替えを行います。





参考にしたサイト



こちらは文字コードについての技術文書が大変勉強になりました。

http://ash.jp/code/index.htm

又、こちらの16進ダンプツールの、文字コード判定ライブラリも活用させて頂きました。

(有難うございました。)



こちらも非常に解りやすい

http://www.kanzaki.com/docs/jcode.html



JISコード表です

http://charset.7jp.net/jis.html



SJIS -> Unicode

ftp://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT



JIS0201 -> Unicode

ftp://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0201.TXT



JIS0208 -> Unicode

ftp://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0208.TXT



JIS0212 -> Unicode

ftp://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/JIS0212.TXT



......http://www.unicode.org/



こちらからJISコードからUnicodeに変換するためのテーブルを拝借。

http://www.unicode.org/




サンプル

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

#pragma comment(lib,"SDL.lib")
#pragma comment(lib,"SDLmain.lib")
#pragma comment(lib,"SDL_ttf.lib")

static const char *TEXT[] = {
    "Hello SDL_ttf","SDLで日本語表示",
    "ブ━━⊂二二二( ^ω^)二⊃━━ン",
};

static SDL_Surface *screen;
static TTF_Font *font;
static int returnFlag = 0;

static int init(void);
static void run(void);
static void quit(void);
static int print(const char *str,int x,int y);

// returns : 1 if ready OK! ... 0 if ready NG!
#define IS_READY() ((screen != NULL)&&(font != NULL))
#define FONTW (52)

int main(int argc,char *argv[])
{
    if( init() ) run(); 
    else returnFlag = -1;
    quit();

    return returnFlag;
}

static int init(void)
{
    if(SDL_Init(SDL_INIT_VIDEO) < 0)
        return 0;

    if( TTF_Init() )
        return 0;

    screen = SDL_SetVideoMode(920,300,32,SDL_SWSURFACE);
    font = TTF_OpenFont("./ume-pgo5.ttf",FONTW);
    if( !IS_READY() )
        return 0;

    return 1;
}

static void run(void)
{
    int i;
    const int ts = sizeof(TEXT)/sizeof(const char*);
    SDL_Event ev;

    for(i = 0;i < ts;i++)
    {
        if( !print(TEXT[i],FONTW,FONTW*(i+1)) )
            printf("Failing Print Text...%s\n",TEXT[i]);
    }

    SDL_Flip(screen);

    /*************************************
    ** キーボードが押されたら終了する   **
    *************************************/
    while(SDL_WaitEvent(&ev))
    {
        switch(ev.type)
        {
        case SDL_KEYUP: return;
        default:        break;
        }
    }

    return;
}

static void quit(void)
{
    if(screen != NULL)
        SDL_FreeSurface(screen);
    if(font != NULL)
        TTF_CloseFont(font);
    SDL_Quit();
}

static int print(const char *str,int x,int y)
{
    SDL_Surface *surface;
    SDL_Color rgb = {0xff,0xff,0xff};
    SDL_Rect r = {x,y,0,0,};    //w, hは使わない...

    if( !IS_READY() )
        return 0;

    surface = TTF_RenderSJIS_Solid(font,str,rgb);
    if(surface != NULL)
    {
        SDL_BlitSurface(surface,NULL,screen,&r);
        SDL_FreeSurface( surface );
    }else   return 0;
    
    return 1;
}