FreeTypeライブラリは、完全に無料(オープンソース)の高品質でポータブルなフォントエンジンです。TrueType、 OpenType、Type1、CID、 CFF、Windows FON / FNT、など、さまざまなフォント形式のファイルにアクセスするための統一されたインターフェイスを提供します。X11PCFなど モノクロビットマップとアンチエイリアシングビットマップのレンダリングをサポートします。FreeTypeライブラリは高度にモジュール化されたライブラリです。ANSICを使用して開発されていますが、オブジェクト指向のアイデアを採用しているため、FreeTypeユーザーは柔軟に調整できます。freetypeの詳細については、freetypeの公式Webサイト(https://www.freetype.org/)を参照してください。
これまで、シングルチップマイクロコンピュータで中国語のフォントライブラリを使用する場合、さまざまなフォントサイズのフォントを作成することは避けられませんでした。また、一部の制作の効果はあまり良くなく、必要なフォントサイズを事前に準備しておく必要があります。FreeTypeを使用できる場合、これらは問題ではなく、さまざまな変更を加えることができます。ただし、freetypeは、カットされていても大量のリソースを占有する可能性があり、90kを超える可能性があります。リソースに制約のあるMCU環境ではお勧めしません。フォントを直接取得して、で再生することをお勧めします。リソースが豊富な組み込みLinuxボード。
Freetypeソースのダウンロードアドレス:
クロスコンパイルの手順:
tar zxvffreetype-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
作る
インストールする
コンパイルプロセス全体はスムーズで、エラーは報告されませんでした。
次に、組み込みLinuxでの簡単な使用法をテストし、画像表示はLinuxでfb0を使用します。
一般的な手順:
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;
}
以下は、単純な完全なテストケースとメイクファイルです。
#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;
}
次の図に示すように、フォントの背景を変更する方法、領域をクリアして背景色、または背景色を入力する方法。
フォントの色を変更する方法、キーはここにあります:
画面に表示されている画像がミラーリングされて反転している場合、正しく表示されるように調整するには、次のように、x座標とy座標を調整するだけです。
完全なメイクファイルを添付します。
########################################
#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!