FreeType2的簡單使用:
FreeType2是一個簡單的跨平台的字體繪制引擎.目前支持TrueType Type1 Type2等字體格式.不過目前好象還不支持OpenType.
使用FreeType的應用很多.著名的FTGL就是使用FreeType的.能在OpenGL高效率的繪制矢量字體.
FTGL我沒用過.因為不想在沒了解該怎么用FreeType的情況下就去用FTGL.
經過一個晚上的閱讀代碼(我的代碼閱讀能力是很差的).終於知道了如何使用FreeType2了。不過是簡單的使用,還不知道如何設置Bold Itainly等屬性.主要是簡單的演示.以后准備做成一個完善的字體引擎.
下面簡單的介紹一下.
首先當然是包含頭文件了。頭文件要這樣包含:
#include [ft2build.h]
#include FT_FREETYPE_H
不知道為什么.反正就是要這么包含.
以下為FT2的初始化代碼.和繪制以及釋放的代碼>
注意這里繪制代碼接受的字符是Unicode.表示你這樣舊可以繪制了
FT2_Obj font;
font.Init("SimSun.ttf",32);
wchat_t pText[]=L"潘李亮是一頭野豬";
for(int n = 0 ; n< wcslen(pText);n++)
{
font.DrawAUnicode(pText[n];
}
font.Free();
//以下為FT2_Obj的代碼.
//主要參考了Nehe的Lesson 43
class FT2_Obj
{
FT_Library library;
int h ;
FT_Face face;
public:
void Init(const char * fname, unsigned int h);
void Free();
void DrawAUnicode(wchar_t ch)
};
void FT2_Obj::Init(const char * fname, unsigned int h)
{
this->h=h;
//初始化FreeType庫..
if (FT_Init_FreeType( &library ))
throw std::runtime_error("FT_Init_FreeType failed");
//加載一個字體,取默認的Face,一般為Regualer
if (FT_New_Face( library, fname, 0, &face ))
throw std::runtime_error("FT_New_Face failed (there is probably a problem with your font file)");
//大小要乘64.這是規定。照做就可以了。
FT_Set_Char_Size( face,h<< 6, h << 6, 96, 96);
FT_Matrix matrix; /* transformation matrix */
FT_UInt glyph_index;
FT_Vector pen;
//給它設置個旋轉矩陣
float angle = -20/180.* 3.14;
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 );
FT_Set_Transform( face, &matrix, &pen );
}.
/*
繪制操作.
*/
void FT2_Obj::DrawAUnicode(wchar_t ch)
{
if(FT_Load_Glyph( face, FT_Get_Char_Index( face, ch ), FT_LOAD_DEFAULT ))
throw std::runtime_error("FT_Load_Glyph failed");
//得到字模
FT_Glyph glyph;
if(FT_Get_Glyph( face->glyph, &glyph ))
throw std::runtime_error("FT_Get_Glyph failed");
//轉化成位圖
FT_Render_Glyph( face->glyph, FT_RENDER_MODE_NORMAL );
FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
//取道位圖數據
FT_Bitmap& bitmap=bitmap_glyph->bitmap;
//把位圖數據拷貝自己定義的數據區里.這樣舊可以畫到需要的東西上面了。
int width = bitmap.width;
int height = bitmap.rows;
usigned char* expanded_data = new usigned char[ 3 * width * height];
for(int j=0; j
< height ; j++)
{
for(int i=0; i < width; i++)
{
expanded_data[3*(i+(height-j-1)*width)]=
expanded_data[3*(i+(height-j-1)*width)+1] =
expanded_data[3*(i+(height-j-1)*width)+2] =
(i>=bitmap.width || j>=bitmap.rows) ?
0 : bitmap.buffer[i + bitmap.width*j];
}
}
}
}
void FT2_Obj::Free()
{
FT_Done_Face(face);
FT_Done_FreeType(library);
}
FreeType 2 Library
FAQ
(當前下載地址: http://sourceforge.net/project/showfiles.php?group_id=3157 版本 2.2.1 )
1、 FreeType2 是什么?
它是一個為各種應用程序提供通用的字體文件訪問的軟件包。尤其值得注意的以下特性:
l 提供統一的字體文件訪問接口。支持位圖和向量格式,包括 TrueType 、 OpenType 、 Typel 、 CID 、 CFF 、 Windows FON/FNT 、 X11 PCF 。
l 提供高效反走樣的基於 256 灰度級的位圖字形的生產。
l 模塊清晰,每種字體格式對於一個模塊。類庫的構建可以按照你需要支持的格式進行裁減以減小代碼尺寸。(最小的反走樣 FreeType 庫 <30Kb )
2、 FreeType2 能做什么?
FT2 已經易用於許多領域。例如:
l 圖形子系統和文本顯示庫
l 文本排版(布局、分頁、渲染)
l 字體識別和轉換工具
一般來說,該庫使得你能輕松的操縱字體文件。
3、 FreeType2 不能做什么?
FT2 並不包含大量豐富的高級特性,它只定位於出色的字體服務。也就是說下面的一些特性 FT2 類庫並不直接提供支持,然而你可以以它為基礎在上層進行實現:
l 任意表面的文字渲染
FT2 不是圖形庫所以它僅支持兩種象素格式的文本渲染: 1-bit 的單色位圖和 8-bit 的灰度象素。
如果你需要繪制其它格式的表面(例如 24-bit RGB 象素),你就得選擇其它你喜愛的圖形庫來做。
注意:為了渲染向量輪廓文本而不是放走樣的象素,應用程序可以提供自己的渲染回調以繪制或者直接組合反走樣文本到任意目標表面。
l 文本緩存
每次從字體中請求文本圖象, FT2 都要解析字體文件 / 流相關部分,通過它的字體格式進行解釋。對於某些特殊格式可能會很慢包括像 TrueType (或者 Type1 )這樣的向量字體。
注意:自從 2.0.1 版本開始 FT2 提供了一個 beta 版本的緩存子系統。當然你還是可以寫自己的緩存來滿足某種特殊需求。
l 文本布局
不支持文本布局操作。高級操作例如文本替換、字距調整、兩端調整等都不屬於字體服務本身職責。
4、 FreeType2 可移植性?
FT2 源碼可移植性很好由於以下原因:
l 代碼書寫遵循 ANSI C 標准
l 對於各種編譯警告我們都謹慎的避免。當前代碼在很多編譯器上編譯通過且沒有產生一條警告。
l 庫沒有使用任何硬編碼,是嵌入式系統開發的一個好的選擇。(例如它能夠直接在 ROM 中運行)
同時,我們盡最大努力確保庫的高效、緊湊和友好性。
5、 FreeType2 與 FreeType1.x 的區別?
最大的區別就是:
l FT1 僅支持 TrueType 格式,而 FT2 支持很多格式。
l FT2 APIs 比 FT1 APIs 簡單且強大。
l FT1 包括 OpenType 文本布局處理擴展,而 FT2 中則不包括而是移到獨立的工程里面――FreeType Layout 。( FT 布局目前無法獲取)
6、 FreeType2 是否兼容 FreeType 1.x ?
FreeType2 不直接兼容 FreeType 1.x ,但是我們可以提供一個二進制兼容層使得應用程序重鏈接到新版本。我們最終放棄了這種想法因為兩個版本可以共存在一個系統中。(沒有命名沖突)
FT2 API 比 1.x 簡單且強大,所以我們鼓勵你采用新版本,這樣可以使你減少很多不必要的工作。
7、 是否可以使用 FreeType2 編輯字體或者創建新字體?
答案是明確的:不可以。因為該庫設計明確,用較少代碼和內存讀取字體文件。所以我們不打算以任何方式在字體引擎里面支持編輯或者創建功能,因為這樣將導致整個代碼重寫。這並不意味我們將來不會引入字體編輯 / 創建功能庫,這取決於需求(或者說有多少人願意為此買單)。
在我們正式發布前不要在這方面進行揣測,對我們而言這個項目存在其他一些更重要的部分需要解決(像文字布局、文本緩存)。
編譯 & 配置
1、 如何編譯 FreeType2 庫?
可以采取多種編譯方式,在 freetype2/docs/build 下有詳細說明文檔。
這里介紹最簡單的基於 VS IDE 的編譯方式。 freetype\builds\win32\visualc 下有 VC6 和 VC7.1 的工作區文件。 VC6 打開后直接編譯,有幾個警告。
光看或許無法到感性認識,於是來兩個demo。網上比較少,我是參考nehe教程寫的。總體來說會簡單使用了,如果想深入了解怕是非看他的document不可。
簡單使用示例
FT_Library pFTLib = NULL;
FT_Face pFTFace = NULL;
FT_Error error = 0 ;
// Init FreeType Lib to manage memory
error = FT_Init_FreeType( & pFTLib);
if (error)
{
pFTLib = 0 ;
printf( " There is some error when Init Library
" );
return - 1 ;
}
// create font face from font file
error = FT_New_Face(pFTLib, " C:\\WINDOWS\\Fonts\\arial.ttf " , 0 , & pFTFace);
if ( ! error)
{
FT_Set_Char_Size(pFTFace, 16 << 6 , 16 << 6 , 300 , 300 );
FT_Glyph glyph;
// load glyph 'C'
FT_Load_Glyph(pFTFace, FT_Get_Char_Index(pFTFace, 67 ), FT_LOAD_DEFAULT);
error = FT_Get_Glyph(pFTFace -> glyph, & glyph);
if ( ! error)
{
// convert glyph to bitmap with 256 gray
FT_Glyph_To_Bitmap( & glyph, ft_render_mode_normal, 0 , 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
FT_Bitmap & bitmap = bitmap_glyph -> bitmap;
for ( int i = 0 ; i < bitmap.rows; ++ i)
{
for ( int j = 0 ; j < bitmap.width; ++ j)
{
// if it has gray>0 we set show it as 1, o otherwise
printf( " %d " , bitmap.buffer[i * bitmap.width + j] ? 1 : 0 );
}
printf( " \n " );
}
// free glyph
FT_Done_Glyph(glyph);
glyph = NULL;
}
// free face
FT_Done_Face(pFTFace);
pFTFace = NULL;
}
// free FreeType Lib
FT_Done_FreeType(pFTLib);
pFTLib = NULL;