首页 > 其他分享 >SDL应用之三种字库

SDL应用之三种字库

时间:2022-10-11 23:33:28浏览次数:71  
标签:code int screen char color 三种 SDL 字库


SFont 库

sfont用大小写英文字母和符号进行内容显示,资源即是字体图片。

sfont下载:​​http://www.linux-games.com/sfont​

我下载SFont 2.03后,解压并make,产生了许多的文件,其中包括三个SFont的测试文件,下面是SFontTest3的效果:

SDL应用之三种字库_字体


自己来写一个试试,将​​.h​​​文件,​​.c​​​文件,要使用的图片文件(我就直接使用​​24P_Copperplate_Blue.png​​​了)复制到代码文件目录。官网上有更多的字体 ​​http://www.linux-games.com/sfont-fonts/​

#include <SDL.h>
#include <SDL_image.h>
#include "SFont.h"

int main(){
SDL_Surface *screen, *font;
SFont_Font* myFont;
if(SDL_Init(SDL_INIT_VIDEO) < 0){
fprintf(stderr,"SDL init error: %s\n",SDL_GetError());
exit(1);
}
screen = SDL_SetVideoMode(640,480,16,SDL_SWSURFACE);
if(screen == NULL){
fprintf(stderr,"Error: %s\n",SDL_GetError());
exit(1);
}
atexit(SDL_Quit);

font = IMG_Load("24P_Copperplate_Blue.png");
if(font == NULL){
fprintf(stderr,"IMG_Load Error: %s\n",SDL_GetError());
exit(1);
}
myFont = SFont_InitFont(font);
/* void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, int x, int y, const char *text); */
SFont_Write(screen,myFont,100,220,"SFont works, hello world");
SDL_UpdateRect(screen,0,0,0,0);
SDL_Delay(5000);
SFont_FreeFont(myFont);
//SDL_FreeSurface(font); /* SDL_FreeFont(myFont) has free font before.*/
//SDL_FreeSurface(screen); /* SDL_quit has handled it.*/
return 0;
}
edemon@ubuntu1:~/workspace$ gcc SFontTest.c SFont.c -o exe -lSDL -lSDL_image
edemon@ubuntu1:~/workspace$ ./exe

SDL应用之三种字库_图片_02

TrueType库

SDL_ttf支持utf8和unicode中文编码,字体美观,缩放简单,可是字库是比较大的。计量单位是MB。
arphic是truetype下的一个库:

edemon@ubuntu1:/usr/share/fonts/truetype$ du -sh arphic
37M arphic

关于TrueType库的安装和使用在博文linux图形编程之SDL​中的SDL_ttf部分有介绍。
字体绘制函数在SDL_ttf.c中可查看详情

extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderText_Solid(TTF_Font *font,
const char *text, SDL_Color fg);
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUTF8_Solid(TTF_Font *font,
const char *text, SDL_Color fg);
extern DECLSPEC SDL_Surface * SDLCALL TTF_RenderUNICODE_Solid(TTF_Font *font,
const

如在安装后想立刻观看效果,可以使用安装包解压后文件夹中的测试文件:

Usage: /home/edemon/SDL_ttf-2.0.11/.libs/lt-showfont [-solid] [-utf8|-unicode] [-b] [-i] [-u] [-s] [-outline size] [-hintlight|-hintmono|-hintnone] [-nokerning] [-fgcol r,g,b] [-bgcol r,g,b] <font>.ttf [ptsize] [text]


edemon@ubuntu1:~/SDL_ttf-2.0.11$ sudo ./showfont -bgcol 255,255,0 /usr/share/fonts/truetype/freefont/FreeSans.ttf 23 hello\ world
Font is generally 26 big, and string is 26 big

SDL应用之三种字库_ubuntu_03


在终端shell上使用中文,测试演示出来是乱码。不过自己在代码中写入中文是不会有这种现象的,可看linux图形编程之SDL中的SDL_ttf部分。

点阵字库

点阵字库保存着英文和中文的字体信息,字体文件大小单位是KB,很小。它通过在屏幕上特定矩阵范围内画出字体的每一点,然后显示出来,处理速度很快,不过显示大字号的时候有锯齿感。

edemon@ubuntu1:~/asc_hzk$ du -sh HZK-16
352K HZK-16

在ubuntu上写程序时,我输入一个汉字结果终端显示了两个中文字符,开始以为是程序错误了,经查证是字符编码的问题。
UTF-8编码是变长编码,通常汉字占三个字节,扩展B区以后的汉字占四个字节。GBK编码,一个汉字占两个字节。程序是按照一个汉字两个字节进行处理的,所以将文件变成GBK编码。
查看文件的字符编码:
用vim打开文件,​​​set fileencoding​​​可以得到 ​​fileencoding=utf-8​​,接着我们设置文件编码为GBK

command> set fileencoding=GBK

不过我再次打开vim时,仍然显示utf-8,看了网上的许多教程,感觉有问题。然后我粗暴地解决了这个次要问题:直接用Geany设置字符编码为GBK。
然后编译测试。

参考博文:​​https://blog.twofei.com/embedded/hzk.html​

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

void initSDL();
void eputc(int x, int y, Uint32 color, char code);
void cputc(int x, int y, Uint32 color, char *code);
void ecputs(int x, int y, Uint32 color, char *str);
void drawPixel(int x, int y, Uint32 color);

SDL_Surface *screen;
Uint32 color;
char *efont;
char *cfont;
FILE *efp,*cfp;

#define meme 20000
#define memc 200000
int main(){
efont = (char *)malloc(meme);
cfont = (char *)malloc(memc);
if(efont==NULL && cfont==NULL){
fprintf(stderr,"can't malloc memory\n");
exit(1);
}
efp = fopen("../asc_hzk/ASC-16/ASC16","r");
//cfp = fopen("/home/edemon/font_lib/16x16/HZK16C","r");
cfp = fopen("../asc_hzk/HZK-16/HZK16","r");
if(efp==NULL || cfp==NULL){
fprintf(stderr,"ASC16 or HZK16 is not found\n");
exit(1);
}
fread(efont,sizeof(char),meme,efp);
fread(cfont,sizeof(char),memc,cfp);
fclose(efp);
fclose(cfp);

initSDL();
color = SDL_MapRGB(screen->format,255,255,255);
SDL_FillRect(screen,&screen->clip_rect,color); /* set the screen color */
color = SDL_MapRGB(screen->format,0,0,0);
ecputs(200,20,color,"一 二 三 四 五");
SDL_UpdateRect(screen,0,0,0,0);
SDL_Delay(10000);
free(efont);
free(cfont);
return 0;
}

void initSDL(){
if(SDL_Init(SDL_INIT_VIDEO) < 0){
fprintf(stderr,"SDL init error: %s\n",SDL_GetError());
exit(1);
}
screen = SDL_SetVideoMode(640,480,16,SDL_SWSURFACE);
if(screen == NULL){
fprintf(stderr,"Error: %s\n",SDL_GetError());
exit(1);
}
atexit(SDL_Quit);
}

void drawPixel(int x, int y, Uint32 color){
Uint16 *bufp;
if(SDL_MUSTLOCK(screen)){
if(SDL_LockSurface(screen) < 0){
return ;
}
}
bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
*bufp = color;
if(SDL_MUSTLOCK(screen)){
SDL_UnlockSurface(screen);
}
SDL_UpdateRect(screen,x,y,1,1);
}

void eputc(int x, int y, Uint32 color, char code){
int i, j;
char mask = 0x80;
char *ptr = efont+code*16;
for(i=0;i<16;i++){
for(j=0;j<8;j++){
if(ptr[i] & (mask>>j)) drawPixel(x+j,y+i,color);
}
}
}

void cputc(int x, int y, Uint32 color, char *code){
int i,j,k;
char mask = 0x80; /* 0xFF = 255 = 2^8-1, 0x80 = 16*8 = 2^7 */
char q, w;
char *ptr;
q = code[0]-0xA1;
w = code[1]-0xA1;
ptr = cfont+(q*94+w)*32;
for(i=0;i<16;i++){ /* 16 rows */
for(j=0;j<2;j++){ /* 2 cols, one col has 8 points, which is presented by 8 bits.*/
for(k=0;k<8;k++){ /* check 8 bits for every col */
if(ptr[2*i+j]&(mask>>k)) drawPixel(x+j*8+k,y+i,color);
}
}
}
}

void ecputs(int x, int y, Uint32 color, char *str){
char *ptr = str;
char code[2] = {0};
int len = strlen(str);
char mask = 0x80;
while(len > 0){
if(ptr[0]&mask){ /* Chinese character */
code[0] = ptr[0];
code[1] = ptr[1];
cputc(x,y,color,code);
len -= 2;
x += 16;
ptr += 2;
}
else { /* English character */
code[0] = ptr[0];
eputc(x,y,color,code[0]);
len--;
x += 8;
ptr++;
}
}
}

SDL应用之三种字库_字体_04


可能是字体小的缘故,一旦写复杂的汉字,效果就会变差。除非采用更大的点阵。


标签:code,int,screen,char,color,三种,SDL,字库
From: https://blog.51cto.com/u_15746559/5748425

相关文章

  • 22_播放器之使用SDL显示YUV视频
    简介使用SDL实现简单的YUV播放器。这里还需要使用到像素格式和计算图片大小,这两个我们直接使用ffmpeg来实现,因此需要使用ffmpeg的libavutil/avutil.h和libavutil/imgut......
  • Go协程超时退出的三种方式
    主要介绍如何实现超时控制,主要有三种1、context.WithTimeout/context.WithDeadline+time.After2、context.WithTimeout/context.WithDeadline+time.NewTimer3、chan......
  • 分散式、集中式以及分布式三种模式
    例如:我所工作的地方是一个软件园中的一座大楼,而这座大楼的整个温度调节问题由某一物业公司搞定。现在,摆在他们面前存在多种选择方案。第一种:分散式,即大楼中的各个公司自己......
  • apache MPM的三种工作模式
    apache和httpd的关系:apache刚开始靠apache这个软件起家,后来发展成为一个基金会,拥有了几十种开源项目,所以就把提供web服务的apache这个软件更名为httpd(apache2以上版本改称......
  • Spring事务的三种实现方式
    spring中事务的三种实现方式1.编程式事务管理过时了,一般不用,略2.声明式事务管理2.1基于TransactionProxyFactoryBean的声明式事务管理1创建异常类publicclassMyException......
  • Tkinter布局管理器(三种方法详解)
    当我们在开发一个GUI程序的时候,布局管理发挥着非常重要的作用,它指的是通过管理控件在窗口中的位置(排版),从而实现对窗口和控件布局的目的。一个优秀的图形用户界面,更像是艺......
  • Springboot异常处理和自定义错误页面及@ControllerAdvice 注解的三种使用场景!五、@Con
    一、前言springboot默认发生4xx错误时候,pc端响应的页面如下如果是移动端(手机端)将会响应json格式的数据,如下二、Springboot异常处理为什么我们请求错误的路径,boot会给我们返......
  • java获取当前时间戳的三种方法比较效率(*)
    java获取当前时间戳的三种方法比较效率(*)获取当前时间戳//方法一System.currentTimeMillis();//方法二Calendar.getInstance().getTimeInMillis();//方法三ne......
  • MyBatis的三种分页方式
    一、Limit分页<select id="getUserInfo1" parameterType="map" resultType="dayu">    select * from user    <if test="startPos!=null and pageSize!......
  • 【Java基础】IO流概述分类、字节流写数据、字节流写数据的三种方式及写数据的两个小问
    目录​​一、IO流概述和分类​​​​二、字节流写数据​​​​三、字节流写数据的三种方式​​​​四、字节流写数据的两个小问题​​一、IO流概述和分类IO流介绍:●IO:输入/......