輕量級的lvgl的字體轉(zhuǎn)換工具lv_font_conv
????繼lv_img_conv圖片轉(zhuǎn)換工具之后,我做了lvgl另一個常用的輕量級工具——字體轉(zhuǎn)換工具lv_font_conv。仿照先前 lv_img_conv的思路,用C++和FreeType寫了一個輕量版的lvgl字體轉(zhuǎn)換工具, 目前也主要是在Linux下命令行的方式使用,因為先前在windows下用的是里飛大佬的 LvglFontTool,因此很多地方都是模仿著寫的,不過我也加入了一個新的功能。
項目鏈接:https://gitee.com/Jumping99/lv_font_conv
????工具的制作原理就是通過freetype讀取ttf字體文件,然后生成對應(yīng)文字的字模信息和位圖,然后根據(jù)需要寫入C文件或者bin文件。這個工具還是做的比較久的,主要是花了很多時間搞清楚lvgl對字體的渲染和一些參數(shù)的意義,當然少不了的還是找bug修bug了。
????工具目前支持1bpp、2bpp、4bpp、8bpp的字體轉(zhuǎn)換,轉(zhuǎn)換的字體主要是從.txt文本文件獲取,把需要轉(zhuǎn)換的文字寫入到.txt文本文件就可以使用這個工具轉(zhuǎn)換了,當然工具有提供參數(shù)可以便捷轉(zhuǎn)換,比如添加ascii字符,添加常用的漢字或者所有的漢字,只需要指定一個參數(shù)即可,不需要特地創(chuàng)建txt文件再寫入轉(zhuǎn)換。在字體的存儲方面也支持內(nèi)部c數(shù)組字體和外部bin文件字體的方式,而且外部字體還分為2個等級,這便是我開頭所說的新功能,具體見文件末尾吧。
????不過目前有個小bug,轉(zhuǎn)換為1bpp的字體時,有部分字符會錯亂,我猜想可能跟lvgl內(nèi)部對1bpp的處理和繪制有關(guān),由于常用的都是2bpp或者4bpp的抗鋸齒字體,因此后續(xù)也沒有花太多時間去研究了,有興趣的朋友可以自己嘗試查找和修復一下。
先上個效果圖:

????最后說一下上文所說的外部字體等級, 其實就是當使用外部字體時,c文件保存的字體信息等級,對于level 0的外部字體,c文件除了函數(shù)和lvgl的字體變量外,其余均存儲到bin文件中;而對于level 1的外部字體,c文件存儲了字體的信息,包括每個字模的高度、寬度,以及這個字體所有文字的unicode表,為什么要這樣分呢,原因在下面。
????根據(jù)里飛大佬的LvglFontTool生成的外部字體bin文件, 讀一個字體的位圖需要進行3次文件IO、一次字體的信息需要進行2次文件IO,而且沒有緩存,如果有很多字體需要顯示,會對幀率產(chǎn)生比較大的影響。 而我將內(nèi)部字體和外部字體進行結(jié)合,即除了字體位圖保存到bin文件外,其余均與內(nèi)部字體無異,這樣不僅只需要在讀取字體位圖時進行1次文件IO, 而且還具備了緩存的功能,如果當前要顯示的字體與上一個字體相同,則可以不需要重新讀取字體位圖數(shù)據(jù)。
????不過這樣做會增加編譯后的程序固件大小,每一個文字需要占用14byte的空間保存文字信息,當然如果字體的位圖特別大,這點空間也不算什么了。 但如果你設(shè)備的flash空間實在吃緊,也可以使用level 0級別,將除了lvgl的字體描述和相關(guān)函數(shù)保存在C文件,其余均保存在bin文件,這也就是 里飛大佬的LvglFontTool的做法了,能最大限度節(jié)省flash空間。當然,如果你的ram夠大,將字庫直接加載到ram中,讀取時采用直接返回首地址+偏移量的方式,是最高效的方法了。
????總結(jié)來說,如果ram很大足夠用,直接將lvgl字體加載到ram中就可以了,最高效;
如果空閑ram不足以加載整個lvgl字體,但flash空間有較大的空閑可以容納字體的信息卻不足以容納字體的位圖,這樣可以使用level 1的外部字體,將全部的信息保存在c文件,僅將字體的位圖這一最龐大的部分保存到bin文件中,以提升效率;
而level 0適用于flash沒有多少空閑空間的設(shè)備了,盡可能將字體的信息保存到bin文件中。
????工具的具體安裝和使用方法可以看上面鏈接的gitee倉庫,里面有詳細的介紹。歡迎使用和指出bug。