📄 基于 linux 和 minigui 的嵌入式系统软件开发指南(四).htm
字号:
446 void GUIAPI MoveTo (HDC hdc, int x, int y);
447
448 void GUIAPI Circle (HDC hdc, int x, int y, int r);
449 void GUIAPI Rectangle (HDC hdc, int x0, int y0, int x1, int y1);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>这里有两个基本的概念需要明确区分,即象素值和 RGB 值。RGB 是计算机中通过三原色的不同比例表示某种颜色的方法。通常,RGB
中的红、绿、蓝可取 0 ~ 255 当中的任意值,从而可以表示 255x255x255 种不同的颜色。而在显示内存当中,要显示在屏幕上的颜色并不是用
RGB 这种方式表示的,显存当中保存的其实是所有象素的象素值。象素值的范围根据显示模式的不同而变化。在 16 色显示模式下,象素值范围为 [0,
15];而在 256 色模式下,象素值范围为 [0, 255];在 16 位色模式下,象素值范围为 [0, 2^16 -
1]。通常我们所说显示模式是多少位色,就是指象素的位数。</P>
<P>在 MiniGUI 中,设置某个象素点的颜色,既可以直接使用象素值(SetPixel),也可以间接通过 RGB
值来设置(SetPixelRGB),并且通过 RGB2Pixel 函数,可以将 RGB 值转换为象素值。</P>
<P>调色板是低颜色位数的模式下(比如 256 色或者更少的颜色模式),用来建立有限的象素值和 RGB 对应关系的一个线性表。在 MiniGUI
当中,可以通过 SetPalette和 GetPalette 进行调色板的操作,而SetColorfulePalette
将调色板设置为默认的调色板。一般而言,在更高的颜色位数,比如 15
位色以上,因为象素值范围能够表达的颜色已经非常丰富了,加上存储的关系,就不再使用调色板建立象素值和 RGB 的对应关系,而使用更简单的方法建立
RGB 和实际象素之间的关系,如下所示(src/gal/native/native.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>174 /* Truecolor color conversion and extraction macros */
175 /*
176 * Conversion from RGB to gal_pixel
177 */
178 /* create 24 bit 8/8/8 format pixel (0x00RRGGBB) from RGB triplet*/
179 #define RGB2PIXEL888(r,g,b) \
180 (((r) << 16) | ((g) << 8) | (b))
181
182 /* create 16 bit 5/6/5 format pixel from RGB triplet */
183 #define RGB2PIXEL565(r,g,b) \
184 ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3))
185
186 /* create 15 bit 5/5/5 format pixel from RGB triplet */
187 #define RGB2PIXEL555(r,g,b) \
188 ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3))
189
190 /* create 8 bit 3/3/2 format pixel from RGB triplet*/
191 #define RGB2PIXEL332(r,g,b) \
192 (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6))
</CODE>
</PRE></TD></TR></TBODY></TABLE>RGB2PIXEL888 将 [0, 255] 的 RGB 值转换为 24
位色的象素值;而 RGB2PIXEL565 转换为 16 位色的象素值;RGB2PIXEL555 和RGB2PIXEL332 分别转换为 15
位色和 8 位色。<BR><BR>
<P><SPAN class=atitle3>4.3
剪切域操作函数</SPAN><BR>在利用设备上下文进行绘图时,还可以进行剪切处理。MiniGUI
提供了如下函数完成对指定设备上下文的剪切处理(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>468 // Clipping support
469 void GUIAPI ExcludeClipRect (HDC hdc, int left, int top,
470 int right, int bottom);
471 void GUIAPI IncludeClipRect (HDC hdc, int left, int top,
472 int right, int bottom);
473 void GUIAPI ClipRectIntersect (HDC hdc, const RECT* prc);
474 void GUIAPI SelectClipRect (HDC hdc, const RECT* prc);
475 void GUIAPI SelectClipRegion (HDC hdc, const CLIPRGN* pRgn);
476 void GUIAPI GetBoundsRect (HDC hdc, RECT* pRect);
477 BOOL GUIAPI PtVisible (HDC hdc, const POINT* pPt);
478 BOOL GUIAPI RectVisible (HDC hdc, const RECT* pRect);
</CODE>
</PRE></TD></TR></TBODY></TABLE>ExcludeClipRect
从设备上下文的当前可见区域中排除给定的矩形区域,设备上下文的可见区域将缩小;IncludeClipRect
向当前设备上下文的可见区域中添加一个矩形区域,设备上下文的可见区域将扩大;ClipRectIntersect
将设备上下文的可见区域设置为已有区域和给定矩形区域的交集;SelectClipRect
将设备上下文的可见区域重置为一个矩形区域;SelectClipRegion 将设备上下文的可见区域设置为一个指定的区域;GetBoundsRect
获取当前可见区域的外包最小矩形;PtVisible 和 RectVisible
用来判断给定的点或者矩形是否可见,即是否全部或部分落在可见区域当中。<BR><BR>
<P><A id=5 name=5><SPAN class=atitle2>5 位图操作函数</SPAN></A><BR>在 MiniGUI 的
GDI 函数中,位图操作函数占有非常重要的地位。实际上,许多高级绘图操作函数均建立在位图操作函数之上,比如文本输出函数。MiniGUI
的主要位图操作函数如下所示(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>495 void GUIAPI FillBox (HDC hdc, int x, int y, int w, int h);
496 void GUIAPI FillBoxWithBitmap (HDC hdc, int x, int y, int w, int h,
497 PBITMAP pBitmap);
498 void GUIAPI FillBoxWithBitmapPart (HDC hdc, int x, int y, int w, int h,
499 int bw, int bh, PBITMAP pBitmap, int xo, int yo);
500
501 void GUIAPI BitBlt (HDC hsdc, int sx, int sy, int sw, int sh,
502 HDC hddc, int dx, int dy, DWORD dwRop);
503 void GUIAPI StretchBlt (HDC hsdc, int sx, int sy, int sw, int sh,
504 HDC hddc, int dx, int dy, int dw, int dh, DWORD dwRop);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>FillBox 用当前填充色填充矩形框;FillBoxWithBitmap
用设备相关位图对象填充矩形框,可以用来扩大或者缩小位图;FillBoxWithBitmapPart
用设备相关位图对象的部分填充矩形框,也可以扩大或缩小位图。BitBlt 函数用来实现两个不同设备上下文之间的显示内存复制。StretchBlt 则在
BitBlt 的基础上进行缩放操作。</P>
<P>通过 MiniGUI 的 LoadBitmap 函数,可以将某种位图文件装载为 MiniGUI 设备相关的位图对象,即 BITMAP
对象。设备相关的位图指的是,位图当中包含的是与指定设备上下文的显示模式相匹配的象素值,而不是设备无关的位图信息。MiniGUI
目前可以用来装载BMP 文件、JPG 文件、GIF 文件以及 PCX、TGA 等格式的位图文件,而 LoadMyBitmap
函数则用来将位图文件装载成设备无关的位图对象。在 MiniGUI 中,设备相关的位图对象和设备无关的位图对象分别用 BITMAP 和
MYBITMAP 两种数据结构表示。相关函数的原型如下(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>666 int GUIAPI LoadMyBitmap (HDC hdc, PMYBITMAP pMyBitmap, RGB* pal, const char* spFileName);
667 int GUIAPI LoadBitmap (HDC hdc, PBITMAP pBitmap, const char* spFileName);
668 #ifdef _SAVE_BITMAP
669 int GUIAPI SaveBitmap (HDC hdc, PBITMAP pBitmap, const char* spFileName);
670 #endif
671 void GUIAPI UnloadBitmap (PBITMAP pBitmap);
672
673 int GUIAPI ExpandMyBitmap (HDC hdc, const MYBITMAP* pMyBitmap, const RGB* pal, PBITMAP pBitmap);
674
675 void GUIAPI ExpandMonoBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
676 BYTE* bitmap, int bg, int fg);
677 void GUIAPI Expand16CBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
678 BYTE* bitmap, const RGB* pal);
679 void GUIAPI Expand256CBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
680 BYTE* bitmap, const RGB* pal);
681 void GUIAPI CompileRGBBitmap (HDC hdc, int w, int h, const BYTE* bits, int bits_flow, int pitch,
682 BYTE* bitmap, int rgb_order);
683
684 void GUIAPI ReplaceBitmapColor (HDC hdc, PBITMAP pBitmap, int iOColor, int iNColor);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>上面的 Expand 函数组,用来将设备无关的位图转化为与指定设备上下文相关的位图对象。</P>
<P>有关位图操作的详细使用方法,可见 mglite-exec 包中的 bitmaptest 示例程序。</P>
<P><A id=6 name=6><SPAN class=atitle2>6 逻辑字体和文本输出函数</SPAN></A><BR>MiniGUI
的逻辑字体功能强大,它包括了字符集、字体类型、风格、样式等等丰富的信息,不仅仅可以用来输出文本,而且可以用来分析多语种文本的结构。这在许多文本排版应用中非常有用。在使用
MiniGUI
的逻辑字体之前,首先要创建逻辑字体,并且将其选择到要使用这种逻辑字体进行文本输出的设备上下文当中。每个设备上下文的默认逻辑字体是系统字体,即用来显示菜单、标题的逻辑字体。你可以调用
CreateLogFont 和 CreateLogFontIndirect 两个函数来建立逻辑字体,并利用 SelectFont
函数将逻辑字体选择到指定的设备上下文中,在使用结束之后,用 DestroyLogFont
函数销毁逻辑字体。注意你不能销毁正被选中的逻辑字体。这几个函数的原型如下(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>555 PLOGFONT GUIAPI CreateLogFont (const char* type, const char* family,
556 const char* charset, char weight, char slant, char set_width,
557 char spacing, char underline, char struckout,
558 int size, int rotation);
559 PLOGFONT GUIAPI CreateLogFontIndirect (LOGFONT* logfont);
560 void GUIAPI DestroyLogFont (PLOGFONT log_font);
561
562 void GUIAPI GetLogFontInfo (HDC hdc, LOGFONT* log_font);
563
564 #define SYSLOGFONT_DEFAULT 0
565 PLOGFONT GUIAPI GetSystemFont (int font_id);
566
567 PLOGFONT GUIAPI GetCurFont (HDC hdc);
568 PLOGFONT GUIAPI SelectFont (HDC hdc, PLOGFONT log_font);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>GetSystemFont 函数返回默认的系统逻辑字体,GetCurFont
函数返回当前选中的逻辑字体。注意不要删除系统逻辑字体。下面的程序段建立了多个逻辑字体:</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE> static LOGFONT *logfont, *logfontgb12, *logfontbig24;
logfont = CreateLogFont (NULL, "SansSerif", "ISO8859-1",
FONT_WEIGHT_REGULAR, FONT_SLANT_ITALIC, FONT_SETWIDTH_NORMAL,
FONT_SPACING_CHARCELL, FONT_UNDERLINE_NONE, FONT_STRUCKOUT_LINE,
16, 0);
logfontgb12 = CreateLogFont (NULL, "song", "GB2312",
FONT_WEIGHT_REGULAR, FONT_SLANT_ROMAN, FONT_SETWIDTH_NORMAL,
FONT_SPACING_CHARCELL, FONT_UNDERLINE_LINE, FONT_STRUCKOUT_LINE,
12, 0);
logfontbig24 = CreateLogFont (NULL, "ming", "BIG5",
FONT_WEIGHT_REGULAR, FONT_SLANT_ROMAN, FONT_SETWIDTH_NORMAL,
FONT_SPACING_CHARCELL, FONT_UNDERLINE_LINE, FONT_STRUCKOUT_NONE,
24, 0);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>其中,第一个字体,即 logfont 是属于字符集 ISO8859-1 的字体,并且选用 SansSerif 体,大小为 16
象素高;logfontgb12 是属于字符集 GB2312 的字体,并选用 song 体(宋体),大小为 12 象素高;logfontbig24
是属于字符集 BIG5 的字体,并选用 ming 体(即明体)。</P>
<P>在建立了逻辑字体之后,应用程序可以利用逻辑字体进行多语种混和文本的分析。这里的多语种混和文本是指,两个不相交字符集的文本组成的字符串,比如
GB2312 和 ISO8859-1,或者 BIG5 和
ISO8859-2,通常是多字符集和单字符集之间的混和。利用下面的函数,可以实现多语种混和文本的文本组成分析(include/gdi.h):</P>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc
border=1><TBODY>
<TR>
<TD><PRE><CODE>570 // Text parse support
571 int GUIAPI GetTextMCharInfo (PLOGFONT log_font, const char* mstr, int len,
572 int* pos_chars);
573 int GUIAPI GetTextWordInfo (PLOGFONT log_font, const char* mstr, int len,
574 int* pos_words, WORDINFO* info_words);
575 int GUIAPI GetFirstMCharLen (PLOGFONT log_font, const char* mstr, int len);
576 int GUIAPI GetFirstWord (PLOGFONT log_font, const char* mstr, int len,
577 WORDINFO* word_info);
</CODE>
</PRE></TD></TR></TBODY></TABLE><BR><BR>
<P>GetTextMCharInfo 函数返回多语种混和文本中每个字符的字节位置。比如对"ABC汉语"字符串,该函数将在 pos_chars
中返回{0, 1, 2, 3, 5} 5 个值。GetTextWordInfo
函数则将分析多语种混和文本中每个单词的位置。对单字节字符集文本,单词以空格、TAB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -