【原创】Android 移植 freetype 应用实例

本例程使用Bitmap模拟嵌入式 LCD 屏

1、移植 freetype 源码

这个捡现成,可以使用cyanogenmod源码,

https://github.com/julienr/libfreetype-android

https://github.com/CyanogenMod/android_external_freetype

我用的第一个人的,下载下来直接复制过去即可,第二个你可以选不同版本

 

2、封装freetype接口

参考项目:https://github.com/julienr/libfont

freetype 接口使用很简单,可以分3步

  • FT_Init_FreeType 初始化库,library 是全局变量,后面都要使用
if (FT_Init_FreeType(&library)) {
        LOGE("Failed to initialize freetype library");
        error = 1;
        return error;
    }
  • FT_New_Face 加载ttf字体
if (FT_New_Face(library, path, 0, &fontFace)) { //path ttf文件路径
        LOGE("Error loading font face %s", path);
        error = 2;
        return error;
    }
  • FT_Load_Char 加载字符
    wchar_t word = L"鼎";
    
    FT_Set_Pixel_Sizes(fontFace, width, 0); //width字体宽度,单位不是像素
    if (FT_Load_Char(fontFace, word, FT_LOAD_RENDER)) {
    	LOGE("Error loading char %c", word);
    	return;
    }

    FT_Set_Pixel_Sizes用于设置字体尺寸,一般只传 width 或者 height,让字体按比例缩放,不至于变形,
    word 是unicode编码,FT_LOAD_RENDER 模式直接渲染字体,渲染之后可以得到字体点阵,有了点阵就可以渲染了,

        FT_GlyphSlot glyph = fontFace->glyph;
    	
        const int gr = glyph->bitmap.rows; //点阵高度
        const int gw = glyph->bitmap.width; //点阵宽度
    
        x += glyph->bitmap_left; //屏幕上位置 加上字体偏移 不然排版有问题
        y -= glyph->bitmap_top;
    
        for (int h = 0; h < gr; h++) {
            for (int w = 0; w < gw; w++) {
                //Need to add the top margin (marginSize*texSize offset) and the left margin (marginSize)
    //            setPixel(texture, x + w, y + h, texWidth, glyph->bitmap.buffer[w + h * gw], color);
                uint8_t g = glyph->bitmap.buffer[w + h * gw];
                if (g > 0) { //g取值 0~256,0表示透明,其他值可以称作不透明度,可以直接作为32位色的alpha通道,无通道你需要做颜色混合运算
                    if(x + w >= texW || y + h >= texH)
                        continue;
    
                    texture[(y + h) * texW + x + w] = color; //color就是渲染颜色
                    //setPixel(x+w, y+h, g, color);
                }
            }
        }
    //这是一个 rgb565 颜色混合算法
    static void setPixel(int x, int y, uint8_t val, uint16_t color) {
        uint16_t src = texture[x + y * texW];
    
        register uint32_t d1; // 计算用的中间变量,声明为寄存器变量快些
        register uint16_t wa = src; // 源颜色
        register uint16_t wb = color; // 目的颜色
        register uint32_t alpha = 32 - (0.125 * val); // alpha值,16位色的色深为32级,
    
        d1 = (((((((wa << 16) | wa) & 0x7e0f81f) - (((wb << 16) | wb) & 0x7e0f81f)) * alpha) >> 5) +
              (((wb << 16) | wb) & 0x7e0f81f)) & 0x7e0f81f;
        wa = (d1 & 0xffff0000) >> 16; // g...r...b => ..g..
        wb = d1 & 0xffff; // g...r...b => r...b
        uint16_t dst = wa | wb; // rgb
    
        texture[x + y * texW] = dst;
    }

    如此就完成了最简单也最实用的使用方式,大工告成,

  • 附上 demo https://github.com/Yichou/android-freetype-demo

 

参考

rgb565 像素混合算法:https://www.cnblogs.com/yaozhongxiao/archive/2011/12/20/2294544.html

freetype2的FT_Load_Char使用实例:https://blog.csdn.net/dreamInTheWorld/article/details/57413335

你可能感兴趣的:(Android开发笔记)