天天看點

SDL文字和圖形

SDL本身沒有顯示文字功能,它需要用擴充庫SDL_ttf來顯示文字。ttf是True Type Font的縮寫,ttf是Windows下的預設字型,它有美觀,放大縮小不變形的優點,是以廣泛應用很多場合。freeType是一個跨平台開源項目, 它可以在利用ttf字型輸出到螢幕上。一般的linux發行版本都帶了這個庫(libfreetype.so),Windows下也有相應的移植版本。

    SDL_ttf封裝freetype的庫函數,提供一些簡化的擴充接口提供SDL開發者使用。

使用ttf庫的第一件事要從Windows的字庫下拷貝出一個字庫出來,最好是中文字型,這樣可以同時支援英文和中文顯示。它一般在c:\windows \fonts 目錄下面。比如simsun.ttf 就是仿宋體的字庫,将這個檔案拷貝到你的項目目錄下。或者一個指定目錄。

在上一篇,加入下面代碼:

Tao.Sdl.SdlTtf.TTF_Init();

            font36 = Tao.Sdl.SdlTtf.TTF_OpenFont(Application.StartupPath + "\\simfang.ttf", 36);

            if (font36 == IntPtr.Zero)

            {

                MessageBox.Show("SDL字型初始化失敗!");

                return;

            }

            font24 = Tao.Sdl.SdlTtf.TTF_OpenFont(Application.StartupPath + "\\simfang.ttf", 24);

            if (font24 == IntPtr.Zero)

                font24 = font36;

            Tao.Sdl.SdlTtf.TTF_SetFontStyle(font36, Tao.Sdl.SdlTtf.TTF_STYLE_BOLD);

            Tao.Sdl.SdlTtf.TTF_SetFontStyle(font24, Tao.Sdl.SdlTtf.TTF_STYLE_BOLD);

            int w = 0, h = 0;

            Tao.Sdl.SdlTtf.TTF_SizeUNICODE(font36, "測試文字1", out w, out h);

            rect2 = new Tao.Sdl.Sdl.SDL_Rect(5, (short)(20), 400, 400);

            IntPtr chinese = Tao.Sdl.SdlTtf.TTF_RenderUNICODE_Blended(font36, "測試文字1",new Tao.Sdl.Sdl.SDL_Color(255, 255, 0));

            Tao.Sdl.Sdl.SDL_BlitSurface(chinese, ref rect, surfacePtr, ref rect2);

            Tao.Sdl.Sdl.SDL_FreeSurface(chinese);

            rect2 = new Tao.Sdl.Sdl.SDL_Rect(5, (short)(20 + h), 400, 400);

            chinese = Tao.Sdl.SdlTtf.TTF_RenderUNICODE_Blended(font24, "測試文字2", newTao.Sdl.Sdl.SDL_Color(255, 0, 255));

            Tao.Sdl.SdlGfx.stringRGBA(surfacePtr, 300, 300, "test string", 0, 255, 0, 255);

            Tao.Sdl.SdlGfx.lineRGBA(surfacePtr, 150, 150, 300, 300, 255, 60, 255, 255);

            short[] xs = new short[4];

            short[] ys = new short[4];

            xs[0] = 20;

            xs[1] = 120;

            xs[2] = 120;

            xs[3] = 20;

            ys[0] = 20;

            ys[1] = 20;

            ys[2] = 120;

            ys[3] = 120;

            Tao.Sdl.SdlGfx.polygonRGBA(surfacePtr, xs, ys, 4, 255, 0, 0, 255);

            Tao.Sdl.SdlGfx.circleRGBA(surfacePtr, 200, 200, 100, 0, 0, 255, 255);

            Tao.Sdl.SdlGfx.boxRGBA(surfacePtr, 350, 350, 450, 450, 0, 0, 255, 255);

            Tao.Sdl.SdlGfx.filledTrigonRGBA(surfacePtr, 300, 50, 200, 150, 400, 150, 255, 255, 0, 255);

            Tao.Sdl.Sdl.SDL_Flip(surfacePtr);

            Tao.Sdl.Sdl.SDL_UpdateRect(surfacePtr, 0, 0, rect.w, rect.h);

釋放:

Tao.Sdl.SdlTtf.TTF_CloseFont(font36);

            Tao.Sdl.SdlTtf.TTF_CloseFont(font24);

            Tao.Sdl.SdlTtf.TTF_Quit();

TTF_OpenFont:打開字型,因為中途不能修改字型大小,是以打開2個,沒辦法的辦法。另外注意字型路徑下不能包含任何中文字元。

TTF_SetFontStyle:設定字型樣式

TTF_SizeUNICODE:擷取字型高度寬度,可以控制字元間距和行距。

TTF_RenderUNICODE_Blended:渲染字型,得到一個surface

stringRGBA:隻能渲染英文字元,比較簡單

lineRGBA:畫線

polygonRGBA:畫面

circleRGBA:畫圓

boxRGBA:畫填充矩形

filledTrigonRGBA:畫填充三角形

SDL_ttf的程式設計的核心資料結構是TTF_Font 所有的文字輸出都是圍繞這個結構展開的。

    顯示一段文字的流程

    一.初始TTF庫

    二.建立一個對應某個字型檔案的TTF_Font.

    三.用TTF輸出函數把一段文字輸出成SDL_Surface.其中TTF_font是其中必須參數

    四.把這個SDL_Surface 輸出到螢幕顯示,如果不需它,必須釋放它

    五.釋放TTF_Font

    六.關閉TTF庫

其中在一個程式中,可以同時打開多個TTF_Font.可以可以用輸出方法輸出N個SDL_Surface.這個完全看你的設計要求。隻要在退出時記得一一釋放即可。

關于中文輸出

    這個問題是一個比較複雜的問題,複雜的原因在于SDL是一個跨平台的庫,而兩大平台Linux和Windows對于中文的内部編碼是不一緻的。分别采用UTF-8和Unicode.

    而SDL_ttf對于編碼是非常敏感的,必須明确告訴它是哪一種編碼,才能正确輸出。否則将輸出亂碼。可以用iconv轉換編碼。

    SDL兩種編碼都可以直接輸出

    UNICODE輸出:

    SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font, const Uint16 *text, SDL_Color fg) ;

    UTF-8輸出:

    SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font, const char *text, SDL_Color fg) ;

    簡單言之,如果你的在LINUX下輸入在代碼中直接寫成的中文,那它就是UTF-8的編碼,如果在WINDOWS用文本編輯器輸出中文,它就是Unicode的編碼,這個你可以用二進制編輯工具檢視。

    這樣如果源碼是在WINDOWS編輯後,拷貝到LINUX上編譯,這個時候就會發生混亂了,用TTF_RenderUTF8_Solid輸出必然是亂碼.

    是以為了保險,可以在源代碼用數組用固定的編碼。這樣無論在哪個平台都能正确輸出。另外一種情況把檔案寫在帶BOM頭的檔案裡,這樣可以知道檔案内部編碼,以便程式采用相應用輸出。

    還一些特殊情況,比如網上所有LRC歌詞檔案,必須是GBK格式,實測所有音樂軟體都隻認這個編碼。這樣需要用iconv轉換成Unicode或UTF-8格式.

    同樣的 Unicode/UTF-8的輸出還有其它兩組

    TTF_RenderUTF8_Shaded

    TTF_RenderUNICODE_Shaded

    TTF_RenderUTF8_Blended

    TTF_RenderUNICODE_Blended