?? minigui 體系結構之三邏輯字體以及多字體和多字符集實現.htm
字號:
560 }
561
562 return -1;
563 }
564
565 #ifndef _LITE_VERSION
566 static unsigned short euckr_conv_to_uc16 (const unsigned char* mchar, int len)
567 {
568 return '?';
569 }
570 #endif
571
572 static CHARSETOPS CharsetOps_euckr = {
573 8836,
574 2,
575 2,
576 FONT_CHARSET_EUCKR,
577 {'\xA1', '\xA1'},
578 euckr_len_first_char,
579 euckr_char_offset,
580 db_nr_chars_in_str,
581 euckr_is_this_charset,
582 euckr_len_first_substr,
583 db_get_next_word,
584 euckr_pos_first_char,
585 #ifndef _LITE_VERSION
586 euckr_conv_to_uc16
587 #endif
588 };
589 /************************* End of EUCKR *************************************/
590 #endif /* _EUCKR_SUPPORT */
</PRE></TD></TR></TBODY></TABLE><A id=4 name=4></A>
<P><STRONG class=subhead>4 MiniGUI 中的字體支持</STRONG></P><STRONG>4.1
設備字體</STRONG>
<P>在 MiniGUI 中,設備字體定義如下(include/gdi.h):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 319 struct _DEVFONT
320 {
321 char name [LEN_DEVFONT_NAME + 1];
322 DWORD style;
323 FONTOPS* font_ops;
324 CHARSETOPS* charset_ops;
325 struct _DEVFONT* sbc_next;
326 struct _DEVFONT* mbc_next;
327 void* data;
328 };
</PRE></TD></TR></TBODY></TABLE>
<P>其中各字段說明如下:</P>
<UL class=noindent>
<LI>name:該設備字體的名稱。MiniGUI 中設備字體的名稱格式如下:<BR></LI></UL>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE><type>-<name>-<style>-<width>-<height>-<charset1[,charset2]>
</PRE></TD></TR></TBODY></TABLE><BR>其中每個域的含義如下:<BR>
<UL>
<LI>type:字體類型,比如RBF(MiniGUI 定義的等寬字體格式)、VBF(MiniGUI
定義的變寬字體格式)、TTF(TrueType 字體)等等。
<LI>name:名稱,比如 Song、Hei、Times 等等。
<LI>style:該字體的樣式,比如黑體、斜體等等。
<LI>width:該字體的寬度,對矢量字體來說,可取 0。
<LI>height:該字體的高度,對矢量字體來說,可取 0。
<LI>charset1, charset2:該字體適用的字符集名稱。 </LI></UL>
<UL class=noindent>
<LI>style:字體樣式。
<LI>font_ops:設備字體對應的字體操作集。
<LI>charset_ops:設備字體對應的字符集操作集。
<LI>sbc_next、mbc_next:內部使用的鏈表維護字段。
<LI>data:該設備字體相關的內部數據。 </LI></UL>
<P>在 MiniGUI 啟動時,將根據 MiniGUI.cfg
文件中的定義建立兩個設備字體鏈表,分別為單字節設備字體鏈和多字節設備字體鏈。這兩個鏈表將由 CreateLogFont
使用,通過查找和匹配,建立對應的邏輯字體。</P><STRONG>4.2 邏輯字體</STRONG>
<P>邏輯字體的定義如下(include/gdi.h):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 228 typedef struct _LOGFONT {
229 char type [LEN_FONT_NAME + 1];
230 char family [LEN_FONT_NAME + 1];
231 char charset [LEN_FONT_NAME + 1];
232 DWORD style;
233 int size;
234 int rotation;
235 DEVFONT* sbc_devfont;
236 DEVFONT* mbc_devfont;
237 } LOGFONT;
238 typedef LOGFONT* PLOGFONT;
</PRE></TD></TR></TBODY></TABLE>
<P>顯然,每個邏輯字體由最匹配該字體要求(大小、字符集、樣式等)的兩個設備字體(sbc_devfont和
mbc_devfong)組成,分別用來處理多字節字符串中的單字節字符和多字節字符。其中單字節設備字體是必不可少的。</P>
<P>邏輯字體的匹配算法可參見 src/gdi/logfont.c 和src/font/devfont.c
文件。限于篇幅,不再贅述。</P><STRONG>4.3 設備字體操作集</STRONG>
<P>和字符集操作集一樣,MiniGUI
中的設備字體操作集針對每種設備字體類型而定義,包括對這種設備字體的各種操作函數(include/gdi.h):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 276 typedef struct _FONTOPS
277 {
278 int (*get_char_width) (LOGFONT* logfont, DEVFONT* devfont,
279 const unsigned char* mchar, int len);
280 int (*get_str_width) (LOGFONT* logfont, DEVFONT* devfont,
281 const unsigned char* mstr, int n, int cExtra);
282 int (*get_ave_width) (LOGFONT* logfont, DEVFONT* devfont);
283 int (*get_max_width) (LOGFONT* logfont, DEVFONT* devfont);
284 int (*get_font_height) (LOGFONT* logfont, DEVFONT* devfont);
285 int (*get_font_size) (LOGFONT* logfont, DEVFONT* devfont, int expect);
286 int (*get_font_ascent) (LOGFONT* logfont, DEVFONT* devfont);
287 int (*get_font_descent) (LOGFONT* logfont, DEVFONT* devfont);
288
289 /* TODO */
290 // int (*get_font_ABC) (LOGFONT* logfont);
291
292 size_t (*char_bitmap_size) (LOGFONT* logfont, DEVFONT* devfont,
293 const unsigned char* mchar, int len);
294 size_t (*max_bitmap_size) (LOGFONT* logfont, DEVFONT* devfont);
295 const void* (*get_char_bitmap) (LOGFONT* logfont, DEVFONT* devfont,
296 const unsigned char* mchar, int len);
297
298 const void* (*get_char_pixmap) (LOGFONT* logfont, DEVFONT* devfont,
299 const unsigned char* mchar, int len, int* pitch);
300 /* Can be NULL */
301
302 void (*start_str_output) (LOGFONT* logfont, DEVFONT* devfont);
303 /* Can be NULL */
304 int (*get_char_bbox) (LOGFONT* logfont, DEVFONT* devfont,
305 const unsigned char* mchar, int len,
306 int* px, int* py, int* pwidth, int* pheight);
307 /* Can be NULL */
308 void (*get_char_advance) (LOGFONT* logfont, DEVFONT* devfont,
309 int* px, int* py);
310 /* Can be NULL */
311
312 DEVFONT* (*new_instance) (LOGFONT* logfont, DEVFONT* devfont,
313 BOOL need_sbc_font);
314 /* Can be NULL */
315 void (*delete_instance) (DEVFONT* devfont);
316 /* Can be NULL */
317 } FONTOPS;
</PRE></TD></TR></TBODY></TABLE>
<P>比如,get_char_width 用來獲得某個字符的寬度,而 get_char_bitmap 用來獲得某個字符的位圖信息等等。</P>
<P>在 src/font/rawbitmap.c 和 src/font/varbitmap.c 文件中分別定義了對 RBF 和 VBF
兩種字體的操作函數,比如對變寬光柵字體來講(VBF),其 get_char_bitmap
定義如下(src/font/rawbitmap.c):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 155 static const void* get_char_bitmap (LOGFONT* logfont, DEVFONT* devfont,
156 const unsigned char* mchar, int len)
157 {
158 int offset;
159 unsigned char eff_char = *mchar;
160 VBFINFO* vbf_info = VARFONT_INFO_P (devfont);
161
162 if (*mchar < vbf_info->first_char || *mchar > vbf_info->last_char)
163 eff_char = vbf_info->def_char;
164
165 if (vbf_info->offset == NULL)
166 offset = (((size_t)vbf_info->max_width + 7) >> 3) * vbf_info->height
167 * (eff_char - vbf_info->first_char);
168 else
169 offset = vbf_info->offset [eff_char - vbf_info->first_char];
170
171 return vbf_info->bits + offset;
172 }
</PRE></TD></TR></TBODY></TABLE>
<P>其中,VARFONT_INFO_P 是一個宏,用來從設備字體的 data 字段中獲得 VBFINFO
結構的指針。有了這個指針之后,該函數計算字符位圖的偏移量最后返回字符的位圖。</P><STRONG>4.4 新設備字體的實現舉例</STRONG>
<P>這里以 Adobe Type1 字體的實現為例,說明如何在 MiniGUI 中實現一種新的設備字體。MiniGUI 借用了 T1Lib
函數庫實現了對 Type1 字體的支持。</P>
<P><B><I>4.4.1 Type1 字體簡介</I></B></P>
<P>Type1 矢量字體1格式由 Adobe 公司設計,并被該公司的ps標準支持。因此,它在Linux下也被支持得很好。它被 X和
ghostscript支持。一個典型的Type1字體包括一個afm(adobe font metric) 度量文件,一個外形文件,通常是一個pfb
( printer font binary) 或者 pfa (printer font ascii)
文件,外形文件包括所有的輪廓,而度量文件包含了所有的度量。比如緊排,連字等信息。</P>
<P><B><I>4.4.2 T1Lib 簡介</I></B></P>
<P>T1Lib 是用 C 語言實現的一個庫,它可以從 Adobe Type 1 字體生成位圖。它可以使用X11R5
或者更新版本提供的光柵化工具的很多功能,但避免了其已知的缺點。當然,T1Lib完全可以在沒有 X11 的環境下工作。T1Lib
可以被編譯成靜態或者動態庫,從而可以方便地連接。</P>
<P>這里是T1Lib 的一些特性:</P>
<UL>
<LI>字體通過運行時讀取字庫而被T1lib得知。即它是靈活可配置的。當然,它只支持Type 1字體。
<LI>字符或字符串只在需要時才被光柵化。
<LI>對字符串光柵化時支持字符間緊排,并且可以利用一個AFM文件提供緊排信息,如果沒有這個文件,T1Lib可以直接生成這些信息,也可以將其輸出到一個文件以備后用。
<LI>支持連字,連字是一個好的字體模型會提供的功能,目前,只有TEX和與其相關的軟件包對連字支持得比較好。連字信息也包含在AFM文件里。
<LI>支持旋轉和各種仿射變換。支持字體擴展,傾斜。
<LI>可以動態載入新的解碼矢量。用新的解碼矢量解析字體。
<LI>支持5灰度的低分辨率和17灰度的高分辨率的反走樣。
<LI>字符串可以被添加下劃線,上劃線或者橫線。 </LI></UL>
<P><B><I>4.4.3 Adobe Type1 字體支持的實現</I></B></P>
<P>在 MiniGUI 設備字體定義中,有一個 data 字段可用來保存設備字體相關的數據結構。對 Type1 字體來講,我們使用
TYPE1INFO和TYPE1INSTANCEINFO兩個數據結構來存儲這種設備字體的類信息和實例信息。</P>
<P>1) TYPE1INFO和TYPE1INSTANCEINFO 結構</P>
<P>這兩個結構的定義如下(src/font/type1.h):</P>
<TABLE class=code-sample cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><PRE> 22 typedef struct tagTYPE1GLYPHINFO {
23 int font_id;
24 //BBox font_bbox;
25 //int ave_width;
26 BOOL valid;
27 } TYPE1INFO, *PTYPE1INFO;
28
29 typedef struct tagTYPE1INSTANCEINFO {
30 PTYPE1INFO type1_info;
31 int rotation;/*in tenthdegrees*/
32 T1_TMATRIX * pmatrix;
33 int size;
34 int font_height;
35 int font_ascent;
36 int font_descent;
37
38 int max_width;
39 int ave_width;
40
41 double csUnit2Pixel;
42 /*
43 * last char or string's info
44 * T1_SetChar, T1_SetString, T1_AASetSting, T1_AASetString all return a static
45 * glyph pointer, we save the related infomation here for later use.
46 * */
47 char last_bitmap_char;
48 char last_pixmap_char;
49 char * last_bitmap_str;
50 char * last_pixmap_str;
51 int last_ascent;
52 int last_descent;
53 int last_leftSideBearing;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -