在天龍八部,聊個齋這些國產的游戲中,都用到了freetype,并使用到freetype提供的描邊生成方法。
關于freetype怎么應用描邊,有個sample,鏈接如下
http://www.freetype.org/freetype2/docs/tutorial/example2.cpp
但是這個sample中的生成描邊的方式是低效率的,因為是間接生成的,在描繪函數里面得到span的信息,然后又遍歷了span再生成bitmap,最后再輸出。
經過我一個通宵研究,我想出了一個更為直接的描繪方式。
只要把這個sample中間的一部分替換成如下代碼就可以了:
FT_Outline *outline = &reinterpret_cast<FT_OutlineGlyph>(glyph)->outline;
FT_Glyph_Get_CBox(glyph,
FT_GLYPH_BBOX_GRIDFIT,
&bbox);
int width = (bbox.xMax - bbox.xMin)>>6;
int rows = (bbox.yMax - bbox.yMin)>>6;
bmp.buffer = new unsigned char[width * rows];
memset(bmp.buffer, 0, width * rows);
bmp.width = width;
bmp.rows = rows;
bmp.pitch = width;
bmp.pixel_mode = FT_PIXEL_MODE_GRAY;
bmp.num_grays = 256;
memset(¶ms, 0, sizeof (params));
params.source = outline;
params.target = &bmp;
params.flags = FT_RASTER_FLAG_AA;
FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
FT_Outline_Render(library, outline, ¶ms);
save_edge_buffer = bmp.buffer;
FT_BBox bbox_in;
FT_Glyph glyph_fg;
FT_Get_Glyph(size->face->glyph, &glyph_fg);
FT_Glyph_Get_CBox(glyph_fg,
FT_GLYPH_BBOX_GRIDFIT,
&bbox_in);
bmp.buffer = new unsigned char[width * rows];
memset(bmp.buffer, 0, width * rows);
bmp.width = width;
bmp.rows = rows;
bmp.pitch = width;
bmp.pixel_mode = FT_PIXEL_MODE_GRAY;
bmp.num_grays = 256;
outline = &reinterpret_cast<FT_OutlineGlyph>(glyph_fg)->outline;
memset(¶ms, 0, sizeof (params));
params.source = outline;
params.target = &bmp;
params.flags = FT_RASTER_FLAG_AA;
FT_Outline_Translate(outline,-bbox.xMin,-bbox.yMin);
FT_Outline_Render(library, outline, ¶ms);
save_buffer = bmp.buffer;
int inner_h = (bbox.yMax-bbox_in.yMax)>>6 ;
int w = (bbox_in.xMax-bbox_in.xMin)>>6 ;
int left = (bbox.xMin-bbox_in.xMin)>>6 ;
width=width;
height=rows;
pitch = (size->face->glyph->advance.x >> 6)+width-w ;
key_x=-(size->face->glyph->metrics.horiBearingX >> 6)-left ;
key_y=-_ascent+inner_h+((size->face->glyph->metrics.horiBearingY) >> 6);
代碼我做了刪減,稍微修改一下就可以替代里面用到的描繪方式。
得到bitmap之后,你想怎么畫就怎么畫。
其實上是得到兩張alpha圖,一張是描邊信息的alpha圖,一張是字體本身的alpha圖,剩下的事情,只是在畫出來的時候加上你需要的顏色就可以了。
關于這種方式的描邊,其實還有個bug,這個freetype的開發組還沒完全解決,這個bug如下
http://lists.nongnu.org/archive/html/freetype/2011-01/msg00022.html。
有人說魔獸世界也用到了freetype,但是我仔細觀察了魔獸的字體,發現魔獸最大也好像只支持兩個像素的描邊,而且魔獸的描邊方式也和freetype提供的這種使用stokers的描邊不一樣。