zoukankan      html  css  js  c++  java
  • SDL显示文字及中文

    一.ttf字体
    -----------------------------------------------------------------
    SDL本身没有显示文字功能,它需要用扩展库SDL_ttf来显示文字。ttf是True Type Font的缩写,ttf是Windows下的缺省字体,它有美观,放大缩小不变形的优点,因此广泛应用很多场合。freeType是一个跨平台开源项目,它可以在利用ttf字体输出到屏幕上。一般的Linux发行版本都带了这个库(libfreetype.so),Windows下也有相应的移植版本。
    SDL_ttf封装freetype的库函数,提供一些简化的扩展接口提供SDL开发者使用。

    使用ttf库的第一件事要从Windows的字库下拷贝出一个字库出来,最好是中文字体,这样可以同时支持英文和中文显示。它一般在c:windowsfonts 目录下面。比如simsun.ttf 就是仿宋体的字库,将这个文件拷贝到你的项目目录下。或者一个指定目录。


    二.SDL_ttf 库的使用
    -------------------------------------------------------------------------

    在进行开发前确认你的SDL库和SDL_ttf库是否已经编译成功,Windows版本可以直接从官方网上下载编译好的开发包(头文件,动态库和静态)

    Linux下,只需要简单用 ./configure ; make ; make install 即可编译好这个库,默认安装在/usr/local/lib 下面。

    嵌入式SDL库移植参见我的博文:
    http://blog.chinaunix.net/u3/105675/showart_2149945.html

    在程序中使用SDL_ttf库,必须使用如下两个头文件,注意SDL是大写
    #include SDL.h>
    #include

    Linux应用程序链接时要也要链接两个库的 -lSDL_ttf -lSDL

    完整的TTF库说明参见
    http://jcatki.no-ip.org/SDL_ttf/SDL_ttf_59.html#SEC59

    可以查看一下SDL_ttf完整版本
    http://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf.html


    三.SDL_ttf编程
    --------------------------------------------------------------------

    SDL_ttf的编程的核心数据结构是 TTF_Font
    所有的文字输出都是围绕这个结构展开的。

    显示一段文字的流程
    一.初始TTF库

    二.创建一个对应某个字体文件的TTF_Font.

    三.用TTF输出函数把一段文字输出成SDL_Surface.其中TTF_font是其中必须参数

    四,把这个SDL_Surface 输出到屏幕显示,如果不需它,必须释放它

    五.释放TTF_Font

    六.关闭TTF库


    其中在一个程序中,可以同时打开多个TTF_Font.可以可以用输出方法输出N个SDL_Surface.这个完全看你的设计要求。只要在退出时记得一一释放即可。


    初始化TTF库

    #include <SDL_ttf.h>

    //Initialize SDL_ttf

    if( TTF_Init() == -1 )
    return -1;

    打开一个字体

    使用 TTF_Font *TTF_OpenFont(const char *file, int ptsize);

    其中file是指字体文件的路径,可以为相对路径或绝对路径, ptsize是指字号,即字体大小。它是基于720DPI的,有一个简单办法来估算字体大小,在Word中选择相应的字号即可看出效果来。

    中文字体的(五号字,小五,四号,小四)与数字字号有一个对应关系。

    英文字体“磅”(Point)和中文字号的关系
    美国人习惯于用“磅”作为文字的计量单位,而中国人却习惯于字号作为文字的计量单位。它们的对应关系是:
    初号=42磅=14.82毫米
    小初=36磅=12.70毫米
    一号=26磅=9.17毫米
    小一=24磅=8.47毫米
    二号=22磅=7.76毫米
    小二=18磅=6.35毫米
    三号=16磅=5.64毫米
    小三=15磅=5.29毫米
    四号=14磅=4.94毫米
    小四=12磅=4.23毫米
    五号=10.5磅=3.70毫米
    小五=9磅=3.18毫米
    六号=7.5磅=2.56毫米
    小六=6.5磅=2.29毫米
    七号=5.5磅=1.94毫米
    八号=5磅=1.76毫米

    其中的磅值就是你要设置的ptsize大致的值。


    以下是打开一个仿宋字体的代码,字号为三号字,字体文件跟可执行文件在同一个目录下。

    TTF_Font *font;
    font=TTF_OpenFont("simsun.ttf", 16);
    if(!font)
    {
    printf("TTF_OpenFont: Open simsun.ttf %s ", TTF_GetError());
    return -1;
    }


    输出英文/数字到一个SDL_Surface

    它使用 SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, const char *text, SDL_Color fg);来输出一段英文

    其中font是某个打开的字体,text是输出的文本,fg是文字的颜色采用类型SDL_Color.采用RGB三色定义


    SDL_Color black = { 255, 255, 255 }; //黑色
    SDL_Color red = { 255, 0, 0 }; //红色

    如果成功将文字输出一个SDL_Surface,如果失败将返回一个空值.

    其中Solid是单色的意思,类似输出有,空心字体:

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

    着色输出
    SDL_Surface *TTF_RenderText_Blended(TTF_Font *font, const char *text, SDL_Color fg) ;


    其中Solid输出,速度最快,但是字体不太美观。而Shaded 有点慢,但是字体美观,但是字体内部是空心的。
    Blend输出是非常之慢的,但是字体最为美观




    显示文字
    输出成SDL_Surface 意味着文字已经转换一个图像数据,把它象一个图象一样粘贴到屏幕SDL_Surface上后刷新即可显示。

    用前面讲的apply_surface()把文字加入到屏幕Surface当中。

    用SDL_Flip来刷新屏幕让文字显示

    注意,用完Surface后一定要调用SDL_FreeSurface()来释放它。

    void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
    {
    //Temporary rectangle to hold the offsets

    SDL_Rect offset;

    //Get the offsets

    offset.x = x;
    offset.y = y;

    //Blit the surface

    SDL_BlitSurface( source, NULL, destination, &offset );
    }


    //字体颜色

    SDL_Color textColor = { 255, 255, 255 };

    SDL_Surface * message;

    message = TTF_RenderText_Solid( font, "hello ,bluedrum ", textColor );
    if(message)
    {
    apply_surface(0,0,message,screen); //加入文本数据到屏幕

    }

    //刷新屏幕,让刚才的修改生效

    if(SDL_Flip(screen) == -1_
    {
    return -2;
    }


    SDL_FreeSurface(message);


    释放字体
    使用 void TTF_CloseFont(TTF_Font *font) ;

    关闭TTF库

    使用 void TTF_Quit() ;

    //Close the font that was used

    TTF_CloseFont( font );

    //Quit SDL_ttf

    TTF_Quit();


    四.关于中文输出
    ------------------------------------------------------------------

    这个问题是一个比较复杂的问题,复杂的原因在于SDL是一个跨平台的库,而两大平台Linux和Windows对于中文的内部编码是不一致的。分别采用UTF-8和Unicode.
    而SDL_ttf对于编码是非常敏感的,必须明确告诉它是哪一种编码,才能正确输出。否则将输出乱码。

    因此在使用SDL_ttf中文前,最好先读我关于文字编码的博文
    http://blog.chinaunix.net/u3/105675/showart_2121442.html
    以及用iconv转换编码的博文
    http://blog.chinaunix.net/u3/105675/showart_2096177.html

    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格式.

    显示中文代码

    //汉字硬编码写法

    //wchar_t msg[] =L"你好"; //如果源码在Windows下,是UNICODE,Linux下是UTF-8

    // wchar_t msg[] = {L'你',L'b', 0x0}; //同上


    //直接采用数字编码

    Uint16 msg[1024] = {0x4F60,0x597D,0}; //=Unicode 编码:你好


    message = TTF_RenderUNICODE_Solid( font, msg, textColor );

    同样的 Unicode/UTF-8的输出还有其它两组


    TTF_RenderUTF8_Shaded
    TTF_RenderUNICODE_Shaded
    TTF_RenderUTF8_Blended
    TTF_RenderUNICODE_Blended


    五.文字的高度和宽度

    ------------------------------------------------------------------------------

    在一个实用的程序中,可能需要更多方法来实现一些复杂功能,比如说一个电子书软件,想整屏显示一个文本,那么文字的高度和宽度就是一个重要选择了。

    SDL_ttf有好几个关于文字高度和宽度的方法

    求一行文本高度和宽度

    求英文/数字文本高度和宽度,返回值为0表示测试成功,高度和宽度分别由w和h返回。
    int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h) ;

    求UTF-8文本高宽
    int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) ;

    求Unicode文本高宽
    int TTF_SizeUNICODE(TTF_Font *font, const Unit16 *text, int *w, int *h) ;

    // get the width and height of a string as it would be rendered in a loaded font

    //TTF_Font *font;

    int w,h;
    Uint16 text[]={'H','e','l','l','o',' ',
    'W','o','r','l','d','!'};
    if(TTF_SizeUNICODE(font,text,&w,&h)) {
    // perhaps print the current TTF_GetError(), the string can't be rendered...

    } else {
    printf("width=%d height=%d ",w,h);
    }

    上述接口计算比较简单,但是对于象整屏输出文本内容,用上面测试并不太方便。SDL_ttf还有更精确的计算方法。
    英文字母对于各部分高度有严格定义

    参见上面图片,以baseline为基准,
    如果有向下伸展的字母 j,g等,额外向下伸出部分称为Descent.
    字母在基线上方的高度称Ascent.
    字母总高度称为 Height = Ascent + Descent
    每一行文字与下一方的行间距称为 Link Skip
    这四个参数分别用如下方法测试
    int TTF_FontLineSkip(const TTF_Font *font) ;
    int TTF_FontAscent(const TTF_Font *font) ;
    int TTF_FontDescent(const TTF_Font *font) ;
    int TTF_FontHeight(const TTF_Font *font) ;
    当然中文只需要TTF_FontHeight/TTF_FontLineSkip两个字符即可。

    还有一种把文字当成图像,这个一直没找用如何使用,但是这个图算得很细,一并留在记在这里


    它使用如下方法来测如下各个字.
    int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, int *minx, int *maxx, int *miny, int *maxy, int *advance) ;




    // get the glyph metric for the letter 'g' in a loaded font

    //TTF_Font *font;

    int minx,maxx,miny,maxy,advance;
    if(TTF_GlyphMetrics(font,'g',&minx,&maxx,&miny,&maxy,&advance)==-1)
    printf("%s ",TTF_GetError());
    else {
    printf("minx : %d ",minx);
    printf("maxx : %d ",maxx);
    printf("miny : %d ",miny);
    printf("maxy : %d ",maxy);
    printf("advance : %d ",advance);
    }



    五.文字特效
    ------------------------------------------
    TTF使用如下方法来显示特殊效果
    void TTF_SetFontStyle(TTF_Font *font, int style)


    style 参数可以设为如下几种效果
    TTF_STYLE_BOLD #粗体
    TTF_STYLE_ITALIC #斜体
    TTF_STYLE_UNDERLINE #下划线
    TTF_STYLE_STRIKETHROUGH #删除线(即中划线)

    如果Style设为 TTF_STYLE_NORMAL, 效果将变成缺省效果

    // set the loaded font's style to bold italics

    //TTF_Font *font;

    TTF_SetFontStyle(font, TTF_STYLE_BOLD|TTF_STYLE_ITALIC);

    // render some text in bold italics...


    // set the loaded font's style back to normal

    TTF_SetFontStyle(font, TTF_STYLE_NORMAL);

    六.测试代码
    ---------------------------------------------------------
    本测试代码在RHEL5下测试通过,这是测试结果,在运行前把从c:windowsfonts拷贝simfang.ttf 到项目目录下。

  • 相关阅读:
    [SSRS] Use Enum values in filter expressions Dynamics 365 Finance and Operation
    Power shell deploy all SSRS report d365 FO
    display method in Dynamics 365 FO
    How To Debug Dynamics 365 Finance and Operation
    Computed columns and virtual fields in data entities Dynamics 365
    Azure DevOps for Power Platform Build Pipeline
    Create readonly entities that expose financial dimensions Dynamics 365
    Dataentity call stack dynamics 365
    Dynamics 365 FO extension
    Use singletenant servertoserver authentication PowerApps
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/12455462.html
Copyright © 2011-2022 走看看