天天看點

Foxdisk10-小字庫顯示漢字1

(請保留 -> 作者:羅冰 )

在以前的部落格中曾經讨論過,設計的Foxdisk代碼段和資料段總共隻能128K。可是随便哪個漢字庫輕輕松松都超過了100K,大的有近500K(我設計的時候隻用了24×24以及16×16的字模),無論如何是不能包含在程式中的。唯一的辦法,是将需要用的漢字字模提取出來,實作小字庫的漢字顯示。

當然,如果改變Foxdisk的設計方法,比如采用很久以前用過的一種技術:在硬碟的末端存一個裁剪的DOS或者linux,用OS來支援。現在遇到的存儲空間不夠啊、想實作的功能難以實作啊,都能解決。并且還能複用大量的DOS/Linux的軟體,還是很不錯的。不過,這就失去了我當時設計的初衷了,本來就是用來學習底層知識的一個小項目,用這種方法則屏蔽了大量的實作細節,是以我就放棄了。不過,在公司早期的一款産品中(賣了好幾年,技術支援巨難,後來被我停掉了)是用了這種方法的,有機會也開個部落格仔細探讨下。

文字顯示主要包括文字的讀取和顯示兩個步驟。西方文字顯示完全可以內建在一個ROM内,但是中文字太多,通常都要用到字庫。中文字庫有兩大類型:點陣式字庫和矢量字庫。

點陣式字庫是通過将中文字看成一個個點組成的二維陣列來實作顯示;矢量字庫則通過對文字每個筆劃的起始點和結束點的記錄來完成文字顯示。很明顯,點陣字如果要放大文字将會出現明顯的不平滑現象;而矢量字無論字的大小都可以保證字型圓滑。但是由于點陣字了解簡單、便于程式設計等原因,在很多領域點陣字庫成為了主流。

目前隻針對點陣字庫進行讨論研究,并針對研究的各字型庫進行分析,闡述其在程式設計上的一些差別。在此基礎上,提供了無字庫方案的實作過程及代碼。 點陣字的顯示原理其實很簡單。在規定大小的區域格内,如16×16、24×24等,将需要顯示的字的對應格填充即可。字庫内對應的格則以1表示,沒有填充的以0表示。如圖所示:

Foxdisk10-小字庫顯示漢字1

圖1 英文字模圖樣

這是英文字模的圖樣,而中文字模的圖樣是這樣的:

Foxdisk10-小字庫顯示漢字1

圖2 中文字模的圖樣

圖中的字模資訊就存儲在相應的字庫中,而程式員就可以按照顯示原理在顯示器上以點位的方式顯示字元。

每個英文字母都是由一個ASCII碼組成的,而中文字是擴充ASCII碼組成的。也就是說一個中文字是由左半邊和右半邊兩部分的資訊組成的。字庫中的文字一般是按區位碼的形式存放的,大體原理相同,但是在實際組織的時候有些細微的差别。[1]

本文所讨論的字庫有HZK16(16×16漢字庫)、HZK24S(24×24宋體)、HZK24H(24×24黑體)、HZK24F(24×24仿宋)、HZK24K(24×24楷體)、HZK24T(24×24漢字全角字元)。

對于24×24以上的漢字字庫,比如48×48漢字字庫,其存儲方式與24×24 的相同,隻是大小不同,簡單修改就可适用,以下将作詳細說明。

HZK16的中漢字存儲可以用公式表示如下:

  • 區碼 = 文字左半邊資訊(擴充ASCII碼) – 0xA0
  • 位碼 = 文字右半邊資訊 – 0xA0
  • 在字庫中的位址 = [(區碼-1) *94 + (位碼-1)] * 32

其中1、2步減去0xA0的原因是中文字元用到的擴充ASCII碼是從0xA0之後開始計算的,94的來源是字庫中每個區最多存放94個中文字點陣。另外,因為HZK16是16×16字型,每個字由32個位元組組成(16位x16)。[1]

24×24字型庫中文字庫與 16×16字型庫的組織有些不同。HZK24T中已經存放了漢字的全角字元,其餘的各種字型的漢字庫16區之前是獨立在此的。也就是說,對HZK24S、HZK24H、HZK24F和HZK24K,公式如下:

  • 區碼 = 文字左半邊資訊(擴充ASCII碼) – 0xA0
  • 位碼 = 文字右半邊資訊 – 0xA0
  • 在字庫中的位址 = [(區碼-1- 15) *94 + (位碼-1)] * 72

注意在第三步要減去15,前15區的字元存放在HZK24T中了。72表示24×24字庫中漢字是按72位元組存儲的(24位x24)。

對于更大的字型,如32×32、48×48等,也是按照這樣的方式存儲。隻是在第3步的計算中,32×32字型庫中漢字占用 128位元組,48×48字型庫中漢字占用288位元組。

漢字的點陣結構介紹完了,後面就面臨着怎麼提取字模以及顯示的問題。實際上,在工具篇中已經有所涉及提取的問題了,下面兩篇部落格中較長的描述。

繼續閱讀