基于QNX7.0 矢量字体FreeType中英文渲染

第一篇用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指令集)

你可能感兴趣的:(QNX,FREETYPE,qnx,linux,c++,嵌入式)