freetype2 下载编译以及测试代码

源码: https://sourceforge.net/projects/freetype/files/freetype2

  1. 下载解压后,进入源码目录执行cmake-gui,界面中配置源码目录与编译目录,然后点击左下角Configure。
  2. 界面中FT_DISABLE_BROTLI、FT_DISABLE_BZIP2、FT_DISABLE_HARFBUZZ、FT_DISABLE_PNG、FT_DISABLE_ZLIB全部选中。
  3. 再次点击Configure,点击Generate。
  4. 进入配置的编译目录,执行make命令即可编译出静态库。
  5. 编辑CMakeLists.txt,找到"add_library(freetype"这一行,改为 "add_library(freetype SHARED",保存后重新执行cmake-gui,Configure、Gernerate,进入编译目录执行make命令后即可编译出动态库。

以下为测试代码。

#include <stdio.h>
#include <string.h>
#include <freetype/freetype.h>
#include <freetype/ftoutln.h>
#include <freetype/ftglyph.h>

int main(int argc, char* argv[])
{
    FT_Library  library;
    FT_Face     face;
    FT_Vector   pen;
    FT_Error    error;
    FT_UInt     charIdx;
    wchar_t     wch_data[] = L"pp happy, new year!!!\n天地转,光阴迫,一万年太久,只争朝夕!";//u'Z', U'Z'
    char*       char_buffer;        // 用户申请的显示区域空间
    int         startX, startY; // 字符图像开始装入的位置
    
    char *font_file = "simfang.ttf";
    int font_width = 32;//
    int font_height = 32;//!!!
    printf("sizeof(wchar_t) = %ld\n", sizeof(wchar_t));
    /*
    1.在windows平台下sizeof(wchar_t)为2,而在linux平台下sizeof(wchar_t)为4。
    2.在windows平台下宽字符(或字符串)字面量使用UTF-16编码,linux平台下使用UTF-32编码。
    */
    if(argc <= 1){
        
    }else if(argc <= 2){
        font_file = argv[1];
    }else if(argc <= 3){
        font_file = argv[1];
        font_width = atoi(argv[2]);
        font_height = atoi(argv[2]);
    }else if(argc <= 4){
        font_file = argv[1];
        font_width = atoi(argv[2]);
        font_height = atoi(argv[3]);
    }
    // 1. 初始化freetype2库
    error = FT_Init_FreeType(&library);
 
    // 2. 创建一个face
    error = FT_New_Face(library, font_file, 0, &face);

    // 3. 设置字体尺寸
#if 0
    /*
    字符宽度和高度以1/64点为单位表示。点是物理上的距离,一个点代表1/72英寸(2.54cm)
    分辨率以dpi(dots per inch)为单位表示,表示一个英寸有多少个像素
    字符物理大小为: char_width*64* (1/64) * (1/72)英寸
    字符的像素为: char_width*64* (1/64) * (1/72)*horz_resolution
    
    FT_Set_Char_Size( FT_Face     face,
                  FT_F26Dot6  char_width,  //字符宽度,单位为1/64点
                  FT_F26Dot6  char_height, //字符高度,单位为1/64点
                  FT_UInt     horz_resolution, //水平分辨率
                  FT_UInt     vert_resolution ); //垂直分辨率
    */
    error = FT_Set_Char_Size(face, 0, font_height*64, 72, 72);
#else
    error = FT_Set_Pixel_Sizes(face, font_width, font_height);
#endif
    //斜体在FreeType中可以通过矩阵变换来实现,只要把矩阵设置成一个切边矩阵就可以了
    // 倾斜度,越大就越斜
    float lean = 0.6f;
    FT_Matrix matrix;
    matrix.xx = 0x10000L;
    matrix.xy = lean * 0x10000L;
    matrix.yx = 0;
    matrix.yy = 0x10000L;
    //FT_Set_Transform(face, &matrix, 0);
    //pen.x = img_x*64;
    //pen.y = (img_y)*64;//
    pen.x = 0;
    pen.y = 0;
    FT_Set_Transform(face, &matrix, &pen);
    //error = FT_Select_Charmap(fontFace, FT_ENCODING_UNICODE);
    //error = FT_Select_Charmap(face, FT_ENCODING_BIG5 ); /* big5编码 , 默认为UNICODE */
    //error = FT_Set_Transform( face, &matrix, &pen );//旋转
    
    char bitmap_file[256];
    int img_width = 320;
    int img_height = 240;
    int img_x = 0;
    int img_y = 0;
    char *bitmap_buffer = malloc(img_width*img_height);
    memset(bitmap_file, 0, sizeof(bitmap_file));
    sprintf(bitmap_file, "bitmap_%d_%d_gray.yuv", img_width, img_height);
    FILE *pBitMapFd = fopen(bitmap_file, "wb");
    
    for(int index = 0; index < sizeof(wch_data)/sizeof(wch_data[0]); index++){
        wchar_t wch = wch_data[index];
        if(wch == 0){
            break;
        }else if(wch == U'\r'){
            img_x = 0;
            continue;
        }else if(wch == U'\n'){
            img_x = 0;
            img_y += font_height;
            continue;
        }
        
#if 0
        // 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);
        }
#else
        error = FT_Load_Char(face, wch, FT_LOAD_RENDER);//FT_LOAD_MONOCHROME 8pixel per byte
#endif
        /*
        FT_Bitmap(字形位图对象):
            rows:  位图行数(高度)
            width:  位图宽度
            buffer:  位图数据(默认8位灰度值)
        */
        
        FT_Glyph  glyph;
        FT_BBox   acbox;
        FT_GlyphSlot  slot     = face->glyph;
        error = FT_Get_Glyph(face->glyph, &glyph);
        FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &acbox);
        int lcd_x_min = acbox.xMin;
        int lcd_x_max = acbox.xMax;
        int lcd_y_min = font_height - acbox.yMax;
        int lcd_y_max = font_height - acbox.yMin;
        lcd_y_min -= (font_height/8);
        lcd_y_max -= (font_height/8);
        printf("0x%x: xMin=%ld, xMax=%ld, yMin=%ld, yMax=%ld, V-yMin = %ld, v-yMax = %ld, advance x = %ld, advance y = %ld, w = %d, h = %d, left = %d, top = %d\n", \
            wch, acbox.xMin, acbox.xMax, acbox.yMin, acbox.yMax, font_height - acbox.yMax, font_height - acbox.yMin, slot->advance.x, slot->advance.y, \
            slot->bitmap.width, slot->bitmap.rows, slot->bitmap_left, slot->bitmap_top);
        
        int wch_h_size = (slot->advance.x/64)>=slot->bitmap.width ? (slot->advance.x/64) : slot->bitmap.width;
        
        if(img_x + wch_h_size >= img_width){
            img_x = 0;
            img_y += font_height;
        }
        
        if(img_y + font_height >= img_height){
            img_y = 0;
            break;//
        }
        for(int j = 0; j < slot->bitmap.rows; j++){
            for(int i = 0; i < slot->bitmap.width; i++){
                if(slot->bitmap.buffer[j*slot->bitmap.width + i]){
#if 1//
                    //if(lcd_x_min < 0){
                    if(img_x + lcd_x_min + i < 0){
                        bitmap_buffer[img_width*img_y + img_x + (j+lcd_y_min)*img_width + i] = slot->bitmap.buffer[j*slot->bitmap.width + i];
                    }else
#endif
                    {
                        bitmap_buffer[img_width*img_y + img_x + (j+lcd_y_min)*img_width + i + lcd_x_min] = slot->bitmap.buffer[j*slot->bitmap.width + i];
                    }
                }
            }
        }
        img_x += slot->advance.x/64;
        //img_x += wch_h_size;
    }
    
    fwrite(bitmap_buffer, 1, img_width*img_height, pBitMapFd);
    fclose(pBitMapFd);
    
    FT_Done_Face(face);
    FT_Done_FreeType(library);
    printf("-------------- end ----------------\n");
        
}

预览生成的yuv数据

ffplay -i bitmap_320_240_gray.yuv -pixel_format gray  -video_size 320*240 
ffplay显示结果.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容