|
Totalhtml |
Utf8-ucs2ios |
Html_parse算法 |
Layoutsql |
Render_string瀏覽器 |
Init_texture緩存 |
Ft_load_glyphapp |
原始函數 |
2293佈局 |
1性能 |
26 |
708 |
1556 |
2 |
1403 |
|
|
|
|
|
|
|
|
上表用於記錄優化各步驟的消耗時間。
生成的文本紋理,文本是加州賓館的全歌詞。
原始版本整個紋理的生成耗時2300毫秒左右,能夠看到實際是慢得髮指。
究其緣由,是因爲實現iron引擎的時候未進行任何性能方面的考慮。
上述時間表的構成:
total : 總消耗時間
utf8-ucs2: 將utf8字符串轉換爲ucs2的時間
html_parse : 引擎須要支持必定程度的富文本,因此須要支持簡單的html解析.
render_string: 將字符串轉換爲紋理所消耗的總時間
Ft_load_glygh : 在整個過程當中, 調用Ft_load_glygh 消耗的總時間。
由以上分析可知,最消耗時間的調用是Ft_load_glygh。
尚不知道爲何Ft_load_glygh消耗的時間這麼大,原覺得是由於每次Ft_load_glygh會到文件中去查詢加載具體字符數據,而將程序改形成從內存加載字庫數據,仍然耗時巨大。
若是freetype自己沒法優化,那麼就須要從其餘方向來考慮這個問題。
首先從新闡述一下字體渲染的需求:
(1) 常規的字體屬性須要支持,如font_size
(2) 可以爲字體指定邊框顏色,邊框尺寸,填充顏色。
(3) 可以按單行,或者多行進行佈局。
(4) 可以必定程度支持富文本, 例如爲精靈設置text = <font style="color:#FF0000; ">某X</font>施展了<font style=" color:#FF0000;outline:1;outline_color:#00FFFF">憤怒一擊</font>
(5) 性能不須要達到多高,但至少作到切換場景,不能由於字體紋理生成而產生明顯卡頓(特別是有動態字體的時候,好比聊天).
綜上所屬,一次紋理生成的過程至少包含以下邏輯
--> 將utf8轉換爲ucs2
--> 解析富文本
--> 計算佈局
--> 生成紋理
這裏須要說明的是: 按上表所述, Layout 消耗掉708ms的緣由是,Layout須要獲取各字符的尺寸. 因此調用了FT_Load_Glyph, 該函數起碼就佔用了700ms。
以後在生成紋理過程當中,對FT_Load_Glyph再次進行調用,因此不慢都不行。
問題大體清楚後,考慮解決方案.
目前初步考慮的優化方案是:避免每次生成字符紋理,都去調用Ft_load_glyph加載字模數據,改成採用緩存機制.僅在第一次加載字體時,纔會調用Ft_load_glyph。以後的調用,會從緩存中讀取。 至因而不是要對緩存設置閥值,控制內存增加,這裏先暫時不考慮。
那麼接下來就須要肯定我到底應該緩存什麼。
緩存什麼呢,緩存什麼呢。
先把參考用的freetype庫,生成帶邊框字體的example代碼貼上。
http://www.freetype.org/freetype2/docs/tutorial/example2.cpp
這個範例代碼寫得醜陋,可是邏輯仍是很簡單的。
大致上的過程實際就是加載字模後,
獲取字模fill 部分的Span表,
獲取字模outline 部分的Span表,
將兩部分數據打到一個Bitmap中.
這個Span結構須要特別說明一下,頗有意思。
struct Span { Span() { } Span(int _x, int _y, int _width, int _coverage) : x(_x), y(_y), width(_width), coverage(_coverage) { } int x, y, width, coverage; };
他實際描述的是一條橫向掃描線,起點在(x, y), 寬度爲with, converage 存儲的是灰度數據(0-255)。你後面須要作的是拿到這個表之後,進行遍歷,將Span數據外加外部輸入的顏色值(邊框顏色 和 填充顏色) 轉換成最終的Bitmap。
因爲咱們的字體支持包邊,因此咱們可能會拿到兩個Span表,一個是用於渲染outline的,姑且叫他outlineSpans, 另外一個是用於渲染填充區的,姑且叫他fillSpans。
實際上,outlineSpan 和 fillSpan 所須要的Bitmap尺寸是不一樣的,一般是邊框須要的Bitmap略大於填充區所須要的Bitmap。
Freetype的設計,因爲是一次Ft_load_glyp得到outlineSpans 和 fillSpans, 因此能夠猜測,他們的座標系統是統一的,也就是說原點(0,0)點是重合的, 這也是爲何x, y 有時會出現負數的緣由。
這個span啥的有個好處,實際上有了這個span, 基本上就能夠脫離freetype的接口本身畫文字了。固然他應該還有更raw的東西,目前沒考慮要接觸。
爲了證明猜測,我首先作了一個測試。
打印出字符'g'的outlineSpans 和 fillSpans的數據.
其結果顯示以下:
[2.24 19:55:11] [INFO] there are 94 span in fill rect. [2.24 19:55:11] [INFO] [0] x:2 y:-5 width:1 gray8:38 [2.24 19:55:11] [INFO] [1] x:3 y:-5 width:1 gray8:163 [2.24 19:55:11] [INFO] [2] x:4 y:-5 width:1 gray8:232 [2.24 19:55:11] [INFO] [3] x:5 y:-5 width:1 gray8:251 [2.24 19:55:11] [INFO] [4] x:6 y:-5 width:1 gray8:232 [2.24 19:55:11] [INFO] [5] x:7 y:-5 width:1 gray8:179 [2.24 19:55:11] [INFO] [6] x:8 y:-5 width:1 gray8:74 [2.24 19:55:11] [INFO] [7] x:2 y:-4 width:1 gray8:245 [2.24 19:55:11] [INFO] [8] x:3 y:-4 width:6 gray8:255 [2.24 19:55:11] [INFO] [9] x:9 y:-4 width:1 gray8:134 [2.24 19:55:11] [INFO] [10] x:2 y:-3 width:1 gray8:225 [2.24 19:55:11] [INFO] [11] x:3 y:-3 width:1 gray8:103 [2.24 19:55:11] [INFO] [12] x:4 y:-3 width:1 gray8:25 [2.24 19:55:11] [INFO] [13] x:5 y:-3 width:1 gray8:6 [2.24 19:55:11] [INFO] [14] x:6 y:-3 width:1 gray8:42 [2.24 19:55:11] [INFO] [15] x:7 y:-3 width:1 gray8:158 [2.24 19:55:11] [INFO] [16] x:8 y:-3 width:2 gray8:255 [2.24 19:55:11] [INFO] [17] x:10 y:-3 width:1 gray8:63 [2.24 19:55:11] [INFO] [18] x:2 y:-2 width:1 gray8:12 [2.24 19:55:11] [INFO] [19] x:8 y:-2 width:1 gray8:168 [2.24 19:55:11] [INFO] [20] x:9 y:-2 width:1 gray8:255 [2.24 19:55:11] [INFO] [21] x:10 y:-2 width:1 gray8:167 [2.24 19:55:11] [INFO] [22] x:8 y:-1 width:1 gray8:59 [2.24 19:55:11] [INFO] [23] x:9 y:-1 width:1 gray8:255 [2.24 19:55:11] [INFO] [24] x:10 y:-1 width:1 gray8:223 [2.24 19:55:11] [INFO] [25] x:2 y:0 width:1 gray8:16 [2.24 19:55:11] [INFO] [26] x:3 y:0 width:1 gray8:147 [2.24 19:55:11] [INFO] [27] x:4 y:0 width:1 gray8:230 [2.24 19:55:11] [INFO] [28] x:5 y:0 width:1 gray8:247 [2.24 19:55:11] [INFO] [29] x:6 y:0 width:1 gray8:206 [2.24 19:55:11] [INFO] [30] x:7 y:0 width:1 gray8:80 [2.24 19:55:11] [INFO] [31] x:8 y:0 width:1 gray8:13 [2.24 19:55:11] [INFO] [32] x:9 y:0 width:1 gray8:255 [2.24 19:55:11] [INFO] [33] x:10 y:0 width:1 gray8:247 [2.24 19:55:11] [INFO] [34] x:1 y:1 width:1 gray8:8 [2.24 19:55:11] [INFO] [35] x:2 y:1 width:1 gray8:207 [2.24 19:55:11] [INFO] [36] x:3 y:1 width:4 gray8:255 [2.24 19:55:11] [INFO] [37] x:7 y:1 width:1 gray8:254 [2.24 19:55:11] [INFO] [38] x:8 y:1 width:1 gray8:88 [2.24 19:55:11] [INFO] [39] x:9 y:1 width:2 gray8:255 [2.24 19:55:11] [INFO] [40] x:11 y:1 width:0 gray8:248 [2.24 19:55:11] [INFO] [41] x:1 y:2 width:1 gray8:119 [2.24 19:55:11] [INFO] [42] x:2 y:2 width:1 gray8:255 [2.24 19:55:11] [INFO] [43] x:3 y:2 width:1 gray8:247 [2.24 19:55:11] [INFO] [44] x:4 y:2 width:1 gray8:108 [2.24 19:55:11] [INFO] [45] x:5 y:2 width:1 gray8:21 [2.24 19:55:11] [INFO] [46] x:6 y:2 width:1 gray8:24 [2.24 19:55:11] [INFO] [47] x:7 y:2 width:1 gray8:113 [2.24 19:55:11] [INFO] [48] x:8 y:2 width:1 gray8:227 [2.24 19:55:11] [INFO] [49] x:9 y:2 width:2 gray8:255 [2.24 19:55:11] [INFO] [50] x:1 y:3 width:1 gray8:205 [2.24 19:55:11] [INFO] [51] x:2 y:3 width:1 gray8:255 [2.24 19:55:11] [INFO] [52] x:3 y:3 width:1 gray8:120 [2.24 19:55:11] [INFO] [53] x:8 y:3 width:1 gray8:114 [2.24 19:55:11] [INFO] [54] x:9 y:3 width:2 gray8:255 [2.24 19:55:11] [INFO] [55] x:1 y:4 width:1 gray8:244 [2.24 19:55:11] [INFO] [56] x:2 y:4 width:1 gray8:255 [2.24 19:55:11] [INFO] [57] x:3 y:4 width:1 gray8:31 [2.24 19:55:11] [INFO] [58] x:8 y:4 width:1 gray8:25 [2.24 19:55:11] [INFO] [59] x:9 y:4 width:2 gray8:255 [2.24 19:55:11] [INFO] [60] x:1 y:5 width:1 gray8:250 [2.24 19:55:11] [INFO] [61] x:2 y:5 width:1 gray8:255 [2.24 19:55:11] [INFO] [62] x:3 y:5 width:1 gray8:9 [2.24 19:55:11] [INFO] [63] x:9 y:5 width:2 gray8:255 [2.24 19:55:11] [INFO] [64] x:1 y:6 width:1 gray8:228 [2.24 19:55:11] [INFO] [65] x:2 y:6 width:1 gray8:255 [2.24 19:55:11] [INFO] [66] x:3 y:6 width:1 gray8:41 [2.24 19:55:11] [INFO] [67] x:8 y:6 width:1 gray8:10 [2.24 19:55:11] [INFO] [68] x:9 y:6 width:2 gray8:255 [2.24 19:55:11] [INFO] [69] x:1 y:7 width:1 gray8:172 [2.24 19:55:11] [INFO] [70] x:2 y:7 width:1 gray8:255 [2.24 19:55:11] [INFO] [71] x:3 y:7 width:1 gray8:141 [2.24 19:55:11] [INFO] [72] x:8 y:7 width:1 gray8:83 [2.24 19:55:11] [INFO] [73] x:9 y:7 width:2 gray8:255 [2.24 19:55:11] [INFO] [74] x:1 y:8 width:1 gray8:68 [2.24 19:55:11] [INFO] [75] x:2 y:8 width:1 gray8:255 [2.24 19:55:11] [INFO] [76] x:3 y:8 width:1 gray8:252 [2.24 19:55:11] [INFO] [77] x:4 y:8 width:1 gray8:128 [2.24 19:55:11] [INFO] [78] x:5 y:8 width:1 gray8:32 [2.24 19:55:11] [INFO] [79] x:6 y:8 width:1 gray8:16 [2.24 19:55:11] [INFO] [80] x:7 y:8 width:1 gray8:91 [2.24 19:55:11] [INFO] [81] x:8 y:8 width:1 gray8:235 [2.24 19:55:11] [INFO] [82] x:9 y:8 width:2 gray8:255 [2.24 19:55:11] [INFO] [83] x:2 y:9 width:1 gray8:147 [2.24 19:55:11] [INFO] [84] x:3 y:9 width:5 gray8:255 [2.24 19:55:11] [INFO] [85] x:8 y:9 width:1 gray8:142 [2.24 19:55:11] [INFO] [86] x:9 y:9 width:2 gray8:255 [2.24 19:55:11] [INFO] [87] x:3 y:10 width:1 gray8:100 [2.24 19:55:11] [INFO] [88] x:4 y:10 width:1 gray8:205 [2.24 19:55:11] [INFO] [89] x:5 y:10 width:1 gray8:246 [2.24 19:55:11] [INFO] [90] x:6 y:10 width:1 gray8:231 [2.24 19:55:11] [INFO] [91] x:7 y:10 width:1 gray8:132 [2.24 19:55:11] [INFO] [92] x:8 y:10 width:1 gray8:3 [2.24 19:55:11] [INFO] [93] x:9 y:10 width:2 gray8:255 [2.24 19:55:11] [INFO] fill rect :(0.000000,-5.000000) - (11.000000,10.000000), w:12.000000, h:16.000000 [2.24 19:55:11] [INFO] --------------------------------------------------- [2.24 19:55:11] [INFO] there are 91 span in outline rect. [2.24 19:55:11] [INFO] [0] x:2 y:-6 width:1 gray8:70 [2.24 19:55:11] [INFO] [1] x:3 y:-6 width:1 gray8:178 [2.24 19:55:11] [INFO] [2] x:4 y:-6 width:1 gray8:235 [2.24 19:55:11] [INFO] [3] x:5 y:-6 width:1 gray8:250 [2.24 19:55:11] [INFO] [4] x:6 y:-6 width:1 gray8:233 [2.24 19:55:11] [INFO] [5] x:7 y:-6 width:1 gray8:185 [2.24 19:55:11] [INFO] [6] x:8 y:-6 width:1 gray8:97 [2.24 19:55:11] [INFO] [7] x:9 y:-6 width:1 gray8:5 [2.24 19:55:11] [INFO] [8] x:1 y:-5 width:1 gray8:139 [2.24 19:55:11] [INFO] [9] x:2 y:-5 width:7 gray8:255 [2.24 19:55:11] [INFO] [10] x:9 y:-5 width:1 gray8:207 [2.24 19:55:11] [INFO] [11] x:10 y:-5 width:1 gray8:28 [2.24 19:55:11] [INFO] [12] x:1 y:-4 width:1 gray8:252 [2.24 19:55:11] [INFO] [13] x:2 y:-4 width:8 gray8:255 [2.24 19:55:11] [INFO] [14] x:10 y:-4 width:1 gray8:202 [2.24 19:55:11] [INFO] [15] x:11 y:-4 width:1 gray8:4 [2.24 19:55:11] [INFO] [16] x:1 y:-3 width:10 gray8:255 [2.24 19:55:11] [INFO] [17] x:11 y:-3 width:1 gray8:86 [2.24 19:55:11] [INFO] [18] x:1 y:-2 width:1 gray8:225 [2.24 19:55:11] [INFO] [19] x:2 y:-2 width:1 gray8:246 [2.24 19:55:11] [INFO] [20] x:3 y:-2 width:1 gray8:128 [2.24 19:55:11] [INFO] [21] x:4 y:-2 width:1 gray8:30 [2.24 19:55:11] [INFO] [22] x:5 y:-2 width:1 gray8:11 [2.24 19:55:11] [INFO] [23] x:6 y:-2 width:1 gray8:66 [2.24 19:55:11] [INFO] [24] x:7 y:-2 width:1 gray8:221 [2.24 19:55:11] [INFO] [25] x:8 y:-2 width:3 gray8:255 [2.24 19:55:11] [INFO] [26] x:11 y:-2 width:1 gray8:173 [2.24 19:55:11] [INFO] [27] x:1 y:-1 width:1 gray8:19 [2.24 19:55:11] [INFO] [28] x:2 y:-1 width:1 gray8:70 [2.24 19:55:11] [INFO] [29] x:3 y:-1 width:1 gray8:171 [2.24 19:55:11] [INFO] [30] x:4 y:-1 width:1 gray8:234 [2.24 19:55:11] [INFO] [31] x:5 y:-1 width:1 gray8:247 [2.24 19:55:11] [INFO] [32] x:6 y:-1 width:1 gray8:215 [2.24 19:55:11] [INFO] [33] x:7 y:-1 width:1 gray8:197 [2.24 19:55:11] [INFO] [34] x:8 y:-1 width:3 gray8:255 [2.24 19:55:11] [INFO] [35] x:11 y:-1 width:1 gray8:225 [2.24 19:55:11] [INFO] [36] x:1 y:0 width:1 gray8:81 [2.24 19:55:11] [INFO] [37] x:2 y:0 width:1 gray8:250 [2.24 19:55:11] [INFO] [38] x:3 y:0 width:8 gray8:255 [2.24 19:55:11] [INFO] [39] x:11 y:0 width:1 gray8:246 [2.24 19:55:11] [INFO] [40] x:0 y:1 width:1 gray8:29 [2.24 19:55:11] [INFO] [41] x:1 y:1 width:1 gray8:243 [2.24 19:55:11] [INFO] [42] x:2 y:1 width:10 gray8:255 [2.24 19:55:11] [INFO] [43] x:12 y:1 width:0 gray8:248 [2.24 19:55:11] [INFO] [44] x:0 y:2 width:1 gray8:139 [2.24 19:55:11] [INFO] [45] x:1 y:2 width:11 gray8:255 [2.24 19:55:11] [INFO] [46] x:0 y:3 width:1 gray8:211 [2.24 19:55:11] [INFO] [47] x:1 y:3 width:3 gray8:255 [2.24 19:55:11] [INFO] [48] x:4 y:3 width:1 gray8:177 [2.24 19:55:11] [INFO] [49] x:5 y:3 width:1 gray8:22 [2.24 19:55:11] [INFO] [50] x:6 y:3 width:1 gray8:25 [2.24 19:55:11] [INFO] [51] x:7 y:3 width:1 gray8:175 [2.24 19:55:11] [INFO] [52] x:8 y:3 width:4 gray8:255 [2.24 19:55:11] [INFO] [53] x:0 y:4 width:1 gray8:245 [2.24 19:55:11] [INFO] [54] x:1 y:4 width:3 gray8:255 [2.24 19:55:11] [INFO] [55] x:4 y:4 width:1 gray8:34 [2.24 19:55:11] [INFO] [56] x:7 y:4 width:1 gray8:29 [2.24 19:55:11] [INFO] [57] x:8 y:4 width:4 gray8:255 [2.24 19:55:11] [INFO] [58] x:0 y:5 width:1 gray8:250 [2.24 19:55:11] [INFO] [59] x:1 y:5 width:3 gray8:255 [2.24 19:55:11] [INFO] [60] x:4 y:5 width:1 gray8:9 [2.24 19:55:11] [INFO] [61] x:8 y:5 width:4 gray8:255 [2.24 19:55:11] [INFO] [62] x:0 y:6 width:1 gray8:230 [2.24 19:55:11] [INFO] [63] x:1 y:6 width:3 gray8:255 [2.24 19:55:11] [INFO] [64] x:4 y:6 width:1 gray8:48 [2.24 19:55:11] [INFO] [65] x:7 y:6 width:1 gray8:9 [2.24 19:55:11] [INFO] [66] x:8 y:6 width:4 gray8:255 [2.24 19:55:11] [INFO] [67] x:0 y:7 width:1 gray8:181 [2.24 19:55:11] [INFO] [68] x:1 y:7 width:3 gray8:255 [2.24 19:55:11] [INFO] [69] x:4 y:7 width:1 gray8:191 [2.24 19:55:11] [INFO] [70] x:5 y:7 width:1 gray8:34 [2.24 19:55:11] [INFO] [71] x:6 y:7 width:1 gray8:17 [2.24 19:55:11] [INFO] [72] x:7 y:7 width:1 gray8:149 [2.24 19:55:11] [INFO] [73] x:8 y:7 width:4 gray8:255 [2.24 19:55:11] [INFO] [74] x:0 y:8 width:1 gray8:93 [2.24 19:55:11] [INFO] [75] x:1 y:8 width:11 gray8:255 [2.24 19:55:11] [INFO] [76] x:0 y:9 width:1 gray8:5 [2.24 19:55:11] [INFO] [77] x:1 y:9 width:1 gray8:207 [2.24 19:55:11] [INFO] [78] x:2 y:9 width:10 gray8:255 [2.24 19:55:11] [INFO] [79] x:1 y:10 width:1 gray8:32 [2.24 19:55:11] [INFO] [80] x:2 y:10 width:1 gray8:222 [2.24 19:55:11] [INFO] [81] x:3 y:10 width:9 gray8:255 [2.24 19:55:11] [INFO] [82] x:2 y:11 width:1 gray8:13 [2.24 19:55:11] [INFO] [83] x:3 y:11 width:1 gray8:126 [2.24 19:55:11] [INFO] [84] x:4 y:11 width:1 gray8:212 [2.24 19:55:11] [INFO] [85] x:5 y:11 width:1 gray8:246 [2.24 19:55:11] [INFO] [86] x:6 y:11 width:1 gray8:230 [2.24 19:55:11] [INFO] [87] x:7 y:11 width:1 gray8:159 [2.24 19:55:11] [INFO] [88] x:8 y:11 width:1 gray8:212 [2.24 19:55:11] [INFO] [89] x:9 y:11 width:2 gray8:255 [2.24 19:55:11] [INFO] [90] x:11 y:11 width:1 gray8:180 [2.24 19:55:11] [INFO] outline rect :(0.000000,-6.000000) - (12.000000,11.000000), w:13.000000, h:18.000000 [2.24 19:55:11] [INFO] overlapped rect :(0.000000,-6.000000) - (12.000000,11.000000), w:13.000000, h:18.000000由此能夠獲得:
填充區一共有94個span, 分佈在座標左上(0,-5) 右下(11,10) , 其矩形區域尺寸爲(12,16)
溝邊區一共有91個span, 分別在(0, -6) (12,11) 其矩形區域尺寸爲(13,18)
填充與溝邊的合成位圖最終須要尺寸(13, 18)
媽呀,一個g 有94 + 91 = 185個span 只是一個g.
可是鑑於計算機處理的速度比我快,因此先忽略繼續往下走起。
範例中,設置顏色到bitmap的代碼是:
charBitmap[(int)((imgHeight - 1 - (s->y - rect.ymin)) * imgWidth + s->x - rect.xmin + w)] = outLineColor;
因此Bitmap 與 fillRect的座標映射關係是:
y = (imgHeight - 1 - (s->y - rect.ymin)) * imgWidth
x = s->x - rect.xmin
其實是完成形以下圖的座標變換:
那麼實際上,能夠較爲輕鬆的分別保存outlineBitmap 和 fillBitmap , 用於存儲灰度.並記錄offsetX, offsetY 做爲座標參考系對齊的依據。
可是,後來回過頭來考慮這個問題,我幹嗎要分別存儲2個bitmap, 難道是像複用fillBitmap麼? 沒有啊,因此我不用分別存儲outlineBitmap和fillBitmap,僅須要存儲一個總的bitmap, 其大小是outline rect 和 fill rect 的bound rect.而後將兩個灰度存入就好了。實際上,因爲不少設備不支持2通道紋理,這裏我選擇採用RGBA8888的格式存儲, R通道存儲填充灰度, G通道存儲邊框灰度。浪費了2個通道實在屬於無奈之舉,但shader能夠直接拿到這個texture作渲染,也是件好事。
除了bitmap須要關注,還須要取得相關的char metrics 並緩存下來, 由於Layout邏輯須要用到這些位置相關的數據。具體須要的值參考下圖:
另須要注意的是,因爲對邊框的支持, 因此可能會對一些位置數據進行修正。
須要修正的數據包括:
bearingX, bearingY, width, height, advance.
若是不調整會這樣?那麼在字符有邊框的時候,後面的字符極可能把前面的蓋住。
怎麼調整呢,嗯,嗯。直接寫代碼調整,對。
因此整理下載,緩存的結構體大概是這樣的:
CharChache
bitmap : 紋理位圖(r,g有用處, b,a 沒用, 也許未來能夠寫點啥在裏面)
charMetrics
-bearingX
-bearingY
-advance
-width
-height
那麼緩存的Key怎麼考慮呢
Key包含一下部分:
char (uint16) 字符的unicode
font_size(uint8)
outline_size(unit8)
font_size 和 outline_size 採用uint8的緣由是, 這樣能夠用一個32位整形數來做爲緩存對象的鍵值,使用超過一個字節的狀況存儲font_size 和 outline_size 不作考慮,由於那種狀況太極端了。
剩下的工做就至關的輕鬆了.我能夠把大體須要的接口作個列表:
void renderString(string _str, TextStyle _defaultStyle, Texture2D _outTexture)
這個是整個文字渲染的進入點接口, 能夠按Factory模式處理,目前實現FreeTypeWithBitmapCache 實現, 未來還能夠搞個Device 實現,直接向操做系統要紋理,好比ios自己彷佛是支持包邊字體紋理生成的。
_defaultStyle 參數是文本的樣式參數,包含行間距,字符間距,是否換行,換行寬度,首行indent,字體顏色, 邊框顏色等信息.
總之,這個接口就是我把字符串給你,你按我要的效果給生成紋理。
void htmlParse(string _str, HtmlTagList _outHtmlTagList, string _outPureString)
該方法是解析富文本字符串(其實不是html,算是一種私有協議)。
輸出的HtmlTagList 是解析的結果,他不是一顆樹,實際只是一個鏈表而已(不想作那麼複雜, 由於我壓根就沒打算支持標籤的嵌套,簡單實現便可,沒必要搞成瀏覽器,若是策劃問爲啥不支持嵌套表格,文本輸入框, 嵌圖片,爲啥沒有播放音頻功能,直接耳屎扇飛)。
_outPureString 是純文本的內容,實際也能夠經過_outHtmlList 分析獲得,可是這個方法輸出來,做爲順便完成的工做.
ChatCacheEntry* queryCharCache(wchar _ch, uint8 _fontSize, _unit8 _outlineSize)
查詢緩存, 若是緩存中不存在, 則按以前分析的邏輯生成ChatCacheEntry。
這裏還有一個可優化的地方.就是能夠在ChatCacheEntry中存放一個命中次數,內部按該次數對ChatChacheEntry進行排序,在適當的時候刪除掉低命中次數的緩存條目,這樣能夠避免文字緩存把內存搞爆的狀況。
void layout(string _str, TextStyle _style, vector<CharMetrics> _metrics, vector<Point> _outPos)
該方法接受字符串,樣式,以及與字符串對應的每一個字符的metrcis信息,該方法對整個字符串進行佈局,並將位置輸出到_outPos中。
始終 _str.length = _metrics.size = _outPos.size
因此最核心的方法就是上述這些。
其中客戶端真正調用的就是 renderString, 其餘接口都是爲renderString服務,在renderString內部被調用的。
最後就是shader
shader很簡單,
傳入 fillColor, outlineColor
傳入 紋理 texture
那麼pixel顏色爲
outlineColor.rgb = outlineColor.rgb
outlineColor.a = texture.r
outColor.rgb = outlineColor.rgb + (fillColor.rgb - outlineColor.rgb) * texture.g
outColor.a = outlineColor.a + texture.g
而後,就基本上沒有而後了。
雲風有篇博文提到了一種方案,提出直接用一張大texture 做爲文字的緩存。有興趣能夠去看下,不過我基於如下緣由暫時不打算採用。
其一:這一版本個人目標僅是性能足夠而非性能最優。
其二:大紋理而且隨着新字符的生成和老字符的移除,一樣會涉及主存和顯存的換入換出,若是更新頻繁,該方案是否整體上有益不能肯定。
其三:咱們的系統font_size 的尺寸很差估量12pt 和 24pt有可能都有,涉及到裝箱算法,若是單頁滿了,還可能會作multi paging , 總的來講可能會增長大量複雜度。
東西一複雜了我就拉不出屎了。先看看吧,先看看。
因此目前仍是先簡單實現一版,看看性能如何再說。
該文檔。。那啥,主要是整理本身的思路寫下的日誌和開發參考,大量細節都省略。因此估計很難閱讀。也可能有超多的錯漏。
嗯,嗯,明天開始編碼。
如今先去看行屍走肉