第一篇用QNX SCREEN 渲染文字使用基础字库加上点阵放大实现的,放大后字体会很难看,于是考虑使用FreeTpye矢量字体实现。代码实现如下
1、英文矢量字体渲染
#pragma once
#include "libmessage.h"
#include "bagad_module.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include FT_FREETYPE_H
#define WIDTH 1920
#define HEIGHT 720
unsigned char image[HEIGHT][WIDTH];
//渲染
void draw_pix(int x, int y,char *ptr,int stride,int color){
ptr += (stride*y);
ptr[x*4] = ((0xff000000&color)>>24);
ptr[x*4+1] = ((0x00ff0000&color)>>16);
ptr[x*4+2] = ((0x0000ff00&color)>>8);
ptr[x*4+3] = (0x000000ff&color);
}
//获取二维坐标数组
void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y)
{
printf("start draw_bitmap");
FT_Int i, j, p, q;
FT_Int x_max = x + bitmap->width;
FT_Int y_max = y + bitmap->rows;
for ( i = x, p = 0; i < x_max; i++, p++ )
{
for ( j = y, q = 0; j < y_max; j++, q++ )
{
if ( i < 0 || j < 0 ||
i >= WIDTH || j >= HEIGHT )
continue;
image[j][i] |= bitmap->buffer[q * bitmap->width + p];
}
}
}
//filename 字体文件 str 字符串文字 text_size 文字大小
int en_draw(const char * filename ,const char * str, int text_size){
printf("start freetype_draw\n");
printf("filename=%s str=%s text_size=%d \n",filename,str,text_size);
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix matrix;
FT_Vector pen;
FT_Error error;
double angle;
int target_height;
int n, num_chars;
num_chars = strlen( str );
angle = ( 0.0 / 360 ) * 3.14159 * 2;
target_height = HEIGHT;
printf("start freetype_draw 1\n");
error = FT_Init_FreeType( &library );
printf("start freetype_draw 2 error=%d \n",error);
error = FT_New_Face( library, filename, 0, &face );
printf("start freetype_draw 3 error=%d \n",error);
FT_Set_Pixel_Sizes(face, text_size, text_size);
slot = face->glyph;
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
printf("start freetype_draw 4 \n");
pen.x = 0 * 64;
pen.y = ( target_height - (text_size*7)/10) * 64;
printf("start freetype_draw 5 pen.y=%f \n",pen.y);
for ( n = 0; n < num_chars; n++ )
{
FT_Set_Transform( face, &matrix, &pen );
error = FT_Load_Char( face, str[n], FT_LOAD_RENDER );
printf("FT_Load_Char error=%d \n",error);
if ( error )
continue;
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
target_height - slot->bitmap_top );
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}
//show_string();
printf("start freetype_draw 6\n");
FT_Done_Face ( face );
printf("start FT_Done_Face 6\n");
FT_Done_FreeType( library );
printf("start FT_Done_FreeType 6\n");
return 0;
}
//用 QNX screen buf 画出位图坐标
void freetype_main(int x,int y,int l,int w,int text_size,int zoder,const char * str,const char * ttf){
int size[2];
int vis = 1;
int type;
printf("start text_size=%d str=%s ttf=%s\n",text_size,str,ttf);
screen_context_t screen_ctx;
screen_create_context(&screen_ctx, SCREEN_APPLICATION_CONTEXT);
int count = 0;
screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_DISPLAY_COUNT, &count);
printf("start demo count=%d \n",count);
screen_display_t *screen_disps = (screen_display_t *)calloc(count, sizeof(screen_display_t));
screen_get_context_property_pv(screen_ctx, SCREEN_PROPERTY_DISPLAYS, (void **)screen_disps);
screen_display_t screen_disp = screen_disps[1];
int dims[2] = { 0, 0 };
screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, dims);
printf("start screen size w=%d h=%d \n",dims[0],dims[1]);
screen_window_t screen_text_win = NULL;
screen_create_window(&screen_text_win, screen_ctx);
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_VISIBLE, &vis);
screen_set_window_property_pv(screen_text_win,SCREEN_PROPERTY_DISPLAY,(void**)&screen_disps[1]);
printf("start draw_string\n");
int len = strlen(str);
int flag = 1;
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_STATIC, &flag);
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_VISIBLE, &vis);
int format = SCREEN_FORMAT_RGBA8888;
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_FORMAT, &format);
int usage = SCREEN_USAGE_WRITE;
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_USAGE, &usage);
int transparency = SCREEN_TRANSPARENCY_SOURCE_OVER;
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_TRANSPARENCY, &transparency);
int pos[2]={x,y};
int rect[4]= {x, y,l, w};
printf("start text_size=%d len=%d\n",text_size,len);
printf("x=%d y=%d w=%d h=%d\n",x,y,rect[2],rect[3]);
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_POSITION, pos);
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_BUFFER_SIZE, rect+2);
/* 创建窗口缓冲区,然后获取该缓冲区的句柄 . */
screen_buffer_t screen_buf;
screen_create_window_buffers(screen_text_win, 1);
screen_get_window_property_pv(screen_text_win, SCREEN_PROPERTY_RENDER_BUFFERS, (void **)&screen_buf);
int zorder = 24;
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_ZORDER, &zorder);
//获取指向该缓冲区的指针,以填充形状。
char *ptr = NULL;
screen_get_buffer_property_pv(screen_buf, SCREEN_PROPERTY_POINTER, (void **)&ptr);
//不同行像素之间的字节数
int stride = 0;
screen_get_buffer_property_iv(screen_buf, SCREEN_PROPERTY_STRIDE, &stride);
printf("start 0xff text_size= %d\n",text_size);
//字符
printf("ttf=%s\n",ttf);
freetype_draw(ttf, str,text_size);
printf("freetype_draw end \n");
int i, j;
for ( i = 0; i < HEIGHT; i++ ){
for ( j = 0; j < WIDTH; j++ ){
if(image[i][j]){
draw_pix(j, i,ptr, stride, 0xa0a0a0ff);
}
else{
draw_pix(j, i,ptr, stride, 0xffffff00);
}
screen_get_buffer_property_pv(screen_buf, SCREEN_PROPERTY_POINTER, (void **)&ptr);
}
}
printf("screen_post_window \n");
screen_post_window(screen_text_win, screen_buf, 1, rect, 0);
printf("draw_string end \n");
size[0] = 0;
size[1] = 0;
screen_get_window_property_iv(screen_text_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
printf("error size[0]=%d size[1]=%d\n",size[0],size[1]);
screen_set_window_property_iv(screen_text_win, SCREEN_PROPERTY_SIZE, size);
screen_flush_context(screen_ctx, SCREEN_WAIT_IDLE);
}
测试样例:freetype_main(0, 0, 1920, 720, 50, 20, "hello world","/usr/bin/Ubuntu-B.ttf");
中文渲染:
//先将框填充空内容
void init_image(){
int i, j;
for ( i = 0; i < HEIGHT; i++ )
{
for ( j = 0; j < WIDTH; j++ )
image[i][j]=' ';
}
}
//获取中文矩阵填入image[i][j]中
int render_cn(wchar_t *text,int text_size,char *ttfpath){
FT_Library m_pFTLib;
FT_Face m_pFTFace;
int i=0;
int j=0;
int lenChar=wcslen(text);
printf("*****text:********\n");
wprintf(L"%s\n",text);
printf("len=%d\n",lenChar);
FT_Error result = FT_Init_FreeType(&m_pFTLib);
if(FT_New_Face(m_pFTLib, ttfpath, 0, &m_pFTFace)){
printf("FT_New_Face error!\n");
return -1;
}
//FT_ENCODING_GB2312, FT_ENCODING_UNICODE
FT_Select_Charmap(m_pFTFace, FT_ENCODING_UNICODE);
int size_w=text_size;
int size_h=text_size;
FT_Set_Pixel_Sizes(m_pFTFace,size_w, size_h);
printf("init_image\n");
init_image();
printf("init_image end\n");
for (int l=0;lglyph, FT_RENDER_MODE_NORMAL);
printf("result=%d\n", result);
FT_Bitmap bmp = m_pFTFace->glyph->bitmap;
int h = bmp.rows;
int w = bmp.width;
printf("h= %d w= %d \n",h,w);
for (i=0; i
注意:如果执行在QNX环境中要检查 freetype动态库是否是arm指令集的,否则无法识别(linux 是x86指令集)
欢