一、FreeType2簡介

1. 是一個免費、開源、可移植且高質量的字體引擎;

2. 支持多種字體格式文件,並提供了統一的訪問接口;

3. 支持單色位圖、反走樣位圖渲染,這使字體顯示質量達到Mac的水平;

4. 採用面向對象思想設計,用户可以靈活的根據需要裁剪。

 

二、FreeType2字形約定

2.1 基本概念

字形:

  字符映像叫做字形,單個字符能夠有多個不同的映像,即多個字形。多個字符也可以有一個字形。

  (可以理解為一個字形就是一種書寫風格)

字符圖:

  字體文件包含一個或多個表,叫做字符圖。用來將某種字符碼轉換成字形索引。一種字符編碼方式(如ASCII、Unicode、Big5)對應一張表。

 

2.2字形輪廓

點:

  字形文本的大小通常用點(point)表示。點是一種簡單的物理單位,數字印刷中,一點等於1/72英寸。

  設備的分辨率通常使用dpi(每英寸點數)表示的兩個數。

  點數大小和像素數的轉換公式:

  像素大數  = 點數*分辨率/72

輪廓線:

  字形輪廓的源格式是一組封閉的路徑,稱為輪廓線。每個輪廓線劃定字形的外部或內部區域,它們可以是線段或者Bezier曲線。

EM正方形:

  字體在創建字形輪廓時,字體創建者所使用的假象的正方形。他可以將此想象成一個畫字符的平面。它是用來將輪廓線縮放到指定文本尺寸的參考;它的尺寸越大,可以達到更大的字形分辨率。

  注意:字形可以自由的超出EM正方形。

位圖渲染:

  指從字形輪廓轉換成一個位圖的過程。

 

2.3 字形度量

基線、筆和佈局:

  基線是一個假象的線,用來在渲染文本時知道字形,它可以是水平或垂直的。而且,為了渲染文本,在基線上有一個虛擬的點,叫做筆位置或原點,它用來定位字形。每種佈局使用不同的規約來放置字形:

  對水平佈局,字形簡單地擱在基線上;

  對於垂直佈局,字形在基線上句中放置。

 

typescript怎麼把字符串轉成枚舉_#位圖

                      圖1. 水平佈局及其度量    

typescript怎麼把字符串轉成枚舉_基線_02

                            圖2.垂直佈局及其度量


 

重要的字體度量參數:

 上下高度(ascent):   從基線到放置輪廓點最高(上)的距離;

 下行高度(descent):從基線到放置輪廓點最低(下)的距離;

 左跨距(bearingX):  從當前筆位置到輪廓左邊界的水平位置;

 上跨距(bearingY):  從當前筆位置到輪廓上邊界的垂直位置;

 步進寬度(advanceX): 相鄰兩個筆位置的水平距離(字間距);

 字形寬度(width):     字形的水平長度;

 字形高度(height):   字形的垂直長度。

 

 

三、FreeType2基本數據結構及API

3.1 基本數據結構

 

typescript怎麼把字符串轉成枚舉_位圖_03

 

 

FT_Library(庫對象):

  FreeType庫句柄對象

  (不用關心其成員)


FT_Face(外觀對象):

  成員:

  num_faces: 字體文件所含外觀數

  face_index: 當前外觀索引值

  num_glyphs: 當前外觀所含字形文件數

  num_charmaps: 字符表數

  charmaps: 字符表數組

  charmap: 當前字符表

  glyph:  字形槽對象

  size:  字形尺寸


FT_Size(尺寸對象):

  成員:

    face:  指向父對象(FT_Face對象)

    metrics:  字形尺寸對象

 

FT_Size_Metrics(EM度量對象):

  成員:

  x_ppem: EM正方形水平像素數

  y_ppem: EM正方形垂直像素數

  ascender:  EM正方形上行距離

  descender: EM正方形下行距離

  height:  EM正方形高度

  max_advance: 最大步進寬度

 

FT_GlyphSlot(字形槽對象):

  成員:

    face:  指向父對象(FT_Face對象)

    metrics:  字形尺寸對象

    advance:  步進對象

    format:  字形槽格式

    bitmap:  字形位圖

    bitmap_top: 位圖上行距離

    bitmap_left: 位圖左行距離

    outline:  字形輪廓線


FT_Vector(步進向量):

  成員:

    x:  水平步進值

    y:  垂直步進值

 

FT_Bitmap(字形位圖對象):

  成員:

    row:  位圖行數(高度)

    width:  位圖寬度

    buffer:  位圖數據(默認8位灰度值)


FT_Glyph_Metrics(字形槽度量對象):

  成員:

    width:  字符映像寬度

    height:  字符映像高度

    horiBearingX: 左跨距(水平佈局)

    horiBearingY: 右跨距(水平佈局)

    horiAdvance: 水平步進

    vertBearingX: 左跨距(垂直佈局)

    vertBearingY: 右跨距(垂直佈局)

    vertAdvance: 垂直步進


3. 2 基本API

FT_ErrorFT_Init_FreeType(FT_Library *alibrary):

  函數功能:
  實例化一個FreeType庫對象,並返回給alibrary;

  返回值:

  若實例化成功則返回0。


FT_ErrorFT_Done_FreeType(FT_Library library):

  函數功能:
  銷燬FreeType庫對象library,包括其所有子對象;


FT_ErrorFT_New_Face(FT_Library library, const char*      

      filepathname, FT_Longface_index,FT_Face*aface ):

  函數功能:

  打開filepathname所指定的字體文件,加載第index個字體外觀,並返回給aface指定的地址。


FT_ErrorFT_Set_Char_Size(FT_Face face,

  FT_F26Dot6 char_width,  FT_F26Dot6 char_height,

  FT_UInthorz_resolution,FT_UIntvert_resolution ):

  函數功能:
  設置字體大小;

  輸入參數:

  char_width: 以1/64點為單位的字符寬度;

  char_height: 以1/64點為單位的字符高度;

  horz_resolution: 設備水平分辨率;

  vert_resolution: 設備垂直分辨率。

  注意:

  字符寬度或高度可設置為0,這意味着寬度或高度與另一個參數(高度或寬度)相同;

  水平或垂直分辨率設置為0時表示使用默認的72dpi。


FT_UIntFT_Get_Char_Index(FT_Face face,

  FT_ULong charcode):

  函數功能:
  在選定的字符表中,查找與給出的字符碼對應的字形索引。

  返回值:

  如果沒有字符表被選中,這個函數簡單返回字符碼;

  如果該字符表總沒有該字符碼對應的字形圖像,返回0。

  注意: 

  0對應特殊的字符圖像,通常會顯示一個框或空格;

  新建一個face時,默認是Unicode編碼的字符表。


FT_Error  FT_Load_Glyph( FT_Face face, FT_UInt

  glyph_index, FT_Int32load_flags):

  函數功能:

從face中裝載第index個字形圖像到字形槽中(face->glyph)。

  輸入參數:

  load_flags:裝載標誌,默認FT_LOAD_DEFAULT。此時優先裝載嵌入位圖,若無,則裝載該字形的縮放後的輪廓線。

  face->glyph->format描述了字形圖像的格式。若它的值是FT_GLYPH_FORMAT_OUTLINE,則可調用FT_Outline_Embolden加粗輪廓線;若它的值不是FT_GLYPH_FORMAT_BITMAP,則可通過FT_Render_Glyph把它轉換成位圖。


FT_Error FT_Outline_Embolden(FT_Outline* outline,FT_Pos strength):

  函數功能:

  將輪廓線加粗strength(26.6像素格式)。


FT_Error FT_Render_Glyph(FT_GlyphSlot slot,FT_Render_Moderender_mode):

  函數功能:
  將字形槽對象(slot)中的字形圖像轉換成字形位圖。

  輸入參數:

   render_mode:渲染模式位標誌集合,默認使用

  FT_RENDER_MODE_NORMAL渲染模式,表示渲染為一個高質量的抗鋸齒(256級灰度)位圖。



int main()
{
	FT_Library	library;
	FT_Face		face;
	FT_Error	error;
	FT_UInt		charIdx;
	wchar_t		wch = 'a';
	char*		buffer;		// 用户申請的顯示區域空間
	int			startX, startY;	// 字符圖像開始裝入的位置

	// 1. 初始化freetype2庫
	error = FT_Init_FreeType(&library);

	// 2. 創建一個face
	error = FT_New_Face(library, "C:\\windows\\font\\SURSONG.TTF", 0, &face);

	// 3. 設置字體尺寸
	error = FT_Set_Char_Size(face, 16*64, 16*64, 96, 96);

	// 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);
	}

	// 7. 拷貝字符位圖到用户的buffer中(用户私人函數)
	// 注意左邊的計算方法
	ft2CopyBitmapToBuf(buffer, startX+face->glyph->bitmap_left,
		startY+face->size->metrics.ascender/64-face->glyph->bitmap_top,
		face->glyph->bitmap);
	startX += face->glyph->advance.x/64;
}