天天看點

初探freetype字型庫

文字的顯示依賴于字型字庫,大緻的字型字庫分為點陣字庫、筆畫字庫和輪廓字庫。

點陣字庫:缺點比較明顯,縮放存在鋸齒,渲染旋轉等操作相對複雜,且效果不理想,先大多用在嵌入式行業(基本抛棄),常見格式有bdf,pcf,fnt,hbf,hzf等。

筆畫字型:不讨論。

輪廓字型:即矢量字型,利用字型輪廓及填充實作字型顯示,優勢明顯,渲染縮放較容易,但效率相對低些(相對于嵌入式)

簡單來說,freetype為字型字庫提供了一套解決方案,支援文字字型渲染等操作,主要還是其為C語言編寫,跨平台,為很多不支援矢量字型格式的嵌入式系統提供使用嵌入式字型的可能,且效率不低。

基本流程為:

加載字型字庫檔案-> 查找待顯示的文字索引-> 渲染操作(若反走樣處理)->處理為位圖資料->顯示

freetype官網http://freetype.sourceforge.net/index2.html

下面為在XP下顯示中文字型的執行個體,在官方下載下傳源碼,在..\freetype-2.4.2\builds\win32\vc2008\下打開工程,編譯為連結庫,建立VS2008的MFC程式,加載freetype242.lib庫。

簡單考慮,直接在MFC中的draw函數中畫出一個中文漢字。便于顯示,使用GDI+畫出漢字,是以首先對GDI+進行初始化等操作(GDI+的相關知識不讨論,不清楚可以留言或索取GDI+文檔,網上也可以搜搜)

在view.h中添加頭檔案聲明

1 2

#include <ft2build.h>

#include FT_FREETYPE_H

在view.h中添加成員變量

1 2 3

public

:

FT_Library library;

FT_Face face;

在view.cpp的構造函數中添加

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

// 初始化庫

bool

bError = FT_Init_FreeType(&library);

if

(!bError)

{

// 是否初始化成功

}

// 加載一個字庫檔案,這裡為黑體中文字庫

bError = FT_New_Face(library,

"C:\\WINDOWS\\Fonts\\simhei.ttf"

,

0, &face);

if

(bError == FT_Err_Unknown_File_Format)

{

// 表示可以打開和讀此檔案,但不支援此字型格式

}

else

if

(bError)

{

// 其他錯誤

}

// 設定為UNICODE,預設也是

FT_Select_Charmap(face,FT_ENCODING_UNICODE);

// 設定字型字元寬高和分辨率

bError = FT_Set_Char_Size(face, 0, 16*64, 300, 300);

在::OnDraw(CDC* pDC)中添加代碼

1 2 3 4 5 6 7 8 9 10 11 12 13 14

bool

bError;

wchar_t

wChar= _T(

'博'

);

// 查找‘好’的字元索引

FT_UInt glyph_index = FT_Get_Char_Index(face, wChar);

// 裝載字型圖像到字形槽

bError = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);

// 轉換為位圖資料

if

(face->glyph->format != FT_GLYPH_FORMAT_BITMAP)

{

// 第二個參數為渲染模式,這裡渲染為1位位圖(黑白位圖),若為FT_RENDER_MODE_NORMAL則渲染為256級灰階圖

bError = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);

}

這裡便可以通過face->glyph->bitmap獲得字型“博”的位圖資料了,bitmap中存放了如位圖的寬高、色深,調色闆等資訊,便可以通過GDI+繪制該圖像了 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

//建立位位圖

BITMAPINFO bmpinfo = {0};

// 初始化位圖結構體

bmpinfo.bmiHeader.biSize =

sizeof

(BITMAPINFOHEADER);

bmpinfo.bmiHeader.biWidth = face->glyph->bitmap.width;

bmpinfo.bmiHeader.biHeight = face->glyph->bitmap.rows;

bmpinfo.bmiHeader.biBitCount = 1;

// 與渲染模式有關,詳見FreeType API手冊的FT_Bitmap部分說明

bmpinfo.bmiHeader.biClrImportant = 0;

bmpinfo.bmiHeader.biClrUsed = 0;

bmpinfo.bmiHeader.biCompression = BI_RGB;

bmpinfo.bmiHeader.biPlanes = 1;

bmpinfo.bmiHeader.biSizeImage = 0;

// 建立記憶體位圖

unsigned

char

*pvBits =

new

unsigned

char

[10000];

HBITMAP

hBitmap =CreateDIBSection(NULL, &bmpinfo, DIB_RGB_COLORS, (

void

** )&pvBits, NULL, 0 );

int

iLineBytes = (bmpinfo.bmiHeader.biWidth + 7) / 8;

for

(

int

i = 0; i != bmpinfo.bmiHeader.biHeight; ++i)

{

memcpy

(pvBits + i * iLineBytes, face->glyph->bitmap.buffer + i * iLineBytes, iLineBytes);

}

Bitmap *pBitmap = Bitmap::FromHBITMAP(hBitmap, NULL);

Graphics graphic(pDC->m_hDC);

graphic.DrawImage(pBitmap, Point(20, 150));

這部分代碼不多解釋,隻是顯示位圖資料,這裡face->glyph->bitmap是沒有調色闆的1位位圖,源于使用FT_RENDER_MODE_MONO渲染模式

顯示預覽

初探freetype字型庫
1
1

這裡字型倒置與位圖坐标系有關,隻要簡單處理即可,不讨論。

簡單的描述一下freetype的使用流程,更詳細的函數說明及流程請參閱“freetype2開發入門”, 網上有此文檔,感興趣可以看看。

繼續閱讀