SDL_ttf 显示汉字的方法

  SDL_ttf  是SDL基本库的一个扩展。这里我抄录了官方的一个例程:
showfont.c
他这里只是一个main函数,讲了一下整个库的基本用法。
我打算做一个简单的封装,专门为了眼前要做的游戏。

/*
    showfont:  An example of using the SDL_ttf library with 2D graphics.
   Copyright (C) 1997-2004 Sam Lantinga

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not, write to the Free
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   Sam Lantinga
   
slouken@libsdl.org
*/

/* $Id: showfont.c,v 1.10 2006/03/14 08:27:50 slouken Exp $ */

/* A simple program to test the text rendering feature of the TTF library */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef HAVE_ICONV
#include <iconv.h>
#endif

#include "SDL.h"
#include "SDL_ttf.h"

#define DEFAULT_PTSIZE  18
#define DEFAULT_TEXT    "The quick brown fox jumped over the lazy dog"
#define NUM_COLORS      256

static char *Usage =
"Usage: %s [-solid] [-utf8|-unicode] [-b] [-i] [-u] [-fgcol r,g,b] [-bgcol r,g,b] <font>.ttf [ptsize] [text]/n";

int main(int argc, char *argv[])
{
       char *argv0 = argv[0];
       SDL_Surface *screen;
       TTF_Font *font;
       SDL_Surface *text, *temp;
       int ptsize;
       int i, done;
       int rdiff, gdiff, bdiff;
       SDL_Color colors[NUM_COLORS];
       SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
       SDL_Color black = { 0x00, 0x00, 0x00, 0 };
       SDL_Color *forecol;
       SDL_Color *backcol;
       SDL_Rect dstrect;
       SDL_Event event;
       int rendersolid;
       int renderstyle;
       int dump;
       enum {
               RENDER_LATIN1,
               RENDER_UTF8,
               RENDER_UNICODE
       } rendertype;
       char *message, string[128];

       /* Look for special execution mode */
       dump = 0;
       /* Look for special rendering types */
       rendersolid = 0;
       renderstyle = TTF_STYLE_NORMAL;
       rendertype = RENDER_LATIN1;
       /* Default is black and white */
       forecol = &black;
       backcol = &white;
       for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
               if ( strcmp(argv[i], "-solid") == 0 ) {
                       rendersolid = 1;
               } else
               if ( strcmp(argv[i], "-utf8") == 0 ) {
                       rendertype = RENDER_UTF8;
               } else
               if ( strcmp(argv[i], "-unicode") == 0 ) {
                       rendertype = RENDER_UNICODE;
               } else
               if ( strcmp(argv[i], "-b") == 0 ) {
                       renderstyle |= TTF_STYLE_BOLD;
               } else
               if ( strcmp(argv[i], "-i") == 0 ) {
                       renderstyle |= TTF_STYLE_ITALIC;
               } else
               if ( strcmp(argv[i], "-u") == 0 ) {
                       renderstyle |= TTF_STYLE_UNDERLINE;
               } else
               if ( strcmp(argv[i], "-dump") == 0 ) {
                       dump = 1;
               } else
               if ( strcmp(argv[i], "-fgcol") == 0 ) {
                       int r, g, b;
                       if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                               fprintf(stderr, Usage, argv0);
                               return(1);
                       }
                       forecol->r = (Uint8)r;
                       forecol->g = (Uint8)g;
                       forecol->b = (Uint8)b;
               } else
               if ( strcmp(argv[i], "-bgcol") == 0 ) {
                       int r, g, b;
                       if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
                               fprintf(stderr, Usage, argv0);
                               return(1);
                       }
                       backcol->r = (Uint8)r;
                       backcol->g = (Uint8)g;
                       backcol->b = (Uint8)b;
               } else {
                       fprintf(stderr, Usage, argv0);
                       return(1);
               }
       }
       argv += i;
       argc -= i;

       /* Check usage */
       if ( ! argv[0] ) {
               fprintf(stderr, Usage, argv0);
               return(1);
       }

       /* Initialize SDL */
       if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
               fprintf(stderr, "Couldn't initialize SDL: %s/n",SDL_GetError());
               return(2);
       }
       atexit(SDL_Quit);

       /* Initialize the TTF library */
       if ( TTF_Init() < 0 ) {
               fprintf(stderr, "Couldn't initialize TTF: %s/n",SDL_GetError());
               return(2);
       }
       atexit(TTF_Quit);

       /* Open the font file with the requested point size */
       ptsize = 0;
       if ( argc > 1 ) {
               ptsize = atoi(argv[1]);
       }
       if ( ptsize == 0 ) {
               i = 2;
               ptsize = DEFAULT_PTSIZE;
       } else {
               i = 3;
       }
       font = TTF_OpenFont(argv[0], ptsize);
       if ( font == NULL ) {
               fprintf(stderr, "Couldn't load %d pt font from %s: %s/n",
                                       ptsize, argv[0], SDL_GetError());
               return(2);
       }
       TTF_SetFontStyle(font, renderstyle);

       if( dump ) {

               for( i = 48; i < 123; i++ ) {
                       SDL_Surface* glyph = NULL;

                       glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );

                       if( glyph ) {
                               char outname[64];
                               sprintf( outname, "glyph-%d.bmp", i );
                               SDL_SaveBMP( glyph, outname );
                       }

               }

               return( 0 );
       }

       /* Set a 640x480x8 video mode */
       screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
       if ( screen == NULL ) {
               fprintf(stderr, "Couldn't set 640x480x8 video mode: %s/n",
                                                       SDL_GetError());
               return(2);
       }

       /* Set a palette that is good for the foreground colored text */
       rdiff = backcol->r - forecol->r;
       gdiff = backcol->g - forecol->g;
       bdiff = backcol->b - forecol->b;
       for ( i=0; i<NUM_COLORS; ++i ) {
               colors[i].r = forecol->r + (i*rdiff)/4;
               colors[i].g = forecol->g + (i*gdiff)/4;
               colors[i].b = forecol->b + (i*bdiff)/4;
       }
       SDL_SetColors(screen, colors, 0, NUM_COLORS);

       /* Clear the background to background color */
       SDL_FillRect(screen, NULL,
                       SDL_MapRGB(screen->format, backcol->r, backcol->g, backcol->b));
       SDL_UpdateRect(screen, 0, 0, 0, 0);

       /* Show which font file we're looking at */
       sprintf(string, "Font file: %s", argv[0]);  /* possible overflow */
       if ( rendersolid ) {
               text = TTF_RenderText_Solid(font, string, *forecol);
       } else {
               text = TTF_RenderText_Shaded(font, string, *forecol, *backcol);
       }
       if ( text != NULL ) {
               dstrect.x = 4;
               dstrect.y = 4;
               dstrect.w = text->w;
               dstrect.h = text->h;
               SDL_BlitSurface(text, NULL, screen, &dstrect);
               SDL_FreeSurface(text);
       }
       
       /* Render and center the message */
       if ( argc > 2 ) {
               message = argv[2];
       } else {
               message = DEFAULT_TEXT;
       }
       switch (rendertype) {
           case RENDER_LATIN1:
               if ( rendersolid ) {
                       text = TTF_RenderText_Solid(font,message,*forecol);
               } else {
                       text = TTF_RenderText_Shaded(font,message,*forecol,*backcol);
               }
               break;

           case RENDER_UTF8:
               if ( rendersolid ) {
                       text = TTF_RenderUTF8_Solid(font,message,*forecol);
               } else {
                       text = TTF_RenderUTF8_Shaded(font,message,*forecol,*backcol);
               }
               break;

           case RENDER_UNICODE:
               {
                       Uint16 unicode_text[BUFSIZ];
                       int index;
#ifdef HAVE_ICONV
                       /* Use iconv to convert the message into utf-16.
                        * "char" and "" are aliases for the local 8-bit encoding */
                       iconv_t cd;
                       /*ICONV_CONST*/ char *from_str = message;
                       char *to_str = (char*)unicode_text;
                       size_t from_sz = strlen(message) + 1;
                       size_t to_sz = sizeof(unicode_text);
                       size_t res;
                       int i;

                       if ((cd = iconv_open("UTF-16", "char")) == (iconv_t)-1
                           && (cd = iconv_open("UTF-16", "")) == (iconv_t)-1) {
                               perror("Couldn't open iconv");
                               exit(1);
                       }

                       res = iconv(cd, &from_str, &from_sz, &to_str, &to_sz);
                       if (res == -1) {
                               perror("Couldn't use iconv");
                               exit(1);
                       }

                       iconv_close(cd);
#else
                       /* Convert the message from ascii into utf-16.
                        * This is unreliable as a test because it always
                        * gives the local ordering. */
                       for (index = 0; message[index]; index++) {
                               unicode_text[index] = message[index];
                       }
                       unicode_text[index] = 0;
#endif

                       if ( rendersolid ) {
                               text = TTF_RenderUNICODE_Solid(font,
                                       unicode_text, *forecol);
                       } else {
                               text = TTF_RenderUNICODE_Shaded(font,
                                       unicode_text, *forecol, *backcol);
                       }
               }
               break;
           default:
               text = NULL; /* This shouldn't happen */
               break;
       }
       if ( text == NULL ) {
               fprintf(stderr, "Couldn't render text: %s/n", SDL_GetError());
               TTF_CloseFont(font);
               return(2);
       }
       dstrect.x = (screen->w - text->w)/2;
       dstrect.y = (screen->h - text->h)/2;
       dstrect.w = text->w;
       dstrect.h = text->h;
       printf("Font is generally %d big, and string is %hd big/n",
                                               TTF_FontHeight(font), text->h);

       /* Blit the text surface */
       if ( SDL_BlitSurface(text, NULL, screen, &dstrect) < 0 ) {
               fprintf(stderr, "Couldn't blit text to display: %s/n",
                                                               SDL_GetError());
               TTF_CloseFont(font);
               return(2);
       }
       SDL_UpdateRect(screen, 0, 0, 0, 0);

       /* Set the text colorkey and convert to display format */
       if ( SDL_SetColorKey(text, SDL_SRCCOLORKEY|SDL_RLEACCEL, 0) < 0 ) {
               fprintf(stderr, "Warning: Couldn't set text colorkey: %s/n",
                                                               SDL_GetError());
       }
       temp = SDL_DisplayFormat(text);
       if ( temp != NULL ) {
               SDL_FreeSurface(text);
               text = temp;
       }

       /* Wait for a keystroke, and blit text on mouse press */
       done = 0;
       while ( ! done ) {
               if ( SDL_WaitEvent(&event) < 0 ) {
                       fprintf(stderr, "SDL_PullEvent() error: %s/n",
                                                               SDL_GetError());
                       done = 1;
                       continue;
               }
               switch (event.type) {
                       case SDL_MOUSEBUTTONDOWN:
                               dstrect.x = event.button.x - text->w/2;
                               dstrect.y = event.button.y - text->h/2;
                               dstrect.w = text->w;
                               dstrect.h = text->h;
                               if ( SDL_BlitSurface(text, NULL, screen,
                                                       &dstrect) == 0 ) {
                                       SDL_UpdateRects(screen, 1, &dstrect);
                               } else {
                                       fprintf(stderr,
                                       "Couldn't blit text to display: %s/n",
                                                               SDL_GetError());
                               }
                               break;
                               
                       case SDL_KEYDOWN:
                       case SDL_QUIT:
                               done = 1;
                               break;
                       default:
                               break;
               }
       }
       SDL_FreeSurface(text);
       TTF_CloseFont(font);
       return(0);
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值