李 凱 饒?zhí)熨F 胡士杰 曾 升
1(株洲中車時(shí)代電氣股份有限公司軌道交通技術(shù)中心 湖南 株洲 412001)2(株洲中車時(shí)代電氣股份有限公司數(shù)據(jù)與智能技術(shù)中心 湖南 株洲 412001)
目前基于Linux系統(tǒng)的FLTK工具廣泛應(yīng)用于國內(nèi)外機(jī)車、地鐵等車輛顯示器UI軟件開發(fā)。FLTK為Linux系統(tǒng)下輕量級(jí)的圖形數(shù)據(jù)開發(fā)庫[1],開發(fā)的UI軟件具有占用系統(tǒng)資源少、協(xié)議兼容性強(qiáng)、運(yùn)行穩(wěn)定可靠、可配置等優(yōu)點(diǎn)[2],所以目前在軌道交通領(lǐng)域使用廣泛。跟隨智能化的發(fā)展方向,顯示器不僅要能實(shí)時(shí)顯示車輛的基本信息,還要實(shí)時(shí)播報(bào)和記錄車輛發(fā)生的故障情況,并且能向司機(jī)和維護(hù)人員給出每條故障可能發(fā)生的原因和處理措施。通常這類信息描述的文字很多,而每個(gè)界面中FLTK控件寬度有限,且顯示的文字不能自動(dòng)換行,再加上不等寬字體每個(gè)字符所占的像素大小不同[3],普通的分行方法會(huì)導(dǎo)致每行文字顯示參差不齊,影響界面美觀。較好的折行顯示算法尤為重要,因此為了解決FLTK控件不能自動(dòng)分行顯示文字的問題,并針對(duì)不等寬字體,提出了一種兼容多種編碼方式的自適應(yīng)分行顯示方法。
將文本文件中的每條信息按固定字節(jié)數(shù)進(jìn)行分割,然后分別在各控件中顯示,是固定字符數(shù)分行顯示的主要處理思路,如圖1所示。根據(jù)FLTK控件寬度,通過測試,可以找到分行的固定字符數(shù)值,可以保證固定寬度的控件能完整顯示文字,但對(duì)于不等寬字體,比如漢字、數(shù)字、標(biāo)點(diǎn)符號(hào)、英文等所占像素寬度并不相同,會(huì)使得相同字符數(shù)的不同文字顯示得參差不齊,嚴(yán)重影響了界面的美觀。
圖1 固定字符數(shù)分行處理方法
該方法的處理思路是在文本文件中的每條信息適當(dāng)位置上插入特定的字符,然后根據(jù)這些標(biāo)簽進(jìn)行分割,最后分別在各控件中進(jìn)行顯示,如圖2所示。根據(jù)FLTK控件寬度,通過多次測試,在要顯示的文本串中插入特殊的分行符來進(jìn)行差別化分行處理可以解決每行顯示參差不齊的問題,但是對(duì)于上千條的信息,一一測試并在每條信息中插入分行符,工作量極大,效率極低,會(huì)嚴(yán)重影響項(xiàng)目交付進(jìn)度。
圖2 插入標(biāo)簽分行處理方法
文獻(xiàn)[3]給出了針對(duì)不等寬字體分行處理的基本思路,但是只針對(duì)GB2312編碼、ASCII編碼字體的分行處理方法,分行處的英文單詞未做分行處理,而是直接將整個(gè)單詞另起一行,這樣可能會(huì)導(dǎo)致每行顯示參差不齊,影響顯示效果。文獻(xiàn)[4]在Android平臺(tái)中設(shè)計(jì)了一種擴(kuò)展的文本顯示控件,可以實(shí)現(xiàn)對(duì)不等寬字體的分行處理,同樣在兼容文字的多編碼方式、英文分行處理上并未作相關(guān)處理。
該方法是針對(duì)單個(gè)FLTK控件無法顯示大量文字(包含中英文、符號(hào)等)而作出的一種處理方法。是將預(yù)顯示的文字串分割成多個(gè)文字片段,再用多個(gè)相同的控件來顯示,從而達(dá)到分行顯示的效果。整體的文字串分割思路如圖3所示。
圖3 字符串分割再分行的處理思路
目前常用的字體,包括點(diǎn)陣字體和矢量字體,基本都是不等寬字體。不等寬字體的漢字、字母、標(biāo)點(diǎn)符號(hào)等在控件中顯示所占的像素寬度并不相等,使得相同寬度的控件能顯示的字符總數(shù)不同,所以分配給每個(gè)控件顯示的字符數(shù)需要靈活調(diào)整,即圖3中每個(gè)虛線框所分割字符串并不相同。
2.2.1 基于GB2312編碼的處理機(jī)制
基于常用的GB2312編碼的分割處理機(jī)制,根據(jù)分割處字符所屬文字類型的不同,可分為兩種情況,如圖4所示。如果分割處是漢字,根據(jù)GB2312編碼規(guī)則,每個(gè)漢字占用2個(gè)字節(jié)[5],則需回跳2個(gè)字節(jié)字后截?cái)嘧址?;如果分割處是字母、?shù)字或者普通符號(hào),根據(jù)GB2312編碼規(guī)則,只占用1個(gè)字節(jié)[5],只需回跳1個(gè)字節(jié)字后截?cái)嘧址?/p>
圖4 基于GB2312編碼的分割處理機(jī)制
2.2.2 基于UTF-8編碼的處理機(jī)制
UTF-8編碼是變長字節(jié)編碼[6-7],漢字、字母、數(shù)字、符號(hào)等所占字節(jié)數(shù)不相同,不正確的編碼解析易導(dǎo)致亂碼顯示[8-9],使得字符串分割處的情況變得相對(duì)復(fù)雜,如圖5所示。
圖5 基于UTF-8編碼的分割處理機(jī)制
1) 當(dāng)分割處是漢字時(shí),獲取的該段字符數(shù)減n(n為分割處漢字所占字節(jié)數(shù),1≤n≤6);
2) 當(dāng)分割處是字母/字符時(shí),分兩種情況:(1) 一般情況下獲取的該段字符數(shù)為能正常顯示的字符數(shù)減1。(2) 對(duì)于英語單詞的截?cái)鄵Q行,需考慮在行末添加短橫線,這樣獲取的該段字符數(shù)需減2;對(duì)于該行最后一個(gè)字符為單詞首字母的情況,需將該字母移劃分到下一個(gè)字段中,同時(shí)添加空格字符,這樣獲取的該段字符數(shù)也需減2。
具體實(shí)現(xiàn)的流程圖如圖6所示。
圖6 基于FLTK的字符分割處理流程
字符分割處理流程如下:
1) 判斷預(yù)分割處理的字符串str[]是否為空,若為空,則退出,否則向下執(zhí)行。
2) 通過FLTK函數(shù)庫中的函數(shù),分別測量出顯示字符的控件寬度widge_width、字體類型font_index、字體大小font_size參數(shù)。
3) 通過FLTK函數(shù)庫中的函數(shù),以及步驟2測量的字體類型font_index、字體大小font_size參數(shù)來標(biāo)定測量屬性,這樣后續(xù)測量的字符串所占像素寬度才是正確的。
4) 設(shè)字符串str[]的下標(biāo)為i,分段數(shù)為j,已拷貝至blocks[j][256]的字符總數(shù)為len。如果i<1 024,根據(jù)i、len值將下標(biāo)為len至i-len+1(不包含)間字符拷貝至用于臨時(shí)存取本次截取的片段的數(shù)組dest[]中。
5) 使用TLFK函數(shù)庫中函數(shù)測量當(dāng)前dest[]中所有字符所占像素值wi。
6) 比較wi與widge_width,若wi 7) 如果漢字標(biāo)志chinese_flag大于1,i=i-chinese_flag_old,同時(shí)將dest[]中前strlen(dest)- chinese_flag_old-1個(gè)字符拷貝至blocks[j][256]中,len=len+strlen(char_blocks[j]),j=j+1,返回至步驟4,否則,執(zhí)行步驟8。 8) 如果漢字標(biāo)志chinese_flag小于等于1,i=i-1,如果同時(shí)dest[i-len-1]為字母,dest[i-len]不為“,”、“.”或空格,則dest[i-len]變換為“-”,len=len-1,即解決單詞分割后,前半部分結(jié)尾處添加短橫線的問題。如果漢字標(biāo)志chinese_flag=0,同時(shí)dest[i-len]為字母,dest[i-len-1]為“,” 或“.”或空格,則dest[i-len]變換為空格,len=len-1,即解決分割的單詞前半部分僅有一個(gè)字母的顯示的問題。將dest[]中前strlen(dest)-1個(gè)字符拷貝至blocks[j][ 256]中,j=j+1,len=len+strlen(char_blocks[j]),返回至步驟4。 以上介紹了該方法的整體思路、處理機(jī)制、具體實(shí)現(xiàn)流程。 為了證明本文提出的文本分行顯示算法在FLTK控件上實(shí)現(xiàn)的優(yōu)異性,與目前應(yīng)用較多的分行方法在文本編輯格式和顯示效果上進(jìn)行了比較。 固定字符數(shù)分行方法對(duì)文本格式舉例如下(左右兩項(xiàng)內(nèi)容各固定分四行): 1001:1.X出現(xiàn)故障原因1;:1.請(qǐng)檢查X1;. 1001:2.X出現(xiàn)故障原因2;:2.請(qǐng)檢查X2;. 1001:3.X出現(xiàn)故障原因3;:3.請(qǐng)檢查X3;. 1001:4.X出現(xiàn)故障原因4。:4.請(qǐng)檢查X4。. 該方法需預(yù)先確定分行數(shù)目以及固定分行的字節(jié)數(shù),文本編輯時(shí)需嚴(yán)格確保分行字符對(duì)齊。使用該方法的顯示效果如圖7所示,從圖中可明顯看到相同字符數(shù)分行有時(shí)會(huì)因?yàn)椴坏葘捵煮w的差異導(dǎo)致行末參差不齊,影響美觀。 圖7 固定字符數(shù)分行顯示方法的顯示效果 文本中手動(dòng)插入標(biāo)簽分行方法的文本編輯格式如下: 1001:1.X出現(xiàn)故障原因1;:2.X出現(xiàn)故障原因2;:3.X出現(xiàn)故障原因3;:4.X出現(xiàn)故障原因4。: 1001:X故障導(dǎo)致的結(jié)果1;:X故障導(dǎo)致的結(jié)果2。: 1001:司機(jī)對(duì)應(yīng)的處理措施。: 1001:維護(hù)人員對(duì)應(yīng)的處理措施。: 該方法需根據(jù)控件實(shí)際顯示情況調(diào)整分行符標(biāo)簽位置,這樣使得每條信息文本分行位置并不固定。該方法分行顯示效果較好,但對(duì)文本編輯的工作量太大,如圖8所示。 圖8 文本中手動(dòng)插入標(biāo)簽分行方法的顯示效果 本文提出的新方法對(duì)文本編輯格式要求如下: 1001:1.X出現(xiàn)故障原因1;2.X出現(xiàn)故障原因2;3.X出現(xiàn)故障原因3;4.X出現(xiàn)故障原因4。: 1001:處理措施1;處理措施2;處理措施3。: 從文本格式可以看出,只需要將每條文本信息單獨(dú)在一行列出,無需添加任何分行標(biāo)簽或其他處理,明顯降低了對(duì)文本格式的要求。量寬式的文本分行顯示方法不僅大大減少了文本編輯工作量,而且在顯示效果上也保持了較高的質(zhì)量,行末文字參差不齊的現(xiàn)象基本解決,同時(shí)也具備對(duì)英文單詞換行處理的能力,如圖9所示。同時(shí),該方法兼容多種文本編碼格式,在減少亂碼顯示方面,也具備較強(qiáng)的能力。 圖9 量寬式分行方法的顯示效果 通過對(duì)比分析,本文提出的新的量寬式分行顯示方法,在有效降低文本編輯工作量和提高文本分行顯示效果上,均得到了提高。 目前,該方法已在出口埃塞俄比亞電力機(jī)車等項(xiàng)目上進(jìn)行了應(yīng)用。 根據(jù)控件的像素寬度、字體類型、字體大小屬性來對(duì)預(yù)顯示的字符串進(jìn)行自適應(yīng)分割處理再分行顯示的方法,不僅可以充分利用控件寬度大小來進(jìn)行文字顯示,而且不會(huì)出現(xiàn)文字的漏顯問題,保證了文字顯示的正確性、美觀性。因?yàn)樵摲椒ㄖ恍枰@取控件名稱,就會(huì)自動(dòng)獲取其基本屬性,并對(duì)需要顯示的文字串進(jìn)行自適應(yīng)分割處理,使得對(duì)文本格式的要求降低,大大減少了對(duì)文本的處理時(shí)間;該方法還解決了每行顯示參差不齊的問題,較好地保證了文本顯示的美觀性。該方法在對(duì)待編號(hào)分行處理上的能力還有待提高,這也是今后需要進(jìn)一步研究的方向。3 實(shí)現(xiàn)效果與應(yīng)用法
4 結(jié) 語