Freetype cross-compilation and simple use on embedded linux and change font background and color

The FreeType library is a completely free (open source), high-quality and portable font engine. It provides a unified interface to access a variety of font format files, including TrueTypeOpenType , Type1, CID,  CFF , Windows FON/FNT, X11 PCF etc. It supports the rendering of monochrome bitmaps and anti-aliasing bitmaps. The FreeType library is a highly modular library. Although it is developed using ANSI C, it adopts an object-oriented idea. Therefore, FreeType users can flexibly tailor it. For more information about freetype, please refer to the official website of freetype: https://www.freetype.org/ for more related information.

In the past, when using the Chinese font library in the single-chip microcomputer, it was inevitable to make fonts of various font sizes. And the effect of some production is not very good, and the font size needed needs to be prepared in advance. If you can use FreeType, these are not problems, and various changes can be made. However, freetype may occupy a large amount of resources, even if it has been cut, it may be more than 90k. It is not recommended in the resource-constrained MCU environment. It is better to take the font directly and play it on the resource-rich embedded linux board. .

Freetype source download address:

freetype official website

freetype2.8.1 download

Cross compilation steps:

tar zxvf freetype-2.8.1.tar.gz

cd freetype-2.8.1/

./configure CC=/home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-gcc --host=arm-linux --prefix=$PWD/INSTALL --with-zlib=no --with-png=n

make

make install

The entire compilation process was smooth and no errors were reported.

Next, test the simple use on embedded linux, and the image display uses fb0 on linux:

General steps:

int main()
{
	FT_Library	library;
	FT_Face		face;
	FT_Error	error;
	FT_UInt		charIdx;
	wchar_t		wch = 'a';
	char*		buffer;		// 用户申请的显示区域空间
	int			startX, startY;	// 字符图像开始装入的位置
 
	// 1. 初始化freetype2库
	error = FT_Init_FreeType(&library);
 
	// 2. 创建一个face
	error = FT_New_Face(library, "C:\\windows\\font\\SURSONG.TTF", 0, &face);
 
	// 3. 设置字体尺寸
	error = FT_Set_Char_Size(face, 16*64, 16*64, 96, 96);
 
	// 4. 获取字符图像索引
	charIdx = FT_Get_Char_Index(face, wch);
 
	// 5. 加载字符图像
	FT_Load_Glyph(face, charIdx, FT_LOAD_DEFAULT);
	if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
	{
		FT_Outline_Embolden(&(face->glyph->outline), 16);	// 加粗轮廓线
	}
 
	// 6. 获取字符位图
	if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP)
	{
		FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
	}
 
	// 7. 拷贝字符位图到用户的buffer中(用户私人函数)
	// 注意左边的计算方法
	ft2CopyBitmapToBuf(buffer, startX+face->glyph->bitmap_left,
		startY+face->size->metrics.ascender/64-face->glyph->bitmap_top,
		face->glyph->bitmap);
	startX += face->glyph->advance.x/64;
}

The following is a simple complete test case and makefile.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <signal.h>
#include <sys/resource.h>

#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <linux/fb.h>

#include <stdio.h>
#include <wchar.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
//#include FT_GLYPH_H

int fd_fb;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
int screen_size;
unsigned char *fbmem;
unsigned int line_width;
unsigned int pixel_width;

void lcd_put_pixel(int x, int y, unsigned int color)
{
	unsigned char *pen_8 = fbmem + y * line_width + x * pixel_width;
	unsigned short *pen_16;
	unsigned int *pen_32;
	unsigned int r,g,b;
	
	pen_16 = (unsigned short *)pen_8;
	pen_32 = (unsigned int *)pen_8;	

	switch(var.bits_per_pixel)
	{
		case 8:
		{
			*pen_8 = color;
			break;
		}
		case 16:
		{
			r = (color>>16) & 0x1f;
			g = (color>>8) & 0x3f;
			b = (color>>0) & 0x1f;
			color = (r<<11) | (g<<5) | (b);
			*pen_16 = color;		
			break;
		}
		case 32:
		{
			*pen_32 = color;
			break;
		}
		default:
		{
			printf("can't support %dbpp\r\n",var.bits_per_pixel);
			break;
		}
	}
}


void draw_bitmap(FT_Bitmap *bitmap,      FT_Int x,FT_Int y)
{
  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 >= var.xres || j >= var.yres)
        continue;

      //image[j][i] |= bitmap->buffer[q * bitmap->width + p];
      lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]);
    }
  }
}

int init_fb0(void){
	fd_fb = open("/dev/fb0",O_RDWR);
	if(fd_fb < 0)
	{
		printf("can't open /dev/fb0\r\n");
		return -1;
	}
	
	if(ioctl(fd_fb,FBIOGET_VSCREENINFO,&var))	
	{
		printf("can't get var\r\n");
		return -1;
	}	
	if(ioctl(fd_fb,FBIOGET_FSCREENINFO,&fix))
	{
		printf("can't get fix\r\n");
		return -1;	
	}	
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;	
	fbmem = (unsigned char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE , MAP_SHARED, fd_fb, 0);	
	if(fbmem == (unsigned char *)-1)
	{
		printf("can't mmap\r\n");
		return -1;
	}
	pixel_width = var.bits_per_pixel / 8;
	line_width = var.xres * pixel_width;

	memset(fbmem,0xffffff,screen_size);
	printf("init fb0 ok\n");
	printf("fb_var_info:%dx%d, %dbpp\n", var.xres, var.yres, var.bits_per_pixel);
	return 0;
}

int main(int argv, char **argc)
{
	FT_Library	  library;
	FT_Face 	  face;
	FT_Vector	  pen;	
	wchar_t 	 *new_str = L"我爱你中国1234567890";
	FT_GlyphSlot  slot;
	double        angle;  
	FT_Matrix     matrix;
	int err;
	int n;
	
	if(argv != 2)
	{
		printf("Usage : %s <font_file>\r\n",argc[0]);
		return -1;
	}
	
	err = init_fb0();
	if(err != 0){
		printf("init fb0 error\n"); 
		return -1;
	}

	err = FT_Init_FreeType(&library);			   	
	err = FT_New_Face(library, argc[1], 0, &face );	
	FT_Set_Pixel_Sizes(face,32,0);

	slot = face->glyph;


	pen.x = var.xres / 2;
	pen.x *= 64;
	pen.y = var.yres / 2;
	pen.y *= 64;
	
	angle = ( 0.0 / 360 ) * 3.14159 * 2;	 

	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 );

	for(n = 0;n < wcslen(new_str);n++)
	{
	    FT_Set_Transform(face,&matrix, &pen);
	    err = FT_Load_Char(face, new_str[n],FT_LOAD_RENDER);
		if(err)
		{
			printf("FT load char err\r\n");
			return -1;
		}		
		draw_bitmap(&slot->bitmap,slot->bitmap_left,var.yres - slot->bitmap_top);
		pen.x += 64*32;
		//pen.y += 64*32;
	}	

	return 0;
}

How to change the background of the font, clear an area and fill in the background color, or the background color as shown in the figure below.

How to change the color of the font, the key is here:

If the image displayed on your screen is mirrored and flipped, how to adjust it to display correctly, as follows, just adjust the x and y coordinates.


Attach a complete makefile:

########################################
#makefile
########################################
#****************************************************************************
# Cross complie path
#****************************************************************************
# CHAIN_ROOT=/home/yang/imax283/ctools/gcc-4.4.4-glibc-2.11.1-multilib-1.0/arm-fsl-linux-gnueabi/bin

# CROSS_COMPILE=$(CHAIN_ROOT)/arm-none-linux-gnueabi-

CHAIN_ROOT= /home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
CROSS_COMPILE=$(CHAIN_ROOT)/arm-linux-gnueabihf-

#CROSS_COMPILE = 

CC     := $(CROSS_COMPILE)gcc
CXX    := $(CROSS_COMPILE)g++
AS     := $(CROSS_COMPILE)as
AR     := $(CROSS_COMPILE)ar 
LD     := $(CROSS_COMPILE)ld
RANLIB := $(CROSS_COMPILE)ranlib
OBJDUMP:= $(CROSS_COMPILE)objdump
OBJCOPY:= $(CROSS_COMPILE)objcopy
STRIP  := $(CROSS_COMPILE)strip

#±àÒëÖ¸¶¨×ÓĿ¼
SUBDIRS := 

define make_subdir
 @ for subdir in $(SUBDIRS) ; do \
 ( cd $$subdir && make $1) \
 done;
endef

#output
BINARY  := test
OBJ_DIR := 

#CFLAGS=   -I./GUI_X -I./GUI/Core -I./GUI/WM -I./GUI/Widget
CFLAGS=  -I./freetype/include/freetype2


LDSCRIPT=  -lfreetype -lm
LDFLAGS= -L./freetype/lib 

# SRC_C=$(shell find . -name "*.c")
# OBJ_C=$(patsubst %.c, %.o, $(SRC_C))
# SRCS := $(SRC_C) $(SRC_C)
# OBJS := $(OBJ_C) 

SRC  = $(wildcard *.c)
DIR  = $(notdir $(SRC))
OBJS = $(patsubst %.c,$(OBJ_DIR)%.o,$(DIR))
#OBJS=  testdb.o
#CFLAGS=-std=c99
#@echo Building lib...
#$(call make_subdir)
.PHONY: clean lib
all:  prebuild  $(BINARY)

prebuild:
	@echo Building app...

$(BINARY) : $(OBJS)
	@echo Generating ...
	$(CC) -o $(BINARY) $(OBJS) $(LDFLAGS) $(LDSCRIPT) 
	@echo OK!

$(OBJ_DIR)%.o : %.c
	$(CC) -c $(CFLAGS) $< -o  $@
	
lib:
	@echo Building lib...
	$(call make_subdir)
	
clean:
	rm -f $(OBJ_DIR)*.o
	find . -name "*.[od]" |xargs rm
	@echo Removed!

 

Guess you like

Origin blog.csdn.net/qq8864/article/details/111058174