Merge pull request #22 from grissiom/rtgui-0.6

sync with rtgui-0.6
This commit is contained in:
Bernard Xiong 2013-01-31 18:59:34 -08:00
commit 9400f237b2
109 changed files with 6724 additions and 1164 deletions

View File

@ -19,13 +19,8 @@
#ifdef _WIN32 #ifdef _WIN32
#pragma warning(disable: 4996) #pragma warning(disable: 4996)
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#else
#include <dfs_posix.h>
#endif #endif
#include <dfs_posix.h>
/* the worst of allocation */ /* the worst of allocation */
#define LZO1X_WORST(x) ( (x) + ((x)/16) + 64 + 3 ) #define LZO1X_WORST(x) ( (x) + ((x)/16) + 64 + 3 )

View File

@ -1,11 +1,13 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import * from building import *
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = Split(''' src = Split('''
tjpgd.c tjpgd.c
''') ''')
CPPPATH = [RTT_ROOT + '/components/external/tjpgd1a']
group = DefineGroup('tjpgd', src, depend = ['RTGUI_IMAGE_TJPGD'], CPPPATH = CPPPATH) group = DefineGroup('tjpgd', src, depend = ['RTGUI_IMAGE_TJPGD'], CPPPATH = CPPPATH)
Return('group') Return('group')

2
components/rtgui/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
common/font_cmp_hz*.c
doc/doxygened/

1826
components/rtgui/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -72,6 +72,8 @@ widgets/edit.c
widgets/mv_view.c widgets/mv_view.c
widgets/plot.c widgets/plot.c
widgets/plot_curve.c widgets/plot_curve.c
widgets/digtube.c
widgets/digfont.c
""") """)
if GetDepend('RTGUI_USING_FONT_COMPACT'): if GetDepend('RTGUI_USING_FONT_COMPACT'):

View File

@ -15,198 +15,101 @@
const rt_uint8_t asc12_font[] = const rt_uint8_t asc12_font[] =
{ {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00,/*"!",1*/
0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/
0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00,/*"#",3*/
0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00,/*"$",4*/
0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00,/*"%",5*/
0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, 0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00,/*"&",6*/
0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/
0xc3, 0xff, 0xff, 0xff, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00,/*"(",8*/
0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,/*")",9*/
0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00,/*"*",10*/
0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00,/*"+",11*/
0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x3e, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,/*",",12*/
0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/
0x18, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,/*".",14*/
0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0xc6, 0x60, 0x38, 0x6c, 0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00,/*"/",15*/
0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,/*"0",16*/
0xfe, 0xfe, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"1",17*/
0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00,/*"2",18*/
0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00,/*"3",19*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00,/*"4",20*/
0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00,/*"5",21*/
0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00,/*"6",22*/
0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00,/*"7",23*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00,/*"8",24*/
0x10, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00,/*"9",25*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x50, 0x50, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00,/*":",26*/
0x00, 0x10, 0x38, 0x40, 0x40, 0x38, 0x48, 0x70, 0x10, 0x10, 0x00, 0x00, 0x00, 0x20, 0x50, 0x20, 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00,/*";",27*/
0x0c, 0x70, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x54, 0x48, 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00,/*"<",28*/
0x34, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,/*"=",29*/
0x00, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x20, 0x20, 0x10, 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/
0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x10, 0x7c, 0x10, 0x28, 0x28, 0x00, 0x00, 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00,/*"?",31*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00,/*"@",32*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00,/*"A",33*/
0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00,/*"B",34*/
0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00, 0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00,/*"C",35*/
0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00,/*"D",36*/
0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x08, 0x10, 0x20, 0x44, 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00,/*"E",37*/
0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/
0x00, 0x0c, 0x14, 0x14, 0x24, 0x44, 0x7c, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x20, 0x20, 0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00,/*"G",39*/
0x38, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x78, 0x44, 0x44, 0x44, 0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00,/*"H",40*/
0x38, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"I",41*/
0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00,/*"J",42*/
0x44, 0x3c, 0x04, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00,/*"K",43*/
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x30, 0x20, 0x00, 0x00, 0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00,/*"L",44*/
0x00, 0x00, 0x0c, 0x10, 0x60, 0x80, 0x60, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00,/*"M",45*/
0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x18, 0x04, 0x18, 0x20, 0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00,/*"N",46*/
0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x04, 0x08, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,/*"O",47*/
0x38, 0x44, 0x44, 0x4c, 0x54, 0x54, 0x4c, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 0x30, 0x10, 0x28, 0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/
0x28, 0x28, 0x7c, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x44, 0x44, 0x78, 0x44, 0x44, 0x44, 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00,/*"Q",49*/
0xf8, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00,/*"R",50*/
0x00, 0xf0, 0x48, 0x44, 0x44, 0x44, 0x44, 0x48, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x44, 0x50, 0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00,/*"S",51*/
0x70, 0x50, 0x40, 0x44, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x20, 0x28, 0x38, 0x28, 0x20, 0x20, 0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"T",52*/
0x70, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x4c, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00,/*"U",53*/
0x00, 0xec, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0x10, 0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00,/*"V",54*/
0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x08, 0x08, 0x48, 0x48, 0x48, 0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00,/*"W",55*/
0x30, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x48, 0x50, 0x70, 0x48, 0x44, 0xe4, 0x00, 0x00, 0x00, 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00,/*"X",56*/
0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xec, 0x6c, 0x6c, 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"Y",57*/
0x54, 0x54, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0xec, 0x64, 0x64, 0x54, 0x54, 0x54, 0x4c, 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00,/*"Z",58*/
0xec, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,/*"[",59*/
0x00, 0x78, 0x24, 0x24, 0x24, 0x38, 0x20, 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00,/*"\",60*/
0x44, 0x44, 0x44, 0x44, 0x38, 0x1c, 0x00, 0x00, 0x00, 0xf8, 0x44, 0x44, 0x44, 0x78, 0x48, 0x44, 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00,/*"]",61*/
0xe0, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x40, 0x38, 0x04, 0x04, 0x64, 0x58, 0x00, 0x00, 0x00, 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/
0x00, 0xfc, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,/*"_",63*/
0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/
0x10, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x54, 0x54, 0x54, 0x54, 0x28, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00,/*"a",65*/
0x00, 0xc4, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0xc4, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x28, 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00,/*"b",66*/
0x28, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x08, 0x10, 0x10, 0x20, 0x44, 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00,/*"c",67*/
0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00,/*"d",68*/
0x00, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00,/*"e",69*/
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x10, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00,/*"f",70*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38,/*"g",71*/
0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00,/*"h",72*/
0x44, 0x3c, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00,/*"i",73*/
0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,/*"j",74*/
0x00, 0x0c, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00,/*"k",75*/
0x44, 0x7c, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"l",76*/
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x38, 0x00, 0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00,/*"m",77*/
0x00, 0xc0, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00,/*"n",78*/
0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00,/*"o",79*/
0x08, 0x08, 0x70, 0x00, 0x00, 0xc0, 0x40, 0x5c, 0x48, 0x70, 0x50, 0x48, 0xdc, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0,/*"p",80*/
0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C,/*"q",81*/
0x54, 0x54, 0x54, 0x54, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x44, 0x44, 0x44, 0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00,/*"r",82*/
0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00,/*"s",83*/
0x00, 0x00, 0x00, 0xd8, 0x64, 0x44, 0x44, 0x44, 0x78, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,/*"t",84*/
0x4c, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x30, 0x20, 0x20, 0x20, 0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00,/*"u",85*/
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x38, 0x04, 0x44, 0x78, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00,/*"v",86*/
0x00, 0x00, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00,/*"w",87*/
0x44, 0x44, 0x44, 0x4c, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x28, 0x28, 0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00,/*"x",88*/
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x54, 0x54, 0x54, 0x28, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0,/*"y",89*/
0x00, 0x00, 0x00, 0xcc, 0x48, 0x30, 0x30, 0x48, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00,/*"z",90*/
0x44, 0x24, 0x28, 0x18, 0x10, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x48, 0x10, 0x20, 0x44, 0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00,/*"{",91*/
0x7c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x08, 0x00, 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,/*"|",92*/
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00,/*"}",93*/
0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x58, 0x00, 0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"~",94*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
const struct rtgui_font_bitmap asc12 = const struct rtgui_font_bitmap asc12 =
@ -216,8 +119,8 @@ const struct rtgui_font_bitmap asc12 =
RT_NULL, /* offset for each character */ RT_NULL, /* offset for each character */
6, /* width */ 6, /* width */
12, /* height */ 12, /* height */
0, /* first char */ 32, /* first char */
255 /* last char */ 127 /* last char */
}; };
struct rtgui_font rtgui_font_asc12 = struct rtgui_font rtgui_font_asc12 =

View File

@ -16,262 +16,101 @@
#ifdef RTGUI_USING_FONT16 #ifdef RTGUI_USING_FONT16
const unsigned char asc16_font[] = const unsigned char asc16_font[] =
{ {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x18,0x18,0x00,0x00,/*"!",1*/
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,0x12,0x36,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x00,0x00,/*"#",3*/
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x10,0x38,0x54,0x54,0x50,0x30,0x18,0x14,0x14,0x54,0x54,0x38,0x10,0x10,/*"$",4*/
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xA8,0x54,0x1A,0x2A,0x2A,0x2A,0x44,0x00,0x00,/*"%",5*/
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x50,0x6E,0xA4,0x94,0x88,0x89,0x76,0x00,0x00,/*"&",6*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x60,0x60,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,/*"(",8*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,/*")",9*/
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,0x00,0x00,0x00,0x10,0x10,0xD6,0x38,0x38,0xD6,0x10,0x10,0x00,0x00,0x00,0x00,/*"*",10*/
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*"+",11*/
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0xC0,/*",",12*/
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,/*".",14*/
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,/*"/",15*/
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"0",16*/
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"1",17*/
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,/*"2",18*/
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"3",19*/
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,/*"4",20*/
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"5",21*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"6",22*/
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,/*"7",23*/
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/*"8",24*/
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,/*"9",25*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,/*":",26*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,/*";",27*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,/*"<",28*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,/*"=",29*/
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x42,0x42,0x62,0x02,0x04,0x08,0x08,0x00,0x18,0x18,0x00,0x00,/*"?",31*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x44,0x5A,0xAA,0xAA,0xAA,0xAA,0xB4,0x42,0x44,0x38,0x00,0x00,/*"@",32*/
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3C,0x44,0x42,0x42,0xE7,0x00,0x00,/*"A",33*/
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xF8,0x44,0x44,0x44,0x78,0x44,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"B",34*/
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3E,0x42,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x44,0x38,0x00,0x00,/*"C",35*/
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00,0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"D",36*/
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x42,0x42,0xFC,0x00,0x00,/*"E",37*/
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x44,0x44,0x80,0x80,0x80,0x8E,0x84,0x44,0x44,0x38,0x00,0x00,/*"G",39*/
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"H",40*/
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"I",41*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0xF0,/*"J",42*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xEE,0x44,0x48,0x50,0x70,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00,/*"K",43*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0xFE,0x00,0x00,/*"L",44*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00,/*"M",45*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xC7,0x62,0x62,0x52,0x52,0x4A,0x4A,0x4A,0x46,0x46,0xE2,0x00,0x00,/*"N",46*/
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,/*"O",47*/
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0xB2,0xCA,0x4C,0x38,0x06,0x00,/*"Q",49*/
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x7C,0x48,0x48,0x44,0x44,0x42,0xE3,0x00,0x00,/*"R",50*/
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x3E,0x42,0x42,0x40,0x20,0x18,0x04,0x02,0x42,0x42,0x7C,0x00,0x00,/*"S",51*/
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"T",52*/
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"U",53*/
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,/*"V",54*/
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xD6,0x92,0x92,0x92,0x92,0xAA,0xAA,0x6C,0x44,0x44,0x44,0x00,0x00,/*"W",55*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00,/*"X",56*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"Y",57*/
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x7E,0x84,0x04,0x08,0x08,0x10,0x20,0x20,0x42,0x42,0xFC,0x00,0x00,/*"Z",58*/
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00,/*"[",59*/
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x02,/*"\",60*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,/*"]",61*/
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,0x1C,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,/*"_",63*/
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x1E,0x22,0x42,0x42,0x3F,0x00,0x00,/*"a",65*/
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x00,0x00,/*"b",66*/
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,/*"c",67*/
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x06,0x02,0x02,0x02,0x1E,0x22,0x42,0x42,0x42,0x26,0x1B,0x00,0x00,/*"d",68*/
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x40,0x42,0x3C,0x00,0x00,/*"e",69*/
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x0F,0x11,0x10,0x10,0x7E,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"f",70*/
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x44,0x44,0x38,0x40,0x3C,0x42,0x42,0x3C,/*"g",71*/
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"h",72*/
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"i",73*/
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x1C,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,/*"j",74*/
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x4E,0x48,0x50,0x68,0x48,0x44,0xEE,0x00,0x00,/*"k",75*/
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"l",76*/
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x49,0x49,0x49,0x49,0x49,0xED,0x00,0x00,/*"m",77*/
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"n",78*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"o",79*/
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x44,0x78,0x40,0xE0,/*"p",80*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x22,0x42,0x42,0x42,0x22,0x1E,0x02,0x07,/*"q",81*/
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x32,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"r",82*/
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x40,0x3C,0x02,0x42,0x7C,0x00,0x00,/*"s",83*/
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,0x00,/*"t",84*/
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x46,0x3B,0x00,0x00,/*"u",85*/
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x10,0x10,0x00,0x00,/*"v",86*/
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD7,0x92,0x92,0xAA,0xAA,0x44,0x44,0x00,0x00,/*"w",87*/
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00,/*"x",88*/
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x18,0x10,0x10,0xE0,/*"y",89*/
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x08,0x10,0x10,0x22,0x7E,0x00,0x00,/*"z",90*/
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,/*"{",91*/
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,/*"|",92*/
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x60,0x00,/*"}",93*/
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,0x4C,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"~",94*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
struct rtgui_font_bitmap asc16 = struct rtgui_font_bitmap asc16 =
@ -281,8 +120,8 @@ struct rtgui_font_bitmap asc16 =
RT_NULL, /* offset for each character */ RT_NULL, /* offset for each character */
8, /* width */ 8, /* width */
16, /* height */ 16, /* height */
0, /* first char */ 32, /* first char */
255 /* last char */ 127 /* last char */
}; };
struct rtgui_font rtgui_font_asc16 = struct rtgui_font rtgui_font_asc16 =
@ -294,5 +133,4 @@ struct rtgui_font rtgui_font_asc16 =
&asc16, /* font private data */ &asc16, /* font private data */
}; };
/* size = 4096 bytes */
#endif #endif

View File

@ -37,13 +37,6 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc *dc);
static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc *dc); static rt_bool_t rtgui_dc_hw_get_visible(struct rtgui_dc *dc);
static void rtgui_dc_hw_get_rect(struct rtgui_dc *dc, rtgui_rect_t *rect); static void rtgui_dc_hw_get_rect(struct rtgui_dc *dc, rtgui_rect_t *rect);
struct rtgui_dc_hw
{
struct rtgui_dc parent;
rtgui_widget_t *owner;
const struct rtgui_graphic_driver *hw_driver;
};
const struct rtgui_dc_engine dc_hw_engine = const struct rtgui_dc_engine dc_hw_engine =
{ {
rtgui_dc_hw_draw_point, rtgui_dc_hw_draw_point,

View File

@ -59,11 +59,12 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
rt_uint8_t chr; rt_uint8_t chr = 0;
const rt_uint8_t *ptr = font_ptr + i * word_bytes; const rt_uint8_t *ptr = font_ptr + i * word_bytes;
for (j = 0; j < w; j++) for (j = 0; j < w; j++)
{ {
if (j % 8 == 0)chr = *ptr++; if (j % 8 == 0)
chr = *ptr++;
if (chr & 0x80) if (chr & 0x80)
rtgui_dc_draw_point(dc, j + x, i + y); rtgui_dc_draw_point(dc, j + x, i + y);
else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND)

View File

@ -351,6 +351,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f
{ {
/* no memory */ /* no memory */
jpeg_finish_decompress(&jpeg->cinfo); jpeg_finish_decompress(&jpeg->cinfo);
jpeg_destroy_decompress(&jpeg->cinfo);
rt_free(jpeg); rt_free(jpeg);
return RT_FALSE; return RT_FALSE;
@ -381,6 +382,7 @@ static void rtgui_image_jpeg_unload(struct rtgui_image *image)
rtgui_filerw_close(jpeg->filerw); rtgui_filerw_close(jpeg->filerw);
jpeg_finish_decompress(&jpeg->cinfo); jpeg_finish_decompress(&jpeg->cinfo);
} }
jpeg_destroy_decompress(&jpeg->cinfo);
rt_free(jpeg); rt_free(jpeg);
} }
} }

View File

@ -2274,3 +2274,13 @@ rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect)
return RT_FALSE; return RT_FALSE;
} }
rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h)
{
RT_ASSERT(rect != RT_NULL);
rect->x1 = x; rect->y1 = y;
rect->x2 = x + w; rect->y2 = y + h;
return rect;
}

View File

@ -30,7 +30,6 @@ static void _rtgui_app_constructor(struct rtgui_app *app)
app->ref_count = 0; app->ref_count = 0;
app->exit_code = 0; app->exit_code = 0;
app->tid = RT_NULL; app->tid = RT_NULL;
app->server = RT_NULL;
app->mq = RT_NULL; app->mq = RT_NULL;
app->modal_object = RT_NULL; app->modal_object = RT_NULL;
app->main_object = RT_NULL; app->main_object = RT_NULL;
@ -51,13 +50,13 @@ DEFINE_CLASS_TYPE(application, "application",
_rtgui_app_destructor, _rtgui_app_destructor,
sizeof(struct rtgui_app)); sizeof(struct rtgui_app));
struct rtgui_app *rtgui_app_create( struct rtgui_app *rtgui_app_create(const char *title)
rt_thread_t tid,
const char *title)
{ {
rt_thread_t srv_tid; rt_thread_t tid = rt_thread_self();
struct rtgui_app *app; struct rtgui_app *app;
struct rtgui_app *srv_app;
struct rtgui_event_application event; struct rtgui_event_application event;
char mq_name[RT_NAME_MAX];
RT_ASSERT(tid != RT_NULL); RT_ASSERT(tid != RT_NULL);
RT_ASSERT(title != RT_NULL); RT_ASSERT(title != RT_NULL);
@ -70,10 +69,9 @@ struct rtgui_app *rtgui_app_create(
/* one thread only can create one rtgui application */ /* one thread only can create one rtgui application */
RT_ASSERT(tid->user_data == 0); RT_ASSERT(tid->user_data == 0);
app->tid = tid; app->tid = tid;
/* set user thread */
tid->user_data = (rt_uint32_t)app;
app->mq = rt_mq_create("rtgui", sizeof(union rtgui_event_generic), 32, RT_IPC_FLAG_FIFO); rt_snprintf(mq_name, RT_NAME_MAX, "g%s", title);
app->mq = rt_mq_create(mq_name, sizeof(union rtgui_event_generic), 32, RT_IPC_FLAG_FIFO);
if (app->mq == RT_NULL) if (app->mq == RT_NULL)
{ {
rt_kprintf("create msgq failed.\n"); rt_kprintf("create msgq failed.\n");
@ -85,31 +83,30 @@ struct rtgui_app *rtgui_app_create(
if (app->name == RT_NULL) if (app->name == RT_NULL)
goto __err; goto __err;
/* send a message to notify rtgui server */ /* the first app should be the server */
srv_tid = rtgui_get_server(); srv_app = rtgui_get_server();
if (srv_tid == RT_NULL) if (srv_app == RT_NULL)
{ {
rt_kprintf("gui server is not running.\n"); /* set user thread */
goto __err; tid->user_data = (rt_uint32_t)app;
} rt_kprintf("RTGUI: creating the server app %p.\n", app);
/* create the rtgui server application */
if (srv_tid == rt_thread_self())
return app; return app;
}
RTGUI_EVENT_APP_CREATE_INIT(&event); RTGUI_EVENT_APP_CREATE_INIT(&event);
event.app = app; event.app = app;
/* notify rtgui server to one application has been created */ /* notify rtgui server to one application has been created */
if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) == RT_EOK) if (rtgui_send_sync(srv_app, RTGUI_EVENT(&event), sizeof(event)) == RT_EOK)
{ {
/* set user thread */
tid->user_data = (rt_uint32_t)app;
return app; return app;
} }
__err: __err:
__mq_err: __mq_err:
rtgui_object_destroy(RTGUI_OBJECT(app)); rtgui_object_destroy(RTGUI_OBJECT(app));
tid->user_data = 0;
return RT_NULL; return RT_NULL;
} }
RTM_EXPORT(rtgui_app_create); RTM_EXPORT(rtgui_app_create);
@ -124,7 +121,7 @@ RTM_EXPORT(rtgui_app_create);
void rtgui_app_destroy(struct rtgui_app *app) void rtgui_app_destroy(struct rtgui_app *app)
{ {
rt_thread_t srv_tid; struct rtgui_app *srv_app;
_rtgui_application_check(app); _rtgui_application_check(app);
if (!(app->state_flag & RTGUI_APP_FLAG_EXITED)) if (!(app->state_flag & RTGUI_APP_FLAG_EXITED))
@ -135,14 +132,14 @@ void rtgui_app_destroy(struct rtgui_app *app)
} }
/* send a message to notify rtgui server */ /* send a message to notify rtgui server */
srv_tid = rtgui_get_server(); srv_app = rtgui_get_server();
if (srv_tid != rt_thread_self()) /* must not the server thread */ if (srv_app != rtgui_app_self())
{ {
struct rtgui_event_application event; struct rtgui_event_application event;
RTGUI_EVENT_APP_DESTROY_INIT(&event); RTGUI_EVENT_APP_DESTROY_INIT(&event);
event.app = app; event.app = app;
if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) != RT_EOK) if (rtgui_send_sync(srv_app, RTGUI_EVENT(&event), sizeof(event)) != RT_EOK)
{ {
rt_kprintf("destroy an application in server failed\n"); rt_kprintf("destroy an application in server failed\n");
return ; return ;
@ -168,25 +165,18 @@ struct rtgui_app *rtgui_app_self(void)
} }
RTM_EXPORT(rtgui_app_self); RTM_EXPORT(rtgui_app_self);
void rtgui_app_set_onidle(rtgui_idle_func_t onidle) void rtgui_app_set_onidle(struct rtgui_app *app, rtgui_idle_func_t onidle)
{ {
struct rtgui_app *app; _rtgui_application_check(app);
app = rtgui_app_self();
if (app != RT_NULL)
app->on_idle = onidle; app->on_idle = onidle;
} }
RTM_EXPORT(rtgui_app_set_onidle); RTM_EXPORT(rtgui_app_set_onidle);
rtgui_idle_func_t rtgui_app_get_onidle(void) rtgui_idle_func_t rtgui_app_get_onidle(struct rtgui_app *app)
{ {
struct rtgui_app *app;
app = rtgui_app_self(); _rtgui_application_check(app);
if (app != RT_NULL)
return app->on_idle; return app->on_idle;
else
return RT_NULL;
} }
RTM_EXPORT(rtgui_app_get_onidle); RTM_EXPORT(rtgui_app_get_onidle);
@ -369,7 +359,7 @@ void rtgui_app_activate(struct rtgui_app *app)
RTGUI_EVENT_APP_ACTIVATE_INIT(&event); RTGUI_EVENT_APP_ACTIVATE_INIT(&event);
event.app = app; event.app = app;
rtgui_send(app->tid, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application)); rtgui_send(app, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application));
} }
RTM_EXPORT(rtgui_app_activate); RTM_EXPORT(rtgui_app_activate);
@ -380,28 +370,28 @@ void rtgui_app_close(struct rtgui_app *app)
RTGUI_EVENT_APP_DESTROY_INIT(&event); RTGUI_EVENT_APP_DESTROY_INIT(&event);
event.app = app; event.app = app;
rtgui_send(app->tid, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application)); rtgui_send(app, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application));
} }
RTM_EXPORT(rtgui_app_close); RTM_EXPORT(rtgui_app_close);
/** /**
* set this application as window manager * set this application as window manager
*/ */
rt_err_t rtgui_app_set_as_wm(void) rt_err_t rtgui_app_set_as_wm(struct rtgui_app *app)
{ {
rt_thread_t srv_tid; struct rtgui_app *srv_app;
struct rtgui_event_set_wm event; struct rtgui_event_set_wm event;
struct rtgui_app *app;
srv_tid = rtgui_get_server(); _rtgui_application_check(app);
app = rtgui_app_self();
if (app != RT_NULL && srv_tid != RT_NULL) srv_app = rtgui_get_server();
if (srv_app != RT_NULL)
{ {
/* notify rtgui server, this is a window manager */ /* notify rtgui server, this is a window manager */
RTGUI_EVENT_SET_WM_INIT(&event); RTGUI_EVENT_SET_WM_INIT(&event);
event.app = app; event.app = app;
rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)); rtgui_send_sync(srv_app, RTGUI_EVENT(&event), sizeof(event));
return RT_EOK; return RT_EOK;
} }
@ -409,15 +399,11 @@ rt_err_t rtgui_app_set_as_wm(void)
} }
RTM_EXPORT(rtgui_app_set_as_wm); RTM_EXPORT(rtgui_app_set_as_wm);
void rtgui_app_set_main_win(struct rtgui_win *win) void rtgui_app_set_main_win(struct rtgui_app *app, struct rtgui_win *win)
{ {
struct rtgui_app *app;
app = rtgui_app_self(); _rtgui_application_check(app);
if (app != RT_NULL)
{
app->main_object = RTGUI_OBJECT(win); app->main_object = RTGUI_OBJECT(win);
} }
}
RTM_EXPORT(rtgui_app_set_main_win); RTM_EXPORT(rtgui_app_set_main_win);

View File

@ -422,7 +422,7 @@ static rt_bool_t _rtgui_mv_model_notify_view(struct rtgui_mv_model *model,
struct rtgui_mv_view *view, struct rtgui_mv_view *view,
struct rtgui_event_mv_model *emodel) struct rtgui_event_mv_model *emodel)
{ {
rt_thread_t target = RTGUI_WIDGET(view)->toplevel->app->tid; struct rtgui_app *target = RTGUI_WIDGET(view)->toplevel->app;
emodel->model = model; emodel->model = model;
emodel->view = view; emodel->view = view;
return rtgui_send(target, (struct rtgui_event *)emodel, sizeof(*emodel)); return rtgui_send(target, (struct rtgui_event *)emodel, sizeof(*emodel));

View File

@ -70,7 +70,7 @@ static void rtgui_time_out(void *parameter)
event.timer = timer; event.timer = timer;
rtgui_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t)); rtgui_send(timer->app, &(event.parent), sizeof(rtgui_event_timer_t));
} }
rtgui_timer_t *rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void *parameter) rtgui_timer_t *rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void *parameter)
@ -78,7 +78,7 @@ rtgui_timer_t *rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeou
rtgui_timer_t *timer; rtgui_timer_t *timer;
timer = (rtgui_timer_t *) rtgui_malloc(sizeof(rtgui_timer_t)); timer = (rtgui_timer_t *) rtgui_malloc(sizeof(rtgui_timer_t));
timer->tid = rt_thread_self(); timer->app = rtgui_app_self();
timer->timeout = timeout; timer->timeout = timeout;
timer->user_data = parameter; timer->user_data = parameter;
@ -371,7 +371,7 @@ const char *event_string[] =
#define DBG_MSG(x) rt_kprintf x #define DBG_MSG(x) rt_kprintf x
static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t *event) static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event)
{ {
char *sender = "(unknown)"; char *sender = "(unknown)";
@ -389,12 +389,12 @@ static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t *event)
if (event->type >= RTGUI_EVENT_COMMAND) if (event->type >= RTGUI_EVENT_COMMAND)
{ {
rt_kprintf("%s -- USER EVENT --> %s \n", sender, tid->name); rt_kprintf("%s -- USER EVENT --> %s \n", sender, app->name);
return ; return ;
} }
else else
{ {
rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->name); rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], app->name);
} }
switch (event->type) switch (event->type)
@ -545,88 +545,68 @@ static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t *event)
} }
#else #else
#define DBG_MSG(x) #define DBG_MSG(x)
#define rtgui_event_dump(tid, event) #define rtgui_event_dump(app, event)
#endif #endif
/************************************************************************/ /************************************************************************/
/* RTGUI IPC APIs */ /* RTGUI IPC APIs */
/************************************************************************/ /************************************************************************/
rt_err_t rtgui_send(rt_thread_t tid, rtgui_event_t *event, rt_size_t event_size) rt_err_t rtgui_send(struct rtgui_app* app, rtgui_event_t *event, rt_size_t event_size)
{ {
rt_err_t result; rt_err_t result;
struct rtgui_app *app;
RT_ASSERT(tid != RT_NULL); RT_ASSERT(app != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0); RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event); rtgui_event_dump(app, event);
/* find struct rtgui_application */
app = (struct rtgui_app *)(tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_send(app->mq, event, event_size); result = rt_mq_send(app->mq, event, event_size);
if (result != RT_EOK) if (result != RT_EOK)
{ {
if (event->type != RTGUI_EVENT_TIMER) if (event->type != RTGUI_EVENT_TIMER)
rt_kprintf("send event to %s failed\n", app->tid->name); rt_kprintf("send event to %s failed\n", app->name);
} }
return result; return result;
} }
RTM_EXPORT(rtgui_send); RTM_EXPORT(rtgui_send);
rt_err_t rtgui_send_urgent(rt_thread_t tid, rtgui_event_t *event, rt_size_t event_size) rt_err_t rtgui_send_urgent(struct rtgui_app* app, rtgui_event_t *event, rt_size_t event_size)
{ {
rt_err_t result; rt_err_t result;
struct rtgui_app *app;
RT_ASSERT(tid != RT_NULL); RT_ASSERT(app != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0); RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event); rtgui_event_dump(app, event);
/* find rtgui_application */
app = (struct rtgui_app *)(tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_urgent(app->mq, event, event_size); result = rt_mq_urgent(app->mq, event, event_size);
if (result != RT_EOK) if (result != RT_EOK)
rt_kprintf("send ergent event failed\n"); rt_kprintf("send ergent event to %s failed\n", app->name);
return result; return result;
} }
RTM_EXPORT(rtgui_send_urgent); RTM_EXPORT(rtgui_send_urgent);
rt_err_t rtgui_send_sync(rt_thread_t tid, rtgui_event_t *event, rt_size_t event_size) rt_err_t rtgui_send_sync(struct rtgui_app* app, rtgui_event_t *event, rt_size_t event_size)
{ {
rt_err_t r; rt_err_t r;
struct rtgui_app *app;
rt_int32_t ack_buffer, ack_status; rt_int32_t ack_buffer, ack_status;
struct rt_mailbox ack_mb; struct rt_mailbox ack_mb;
RT_ASSERT(tid != RT_NULL); RT_ASSERT(app != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0); RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event); rtgui_event_dump(app, event);
/* init ack mailbox */ /* init ack mailbox */
r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0); r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
if (r != RT_EOK) if (r != RT_EOK)
goto __return; goto __return;
app = (struct rtgui_app *)(tid->user_data);
if (app == RT_NULL)
{
r = -RT_ERROR;
goto __return;
}
event->ack = &ack_mb; event->ack = &ack_mb;
r = rt_mq_send(app->mq, event, event_size); r = rt_mq_send(app->mq, event, event_size);
if (r != RT_EOK) if (r != RT_EOK)
@ -728,12 +708,6 @@ rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t *event, rt_size_t eve
} }
RTM_EXPORT(rtgui_recv_filter); RTM_EXPORT(rtgui_recv_filter);
rt_thread_t rtgui_get_server(void)
{
return rt_thread_find("rtgui");
}
RTM_EXPORT(rtgui_get_server);
void rtgui_set_mainwin_rect(struct rtgui_rect *rect) void rtgui_set_mainwin_rect(struct rtgui_rect *rect)
{ {
_mainwin_rect = *rect; _mainwin_rect = *rect;

View File

@ -96,31 +96,34 @@ void rtgui_theme_draw_win(struct rtgui_topwin *win)
if (!(win->flag & WINTITLE_NO)) if (!(win->flag & WINTITLE_NO))
{ {
rt_uint32_t index; rt_uint32_t index;
float r, g, b, delta; rt_uint16_t r, g, b, delta;
#define RGB_FACTOR 4
if (win->flag & WINTITLE_ACTIVATE) if (win->flag & WINTITLE_ACTIVATE)
{ {
r = 10; r = 10 << RGB_FACTOR;
g = 36; g = 36 << RGB_FACTOR;
b = 106; b = 106 << RGB_FACTOR;
delta = 150 / (float)(rect.x2 - rect.x1); delta = (150 << RGB_FACTOR) / (rect.x2 - rect.x1);
} }
else else
{ {
r = 128; r = 128 << RGB_FACTOR;
g = 128; g = 128 << RGB_FACTOR;
b = 128; b = 128 << RGB_FACTOR;
delta = 64 / (float)(rect.x2 - rect.x1); delta = (64 << RGB_FACTOR) / (rect.x2 - rect.x1);
} }
RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(r, g, b);
for (index = rect.x1; index < rect.x2 + 1; index ++) for (index = rect.x1; index < rect.x2 + 1; index ++)
{ {
RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB((r>>RGB_FACTOR), \
(g>>RGB_FACTOR), (b>>RGB_FACTOR));
rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2); rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2);
r += delta; r += delta;
g += delta; g += delta;
b += delta; b += delta;
} }
#undef RGB_FACTOR
if (win->flag & WINTITLE_ACTIVATE) if (win->flag & WINTITLE_ACTIVATE)
{ {

View File

@ -0,0 +1,69 @@
RTGUI 0.6版发布纪要
# 为什么是 0.6
RTGUI 是作为 RT-Thread 的一个组件存在的。这次新发布的版本是在原 RTGUI 基础上重
构而来的。原 RTGUI 没有独立的版本号。暂设其为 0.5。所以本版本号取 0.6,为在原有
基础上改进之意。以后我们会每个月发布一个新版本。下一个版本号会是 0.6.1。
# 运行环境
理论上原来可以运行 RTGUI 的设备上都可以运行新的 RTGUI。本版本自带一个 Windows
模拟器,用来方便地评估运行效果。默认的运行环境是 realtouch。RT-Thread 中的模拟
器也是可以运作的。
# 新版本有什么特点?
0. 新版本的 GUI 摒弃了原有的 workbench/view/window 的工作方式。转换成全面向
window的工作方式。原有的 workbench/view 可以用 notebook 来实现。
0. 用 `rtgui_app` 对线程进行了抽象。
0. 事件驱动更彻底:
0. 将事件处理机制集成进 `rtgui_object`
0. 添加了`RTGUI_EVENT_SHOW` 和 `RTGUI_EVENT_HIDE` 来通知控件将要被显示/隐藏。
0. 底层代码中对事件的应用更加彻底。
0. 重构了自动布局方式。使得控件的摆放更加方便。
# 增强
- 添加了 TJPGD 引擎。使得小内存系统解码 jpeg 图片成为可能。(onelife)
- 添加了对单色屏的支持(onelife)
- bmp 图像引擎的重构(onelife)
- bmp 图像的旋转/缩放,以及功能性增强(amsl)
- 增加屏幕快照功能(amsl)
- PNG 引擎增加 Alpha 通道支持(amsl)
- 新增 edit 多行文本编辑控件。(amsl)
- 增加了 Model/View 的编程框架。(Grissiom)
- 添加了缩减字库的特性,开启后可以自动添加用到的汉字,不用的汉字字形不会加入到
字库当中。使得 GUI 能够在小 ROM 系统上得以应用。(Grissiom)
- 新增 digtube 七段码显示控件(prife)
- demo/benchmark 新增了 FPS 输出(amsl)
- 新增 box/panel/groupbox支持自动布局(Bernard)
# API 变化
除了 workbench/view 的消失以外,还有如下的 API 变化:
- c05a301, 68e3e30: `rtgui_{menu,win}_hiden` 被重命名为 `rtgui_{menu,win}_hide`
- 05e4894: 将 `struct rtgui_widget` 中的 `mini_{height,width}` 重命名为 `min_{height,width}`
- 等等……
今后很长时间内,新版本的 RTGUI 会与此版本的 API 尽量只增不减,保持兼容。
# Bug fixes
- 00a6690: 解决了 `rtgui_notebook_set_current_by_index` 中重绘标签页的 bug。感
谢 prife 提交 bug 信息和补丁。
- 6850ff2: 解决了 `last_mevent_widget` 引起的事件传送失败。感谢 heryon 提交bug
报告。
- 9143e11: 解决了 jpeg 引擎中的内存泄漏。感谢 Young 提供 bug 信息。
- fbd567c: 解决了 `rtgui_textbox_set_line_length` 的 bug。
- 9b67b66: 修复了窗口标题栏渐变效果的绘制。
- fc3abbf: 修复了 `rtgui_label_set_text`。感谢 tanghong668 提供 bug 信息。
- d41586c: 修复了窗口激活时重复刷新的问题。感谢 onelife 提供 bug 信息。
- ab08de6: 修复了字库缓存的 bug。感谢 rtt\_fans 提供 bug 信息。
- 等等……
除了上面提到的luoyuncong2012, lgnq, shaolin 也有贡献。上面的列表也必然是不完
整的。感谢编写了第一版 RTGUI 的 Bernard 和其他大侠们,没有他们的辛勤劳动,也不
会有今天的版本。感谢各位使用和支持RTGUI的开发人员是你们 RTGUI 体现了 RTGUI 的
价值。

View File

@ -0,0 +1,81 @@
/** @~english
@page pg-mv-model Model-View framework
@brief A overview of the Model-View framework
@section Glossary
@li view: widget dedicated to show the data. It could be a graph, list etc.
@li model: abstraction and combination of data.
@li data: things that needed to be delivered or shown. It could be a array of
votage values which is sampled from a AD in an interval. Or it could be the
attributes of all the files in a folder.
@section Design considerations and implementations
@li one model can respond to more than one views. one view can connect to
more than one models.
@li It is guaranteed that the change events of a model will be sent to all
the registered views.
@li Because there are so many formats of data, Model-View neither specify the
format data is stored nor try to abstract them. The only thing stored in
model is a pointer to the underlaying data. It is the responsibility of
inherited classed to implement the boxing/un-boxing operations.
@li Data can be multi-dimensional. The "dimension" does not only means
dimension geometry. It can also means attributes. For example, a folder could
have two attributes which are name and icon. So it's two-dimensional. If take
the size into consideration, it will be three-dimensional. The size of
dimension is saved in model. Each dimension is correspond to a pointer to some
sort of data. Model can save many of them. As above, model does not make
assumptions on the underlaying data structure. It only provide mechanism, not
policy and leave that to the inherited classes.
@section Events
@li model has a record of registered views. When data changes, model notify
views the change by sending events. The event contains the id of the model,
the id of target view, the scope of changed data.
@li views can handle the event by retrieve data from model, and update
themselves according to the scope that data has changed. The connected model
views should have the same presentation of data structure. Views should also
restore all the models it interested. In the case of repainting, it should
re-retrieve data from those models.
@li model send events by rtgui_send. So it's suitable for the synchronization
between threads and even could be used in ISR.
*/
/** @~chinese
@page pg-mv-model Model-View 框架
@brief 对于 Model-View 框架的简介
@section 名词解释
@li view用于显示数据的控件。可以是诸如图表控件、列表控件的控件。
@li model对于数据的组合和抽象。
@li 数据需要显示或传递的数据。它可以是每隔一段时间就从AD读取的电压值也可
以是一个目录下所有文件的属性列表。
@section 设计原则和实现
@li 一个 model 可以对应多个view。一个view可以对应多个 model。
@li 保证 model 的更新事件会同时发送到所有注册的 view 上。
@li 因为数据的形式与内容千差万别,所以 Model-View 不规定数据的存储形式,也不对其进
行抽象。只在 model 中保留指向第一个数据的指针。打包/解包由从m odel/view 派生出
的子类实现。
@li 数据源可以是多维的。这里的维度指的不只是几何的维度,而且可以是属性。比如
一个目录,它可以有名称、图标两个属性,那么它就是两维的。如果加入大小这个属性
,就是三维的。 model 内部存储数据的维度大小。一个维度对应一个数据首地址的指针
。model 中可以存储多个数据首地址。model 对底层数据结构不作假设。只提供机制,不
提供策略。只保证能够多维,但把具体的实现方式留给子类实现。
@subsection 事件
@li model 内部记录对自己感兴趣的 view。在数据变化时用事件通知所有相关 view。事
件内容包含:自己的 id目标 view 的 id所变化数据的 index 范围。
@li view 收到事件之后通过 model id 拿到数据并根据事件中的变化范围更新自己。对于
指针的数据类型转换需要自己实现并保证和 model 一致。view 内部保存与自己相关的
model id在需要重绘的时候要从所有相关 model 提取数据。
@li model 通过 rtgui_send 给 view 发送事件。使得这个模型适用于线程间同步,也
可以在中断上下文里通知事件的发生。
*/

View File

@ -60,6 +60,14 @@ struct rtgui_dc
const struct rtgui_dc_engine *engine; const struct rtgui_dc_engine *engine;
}; };
/* hardware device context */
struct rtgui_dc_hw
{
struct rtgui_dc parent;
rtgui_widget_t *owner;
const struct rtgui_graphic_driver *hw_driver;
};
#define RTGUI_DC_FC(dc) (rtgui_dc_get_gc(dc)->foreground) #define RTGUI_DC_FC(dc) (rtgui_dc_get_gc(dc)->foreground)
#define RTGUI_DC_BC(dc) (rtgui_dc_get_gc(dc)->background) #define RTGUI_DC_BC(dc) (rtgui_dc_get_gc(dc)->background)
#define RTGUI_DC_FONT(dc) (rtgui_dc_get_gc(dc)->font) #define RTGUI_DC_FONT(dc) (rtgui_dc_get_gc(dc)->font)

View File

@ -17,6 +17,7 @@
#include <rtgui/list.h> #include <rtgui/list.h>
#include <rtgui/color.h> #include <rtgui/color.h>
/* graphic driver operations */
struct rtgui_graphic_driver_ops struct rtgui_graphic_driver_ops
{ {
/* set and get pixel in (x, y) */ /* set and get pixel in (x, y) */
@ -30,6 +31,22 @@ struct rtgui_graphic_driver_ops
void (*draw_raw_hline)(rt_uint8_t *pixels, int x1, int x2, int y); void (*draw_raw_hline)(rt_uint8_t *pixels, int x1, int x2, int y);
}; };
/* graphic extension operations */
struct rtgui_graphic_ext_ops
{
/* some 2D operations */
void (*draw_line)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
void (*draw_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
void (*fill_rect)(rtgui_color_t *c, int x1, int y1, int x2, int y2);
void (*draw_circle)(rtgui_color_t *c, int x, int y, int r);
void (*fill_circle)(rtgui_color_t *c, int x, int y, int r);
void (*draw_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
void (*fill_ellipse)(rtgui_color_t *c, int x, int y, int rx, int ry);
};
struct rtgui_graphic_driver struct rtgui_graphic_driver
{ {
/* pixel format and byte per pixel */ /* pixel format and byte per pixel */
@ -43,11 +60,11 @@ struct rtgui_graphic_driver
/* framebuffer address and ops */ /* framebuffer address and ops */
volatile rt_uint8_t *framebuffer; volatile rt_uint8_t *framebuffer;
rt_device_t device; struct rt_device* device;
const struct rtgui_graphic_driver_ops *ops;
};
void rtgui_graphic_driver_add(const struct rtgui_graphic_driver *driver); const struct rtgui_graphic_driver_ops *ops;
const struct rtgui_graphic_ext_ops *ext_ops;
};
struct rtgui_graphic_driver *rtgui_graphic_driver_get_default(void); struct rtgui_graphic_driver *rtgui_graphic_driver_get_default(void);
@ -64,5 +81,19 @@ rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device()
return &_driver; return &_driver;
} }
#ifdef RTGUI_USING_HW_CURSOR
/*
* hardware cursor
*/
enum rtgui_cursor_type
{
RTGUI_CURSOR_ARROW,
RTGUI_CURSOR_HAND,
};
void rtgui_cursor_set_device(const char* device_name);
void rtgui_cursor_set_position(rt_uint16_t x, rt_uint16_t y);
void rtgui_cursor_set_image(enum rtgui_cursor_type type);
#endif #endif
#endif

View File

@ -90,7 +90,7 @@ struct rtgui_event
rt_uint16_t user; rt_uint16_t user;
/* the event sender */ /* the event sender */
rt_thread_t sender; struct rtgui_app *sender;
/* mailbox to acknowledge request */ /* mailbox to acknowledge request */
rt_mailbox_t ack; rt_mailbox_t ack;
@ -98,11 +98,13 @@ struct rtgui_event
typedef struct rtgui_event rtgui_event_t; typedef struct rtgui_event rtgui_event_t;
#define RTGUI_EVENT(e) ((struct rtgui_event*)(e)) #define RTGUI_EVENT(e) ((struct rtgui_event*)(e))
extern struct rtgui_app* rtgui_app_self(void);
#define RTGUI_EVENT_INIT(e, t) do \ #define RTGUI_EVENT_INIT(e, t) do \
{ \ { \
(e)->type = (t); \ (e)->type = (t); \
(e)->user = 0; \ (e)->user = 0; \
(e)->sender = rt_thread_self(); \ (e)->sender = rtgui_app_self(); \
(e)->ack = RT_NULL; \ (e)->ack = RT_NULL; \
} while (0) } while (0)

View File

@ -94,6 +94,7 @@ extern "C" {
int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y); int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y);
int rtgui_rect_is_intersect(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); int rtgui_rect_is_intersect(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2);
int rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); int rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2);
rtgui_rect_t *rtgui_rect_set(rtgui_rect_t *rect, int x, int y, int w, int h);
rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect); rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)

View File

@ -17,6 +17,11 @@
#include <rtthread.h> #include <rtthread.h>
#include <rtgui/rtgui_config.h> #include <rtgui/rtgui_config.h>
#define RTGUI_VERSION 0L /**< major version number */
#define RTGUI_SUBVERSION 6L /**< minor version number */
#define RTGUI_REVISION 0L /**< revise version number */
#define RTGUI_CODENAME "Newton" /**< code name */
#define RT_INT16_MAX 32767 #define RT_INT16_MAX 32767
#define RT_INT16_MIN (-RT_INT16_MAX-1) #define RT_INT16_MIN (-RT_INT16_MAX-1)
#define RTGUI_NOT_FOUND (-1) #define RTGUI_NOT_FOUND (-1)

View File

@ -52,9 +52,6 @@ struct rtgui_app
/* the thread id */ /* the thread id */
rt_thread_t tid; rt_thread_t tid;
/* the RTGUI server id */
rt_thread_t server;
/* the message queue of thread */ /* the message queue of thread */
rt_mq_t mq; rt_mq_t mq;
/* event buffer */ /* event buffer */
@ -70,9 +67,13 @@ struct rtgui_app
}; };
/** /**
* create an application named @myname on thread @param tid * create an application named @myname on current thread.
*
* @param name the name of the application
*
* @return a pointer to struct rtgui_app on success. RT_NULL on failure.
*/ */
struct rtgui_app *rtgui_app_create(rt_thread_t tid, const char *title); struct rtgui_app *rtgui_app_create(const char *name);
void rtgui_app_destroy(struct rtgui_app *app); void rtgui_app_destroy(struct rtgui_app *app);
rt_bool_t rtgui_app_event_handler(struct rtgui_object *obj, rtgui_event_t *event); rt_bool_t rtgui_app_event_handler(struct rtgui_object *obj, rtgui_event_t *event);
@ -81,11 +82,15 @@ void rtgui_app_exit(struct rtgui_app *app, rt_uint16_t code);
void rtgui_app_activate(struct rtgui_app *app); void rtgui_app_activate(struct rtgui_app *app);
void rtgui_app_close(struct rtgui_app *app); void rtgui_app_close(struct rtgui_app *app);
void rtgui_app_set_onidle(rtgui_idle_func_t onidle); void rtgui_app_set_onidle(struct rtgui_app *app, rtgui_idle_func_t onidle);
rtgui_idle_func_t rtgui_app_get_onidle(void); rtgui_idle_func_t rtgui_app_get_onidle(struct rtgui_app *app);
/**
* return the rtgui_app struct on current thread
*/
struct rtgui_app *rtgui_app_self(void); struct rtgui_app *rtgui_app_self(void);
rt_err_t rtgui_app_set_as_wm(void); rt_err_t rtgui_app_set_as_wm(struct rtgui_app *app);
void rtgui_app_set_main_win(struct rtgui_win *win); void rtgui_app_set_main_win(struct rtgui_app *app, struct rtgui_win *win);
#endif /* end of include guard: __RTGUI_APP_H__ */ #endif /* end of include guard: __RTGUI_APP_H__ */

View File

@ -56,8 +56,8 @@ struct rtgui_topwin
/* the window id */ /* the window id */
struct rtgui_win *wid; struct rtgui_win *wid;
/* the thread id */ /* which app I belong */
rt_thread_t tid; struct rtgui_app *app;
/* the extent information */ /* the extent information */
rtgui_rect_t extent; rtgui_rect_t extent;

View File

@ -26,8 +26,8 @@ typedef void (*rtgui_timeout_func)(struct rtgui_timer *timer, void *parameter);
struct rtgui_timer struct rtgui_timer
{ {
/* context thread id */ /* the rtgui application it runs on */
rt_thread_t tid; struct rtgui_app* app;
/* rt timer */ /* rt timer */
struct rt_timer timer; struct rt_timer timer;
@ -58,7 +58,7 @@ void *rtgui_realloc(void *ptr, rt_size_t size);
#define rtgui_exit_critical rt_exit_critical #define rtgui_exit_critical rt_exit_critical
#endif #endif
rt_thread_t rtgui_get_server(void); struct rtgui_app* rtgui_get_server(void);
void rtgui_set_mainwin_rect(struct rtgui_rect *rect); void rtgui_set_mainwin_rect(struct rtgui_rect *rect);
void rtgui_get_mainwin_rect(struct rtgui_rect *rect); void rtgui_get_mainwin_rect(struct rtgui_rect *rect);
void rtgui_get_screen_rect(struct rtgui_rect *rect); void rtgui_get_screen_rect(struct rtgui_rect *rect);
@ -67,9 +67,9 @@ void rtgui_screen_lock(rt_int32_t timeout);
void rtgui_screen_unlock(void); void rtgui_screen_unlock(void);
struct rtgui_event; struct rtgui_event;
rt_err_t rtgui_send(rt_thread_t tid, struct rtgui_event *event, rt_size_t event_size); rt_err_t rtgui_send(struct rtgui_app* app, struct rtgui_event *event, rt_size_t event_size);
rt_err_t rtgui_send_urgent(rt_thread_t tid, struct rtgui_event *event, rt_size_t event_size); rt_err_t rtgui_send_urgent(struct rtgui_app* app, struct rtgui_event *event, rt_size_t event_size);
rt_err_t rtgui_send_sync(rt_thread_t tid, struct rtgui_event *event, rt_size_t event_size); rt_err_t rtgui_send_sync(struct rtgui_app* app, struct rtgui_event *event, rt_size_t event_size);
rt_err_t rtgui_ack(struct rtgui_event *event, rt_int32_t status); rt_err_t rtgui_ack(struct rtgui_event *event, rt_int32_t status);
rt_err_t rtgui_recv(struct rtgui_event *event, rt_size_t event_size); rt_err_t rtgui_recv(struct rtgui_event *event, rt_size_t event_size);
rt_err_t rtgui_recv_nosuspend(struct rtgui_event *event, rt_size_t event_size); rt_err_t rtgui_recv_nosuspend(struct rtgui_event *event, rt_size_t event_size);

View File

@ -0,0 +1,36 @@
#ifndef DIG_FONT_H
#define DIG_FONT_H
struct rtgui_digitfont_data
{
rt_uint16_t x;
rt_uint16_t y;
rt_uint16_t len;
rt_uint16_t type; //ˮƽºÍ´¹Ö±
};
struct rtgui_digitfont
{
int seg1_len;
int seg1_hspace;
int seg1_vspace;
int seg1_nr; //9
int seg2_len;
int seg3_len;
struct rtgui_digitfont_data *data;
};
typedef struct rtgui_digitfont rtgui_digitfont_t;
extern struct rtgui_digitfont digitfont_40;
extern const char digtube_code_table[];
int rtgui_digitfont_create(struct rtgui_digitfont *font);
int rtgui_dc_draw_digitfont(struct rtgui_dc *dc, struct rtgui_digitfont *font, rtgui_rect_t *rect);
int rtgui_get_digfont_metrics(struct rtgui_digitfont * font, rtgui_rect_t * rect);
int rtgui_dc_draw_digitfont_code(struct rtgui_dc *dc, struct rtgui_digitfont * font, rtgui_rect_t * rect, char code);
#endif

View File

@ -0,0 +1,68 @@
/*
* File : digfont.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-12-21 pife first version
*/
#ifndef __RTGUI_DIGTUBE_H__
#define __RTGUI_DIGTUBE_H__
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/widget.h>
#include <rtgui/widgets/digfont.h>
DECLARE_CLASS_TYPE(digtube);
/** Gets the type of a digit tubes */
#define RTGUI_DIGTUBE_TYPE (RTGUI_TYPE(digtube))
/** Casts the object to an rtgui_digtube */
#define RTGUI_DIGTUBE(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_DIGTUBE_TYPE, rtgui_digtube_t))
/** Checks if the object is an rtgui_digtube */
#define RTGUI_IS_DIGTUBE(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_DIGTUBE_TYPE))
/*
* the digit tube widget
*/
struct rtgui_digtube
{
struct rtgui_widget parent;
struct rtgui_digitfont digitfont;
/* number of tubes */
rt_uint8_t tube_count;
rt_uint8_t tube_style;
rt_uint8_t digit_hight;
rt_uint8_t digit_width;
rt_uint8_t digit_space;
rtgui_color_t digit_bc;
void * value;
};
typedef struct rtgui_digtube rtgui_digtube_t;
rtgui_digtube_t *rtgui_digtube_create( struct rtgui_digitfont * digitfont, int count, void * value, int style);
void rtgui_digtube_destroy(rtgui_digtube_t *digtube);
rt_bool_t rtgui_digtube_event_handler(struct rtgui_object *object, struct rtgui_event *event);
#define RTGUI_DIGTUBE_DEFAULT_BC RTGUI_RGB(0, 0, 0)
#define RTGUI_DIGTUBE_DEFAULT_FC RTGUI_RGB(0xFF, 0, 0)
#define RTGUI_DIGTUBE_DEFAULT_DIGIT_BC RTGUI_RGB(100, 100, 100)
#define RTGUI_DIGTUBE_DEFAULT_SPACE 10
#define RTGUI_DIGTUBE_STYLE_NOBACKFONT 0x01
#define RTGUI_DIGTUBE_STYLE_DISHEXNUM 0x02
#define RTGUI_DIGTUBE_STYLE_DISCODES 0x04
//void rtgui_digtube_set_text(rtgui_digtube_t *digtube, const char *text);
//char *rtgui_digtube_get_text(rtgui_digtube_t *digtube);
#endif

View File

@ -72,7 +72,7 @@ void rtgui_menu_set_onmenupop(struct rtgui_menu *menu, rtgui_event_handler_ptr h
void rtgui_menu_set_onmenuhide(struct rtgui_menu *menu, rtgui_event_handler_ptr handler); void rtgui_menu_set_onmenuhide(struct rtgui_menu *menu, rtgui_event_handler_ptr handler);
void rtgui_menu_pop(struct rtgui_menu *menu, int x, int y); void rtgui_menu_pop(struct rtgui_menu *menu, int x, int y);
void rtgui_menu_hiden(struct rtgui_menu *menu); void rtgui_menu_hide(struct rtgui_menu *menu);
#endif #endif

View File

@ -34,6 +34,8 @@ DECLARE_CLASS_TYPE(textbox);
#define RTGUI_TEXTBOX_DEFAULT_WIDTH 80 #define RTGUI_TEXTBOX_DEFAULT_WIDTH 80
#define RTGUI_TEXTBOX_DEFAULT_HEIGHT 20 #define RTGUI_TEXTBOX_DEFAULT_HEIGHT 20
#define RTGUI_TEXTBOX_BORDER_WIDTH 1
#define RTGUI_TEXTBOX_SINGLE 0x00 #define RTGUI_TEXTBOX_SINGLE 0x00
#define RTGUI_TEXTBOX_MULTI 0x01 /* multiline */ #define RTGUI_TEXTBOX_MULTI 0x01 /* multiline */
#define RTGUI_TEXTBOX_MASK 0x02 /* ciphertext */ #define RTGUI_TEXTBOX_MASK 0x02 /* ciphertext */
@ -52,10 +54,13 @@ struct rtgui_textbox
rt_uint32_t flag; rt_uint32_t flag;
/* current line and position */ /* current line and position */
rt_uint16_t line, line_begin, position, line_length; rt_uint16_t line, line_begin, position;
/** maximum chars a line could hold excluding the NULL byte */
rt_uint16_t line_length;
rt_uint16_t dis_length; /*may be display length.*/ rt_uint16_t dis_length; /*may be display length.*/
rt_uint16_t first_pos; rt_uint16_t first_pos;
char mask_char; char mask_char;
/** a NULL terminated string that the textbox is holding */
char *text; char *text;
rt_size_t font_width; rt_size_t font_width;
@ -77,7 +82,20 @@ void rtgui_textbox_set_value(struct rtgui_textbox *box, const char *text);
const char *rtgui_textbox_get_value(struct rtgui_textbox *box); const char *rtgui_textbox_get_value(struct rtgui_textbox *box);
void rtgui_textbox_set_mask_char(rtgui_textbox_t *box, const char ch); void rtgui_textbox_set_mask_char(rtgui_textbox_t *box, const char ch);
char rtgui_textbox_get_mask_char(rtgui_textbox_t *box); char rtgui_textbox_get_mask_char(rtgui_textbox_t *box);
void rtgui_textbox_set_line_length(struct rtgui_textbox *box, rt_size_t length); /** set the maximum chars a line could hold excluding the NULL byte
*
* It will truncate the current line if the length is smaller than the chars
* the box is currently holding. But the box->text is guaranteed to be NULL
* terminated anyway.
*
* @param box the text box it operate on
* @param length the new line length. It should be greater than 0.
*
* @return -RT_ERROR on invalid length; -RT_ENOMEM if there is no enough memory
* to allocate the new buffer. On returning -RT_ENOMEM, the original text would
* remain unchanged.
*/
rt_err_t rtgui_textbox_set_line_length(struct rtgui_textbox *box, rt_size_t length);
void rtgui_textbox_get_edit_rect(struct rtgui_textbox *box, rtgui_rect_t *rect); void rtgui_textbox_get_edit_rect(struct rtgui_textbox *box, rtgui_rect_t *rect);

View File

@ -100,7 +100,7 @@ extern "C" {
rtgui_rect_t extent; rtgui_rect_t extent;
/* minimal width and height of widget */ /* minimal width and height of widget */
rt_int16_t mini_width, mini_height; rt_int16_t min_width, min_height;
/* widget align */ /* widget align */
rt_int32_t align; rt_int32_t align;
rt_uint16_t border; rt_uint16_t border;
@ -151,10 +151,9 @@ extern "C" {
void rtgui_widget_set_rectangle(rtgui_widget_t *widget, int x, int y, int width, int height); void rtgui_widget_set_rectangle(rtgui_widget_t *widget, int x, int y, int width, int height);
void rtgui_widget_get_extent(rtgui_widget_t *widget, rtgui_rect_t *rect); void rtgui_widget_get_extent(rtgui_widget_t *widget, rtgui_rect_t *rect);
#ifndef RTGUI_USING_SMALL_SIZE void rtgui_widget_set_minsize(rtgui_widget_t *widget, int width, int height);
void rtgui_widget_set_miniwidth(rtgui_widget_t *widget, int width); void rtgui_widget_set_minwidth(rtgui_widget_t *widget, int width);
void rtgui_widget_set_miniheight(rtgui_widget_t *widget, int height); void rtgui_widget_set_minheight(rtgui_widget_t *widget, int height);
#endif
void rtgui_widget_set_parent(rtgui_widget_t *widget, rtgui_widget_t *parent); void rtgui_widget_set_parent(rtgui_widget_t *widget, rtgui_widget_t *parent);

View File

@ -130,7 +130,7 @@ void rtgui_win_destroy(rtgui_win_t *win);
rt_bool_t rtgui_win_close(struct rtgui_win *win); rt_bool_t rtgui_win_close(struct rtgui_win *win);
rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal); rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal);
void rtgui_win_hiden(rtgui_win_t *win); void rtgui_win_hide(rtgui_win_t *win);
void rtgui_win_end_modal(rtgui_win_t *win, rtgui_modal_code_t modal_code); void rtgui_win_end_modal(rtgui_win_t *win, rtgui_modal_code_t modal_code);
rt_err_t rtgui_win_activate(struct rtgui_win *win); rt_err_t rtgui_win_activate(struct rtgui_win *win);
rt_bool_t rtgui_win_is_activated(struct rtgui_win *win); rt_bool_t rtgui_win_is_activated(struct rtgui_win *win);

View File

@ -41,6 +41,7 @@ rt_err_t rtgui_graphic_set_device(rt_device_t device)
{ {
rt_err_t result; rt_err_t result;
struct rt_device_graphic_info info; struct rt_device_graphic_info info;
struct rtgui_graphic_ext_ops *ext_ops;
/* get framebuffer address */ /* get framebuffer address */
result = rt_device_control(device, RTGRAPHIC_CTRL_GET_INFO, &info); result = rt_device_control(device, RTGRAPHIC_CTRL_GET_INFO, &info);
@ -59,6 +60,13 @@ rt_err_t rtgui_graphic_set_device(rt_device_t device)
_driver.pitch = _driver.width * _driver.bits_per_pixel / 8; _driver.pitch = _driver.width * _driver.bits_per_pixel / 8;
_driver.framebuffer = info.framebuffer; _driver.framebuffer = info.framebuffer;
/* get graphic extension operations */
result = rt_device_control(device, RTGRAPHIC_CTRL_GET_EXT, &ext_ops);
if (result == RT_EOK)
{
_driver.ext_ops = ext_ops;
}
if (info.framebuffer != RT_NULL) if (info.framebuffer != RT_NULL)
{ {
/* is a frame buffer device */ /* is a frame buffer device */
@ -70,6 +78,11 @@ rt_err_t rtgui_graphic_set_device(rt_device_t device)
_driver.ops = rtgui_pixel_device_get_ops(_driver.pixel_format); _driver.ops = rtgui_pixel_device_get_ops(_driver.pixel_format);
} }
#ifdef RTGUI_USING_HW_CURSOR
/* set default cursor image */
rtgui_cursor_set_image(RTGUI_CURSOR_ARROW);
#endif
return RT_EOK; return RT_EOK;
} }
RTM_EXPORT(rtgui_graphic_set_device); RTM_EXPORT(rtgui_graphic_set_device);
@ -100,3 +113,27 @@ rt_uint8_t *rtgui_graphic_driver_get_default_framebuffer(void)
} }
RTM_EXPORT(rtgui_graphic_driver_get_default_framebuffer); RTM_EXPORT(rtgui_graphic_driver_get_default_framebuffer);
#ifdef RTGUI_USING_HW_CURSOR
void rtgui_cursor_set_position(rt_uint16_t x, rt_uint16_t y)
{
rt_uint32_t value;
if (_driver.device != RT_NULL)
{
value = (x << 16 | y);
rt_device_control(_driver.device, RT_DEVICE_CTRL_CURSOR_SET_POSITION, &value);
}
}
void rtgui_cursor_set_image(enum rtgui_cursor_type type)
{
rt_uint32_t value;
if (_driver.device != RT_NULL)
{
value = type;
rt_device_control(_driver.device, RT_DEVICE_CTRL_CURSOR_SET_TYPE, &value);
}
};
#endif

View File

@ -255,6 +255,10 @@ void rtgui_mouse_moveto(int x, int y)
rtgui_mouse_show_cursor(); rtgui_mouse_show_cursor();
#endif #endif
} }
#ifdef RTGUI_USING_HW_CURSOR
rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
#endif
} }
#ifdef RTGUI_USING_MOUSE_CURSOR #ifdef RTGUI_USING_MOUSE_CURSOR
@ -262,6 +266,17 @@ void rtgui_mouse_moveto(int x, int y)
#endif #endif
} }
void rtgui_mouse_set_position(int x, int y)
{
/* move current cursor */
_rtgui_cursor->cx = x;
_rtgui_cursor->cy = y;
#ifdef RTGUI_USING_HW_CURSOR
rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
#endif
}
#ifdef RTGUI_USING_MOUSE_CURSOR #ifdef RTGUI_USING_MOUSE_CURSOR
void rtgui_mouse_set_cursor_enable(rt_bool_t enable) void rtgui_mouse_set_cursor_enable(rt_bool_t enable)
{ {

View File

@ -31,6 +31,8 @@ typedef struct rtgui_mouse_monitor rtgui_mouse_monitor_t;
void rtgui_mouse_init(void); void rtgui_mouse_init(void);
void rtgui_mouse_fini(void); void rtgui_mouse_fini(void);
void rtgui_mouse_moveto(int x, int y); void rtgui_mouse_moveto(int x, int y);
/* set cursor position */
void rtgui_mouse_set_position(int x, int y);
void rtgui_mouse_set_cursor_enable(rt_bool_t enable); void rtgui_mouse_set_cursor_enable(rt_bool_t enable);
void rtgui_mouse_set_cursor(rtgui_image_t *cursor); void rtgui_mouse_set_cursor(rtgui_image_t *cursor);

View File

@ -22,9 +22,7 @@
#include "mouse.h" #include "mouse.h"
#include "topwin.h" #include "topwin.h"
static struct rt_thread *rtgui_server_tid; static struct rtgui_app *rtgui_server_app = RT_NULL;
static struct rtgui_app *rtgui_server_application = RT_NULL;
static struct rtgui_app *rtgui_wm_application = RT_NULL; static struct rtgui_app *rtgui_wm_application = RT_NULL;
void rtgui_server_handle_update(struct rtgui_event_update_end *event) void rtgui_server_handle_update(struct rtgui_event_update_end *event)
@ -57,6 +55,9 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
/* re-init to server thread */ /* re-init to server thread */
RTGUI_EVENT_MOUSE_BUTTON_INIT(event); RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
/* set cursor position */
rtgui_mouse_set_position(event->x, event->y);
#ifdef RTGUI_USING_WINMOVE #ifdef RTGUI_USING_WINMOVE
if (rtgui_winrect_is_moved() && if (rtgui_winrect_is_moved() &&
event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP)) event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP))
@ -87,7 +88,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
} }
/* send to client thread */ /* send to client thread */
rtgui_send(topwin->tid, &(ewin.parent), sizeof(ewin)); rtgui_send(topwin->app, &(ewin.parent), sizeof(ewin));
return; return;
} }
@ -100,9 +101,10 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
{ {
event->wid = wnd->wid; event->wid = wnd->wid;
if (rtgui_topwin_get_focus() != wnd) /* only raise window if the button is pressed down */
if (event->button & RTGUI_MOUSE_BUTTON_DOWN
&& rtgui_topwin_get_focus() != wnd)
{ {
/* raise this window */
rtgui_topwin_activate_topwin(wnd); rtgui_topwin_activate_topwin(wnd);
} }
@ -114,7 +116,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event)
else else
{ {
/* send mouse event to thread */ /* send mouse event to thread */
rtgui_send(wnd->tid, (struct rtgui_event *)event, sizeof(struct rtgui_event_mouse)); rtgui_send(wnd->app, (struct rtgui_event *)event, sizeof(struct rtgui_event_mouse));
} }
return ; return ;
} }
@ -146,7 +148,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse *event)
{ {
event->wid = last_monitor_topwin->wid; event->wid = last_monitor_topwin->wid;
/* send mouse motion event */ /* send mouse motion event */
rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(last_monitor_topwin->app, &(event->parent), sizeof(struct rtgui_event_mouse));
} }
if (last_monitor_topwin != win) if (last_monitor_topwin != win)
@ -157,7 +159,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse *event)
event->wid = last_monitor_topwin->wid; event->wid = last_monitor_topwin->wid;
/* send mouse motion event */ /* send mouse motion event */
rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(last_monitor_topwin->app, &(event->parent), sizeof(struct rtgui_event_mouse));
} }
} }
@ -183,7 +185,7 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd *event)
event->wid = wnd->wid; event->wid = wnd->wid;
/* send keyboard event to thread */ /* send keyboard event to thread */
rtgui_send(wnd->tid, (struct rtgui_event *)event, sizeof(struct rtgui_event_kbd)); rtgui_send(wnd->app, (struct rtgui_event *)event, sizeof(struct rtgui_event_kbd));
return; return;
} }
@ -207,7 +209,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
if (rtgui_wm_application != RT_NULL) if (rtgui_wm_application != RT_NULL)
{ {
/* forward event to wm application */ /* forward event to wm application */
rtgui_send(rtgui_wm_application->tid, event, sizeof(struct rtgui_event_application)); rtgui_send(rtgui_wm_application, event, sizeof(struct rtgui_event_application));
} }
else else
{ {
@ -349,12 +351,12 @@ static void rtgui_server_entry(void *parameter)
#endif #endif
/* create rtgui server application */ /* create rtgui server application */
rtgui_server_application = rtgui_app_create(rtgui_server_tid, rtgui_server_app = rtgui_app_create("rtgui");
"rtgui"); rt_kprintf("RTGUI: create server: %p", rtgui_server_app);
if (rtgui_server_application == RT_NULL) if (rtgui_server_app == RT_NULL)
return; return;
rtgui_object_set_event_handler(RTGUI_OBJECT(rtgui_server_application), rtgui_object_set_event_handler(RTGUI_OBJECT(rtgui_server_app),
rtgui_server_event_handler); rtgui_server_event_handler);
/* init mouse and show */ /* init mouse and show */
rtgui_mouse_init(); rtgui_mouse_init();
@ -362,24 +364,24 @@ static void rtgui_server_entry(void *parameter)
rtgui_mouse_show_cursor(); rtgui_mouse_show_cursor();
#endif #endif
rtgui_app_run(rtgui_server_application); rtgui_app_run(rtgui_server_app);
rtgui_app_destroy(rtgui_server_application); rtgui_app_destroy(rtgui_server_app);
rtgui_server_application = RT_NULL; rtgui_server_app = RT_NULL;
} }
void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size) void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size)
{ {
if (rtgui_server_tid != RT_NULL) if (rtgui_server_app != RT_NULL)
rtgui_send(rtgui_server_tid, event, size); rtgui_send(rtgui_server_app, event, size);
else else
rt_kprintf("post when server is not running\n"); rt_kprintf("post when server is not running\n");
} }
rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size) rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size)
{ {
if (rtgui_server_tid != RT_NULL) if (rtgui_server_app != RT_NULL)
return rtgui_send_sync(rtgui_server_tid, event, size); return rtgui_send_sync(rtgui_server_app, event, size);
else else
{ {
rt_kprintf("post when server is not running\n"); rt_kprintf("post when server is not running\n");
@ -387,18 +389,27 @@ rt_err_t rtgui_server_post_event_sync(struct rtgui_event *event, rt_size_t size)
} }
} }
struct rtgui_app* rtgui_get_server(void)
{
rt_thread_t tid = rt_thread_find("rtgui");
if (tid == RT_NULL)
return RT_NULL;
return (struct rtgui_app*)tid->user_data;
}
RTM_EXPORT(rtgui_get_server);
void rtgui_server_init(void) void rtgui_server_init(void)
{ {
if (rtgui_server_tid != RT_NULL) rt_thread_t tid;
return;
rtgui_server_tid = rt_thread_create("rtgui", tid = rt_thread_create("rtgui",
rtgui_server_entry, RT_NULL, rtgui_server_entry, RT_NULL,
RTGUI_SVR_THREAD_STACK_SIZE, RTGUI_SVR_THREAD_STACK_SIZE,
RTGUI_SVR_THREAD_PRIORITY, RTGUI_SVR_THREAD_PRIORITY,
RTGUI_SVR_THREAD_TIMESLICE); RTGUI_SVR_THREAD_TIMESLICE);
/* start rtgui server thread */ /* start rtgui server thread */
if (rtgui_server_tid != RT_NULL) if (tid != RT_NULL)
rt_thread_startup(rtgui_server_tid); rt_thread_startup(tid);
} }

View File

@ -102,7 +102,7 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create *event)
#else #else
topwin->extent = event->extent; topwin->extent = event->extent;
#endif #endif
topwin->tid = event->parent.sender; topwin->app = event->parent.sender;
if (event->parent_window == RT_NULL) if (event->parent_window == RT_NULL)
{ {
@ -337,7 +337,7 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin)
topwin->flag |= WINTITLE_ACTIVATE; topwin->flag |= WINTITLE_ACTIVATE;
event.wid = topwin->wid; event.wid = topwin->wid;
rtgui_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win)); rtgui_send(topwin->app, &(event.parent), sizeof(struct rtgui_event_win));
/* redraw title */ /* redraw title */
if (topwin->title != RT_NULL) if (topwin->title != RT_NULL)
@ -366,11 +366,11 @@ static void _rtgui_topwin_deactivate(struct rtgui_topwin *topwin)
struct rtgui_event_win event; struct rtgui_event_win event;
RT_ASSERT(topwin != RT_NULL); RT_ASSERT(topwin != RT_NULL);
RT_ASSERT(topwin->tid != RT_NULL); RT_ASSERT(topwin->app != RT_NULL);
RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event); RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event);
event.wid = topwin->wid; event.wid = topwin->wid;
rtgui_send(topwin->tid, rtgui_send(topwin->app,
&event.parent, sizeof(struct rtgui_event_win)); &event.parent, sizeof(struct rtgui_event_win));
topwin->flag &= ~WINTITLE_ACTIVATE; topwin->flag &= ~WINTITLE_ACTIVATE;
@ -495,7 +495,7 @@ static void _rtgui_topwin_draw_tree(struct rtgui_topwin *topwin, struct rtgui_ev
} }
epaint->wid = topwin->wid; epaint->wid = topwin->wid;
rtgui_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint)); rtgui_send(topwin->app, &(epaint->parent), sizeof(struct rtgui_event_paint));
rtgui_dlist_foreach(node, &topwin->child_list, prev) rtgui_dlist_foreach(node, &topwin->child_list, prev)
{ {
@ -748,7 +748,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event)
struct rtgui_event_paint epaint; struct rtgui_event_paint epaint;
RTGUI_EVENT_PAINT_INIT(&epaint); RTGUI_EVENT_PAINT_INIT(&epaint);
epaint.wid = topwin->wid; epaint.wid = topwin->wid;
rtgui_send(topwin->tid, &(epaint.parent), sizeof(epaint)); rtgui_send(topwin->app, &(epaint.parent), sizeof(epaint));
} }
return RT_EOK; return RT_EOK;
@ -945,7 +945,7 @@ static void rtgui_topwin_update_clip(void)
/* send clip event to destination window */ /* send clip event to destination window */
eclip.wid = top->wid; eclip.wid = top->wid;
rtgui_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info)); rtgui_send(top->app, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
/* move to next sibling tree */ /* move to next sibling tree */
if (top->parent == RT_NULL) if (top->parent == RT_NULL)
@ -991,7 +991,7 @@ static void _rtgui_topwin_redraw_tree(struct rtgui_dlist_node *list,
if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK) if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK)
{ {
epaint->wid = topwin->wid; epaint->wid = topwin->wid;
rtgui_send(topwin->tid, &(epaint->parent), sizeof(*epaint)); rtgui_send(topwin->app, &(epaint->parent), sizeof(*epaint));
/* draw title */ /* draw title */
if (topwin->title != RT_NULL) if (topwin->title != RT_NULL)
@ -1059,7 +1059,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin *win, struct rtgui_event_mou
if (rtgui_rect_contains_point(&win->extent, event->x, event->y) == RT_EOK) if (rtgui_rect_contains_point(&win->extent, event->x, event->y) == RT_EOK)
{ {
/* send mouse event to thread */ /* send mouse event to thread */
rtgui_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(win->app, &(event->parent), sizeof(struct rtgui_event_mouse));
return; return;
} }
@ -1098,7 +1098,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin *win, struct rtgui_event_mou
/* send close event to window */ /* send close event to window */
RTGUI_EVENT_WIN_CLOSE_INIT(&event); RTGUI_EVENT_WIN_CLOSE_INIT(&event);
event.wid = win->wid; event.wid = win->wid;
rtgui_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win)); rtgui_send(win->app, &(event.parent), sizeof(struct rtgui_event_win));
} }
} }
} }

View File

@ -0,0 +1,49 @@
perfect_hash.py
Ilan Schnell <ilanschnell@gmail.com>, 2008
Generate a minimal perfect hash function for the keys in a file,
desired hash values may be specified within this file as well.
A given code template is filled with parameters, such that the
output is code which implements the hash function.
Templates can easily be constructed for any programming language.
The code is based on an a program A.M. Kuchling wrote:
http://www.amk.ca/python/code/perfect-hash
The algorithm the program uses is described in the paper
'Optimal algorithms for minimal perfect hashing',
Z. J. Czech, G. Havas and B.S. Majewski.
http://citeseer.ist.psu.edu/122364.html
Content:
perfect_hash.py The actual program, try $ ./perfect_hash.py animals.txt
doc HTML and plain text documentation
example1-C An example which shows how to generate a C program
which implements a perfect hash table.
example2-C Another example in C.
example-C++ In this C++ example, a class is used to define the
interface to a static lookup table.
example-PyModule A lookup table in implemented as a C extension module
for Python.
example-Python Some small Python programs which show how to access
some functions and classes in perfect_hash.py directly,
i.e. using perfect_hash has a Python module, rather
than a standalone program.
graph A small program `py2dot' which converts the default python
output code from perfect_hash.py into a .dot-file which
can be used by Graphviz (see http://www.graphviz.org/) to
create a picture of the graph.
run Runs some tests.

View File

@ -0,0 +1,7 @@
# 'animals.txt'
Elephant
Horse
Camel
Python
Dog
Cat

View File

@ -0,0 +1,22 @@
all: doc.html doc.txt
doc.html: doc.in parameters.txt mktable.py
./mktable.py >table.html
markdown doc.in | \
sed -e "s,<h6>table</h6>,m4_include(\`table.html')," | \
m4 -P >doc.html
rm table.html
doc.txt: doc.in parameters.txt
sed <doc.in -e "s,###### table,m4_include(\`parameters.txt')," \
-e "s,\`\([^\`]*\)\`,'\1',g" | m4 -P >doc.txt
clean:
rm doc.html doc.txt

View File

@ -0,0 +1,136 @@
<h2>Generic Perfect Hash Generator</h2>
<p><em>Ilan Schnell, 2008</em>
</p>
<p>perfect_hash.py provides a perfect hash generator which is not language
specific. That is, the generator can output a perfect hash function for
a given set of keys in any programming language, this is achieved by
filling a given code template.
</p>
<h3>Acknowledgments:</h3>
<p>This code is derived from A. M. Kuchling's
<a href="http://www.amk.ca/python/code/perfect-hash">Perfect Minimal Hash Generator</a>.
</p>
<h3>Introduction:</h3>
<p>A perfect hash function of a certain set S of keys is a hash function
which maps all keys in S to different numbers.
That means that for the set S,
the hash function is collision-free, or perfect.
Further, a perfect hash function is called minimal when it maps n keys
to n <em>consecutive</em> integers, usually in the range from 0 to n-1.
</p>
<p>After coming across A. M. Kuchling's Perfect Minimal Hash Generator,
I decided to write a general tool for generating perfect hashes.
It is general in the sense that it can produce perfect hash functions
for almost any programming language.
A given code template is filled with parameters,
such that the output is code which implements the hash function.
</p>
<p>The algorithm the program uses is described in the paper
<a href="http://citeseer.ist.psu.edu/122364.html">&quot;Optimal algorithms for minimal perfect hashing&quot;</a>,
Z. J. Czech, G. Havas and B.S. Majewski.
</p>
<p>I tried to illustrate the algorithm and explain how it works on
<a href="http://ilan.schnell-web.net/prog/perfect-hash/algo.html">this page</a>.
</p>
<h3>Usage:</h3>
<p>Given a set of keys which are ordinary character string,
the program returns a minimal perfect hash function.
This hash function is returned in the form of Python code by default.
Suppose we have a file with keys:
</p>
<pre><code># 'animals.txt'
Elephant
Horse
Camel
Python
Dog
Cat
</code></pre><p>The exact way this file is parsed can be specified using command line
options, for example it is possible to only read one column from a file
which contains different items in each row.
The program is invoked like this:
</p>
<pre><code># =======================================================================
# ================= Python code for perfect hash function ===============
# =======================================================================
G = [0, 0, 4, 1, 0, 3, 8, 1, 6]
S1 = [5, 0, 0, 6, 1, 0, 4, 7]
S2 = [7, 3, 6, 7, 8, 5, 7, 6]
def hash_f(key, T):
return sum(T[i % 8] * ord(c) for i, c in enumerate(str(key))) % 9
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % 9
# ============================ Sanity check =============================
K = [&quot;Elephant&quot;, &quot;Horse&quot;, &quot;Camel&quot;, &quot;Python&quot;, &quot;Dog&quot;, &quot;Cat&quot;]
H = [0, 1, 2, 3, 4, 5]
assert len(K) == len(H) == 6
for k, h in zip(K, H):
assert perfect_hash(k) == h
</code></pre><p>The way the program works is by filling a code template with the calculated
parameters. The program can take such a template in form of a file and
fill in the calculated parameters, this allows the generation of perfect
hash function in any programming language. The hash function is kept quite
simple and does not require machine or language specific byte level operations
which might be hard to implement in the target language.
The following parameters are available in the template, and will expand to:
</p>
<table>
<tr><th>string</th><th>expands to</th></tr>
<tr><td><code>$NS</code></td><td>the length of S1 and S2</td></tr>
<tr><td><code>$S1</code></td><td>array of integers S1</td></tr>
<tr><td><code>$S2</code></td><td>array of integers S2</td></tr>
<tr><td><code>$NG</code></td><td>length of array G</td></tr>
<tr><td><code>$G</code></td><td>array of integers G</td></tr>
<tr><td><code>$NK</code></td><td>the number of keys, i.e. length of array K and H</td></tr>
<tr><td><code>$K</code></td><td>array with the quoted keys</td></tr>
<tr><td><code>$H</code></td><td>array of integer hash values</td></tr>
<tr><td><code>$$</code></td><td><code>$</code> (a literal dollar sign)</td></tr>
</table>
<p>A literal <code>$</code> is escaped as <code>$$</code>. Since the syntax for arrays is not the
same in all programming languages, some specifics can be adjusted using
command line options.
The section of the built-in template which creates the actual hash function
is:
</p>
<pre><code>G = [$G]
S1 = [$S1]
S2 = [$S2]
def hash_f(key, T):
return sum(T[i % $NS] * ord(c) for i, c in enumerate(str(key))) % $NG
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % $NG
</code></pre><p>Using code templates, makes this program very flexible. The package comes
with several complete examples for C and C++. There are many choices one
faces when implementing a static hash table: do the parameter lists go into
a separate header file, should the API for the table only contain the hash
values, but not the objects being mapped, and so on.
All these various choices are possible because of the template is simply
filled with the parameters, no matter what else is inside the template.
</p>
<p>Another possible use the program is as a python module. The functions and
classes in <code>perfect_hash.py</code> are documented and have clean interfaces.
The folder <code>example-Python</code> has examples which shows how the module
can be used directly in this way.
</p>
<h3>Requirement:</h3>
<p>Python 2.5
</p>

View File

@ -0,0 +1,130 @@
Generic Perfect Hash Generator
------------------------------
*Ilan Schnell, 2008*
perfect_hash.py provides a perfect hash generator which is not language
specific. That is, the generator can output a perfect hash function for
a given set of keys in any programming language, this is achieved by
filling a given code template.
### Acknowledgments:
This code is derived from A. M. Kuchling's
[Perfect Minimal Hash Generator](http://www.amk.ca/python/code/perfect-hash).
### Introduction:
A perfect hash function of a certain set S of keys is a hash function
which maps all keys in S to different numbers.
That means that for the set S,
the hash function is collision-free, or perfect.
Further, a perfect hash function is called minimal when it maps n keys
to n *consecutive* integers, usually in the range from 0 to n-1.
After coming across A. M. Kuchling's Perfect Minimal Hash Generator,
I decided to write a general tool for generating perfect hashes.
It is general in the sense that it can produce perfect hash functions
for almost any programming language.
A given code template is filled with parameters,
such that the output is code which implements the hash function.
The algorithm the program uses is described in the paper
["Optimal algorithms for minimal perfect hashing"]
(http://citeseer.ist.psu.edu/122364.html),
Z. J. Czech, G. Havas and B.S. Majewski.
I tried to illustrate the algorithm and explain how it works on
[this page](http://ilan.schnell-web.net/prog/perfect-hash/algo.html).
### Usage:
Given a set of keys which are ordinary character string,
the program returns a minimal perfect hash function.
This hash function is returned in the form of Python code by default.
Suppose we have a file with keys:
# 'animals.txt'
Elephant
Horse
Camel
Python
Dog
Cat
The exact way this file is parsed can be specified using command line
options, for example it is possible to only read one column from a file
which contains different items in each row.
The program is invoked like this:
# =======================================================================
# ================= Python code for perfect hash function ===============
# =======================================================================
G = [0, 0, 4, 1, 0, 3, 8, 1, 6]
S1 = [5, 0, 0, 6, 1, 0, 4, 7]
S2 = [7, 3, 6, 7, 8, 5, 7, 6]
def hash_f(key, T):
return sum(T[i % 8] * ord(c) for i, c in enumerate(str(key))) % 9
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % 9
# ============================ Sanity check =============================
K = ["Elephant", "Horse", "Camel", "Python", "Dog", "Cat"]
H = [0, 1, 2, 3, 4, 5]
assert len(K) == len(H) == 6
for k, h in zip(K, H):
assert perfect_hash(k) == h
The way the program works is by filling a code template with the calculated
parameters. The program can take such a template in form of a file and
fill in the calculated parameters, this allows the generation of perfect
hash function in any programming language. The hash function is kept quite
simple and does not require machine or language specific byte level operations
which might be hard to implement in the target language.
The following parameters are available in the template, and will expand to:
###### table
A literal `$` is escaped as `$$`. Since the syntax for arrays is not the
same in all programming languages, some specifics can be adjusted using
command line options.
The section of the built-in template which creates the actual hash function
is:
G = [$G]
S1 = [$S1]
S2 = [$S2]
def hash_f(key, T):
return sum(T[i % $NS] * ord(c) for i, c in enumerate(str(key))) % $NG
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % $NG
Using code templates, makes this program very flexible. The package comes
with several complete examples for C and C++. There are many choices one
faces when implementing a static hash table: do the parameter lists go into
a separate header file, should the API for the table only contain the hash
values, but not the objects being mapped, and so on.
All these various choices are possible because of the template is simply
filled with the parameters, no matter what else is inside the template.
Another possible use the program is as a python module. The functions and
classes in `perfect_hash.py` are documented and have clean interfaces.
The folder `example-Python` has examples which shows how the module
can be used directly in this way.
### Requirement:
Python 2.5

View File

@ -0,0 +1,141 @@
Generic Perfect Hash Generator
------------------------------
*Ilan Schnell, 2008*
perfect_hash.py provides a perfect hash generator which is not language
specific. That is, the generator can output a perfect hash function for
a given set of keys in any programming language, this is achieved by
filling a given code template.
### Acknowledgments:
This code is derived from A. M. Kuchling's
[Perfect Minimal Hash Generator](http://www.amk.ca/python/code/perfect-hash).
### Introduction:
A perfect hash function of a certain set S of keys is a hash function
which maps all keys in S to different numbers.
That means that for the set S,
the hash function is collision-free, or perfect.
Further, a perfect hash function is called minimal when it maps n keys
to n *consecutive* integers, usually in the range from 0 to n-1.
After coming across A. M. Kuchling's Perfect Minimal Hash Generator,
I decided to write a general tool for generating perfect hashes.
It is general in the sense that it can produce perfect hash functions
for almost any programming language.
A given code template is filled with parameters,
such that the output is code which implements the hash function.
The algorithm the program uses is described in the paper
["Optimal algorithms for minimal perfect hashing"]
(http://citeseer.ist.psu.edu/122364.html),
Z. J. Czech, G. Havas and B.S. Majewski.
I tried to illustrate the algorithm and explain how it works on
[this page](http://ilan.schnell-web.net/prog/perfect-hash/algo.html).
### Usage:
Given a set of keys which are ordinary character string,
the program returns a minimal perfect hash function.
This hash function is returned in the form of Python code by default.
Suppose we have a file with keys:
# 'animals.txt'
Elephant
Horse
Camel
Python
Dog
Cat
The exact way this file is parsed can be specified using command line
options, for example it is possible to only read one column from a file
which contains different items in each row.
The program is invoked like this:
# =======================================================================
# ================= Python code for perfect hash function ===============
# =======================================================================
G = [0, 0, 4, 1, 0, 3, 8, 1, 6]
S1 = [5, 0, 0, 6, 1, 0, 4, 7]
S2 = [7, 3, 6, 7, 8, 5, 7, 6]
def hash_f(key, T):
return sum(T[i % 8] * ord(c) for i, c in enumerate(str(key))) % 9
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % 9
# ============================ Sanity check =============================
K = ["Elephant", "Horse", "Camel", "Python", "Dog", "Cat"]
H = [0, 1, 2, 3, 4, 5]
assert len(K) == len(H) == 6
for k, h in zip(K, H):
assert perfect_hash(k) == h
The way the program works is by filling a code template with the calculated
parameters. The program can take such a template in form of a file and
fill in the calculated parameters, this allows the generation of perfect
hash function in any programming language. The hash function is kept quite
simple and does not require machine or language specific byte level operations
which might be hard to implement in the target language.
The following parameters are available in the template, and will expand to:
string | expands to
--------+--------------------------------
$NS | the length of S1 and S2
$S1 | array of integers S1
$S2 | array of integers S2
$NG | length of array G
$G | array of integers G
$NK | the number of keys, i.e. length of array K and H
$K | array with the quoted keys
$H | array of integer hash values
$$ | $ (a literal dollar sign)
A literal '$' is escaped as '$$'. Since the syntax for arrays is not the
same in all programming languages, some specifics can be adjusted using
command line options.
The section of the built-in template which creates the actual hash function
is:
G = [$G]
S1 = [$S1]
S2 = [$S2]
def hash_f(key, T):
return sum(T[i % $NS] * ord(c) for i, c in enumerate(str(key))) % $NG
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % $NG
Using code templates, makes this program very flexible. The package comes
with several complete examples for C and C++. There are many choices one
faces when implementing a static hash table: do the parameter lists go into
a separate header file, should the API for the table only contain the hash
values, but not the objects being mapped, and so on.
All these various choices are possible because of the template is simply
filled with the parameters, no matter what else is inside the template.
Another possible use the program is as a python module. The functions and
classes in 'perfect_hash.py' are documented and have clean interfaces.
The folder 'example-Python' has examples which shows how the module
can be used directly in this way.
### Requirement:
Python 2.5

View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
import re
def convert(line, head = False):
pat = re.compile(r'([$]\S*)')
line = pat.sub(r'<code>\1</code>', line)
row = [x.strip() for x in line.split('|')]
fmt = ' <tr><td>%s</td><td>%s</td></tr>'
if head:
fmt = fmt.replace('td', 'th')
print fmt % tuple(row)
f = file('parameters.txt')
print '<table>'
convert(f.readline(), head = True)
f.readline()
for line in f:
convert(line)
print '</table>'

View File

@ -0,0 +1,11 @@
string | expands to
--------+--------------------------------
$NS | the length of S1 and S2
$S1 | array of integers S1
$S2 | array of integers S2
$NG | length of array G
$G | array of integers G
$NK | the number of keys, i.e. length of array K and H
$K | array with the quoted keys
$H | array of integer hash values
$$ | $ (a literal dollar sign)

View File

@ -0,0 +1,31 @@
CXX = g++ -Wall
lookup: main.o states-code.o
$(CXX) -o $@ $^
main.o: main.cc states-code.hh
$(CXX) -c $<
states-code.o: states-code.cc states-code.hh states.dat.h
$(CXX) -c $<
states-code.cc: states.dat states-tmpl.cc states-code.hh
../perfect_hash.py --splitby '|' --keycol 2 states.dat states-tmpl.cc
states.dat.h: states.dat
./mk_header.py >$@
clean:
rm lookup *.o states.dat.h states-code.cc
test:
./lookup 'NY'
./lookup 'QW'

View File

@ -0,0 +1,24 @@
#include <iostream>
#include <string>
using namespace std;
#include "states-code.hh"
int main (int argc, char *argv[])
{
if (argc != 2) {
printf ("Usage: %s <abbreviation>\n", argv[0]);
return 2;
}
string abbr = argv[1];
State s(abbr);
cout << "The state of " << s.name ()
<< " has a population of " << 1e-6 * s.population () << " million.\n";
return 0;
}

View File

@ -0,0 +1,10 @@
#!/usr/bin/env python
for line in file('states.dat'):
line = line.strip()
if line.startswith('#'):
continue
row = tuple(entry.strip() for entry in line.split('|'))
print ' { "%s", "%s", %s },' % row

View File

@ -0,0 +1,19 @@
#include <string>
using namespace std;
class State
{
public:
State (const string abbr);
string name () const { return nam; };
int population () const { return pop; };
private:
string nam;
int pop;
};

View File

@ -0,0 +1,55 @@
#include <string.h>
#include <iostream>
#include "states-code.hh"
static struct {
char *name;
char *abbr;
int pop;
} states[$NK] = {
#include "states.dat.h"
};
static int T1[] = { $S1 };
static int T2[] = { $S2 };
static int G[] = { $G };
static int hash_g (const char *key, const int *T)
{
int i, sum = 0;
for (i = 0; key[i] != '\0'; i++) {
sum += T[i] * key[i];
sum %= $NG;
}
return G[sum];
}
static int perfect_hash (const char *key)
{
if (strlen (key) > $NS)
return 0;
return (hash_g (key, T1) + hash_g (key, T2)) % $NG;
}
State::State (const string abbr)
{
int hash_value = perfect_hash (abbr.c_str ());
if (hash_value < $NK &&
strcmp(abbr.c_str (), states[hash_value].abbr) == 0)
{
nam = states[hash_value].name;
pop = states[hash_value].pop;
}
else
{
cerr << "'" << abbr << "' is not an abbreviation for a state\n";
}
}

View File

@ -0,0 +1,52 @@
# Name | Abr | Population
#--------------+------+---------
Alabama | AL | 4335400
Alaska | AK | 611500
Arizona | AZ | 4664600
Arkansas | AR | 2531000
California | CA | 33198100
Colorado | CO | 3930700
Connecticut | CT | 3271100
Delaware | DE | 736900
Florida | FL | 15012200
Georgia | GA | 7562200
Hawaii | HI | 1188400
Idaho | ID | 1221500
Illinois | IL | 11981700
Indiana | IN | 5882500
Iowa | IA | 2854700
Kansas | KS | 2603200
Kentucky | KY | 3921000
Louisiana | LA | 4361200
Maine | ME | 1243700
Maryland | MD | 5122400
Massachusetts | MA | 6133500
Michigan | MI | 9825100
Minnesota | MN | 4704200
Mississippi | MS | 2739700
Missouri | MO | 5421400
Montana | MT | 886400
Nebraska | NE | 1661400
Nevada | NV | 1828700
New Hampshire | NH | 1179100
New Jersey | NJ | 8078300
New Mexico | NM | 1738700
New York | NY | 18197800
North Carolina | NC | 7483100
North Dakota | ND | 640000
Ohio | OH | 11197900
Oklahoma | OK | 3328100
Oregon | OR | 3266800
Pennsylvania | PA | 12044200
Rhode Island | RI | 987000
South Carolina | SC | 3781800
South Dakota | SD | 738500
Tennessee | TN | 5398200
Texas | TX | 19274300
Utah | UT | 2071500
Vermont | VT | 590400
Virginia | VA | 6768400
Washington | WA | 5674900
West Virginia | WV | 1813200
Wisconsin | WI | 5224500
Wyoming | WY | 479500

View File

@ -0,0 +1,26 @@
CC = gcc -Wall
stations.so: stationsmodule.c stations.dat.h stations-code.h
$(CC) -shared -fPIC -I/usr/local/include/python2.5 \
-o stations.so stationsmodule.c
stations.dat.h: stations.dat
sed <$< >$@ -e 's:\([^,]*\),\([^,]*\): { "\1", "\2" },:'
stations-code.h: stations.dat stations-tmpl.h
../perfect_hash.py --trails 2 $^
clean:
rm stations-code.h stations.dat.h stations.so
test:
python -c "import stations; print stations.locator('DL5BAC')"

View File

@ -0,0 +1,12 @@
#define NK $NK /* number of keys */
#define NG $NG /* number of vertices */
#define NS $NS /* elements in T */
int G[] = { $G };
int T1[] = { $S1 };
int T2[] = { $S2 };

View File

@ -0,0 +1,500 @@
DL0WM,JO40HM
DM4WDK,JO50OI
M0GHZ,IO81VK
ON2CP,JO21IG
PI4UTR,JO22MC
DO2YMH,JO41AT
ON1GZ,JO20FW
DL5QQ,JO32KB
M0HKB,JO02OB
ON4LBT,JO10WK
SM7VTW,JO65QQ
PA3AYD,JO21UU
DO3LTK,JO43XS
DC0NAC,JO43VI
PD0LQQ,JO20VS
DO1YMJ,JO31WS
DL1EJL,JO31FS
DG3TF,JO53IU
ON1AEN,JO10VW
DL1KDA,JO30FQ
SM7LHI,JO65PO
DG1EIP,JO31JL
PD1AKT,JO22TA
DN1GSK,JO62NL
OQ1AEN,JO10VW
DG9YIH/M,JO31TR
G0UYC,JO02MR
F1PGL,JO20IE
DO1KNB,JO30NQ
DL5NEN,JN59OP
DL1RNO,JO62FK
DO8EF,JO31KK
DL6IY,JN49NI
ON4NOK,JO21LO
DO9MH,JO33QO
PA0PTS,JO23TF
G5LK,IO91SK
DJ6XV,JO31LQ
ON4ARF,JO10MV
PE1OJB,JO22IN
DH1BBO,JO42FS
M1DNJ,JO01GJ
PA0BVD,JO23TF
ON1CJQ,JO10OV
DL2NFX,JN59JU
DL4HG,JO53CM
DG3BEO,JO43JF
OZ4EDR,JO75JF
DD1LT/P,JO44TK
G4OXD,IO91UW
DG1KZF,JO31RN
DO2YPB,JO41JR
DO3JJ,JO31QM
DO5YLM,JO42GA
DL2IAN,JN49BC
PA0ME,JO22OB
DC5PN,JN49HV
PA9JP,JO32MS
PD5RD,JO21IT
PE1PQV,JO32JG
OZ3TT,JO66CB
DO9KS,JO43CE
DJ8MS/P,JO63CT
ON4KBE,JO20BI
PE1JVV,JO21GV
DH0EAQ,JO31IK
DG9RCI,JN59PH
DO6UWE/P,JO31OI
DB7LG,JO44TH
DD5JK,JO31RO
DG6LSW,JO44SP
M1MGD,IO91VC
DL6YAU,JO44PJ
PE1OLM,JO23TF
DG0DRF,JO71JJ
DG3YCB,JO41KV
DF7JS,JO31JM
OZ2NAC,JO55RT
DJ5JD,JO33OO
PA3DHR,JO21DU
PE2JMR,JO33HG
OZ1XAT/A,JO55UL
PA3GKH,JO32HK
G4DCJ,JO02IT
DL4NAC,JN59SV
DF0DS,JO31RM
GW7SMV,IO81LN
DO1AYJ,JO50SU
DL0BAC,JO30BS
DL0JRR,JO31CT
OZ7HAM,JO65CL
DK0ALK,JN38TD
DO6DIB,JO43DA
PA3GTC,JO32LR
DD1LI,JO43WO
DG9ACT/P,JO42QH
PE1PMG,JO31BH
SK7OL,JO66NC
DH0JB,JO31CH
OQ1ARQ,JO10VX
DD7ZT,JO40DH
DL1JJ,JO31IA
DL1EEX,JO31MA
ON4CDF,JO21EE
DL0SE,JO31PG
DO3YY,JO31QM
DK0HC,JO40OQ
DC8BQ,JO31KE
DG1LAR,JO43UP
OZ/DL0IZ/P,JO45GD
DG3TD,JO44GQ
DL6OBH,JO42QI
PA0JCS,JO21DN
DG0OJG,JO50MX
DO1KFB,JO30CS
SM60EW,JO67DA
G4MRS/P,JO01MU
DL5DBM,JO32WO
DK3BM,JO42LH
DD9DV,JO31TO
DO1DQ,JO31TL
OZ5AEK,JO55XO
DG1YAR,JO41CR
OO6LY,JO21LH
DL1PR,JO30JS
DL5ZAB,JO40HC
DO1MGN,JO50DO
SM7UPF,JO65TO
DO1NNN,JO50VF
DK5BD,JO42IX
DL3OCA,JO42VH
HB9MPX,JN47RJ
DG4KAS,JO30DU
DF1UF,JN49HK
DC6GF/P,JN47NX
DG7ES,JN68GI
DF0NF,JO44UH
DG8EKI,JO31MI
OZ9CLN,JO56CE
SK7MW,JO65MJ
DL9ECA,JO31CQ
DF9IC,JN48IW
PD9FJ,JO23KE
DL4LBO,JO43XT
DF0WD,JO42FD
DH4PSG,JO31NN
LA0BY,JO59IX
DJ5FK,JO42SH
DO1ASM,JO50LQ
DL9KCM,JO30IS
DG6MBS,JO41AH
OZ2SYV,JO54RS
DL0HMS,JO42MC
DL2PZ,JN49DW
DG5NEP/P,JO50VF
SM6VKC,JO68CG
DF8AA/P,JO71AA
PA1WM,JO21WW
DO3BTL,JO43HB
PA3GGN,JO21LU
DF1VW,JN39HJ
DJ5KX,JO30PQ
ON1LPA,JO20XO
DJ5QW,JO32SF
G4AJC,IO91VJ
OZ7P,JO45SQ
G4MRS,JO02PB
PD0ZX,JO22QF
DB5BR,JO42FS
DO1JRA,JO42GF
DL1DUF,JO62EJ
DO2NHD,JO40MB
DG6DDE,JO31UM
PA3FBP,JO33GB
DC1GUN,JN68GG
DO2BO,JO33RM
OZ6AQ,JO44UX
OZ1QQ,JO47XG
DG1YBT,JO32QD
DL9YEY,JO41GV
DG1YIV,JO42HF
DB2WD,JN39VV
DF0UKW,JN49HN
OZ1BEF/P,JO46SB
PE1ISU,JO21WD
DO1KOH,JO30HR
DK9SS,JN48OM
PE1OPK,JO23UE
DG3GAQ,JN48GE
DO2FX,JO40LH
SK7BT,JO65MO
OZ1FHU,JO55SR
SK6QW,JO68WR
DL4FBN,JO30WC
DG3FCT,JO41RB
OE2SCM,JN67OV
PA0ZM,JO32GK
DL0MQ,JO41EV
DB3WR,JO31DG
ON2BFV,JO11XA
DJ5DM,JO31FF
G6FPQ,IO91XI
DJ0VZ,JO30GL
OO2WIM,JO20OR
DG7RZ/P,JN59WK
DL5QN,JO42HC
DC9XX,JO43QR
SM7SLU,JO65ML
F1PYW,JN38UP
DG2NJ,JN68OL
DJ5KM,JO42GA
DL3TS,JO30PX
DG4YIE/P,JO41PU
DL0RSH,JO43SV
PE1RYU,JO21GU
DJ3QB,JO32MF
DG4KBY/P,JO42CW
PA3GSX,JO32DM
DG1YRT,JO41KW
DG9BEY,JO42AH
PA3EXO,JO32GW
PE1OPH,JO22XF
DO9FB,JN49BP
F0EUE,JN29VM
G4RRA/P,IO70XR
DL0EDD,JO31IF
SM7MRL,JO66KC
DK5JM,JO43QS
DJ3NU,JO31SL
DH6YMC,JO32MF
DL1DAX,JO31RM
DC4KM,JO30XO
F1TUE,JN38DR
DO4ME,JO43KC
ON7CC,JO10XM
DL1PBC,JO30VJ
DL3IAE,JN49DE
DL1SDN,JN48PP
DL4ANT,JN49LF
DH1NHI,JO50VF
DO1BR,JO42AE
G4ODA,IO92WS
DB2DJ,JO31RM
DL8LAH,JO44QQ
DH9NBB,JN49WS
F1LPV,JO10NP
DL3SF,JO32MF
SM7VXT,JO65NU
DL4LCA/P,JO44XF
DL3FDL,JO40KR
SM7XEN,JO65RL
DL6ABO,JO52GH
EI7IW,IO63SS
DC1QU,JO31TW
DG0OCW,JO50CT
SM7XWM,JO86AJ
ON2MRT,JO20MX
DA0GSN,JO31HB
DL8FBC,JO41UF
F1DBN/P,JO00WT
DJ6CB,JO42JW
DL1SUZ,JO53UN
DJ5NU,JO31QH
DL0SOP,JO54WC
DO1MGN/P,JO50AN
OK1BYR,JN79IP
PD0RAA,JO22WK
DJ9DL,JO31NC
DK5WO,JO30AS
OZ8FYN,JO55EJ
DO1FDR,JO41PD
ON2BIV,JO10RX
ON4AEO,JO10OW
DL4MB,JN49FA
GW4HBZ/P,IO83GC
OZ1BEF,JO46OE
PE0NYJ,JO21VT
DO3LBP,JO43MW
DB3BW,JO42AC
DF6YL,JO31WS
DP0RFU,JO32LS
DF4BV,JO43RH
DJ6GV,JO52HG
DG7KAQ,JO30FS
DH1YPH,JO31VL
SM7JUQ,JO65PO
DG7ACF,JO42UI
DG6NBL,JN59LL
OK1MCS,JN69QR
DL1REM,JO32MF
DN1RDT,JN59WK
OZ3FYN/P,JO55BJ
DB0GSN,JO31JC
DC1GUN/P,JN68GI
DJ1DH/P,JO53BG
DO1RSG/P,JN68KX
PD0FFU,JO20UU
DO8DW,JO31SO
DL8II,JN49GP
PA3DRL,JO21PS
DG8LG,JO44VP
PD0EBF,JO21LQ
OZ9BO,JO46HE
DO3NML,JN59SV
DJ3BP,JO42CX
F6IRS,JN38VN
F5SMZ,JN39EJ
GM1TDU,IO87WE
DL5BAC,JO43LG
DO7OCH,JO51AT
DL1HRY,JO61AD
DK7VA,JO32MK
SM7JPI,JO75DW
DL0GC,JO31CQ
M1IFT,IO93NL
DF5AY,JN49DX
DG1IHH,JN49GJ
DO5BRH,JO43CE
DK6AJ,JO52GH
DL0NF,JN59PL
DG1BHM,JO43PC
DK3RV,JO31DG
DD8EI,JO31NC
PD2PL,JO22HD
DL0GL,JO31LN
DC1PJA,JN49DV
PD2GCM,JO21ET
SI7GM,JO65MO
DG6MOG,JO52XN
OQ4CJU,JO20PS
DG1DPN,JO31RL
DK0BA,JO43NF
DL2HQ,JN48FX
PA4PS,JO33GH
DK0EE,JN58TG
DD9PL,JN49CN
PB0AOK,JO32IH
DC2OOO,JN39NI
DL0NS,JO31IE
ON4BAK,JO31PA
G4DCV,IO91OF
DG4FFF,JO40FA
G3BNE,JO01BJ
DO2GN,JO31PM
DD7PA/P,JN49LM
OZ0A/P,JO55UL
DL8BEV,JO43JH
DJ8UV,JO31OF
PE1PMV,JO32JG
DL8AX,JO31ID
PE1RER,JO22SA
PD0RKC,JO33AD
DC4ASK,JO31MI
DG1YCF,JO42KH
SK7PL,JO76DJ
M1MHZ,IO92WV
DF9PX/P,JO30JF
DG0OZ,JO50LU
DB1BMN/P,JO43HA
DH2UD/P,JO44XS
OZ5AGJ,JO56DF
OZ3AEV,JO55WR
PA1JAN,JO32KV
PE7MO,JO32KR
LA7M,JO48KK
PA1TX,JO32JG
OZ7DAL,JO56IE
PE1PED,JO22QE
DL0WH,JN49HN
DL9KI,JO42GE
M0AIJ,IO92PA
DG0CAL/P,JO31BC
DG1YFF,JO42IG
OZ4DR,JO55WL
G8RWG,JO01BN
OZ3RIN,JO55VK
SM7VXS,JO65UV
DL9EBI,JO31IE
PD5FDV,JO21HV
DL5XB,JO43UL
DJ9IQ,JO30OI
PE1NNX,JO22JN
DB2YC,JO32OF
PA5WT,JO22HG
DO2PK,JO41NW
PE1BVW,JO21DO
DL0TS,JO40FC
DB9KR,JO41DQ
DO1ZB,JO64II
DO4YPM,JO32QI
G0VJG,JO01BL
DD2YCS,JO43FE
DO7MH,JO31MT
G3JHM,IO91LC
DL8FAJ,JO51AD
DG4FR,JO31OJ
ON1DNF,JO20NU
DO4FMK,JO40MF
PI4THT,JO32KF
DK4LI,JO44WQ
DD3FU,JO40IE
DF1LON/P,JO31LH
DL2ARD/P,JO60AR
DH9YBC,JO42HE
G3OHC,IO93KS
DK0HF,JO42IF
DF6QB,JO31WW
DO3HN,JO31LK
M3RCV,JO01AL
DL0SAT,JO41XO
DD7PC,JN49AX
DL2LSM,JO61HH
PA3HHT,JO22QC
PD2OPA,JO21BT
DL0VR,JO31MI
EI3GE,IO63XD
DF9CY,JO54AL
DL1AH,JO42TX
DL1PW,JN49DV
DC9CZ,JO42GA
PA3FJY/P,JO32FI
DG5BGB,JO43HB
ON7LAO,JO20CK
DG0SY,JO54VC
DK5KC,JO30DS
DG6YJ,JO32RB
OO4BAX,JO21IH
DO1LNK,JO53EK
DJ3LE,JO44SK
DO1YCI,JO31NO
DJ8TA,JO41BU
DL8BAV,JO43MF
DO1RSG,JN68ET
DO1PIA,JO31PM
DL1AUW/P,JO51CH
DL0VV,JO64AD
DL3JAN/P,JO60KS
ON50ZTM,JO10UV
PA3GHZ,JO21OI
DL2SDU,JN48XT
DG4YFT,JO31OR
G0UIQ,JO02PW
DF9PX,JN49HU
DG8FAY,JO40GD
DL9LBH,JO30MP
DG5YHK,JO31SR
DC2GY/P,JN48DS
PE1PZS,JO21DV
ON4PS,JO20KQ
PE1PWM,JO22FE
DL2VB/P,JO31KP
DG8BX/P,JO43NA
DK4FG,JO40EM
DO8BAF/P,JN59WK
OK1MSM/P,JN69PR
DC2GY,JN48BQ
DK2LR,JN57KO
DH3UN,JO31TL
DF0SB,JN48GE
ON4CBR,JO10OU
DB3VE,JN39KK
DO2YTM,JO42GA
DJ9CN,JO43DA
M3HKK/P,JO01BB
DK8ZB,JN49KW
DC2AM,JO43WL
DF7KF,JO30GU
DC7KG,JO30LW
SK7CY,JO65RJ
DH6OBN/P,JO42UJ
SK7HR,JO77HM
ON4BAR,JO10MV
DH8OH,JO51AT
DL5OAK,JO52AK
DG1DX,JO31SL
DL0HEU,JN47NX
DL1FX,JN49HS
DN1BE,JO42AH
G4ZTR,JO01KW
DG3YY,JO31QM
DK4WH/P,JN49BH
OK1UEM,JO60TH
PE1LWJ,JO22VJ
OZ0XX,JO54RS
DO1ON,JO51HR
DK0DH,JO31QL
DJ9JY,JO31JM
DG1FDX,JN49LP
DG0CCD,JO52TC
DL5NAV,JO33TF
DL4KCA,JO31JX
DG6NDK,JN59GN
DO9BC,JN48QP
DK1HW,JO42TG
DC4MP,JO31MI
ON4CIN,JO11UB
LA2CFA,JO48JL
DH2SAV,JN48QU
PE1ONM,JO32KR
M5AEH,IO93BS

View File

@ -0,0 +1,69 @@
#include <Python.h>
#include "stations-code.h"
static struct {
char *callsign;
char *locator;
} station_list[] = {
#include "stations.dat.h"
};
static int hash_f (const char *s, const int *T)
{
register int i, sum = 0;
for (i = 0; s[i] != '\0'; i++) {
sum += T[i] * s[i];
sum %= NG;
}
return sum;
}
static int perf_hash (const char *k)
{
if (strlen (k) > NS)
return 0;
return (G[ hash_f(k, T1) ] + G[ hash_f(k, T2)] ) % NG;
}
static int getlocator (char *locator, const char *callsign)
{
int hashval = perf_hash (callsign);
if (hashval < NK && strcmp(callsign, station_list[hashval].callsign) == 0) {
strcpy (locator, station_list[hashval].locator);
return 1;
}
return 0;
}
static PyObject *
stations_locator(PyObject *self, PyObject *args)
{
const char *callsign;
char locator[6];
if (!PyArg_ParseTuple(args, "s", &callsign))
return NULL;
return Py_BuildValue("s", (getlocator (locator, callsign) == 1) ?
locator : NULL);
}
static PyMethodDef StationsMethods[] = {
{"locator", stations_locator, METH_VARARGS,
"Get locator from callsign."},
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC
initstations(void)
{
(void) Py_InitModule("stations", StationsMethods);
}

View File

@ -0,0 +1,28 @@
#!/usr/bin/env python
import sys
from timeit import Timer
from stations import locator
call = sys.argv[1]
print repr(call)
D = {}
for line in file('stations.dat'):
c, l = [x.strip() for x in line.split(',')]
D[c] = l
def test1(c):
return D[c]
print repr(test1(call))
t = Timer("test1(%r)" % call, "from __main__ import test1")
print t.timeit()
# -----
def test2(c):
return locator(c)
print repr(test2(call))
t = Timer("test2(%r)" % call, "from __main__ import test2")
print t.timeit()

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
"""
This example shows how to use the class Graph.
The class implements a graph with 'N' vertices. First, you connect the
graph with edges, which have a desired value associated. Then the vertex
values are assigned, which will fail if the graph is cyclic. The vertex
values are assigned such that the two values corresponding to an edge add
up to the desired edge value (mod N).
"""
import sys
sys.path.append('..')
from perfect_hash import Graph
G = Graph(3)
assert G.assign_vertex_values() == True
# Now we make an edge between vertex 0 and 1 with desired edge value 2:
G.connect(0, 1, 2)
# Make another edge 1:2 with desired edge value 1:
G.connect(1, 2, 1)
# The graph is still acyclic, and assigning values works:
assert G.assign_vertex_values() == True
assert G.vertex_values == [0, 2, 2]
# What do these values mean?
# When you add the values for edge 0:1 you get 0 + 2 = 2, as desired.
# For edge 1:2 you add 2 + 2 = 4 = 1 (mod 3), as desired.
# Adding edge 0:2 produces a loop, so the graph is no longer acyclic.
# Assigning values fails.
G.connect(0, 2, 0)
assert G.assign_vertex_values() == False
print 'OK'

View File

@ -0,0 +1,15 @@
all:
true
clean:
true
test:
./generate_hash.py
./PerfHash.py
./Graph.py

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
"""
This example shows how to use the class PerfHash.
This class is designed for creating perfect hash tables at run time,
which should be avoided, in particulat inserting new keys is
prohibitively expensive since a new perfect hash table needs to be
constructed. However, this class can be usefull for testing.
For practical programming purposes in Python the class PerfHash
should never be used because Python's built-in dictionary is very
efficient and always faster than PerfHash.
"""
import sys
sys.path.append('..')
from perfect_hash import PerfHash
month = dict(zip('jan feb mar apr may jun jul aug sep oct mov dec'.split(),
range(1, 13)))
d = PerfHash(month)
for m in month:
assert month[m] == d[m]
d[True] = False
assert d[True] == False
for i in xrange(10): # very expensive
d[i] = 2*i*i + 3*i -7
assert d[4] == 37
print 'OK'

View File

@ -0,0 +1,38 @@
#!/usr/bin/env python
"""
This example shows how to use the function generate_hash.
generate_hash(kdic, Hash)
returns hash functions f1 and f2, and G for a perfect minimal hash.
Input is dictionary 'kdic' with the keys and desired hash values.
'Hash' is a random hash function generator, that means Hash(N) returns a
returns a random hash function which returns hash values from 0..N-1.
"""
import sys
import random, string
sys.path.append('..')
from perfect_hash import generate_hash
month = dict(zip('jan feb mar apr may jun jul aug sep oct mov dec'.split(),
range(1, 13)))
def mkRandHash(N):
"""
Return a random hash function which returns hash values from 0..N-1.
"""
junk = "".join(random.choice(string.letters + string.digits)
for i in xrange(10))
return lambda key: hash(junk + str(key)) % N
f1, f2, G = generate_hash(month, mkRandHash)
for k, h in month.items():
assert h == ( G[f1(k)] + G[f2(k)] ) % len(G)
print 'OK'

View File

@ -0,0 +1,31 @@
CC = gcc -Wall
lookup: main.o states-code.o
$(CC) -o $@ $^
main.o: main.c states-code.h states.dat.h
$(CC) -c $<
states-code.o: states-code.c states-code.h
$(CC) -c $<
states-code.c: states.dat states-tmpl.c
../perfect_hash.py -vvvv --splitby '|' --keycol 2 $^
states.dat.h: states.dat
./mk_header.py >$@
clean:
rm lookup *.o states.dat.h states-code.c
test:
./lookup 'NY'
./lookup 'QW'

View File

@ -0,0 +1,33 @@
#include <stdio.h>
#include "states-code.h"
struct {
char *name;
char *abbr;
int pop;
} states[] = {
#include "states.dat.h"
};
int main (int argc, char *argv[])
{
if (argc != 2) {
printf ("Usage: %s <abbreviation>\n", argv[0]);
return 2;
}
char *abbr = argv[1];
int hashval;
if ((hashval = has_key(abbr)) == -1)
printf ("'%s' is not an abbreviation for a state.\n", abbr);
else
printf ("The state of %s has a population of %g million.\n",
states[hashval].name,
1e-6 * states[hashval].pop);
return 0;
}

View File

@ -0,0 +1,10 @@
#!/usr/bin/env python
for line in file('states.dat'):
line = line.strip()
if line.startswith('#'):
continue
row = tuple(entry.strip() for entry in line.split('|'))
print ' { "%s", "%s", %s },' % row

View File

@ -0,0 +1,6 @@
/* Return hash value of abbreviation 'abbr' if found, -1 otherwise */
int has_key (const char *abbr);

View File

@ -0,0 +1,42 @@
#include <string.h>
#include "states-code.h"
static int T1[] = { $S1 };
static int T2[] = { $S2 };
static int G[] = { $G };
static char *K[] = { $K };
static int hash_g (const char *key, const int *T)
{
int i, sum = 0;
for (i = 0; key[i] != '\0'; i++) {
sum += T[i] * key[i];
sum %= $NG;
}
return G[sum];
}
static int perfect_hash (const char *key)
{
if (strlen (key) > $NS)
return 0;
return (hash_g (key, T1) + hash_g (key, T2)) % $NG;
}
int has_key (const char *abbr)
{
int hash_value = perfect_hash (abbr);
if (hash_value < $NK && strcmp(abbr, K[hash_value]) == 0)
return hash_value;
return -1;
}

View File

@ -0,0 +1,52 @@
# Name | Abr | Population
#--------------+------+---------
Alabama | AL | 4335400
Alaska | AK | 611500
Arizona | AZ | 4664600
Arkansas | AR | 2531000
California | CA | 33198100
Colorado | CO | 3930700
Connecticut | CT | 3271100
Delaware | DE | 736900
Florida | FL | 15012200
Georgia | GA | 7562200
Hawaii | HI | 1188400
Idaho | ID | 1221500
Illinois | IL | 11981700
Indiana | IN | 5882500
Iowa | IA | 2854700
Kansas | KS | 2603200
Kentucky | KY | 3921000
Louisiana | LA | 4361200
Maine | ME | 1243700
Maryland | MD | 5122400
Massachusetts | MA | 6133500
Michigan | MI | 9825100
Minnesota | MN | 4704200
Mississippi | MS | 2739700
Missouri | MO | 5421400
Montana | MT | 886400
Nebraska | NE | 1661400
Nevada | NV | 1828700
New Hampshire | NH | 1179100
New Jersey | NJ | 8078300
New Mexico | NM | 1738700
New York | NY | 18197800
North Carolina | NC | 7483100
North Dakota | ND | 640000
Ohio | OH | 11197900
Oklahoma | OK | 3328100
Oregon | OR | 3266800
Pennsylvania | PA | 12044200
Rhode Island | RI | 987000
South Carolina | SC | 3781800
South Dakota | SD | 738500
Tennessee | TN | 5398200
Texas | TX | 19274300
Utah | UT | 2071500
Vermont | VT | 590400
Virginia | VA | 6768400
Washington | WA | 5674900
West Virginia | WV | 1813200
Wisconsin | WI | 5224500
Wyoming | WY | 479500

View File

@ -0,0 +1,22 @@
CC = gcc -Wall
a.out: main.c keys.code.h
$(CC) $<
keys.code.h: keys.dat keys.tmpl.h
../perfect_hash.py $^
keys.dat:
./mk_rnd_keys.py 100 >keys.dat
clean:
rm keys.dat keys.code.h a.out
test:
./a.out

View File

@ -0,0 +1,13 @@
#define NK $NK /* number of keys */
#define NG $NG /* number of vertices */
#define NS $NS /* length of array T1 and T2 */
int T1[] = { $S1 };
int T2[] = { $S2 };
int G[] = { $G };
char *K[] = { $K };

View File

@ -0,0 +1,51 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "keys.code.h"
int hash_g (char *s, int *T)
{
int i, f = 0;
for (i = 0; s[i] != '\0'; i++) {
f += T[i] * s[i];
f %= NG;
}
return G[f];
}
int hash (char *k)
{
if (strlen (k) > NS)
return 0;
return (hash_g (k, T1) + hash_g (k, T2)) % NG;
}
bool has_key (char *k)
{
int h = hash (k);
return h < NK && strcmp(k, K[h]) == 0;
}
int main ()
{
int i;
char *junk = "acnhuvn5yushvghnw7og5siuhgsiuhnglsh45vgghwn";
assert (has_key(junk) == 0);
assert (hash(junk) == 0);
for (i = 0; i < NK; i++) {
assert (has_key(K[i]) == true);
assert (hash(K[i]) == i);
}
puts ("OK");
return 0;
}

View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
# ./mk_rnd_keys.py 10000 | sort | uniq | shuf >keywords.txt
import sys
from random import choice, randint
from string import digits, uppercase, lowercase
def key():
return ''.join(choice(uppercase + lowercase + digits)
for i in xrange(randint(6, 20)))
N = int(sys.argv[1])
for n in xrange(N):
print key()

View File

@ -0,0 +1,23 @@
animals.ps: animals.dot
neato -Tps $< -Gstart=100 -o $@
animals.dot: animals.py
./py2dot -l $< -o $@
animals.py: ../animals.txt
../perfect_hash.py $< >$@
clean:
rm animals.py animals.dot animals.ps
test:
true

View File

@ -0,0 +1,4 @@
#!/bin/bash
../perfect_hash.py ../animals.txt | ./py2dot | neato -Tps -Gstart=100 -o out.ps

View File

@ -0,0 +1,216 @@
#!/usr/bin/env python
class Graph:
def __init__(self, N):
self.N = N # number of vertices
# maps a vertex number to the list of (vertices, edge value)
# to which it is connected by edges.
self.adjacent = [[] for n in xrange(N)]
def connect(self, vertex1, vertex2, edge_value):
"""
Connect 'vertex1' and 'vertex2' with an edge, with associated
value 'value'
"""
# Add vertices to each other's adjacent list
self.adjacent[vertex1].append( (vertex2, edge_value) )
self.adjacent[vertex2].append( (vertex1, edge_value) )
def check(self):
"""
See if vertex values add up to edge values (mod N).
"""
for vertex in xrange(self.N):
for neighbor, edge_value in self.adjacent[vertex]:
assert (self.vertex_values[vertex] +
self.vertex_values[neighbor]) % self.N == edge_value
def calc_tree_sizes(self):
"""
After running this method, the attribute size will contain a list,
which maps the vertices to the size of the tree that vertex belongs
to.
"""
visited = self.N * [-1] # -1 unvisited, otherwise the number of tree
treenum = 0
# Loop over all vertices, taking unvisited ones as roots.
for root in xrange(self.N):
if visited[root] >= 0:
continue
# explore tree starting at 'root'
# Stack of vertices to visit, a list of tuples (parent, vertex)
tovisit = [ (None, root) ]
while tovisit:
parent, vertex = tovisit.pop()
visited[vertex] = treenum
# Loop over adjacent vertices, but skip the vertex we arrived
# here from the first time it is encountered.
skip = True
for neighbor, edge_value in self.adjacent[vertex]:
if skip and neighbor == parent:
skip = False
continue
if visited[neighbor] >= 0:
# We visited here before, so the graph is cyclic.
exit('Hmm, graph is cyclic.')
tovisit.append( (vertex, neighbor) )
treenum += 1
# maps the tree number to number of vertices within that tree
treesizes = treenum * [0]
for tree in visited:
treesizes[tree] += 1
self.size = [treesizes[visited[v]] for v in xrange(self.N)]
if verbose:
freq = (self.N+1) * [0]
for size in treesizes:
freq[size] += 1
sys.stderr.write(' Size Trees\n')
for i, f in enumerate(freq):
if f:
sys.stderr.write('%5i %5i\n' % (i, f))
if i == minsize-1:
sys.stderr.write('--------------\n')
def write(self, fo, labels = False):
self.calc_tree_sizes()
fo.write('graph G {\n'
' size = "8,8";\n'
' edge [color="#ff0000"]\n')
if labels:
fo.write(' node [color="#a0e0ee", style=filled];\n')
for vertex, value in enumerate(self.vertex_values):
if self.size[vertex] < minsize: continue
fo.write(' { node [label="%i: %i"] v%i }\n' % (
vertex, value, vertex))
else:
fo.write(' node [color="#3377a0", label="",\n'
' style=filled, shape=circle]\n')
for vertex in xrange(self.N): # edges
if self.size[vertex] < minsize: continue
for neighbor, edge_value in self.adjacent[vertex]:
if neighbor > vertex: continue
fo.write(' v%i -- v%i%s;\n' %
(vertex, neighbor,
(' [label="%s: %i"]' % (K[edge_value], edge_value))
if labels else ''))
fo.write('}\n')
fo.close()
if __name__ == '__main__':
import sys
from optparse import OptionParser
usage = "usage: %prog [options] [PYCODE]"
description = """\
Given the python code for a perfect hash function which was generated by
perfect_hash.py, e.g. by '$ ../perfect_hash.py animals.txt >animals.py',
this program will create the graph which was used in determining the
perfect hash function. The input python code may also be given to stdin.
The output is saved as in the .dot format which is used by the Graphviz
tools (see http://www.graphviz.org/) to generate a picture of the graph.
"""
parser = OptionParser(usage = usage,
description = description,
prog = sys.argv[0])
parser.add_option("-l", "--labels",
action = "store_true",
help = "Be verbose")
parser.add_option("-m", "--minsize",
action = "store",
default = 1,
type = "int",
help = "Include only trees in the output which "
"have at least INT vertices. "
"Default is %default, i.e. all trees are "
"included within the output.",
metavar = "INT")
parser.add_option("-o", "--output",
action = "store",
help = "Specify output FILE explicitly. "
"Default, is stdout. ",
metavar = "FILE")
parser.add_option("-v", "--verbose",
action = "store_true",
help = "Be verbose")
options, args = parser.parse_args()
if options.minsize > 0:
minsize = options.minsize
else:
parser.error("minimal size of trees has to be larger than zero")
verbose = options.verbose
if len(args) > 1:
parser.error("incorrect number of arguments")
# --------------------- end parsing and checking -----------------------
if verbose:
sys.stderr.write('minsize (of trees): %i\n' % minsize)
sys.stderr.write('labels (in output): %s\n' % options.labels)
# ------------ input filehandle
if len(args)==1:
try:
fi = file(args[0])
except IOError :
exit("Error: Can't open `%s' for reading." % args[0])
else:
fi = sys.stdin
# ------------ read input, i.e. execute code
exec(fi.read())
# ------------ make graph
g = Graph(len(G))
g.vertex_values = G
for key, hashval in zip(K, H):
g.connect(hash_f(key, S1),
hash_f(key, S2),
hashval)
g.check()
# ------------ output filehandle
if options.output:
try:
fo = file(options.output, 'w')
except IOError :
exit("Error: Can't open `%s' for writing." % options.output)
else:
fo = sys.stdout
# ------------ write output, i.e. generate .dot output
g.write(fo, options.labels)
# Local Variables:
# mode: python
# End:

View File

@ -0,0 +1,870 @@
#!/usr/bin/env python
"""
Generate a minimal perfect hash function for the keys in a file,
desired hash values may be specified within this file as well.
A given code template is filled with parameters, such that the
output is code which implements the hash function.
Templates can easily be constructed for any programming language.
The code is based on an a program A.M. Kuchling wrote:
http://www.amk.ca/python/code/perfect-hash
The algorithm the program uses is described in the paper
'Optimal algorithms for minimal perfect hashing',
Z. J. Czech, G. Havas and B.S. Majewski.
http://citeseer.ist.psu.edu/122364.html
The algorithm works like this:
1. You have K keys, that you want to perfectly hash against some
desired hash values.
2. Choose a number N larger than K. This is the number of
vertices in a graph G, and also the size of the resulting table G.
3. Pick two random hash functions f1, f2, that return values from 0..N-1.
4. Now, for all keys, you draw an edge between vertices f1(key) and f2(key)
of the graph G, and associate the desired hash value with that edge.
5. Check if G is acyclic, i.e. has no loops; if no, go back to step 2.
6. Assign values to each vertex such that, for each edge, you can add
the values for the two vertices and get the desired (hash) value
for that edge. This task is easy, because the graph is acyclic.
This is done by picking a vertex, and assigning it a value of 0.
Then do a depth-first search, assigning values to new vertices so that
they sum up properly.
7. f1, f2, and vertex values of G now make up a perfect hash function.
For simplicity, the implementation of the algorithm combines steps 5 and 6.
That is, we check for loops in G and assign the vertex values in one procedure.
If this procedure succeeds, G is acyclic and the vertex values are assigned.
If the procedure fails, G is cyclic, and we go back to step 2, replacing G
with a new graph, and thereby discarding the vertex values from the failed
attempt.
"""
__author__ = 'Ilan Schnell <ilanschnell@gmail.com>, 2008 (and AMK 2000)'
__license__ = 'GNU GPL 2'
__version__ = '0.1'
import sys, random, string, cStringIO, StringIO
verbose = False
trails = 5
class Graph:
"""
Implements a graph with 'N' vertices. First, you connect the graph with
edges, which have a desired value associated. Then the vertex values
are assigned, which will fail if the graph is cyclic. The vertex values
are assigned such that the two values corresponding to an edge add up to
the desired edge value (mod N).
Example:
>>> G = Graph(3)
>>> G.assign_vertex_values()
True
Now we make an edge between vertex 0 and 1 with desired edge value 2:
>>> G.connect(0, 1, 2)
Make another edge 1:2 with desired edge value 1:
>>> G.connect(1, 2, 1)
The graph is still acyclic, and assigning values works:
>>> G.assign_vertex_values()
True
>>> G.vertex_values
[0, 2, 2]
What do these values mean?
When you add the values for edge 0:1 you get 0 + 2 = 2, as desired.
For edge 1:2 you add 2 + 2 = 4 = 1 (mod 3), as desired.
Adding edge 0:2 produces a loop, so the graph is no longer acyclic.
Assigning values fails.
>>> G.connect(0, 2, 0)
>>> G.assign_vertex_values()
False
"""
def __init__(self, N):
self.N = N # number of vertices
# maps a vertex number to the list of tuples (vertices, edge value)
# to which it is connected by edges.
self.adjacent = [[] for n in xrange(N)]
def connect(self, vertex1, vertex2, edge_value):
"""
Connect 'vertex1' and 'vertex2' with an edge, with associated
value 'value'
"""
# Add vertices to each other's adjacent list
self.adjacent[vertex1].append( (vertex2, edge_value) )
self.adjacent[vertex2].append( (vertex1, edge_value) )
def assign_vertex_values(self):
"""
Try to assign the vertex values, such that, for each edge, you can
add the values for the two vertices involved and get the desired
value for that edge, i.e. the desired hash key.
This will fail when the graph is cyclic.
This is done by a Depth-First Search of the graph. If the search
finds a vertex that was visited before, there's a loop and False is
returned immediately, i.e. the assignment is terminated.
On success (when the graph is acyclic) True is returned.
"""
self.vertex_values = self.N * [-1] # -1 means unassigned
visited = self.N * [False]
# Loop over all vertices, taking unvisited ones as roots.
for root in xrange(self.N):
if visited[root]:
continue
# explore tree starting at 'root'
self.vertex_values[root] = 0 # set arbitrarily to zero
# Stack of vertices to visit, a list of tuples (parent, vertex)
tovisit = [ (None, root) ]
while tovisit:
parent, vertex = tovisit.pop()
visited[vertex] = True
# Loop over adjacent vertices, but skip the vertex we arrived
# here from the first time it is encountered.
skip = True
for neighbor, edge_value in self.adjacent[vertex]:
if skip and neighbor == parent:
skip = False
continue
if visited[neighbor]:
# We visited here before, so the graph is cyclic.
return False
tovisit.append( (vertex, neighbor) )
# Set new vertex's value to the desired edge value,
# minus the value of the vertex we came here from.
self.vertex_values[neighbor] = \
( edge_value - self.vertex_values[vertex] ) % self.N
# check if all vertices have a valid value
for vertex in xrange(self.N):
assert self.vertex_values[vertex] >= 0
# We got though, so the graph is acyclic,
# and all values are now assigned.
return True
def generate_hash(kdic, Hash):
"""
Return hash functions f1 and f2, and G for a perfect minimal hash.
Input is dictionary 'kdic' with the keys and desired hash values.
'Hash' is a random hash function generator, that means Hash(N) returns a
returns a random hash function which returns hash values from 0..N-1.
"""
# N is the number of vertices in the graph G
N = 1 if not kdic else (max(kdic.values()) + 1)
if verbose >= 2:
sys.stderr.write('N = %i\n' % N)
trail = 0 # Number of trial graphs so far
while True:
if (trail % trails) == 0: # trails failures, increase N slightly
if trail > 0:
N = max(N+1, int(1.05*N))
if verbose:
sys.stderr.write('\n')
sys.stderr.write('Generating graphs N = %i ' % N)
trail += 1
if verbose:
sys.stderr.write('.')
sys.stderr.flush()
G = Graph(N) # Create graph with N vertices
f1 = Hash(N) # Create 2 random hash functions
f2 = Hash(N)
# Connect vertices given by the values of the two hash functions
# for each key. Associate the desired hash value with each edge.
for key, hashval in kdic.iteritems():
G.connect(f1(key), f2(key), hashval)
# Try to assign the vertex values. This will fail when the graph
# is cyclic. But when the graph is acyclic it will succeed and we
# break out, because we're done.
if G.assign_vertex_values():
break
if verbose:
sys.stderr.write('\nAcyclic graph found after %i trails.\n' % trail)
if verbose >= 2:
sys.stderr.write('N = %i\n' % N)
if verbose:
sys.stderr.write('Checking generated hash function... ')
# Sanity check the result by actually verifying that all the keys
# hash to the right value.
for key, hashval in kdic.iteritems():
assert hashval == ( G.vertex_values[f1(key)] +
G.vertex_values[f2(key)] ) % N
if verbose:
sys.stderr.write('OK\n')
return f1, f2, G.vertex_values
class Hash1:
"""
Random hash function generator.
For simplicity and speed, this doesn't implement any byte-level hashing
scheme. Instead, a random string is generated and prefixing to str(key),
and then Python's hashing function is used.
"""
def __init__(self, N):
self.N = N
self.salt = "".join(random.choice(string.letters + string.digits)
for i in xrange(8))
def __call__(self, key):
return hash(self.salt + str(key)) % self.N
template = """
def perfect_hash(key):
return (G[ hash('$S1' + str(key)) % $NG ] +
G[ hash('$S2' + str(key)) % $NG ]) % $NG
"""
class Hash2:
"""
Random hash function generator.
Simple byte level hashing, each byte is multiplied in sequence to a table
containing random numbers modulo N, and then these products are summed up.
The table with random numbers is dynamically expanded whenever
a key longer than the current table size is encountered.
"""
def __init__(self, N):
self.N = N
self.salt = []
def __call__(self, key):
skey = key
while len(self.salt) < len(skey): # add more salt if necessary
self.salt.append(random.randint(0, self.N-1))
return sum(self.salt[i] * ord(c)
for i, c in enumerate(skey)) % self.N
template = """
S1 = [$S1]
S2 = [$S2]
def hash_f(key, T):
return sum(T[i % $NS] * ord(c) for i, c in enumerate(str(key))) % $NG
def perfect_hash(key):
return (G[hash_f(key, S1)] + G[hash_f(key, S2)]) % $NG
"""
class PerfHash:
"""
This class is designed for creating perfect hash tables at run time,
which should be avoided, in particulat inserting new keys is
prohibitively expensive since a new perfect hash table needs to be
constructed. However, this class can be usefull for testing.
>>> d = PerfHash({'foo':(429, 'bar'), 42:True, False:'baz'})
>>> d['foo'], d[42], d[False]
((429, 'bar'), True, 'baz')
>>> d[False] = (1, 2)
>>> d[False]
(1, 2)
>>> d.has_key('foo')
True
>>> d.has_key(True)
False
"""
def __init__(self, dic):
self.klst = []
self.objs = []
kdic = {}
for hashval, (key, obj) in enumerate(dic.iteritems()):
self.klst.append(key)
self.objs.append(obj)
kdic[key] = hashval
self.N = len(dic)
self.f1, self.f2, self.G = generate_hash(kdic, Hash1)
def __setitem__(self, newkey, newobj):
dic = {}
for key in self.klst:
dic[key] = self[key]
dic[newkey] = newobj
self.__init__(dic)
def hashval(self, key):
return ( self.G[self.f1(key)] + self.G[self.f2(key)] ) % len(self.G)
def __getitem__(self, key):
h = self.hashval(key)
if h < self.N and key == self.klst[h]:
return self.objs[h]
else:
raise IndexError
def has_key(self, key):
h = self.hashval(key)
return h < self.N and key == self.klst[h]
class Format:
"""
>>> class o:
... pass
>>> o.delimiter = ': '
>>> o.width = 75
>>> o.indent = 4
>>> x = Format( o )
>>> x( range(10) )
'0: 1: 2: 3: 4: 5: 6: 7: 8: 9'
>>> o.delimiter = '; '
>>> x = Format( o )
>>> x( range(5) )
'0; 1; 2; 3; 4'
>>> o.delimiter = ' '
>>> x = Format( o )
>>> x( range(5), quote = True )
'"0" "1" "2" "3" "4"'
>>> x(42)
'42'
>>> x('Hello')
'Hello'
"""
def __init__(self, options):
names = ['width', 'indent', 'delimiter']
for name in names:
setattr(self, name, getattr(options, name))
if verbose >=2:
sys.stderr.write("Format options:\n")
for name in names:
sys.stderr.write(' %s: %r\n' % (name, getattr(self, name)))
def __call__(self, data, quote = False):
if type(data) != type([]):
return str(data)
lendel = len(self.delimiter)
aux = StringIO.StringIO()
pos = 20
for i, elt in enumerate(data):
last = bool(i == len(data)-1)
s = ('"%s"' if quote else '%s') % elt
if pos + len(s) + lendel > self.width:
aux.write('\n' + (self.indent * ' '))
pos = self.indent
aux.write(s)
pos += len(s)
if not last:
aux.write(self.delimiter)
pos += lendel
return aux.getvalue()
def keyDict(keys_hashes):
"""
Checks a list with (key, hashvalue) tupels and returns dictionary.
>>> d = keyDict([(1, 2), (3, 4), (5, 6)])
>>> d[3]
4
"""
K = len(keys_hashes) # number of keys
if verbose >= 2:
sys.stderr.write('K = %i\n' % K)
kdic = dict(keys_hashes)
if len(kdic) < K:
sys.stderr.write('Warning: Input contains duplicate keys\n')
if len(set(kdic.values())) < K:
sys.stderr.write('Warning: Input contains duplicate hash values\n')
return kdic
def generate_code(keys_hashes, template, Hash, options, extra_subs):
"""
Takes a list of key value pairs and inserts the generated parameter
lists into the 'template' strinng. 'Hash' is the random hash function
generator, and the optional keywords are formating options.
The return value is the substituted code template.
"""
f1, f2, G = generate_hash(keyDict(keys_hashes), Hash)
assert f1.N == f2.N == len(G)
assert len(f1.salt) == len(f2.salt)
fmt = Format(options)
return string.Template(template).substitute(
NS = len(f1.salt),
S1 = fmt(f1.salt),
S2 = fmt(f2.salt),
NG = len(G),
G = fmt(G),
NK = len(keys_hashes),
K = fmt([key for key, hashval in keys_hashes], quote = True),
H = fmt([hashval for key, hashval in keys_hashes]),
**extra_subs)
def read_table(filename, options):
"""
Reads keys and desired hash value pairs from a file. If no column
for the hash value is specified, a sequence of hash values is generated,
from 0 to N-1, where N is the number of rows found in the file.
"""
if verbose >= 2:
sys.stderr.write("Reading table from file `%s' to extract keys.\n" %
filename)
try:
f = file(filename)
except IOError :
exit("Error: Could not open `%s' for reading." % filename)
keys_hashes = []
hashval = -1
if verbose >= 2:
sys.stderr.write("Reader options:\n")
for name in ['comment', 'splitby', 'keycol', 'hashcol']:
sys.stderr.write(' %s: %r\n' %
(name, getattr(options, name)))
for n, line in enumerate(f):
line = line.strip()
if not line or line.startswith(options.comment):
continue
if line.count(options.comment): # strip content after comment
line = line.split(options.comment)[0].strip()
row = [col.strip() for col in line.split(options.splitby)]
try:
key = row[options.keycol-1]
except IndexError :
exit("%s:%i: Error: Cannot read key, not enough columns." %
(filename, n+1))
if options.hashcol:
try:
val = row[options.hashcol-1]
except IndexError :
exit("%s:%i: Error: Cannot read hash value, not enough columns."
% (filename, n+1))
try:
hashval = int(val)
except ValueError :
exit("%s:%i: Error: Cannot convert `%s' to int." %
(filename, n+1, row[options.hashcol-1]))
else:
hashval += 1
keys_hashes.append( (key, hashval) )
f.close()
if not keys_hashes:
exit("Error: no keys found in file `%s'." % filename)
return keys_hashes
def print_keys_hashes(keys_hashes):
fmt = '%-20s %10s'
head = fmt % ('Key', 'Hash value')
sys.stderr.write('\n' + head + '\n')
sys.stderr.write(len(head)*'-' + '\n')
for tup in keys_hashes:
sys.stderr.write(fmt % tup + '\n')
sys.stderr.write('\n')
def read_template(filename):
if verbose >= 2:
sys.stderr.write("Reading template from file `%s'.\n" % filename)
try:
f = file(filename)
except IOError :
fatal_error("Error: Could not open `%s' for reading." % filename)
return f.read()
def builtin_template(Hash):
return """\
# =======================================================================
# ================= Python code for perfect hash function ===============
# =======================================================================
G = [$G]
""" + Hash.template + """
# ============================ Sanity check =============================
K = [$K]
H = [$H]
assert len(K) == len(H) == $NK
for k, h in zip(K, H):
assert perfect_hash(k) == h
"""
def print_code(code, name, width = 78):
def center(s):
v = (width - len(s))/2
return '='*v + s + '='*v
sys.stderr.write(center(' BEGIN %s ' % name) + '\n')
sys.stderr.write(code + '\n')
sys.stderr.write(center(' END %s ' % name) + '\n')
def self_test(options):
import doctest
global verbose
print 'Starting self tests ...'
def random_word():
return ''.join(random.choice(string.letters + string.digits)
for i in xrange(random.randint(1, 20)))
def flush_dot():
sys.stdout.write('.')
sys.stdout.flush()
def run(K, Hash):
flush_dot()
keys = [chr(65+i) for i in xrange(K)]
hashes = range(K)
random.shuffle(keys)
random.shuffle(hashes)
code = generate_code(zip(keys, hashes),
builtin_template(Hash),
Hash,
options)
exec(code) in {}
verbose = False
for Hash in [Hash1, Hash2]:
for K in xrange(0, 27):
run(K, Hash)
print
verbose = options.verbose
N = 250
for Hash in [Hash1, Hash2]:
if verbose:
print 'Generating approximately %i key/hash pairs ...' % N
kh = {}
for i in xrange(N):
kh[random_word()] = i
if verbose:
print 'Generating code for %i key/hash pairs ...' % len(kh)
code = generate_code(kh.items(),
builtin_template(Hash),
Hash,
options)
if verbose:
print 'Executing code ...'
flush_dot()
exec(code) in {}
flush_dot()
d = PerfHash(dict([(100-i, i*i) for i in xrange(500)]))
for i in xrange(500):
assert d[100-i] == i*i
flush_dot()
d[None] = True
assert d[None] == True
if verbose:
print 'Running doctest ...'
verbose = False
failure_count, test_count = doctest.testmod(report = True, verbose = False)
print
if failure_count:
sys.stderr.write('FAILED\n')
sys.exit(2)
else:
sys.stderr.write('%i tests passed.\n' % test_count)
sys.stderr.write('OK\n')
sys.exit(0)
if __name__ == '__main__':
from optparse import OptionParser
usage = "usage: %prog [options] KEYS_FILE [TMPL_FILE]"
description = """\
Generates code for perfect hash functions from
a file with keywords and a code template.
If no template file is provided, a small built-in Python template
is processed and the output code is written to stdout.
"""
parser = OptionParser(usage = usage,
description = description,
prog = sys.argv[0],
version = "%prog 0.1")
parser.add_option("--delimiter",
action = "store",
default = ", ",
help = "Delimiter for list items used in output, "
"the default delimiter is '%default'",
metavar = "STR")
parser.add_option("--indent",
action = "store",
default = 2,
type = "int",
help = "Make INT spaces at the beginning of a "
"new line when generated list is wrapped. "
"Default is %default",
metavar = "INT")
parser.add_option("--width",
action = "store",
default = 76,
type = "int",
help = "Maximal width of generated list when "
"wrapped. Default width is %default",
metavar = "INT")
parser.add_option("--comment",
action = "store",
default = "#",
help = "STR is the character, or sequence of "
"characters, which marks the beginning "
"of a comment (which runs till "
"the end of the line), in the input "
"KEYS_FILE. "
"Default is '%default'",
metavar = "STR")
parser.add_option("--splitby",
action = "store",
default = ",",
help = "STR is the character by which the columns "
"in the input KEYS_FILE are split. "
"Default is '%default'",
metavar = "STR")
parser.add_option("--keycol",
action = "store",
default = 1,
type = "int",
help = "Specifies the column INT in the input "
"KEYS_FILE which contains the keys. "
"Default is %default, i.e. the first column.",
metavar = "INT")
parser.add_option("--hashcol",
action = "store",
default = 0,
type = "int",
help = "Specifies the column INT in the input "
"KEYS_FILE which contains the desired "
"hash values. "
"By default the hash values are given by the "
"sequence 0..N-1.",
metavar = "INT")
parser.add_option("--trails",
action = "store",
default = 5,
type = "int",
help = "Specifies the number of trails before "
"N is increased. A small INT will give "
"compute faster, but the array G will be "
"large. A large INT will take longer to "
"compute but G will be smaller. "
"Default is %default",
metavar = "INT")
parser.add_option("--hft",
action = "store",
default = 2,
type = "int",
help = "Hash function type INT (see documentation), "
"The default is %default",
metavar = "INT")
parser.add_option("-e", "--execute",
action = "store_true",
help = "Execute the generated code within "
"the Python interpreter.")
parser.add_option("-o", "--output",
action = "store",
help = "Specify output FILE explicitly. "
"`-o std' means standard output. "
"`-o no' means no output. "
"By default, the file name is obtained "
"from the name of the template file by "
"substituting `tmpl' to `code'.",
metavar = "FILE")
parser.add_option("--test",
action = "store_true",
help = "Perform self test")
parser.add_option("-v", "--verbose",
action = "count",
help = "Be verbose, "
"use -vv to be even more verbose")
options, args = parser.parse_args()
print type(options), '\n', repr(options)
if options.trails > 0:
trails = options.trails
else:
parser.error("trails before increasing N has to be larger than zero")
verbose = options.verbose
if options.test:
self_test(options)
if len(args) not in (1, 2):
parser.error("incorrect number of arguments")
if len(args) == 2 and not args[1].count('tmpl'):
parser.error("template filename does not contain 'tmpl'")
if options.hft == 1:
Hash = Hash1
elif options.hft == 2:
Hash = Hash2
else:
parser.error("Hash function %i not implemented.")
# --------------------- end parsing and checking --------------
# ---------------- keys_file
keys_file = args[0]
if verbose:
sys.stderr.write("keys_file = %r\n" % keys_file)
# ---------------- keys_hashes
keys_hashes = read_table(keys_file, options)
if verbose >= 3:
print_keys_hashes(keys_hashes)
# ---------------- tmpl_file
if len(args) == 2:
tmpl_file = args[1]
else:
tmpl_file = None
if verbose:
sys.stderr.write("tmpl_file = %r\n" % tmpl_file)
# ---------------- template
if tmpl_file:
template = read_template(tmpl_file)
else:
template = builtin_template(Hash)
if verbose >= 3:
print_code(template, 'TEMPLATE')
# ---------------- outname
if options.output:
outname = options.output
else:
if tmpl_file:
if tmpl_file.count('tmpl'):
outname = tmpl_file.replace('tmpl', 'code')
else:
exit("Hmm, template filename does not contain 'tmpl'")
else:
outname = 'std'
if verbose:
sys.stderr.write("outname = %r\n" % outname)
# ---------------- outstream
if outname == 'std':
outstream = sys.stdout
elif outname == 'no':
outstream = None
else:
try:
outstream = open(outname, 'w')
except IOError :
exit("Error: Could not open `%s' for writing." % outname)
# ---------------- generated code
code = generate_code(keys_hashes, template, Hash, options)
if verbose >= 3:
print_code(code, 'GENERATED CODE')
# ---------------- execute code
if options.execute or template == builtin_template(Hash):
if verbose:
sys.stderr.write('Executing code...\n')
exec(code)
# ---------------- write code to output stream
if outstream:
outstream.write(code)
if not outname == 'std':
outstream.close()

View File

@ -0,0 +1,32 @@
#!/bin/bash
function showpwd ()
{
echo '=============' `pwd`
}
# perform programs self test
showpwd
./perfect_hash.py --test || exit 1
# update documentation
for folder in doc
do
cd $folder
showpwd
make
cd ..
done
# run examples
for folder in example* graph
do
cd $folder
showpwd
make || exit 1
make test || exit 1
make clean
cd ..
done
rm perfect_hash.pyc

View File

@ -0,0 +1,163 @@
#encoding: utf-8
from perfect_hash import perfect_hash
import re, string, os, random
cur_dir = os.path.abspath(os.path.dirname(__file__))
unicode_chinese_re = u'[\u2E80-\u2EFF\u2F00-\u2FDF\u3000-\u303F\u31C0-\u31EF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FBF\uF900-\uFAFF\uFE30-\uFE4F\uFF00-\uFFEF]'
match_re = re.compile(unicode_chinese_re)
def _get_font_lib(f):
reading_data = False
data = []
for i in f.readlines():
if i.strip() == 'FONT_BMP_DATA_BEGIN':
reading_data = True
continue
if i.strip() == 'FONT_BMP_DATA_END':
break
if reading_data:
line = [k for k in i.strip().split(',') if k]
data.extend([int(k, 16) for k in line])
return data
class font_lib(object):
def __init__(self, f, width, height, encoding):
self.width = width
self.height = height
self._lib = _get_font_lib(f)
# byte per charactor
self._bpc = (width+7)//8*height
self.encoding = encoding
self._finished_push = False
self.char_dict = {}
def get_char_data(self, char):
#char_gb = char.encode(self.encoding)
# copied from font_hz_bmp.c
sec, idx = [ord(i) - 0xA0 for i in char]
#print 'sec %d, idx %d for' % (sec, idx), char
start = (94 * (sec-1) + (idx-1)) * self._bpc
return self._lib[start:start+self._bpc]
def push_char(self, c):
self.char_dict[c] = self.char_dict.get(c, 0) + 1
def push_file(self, f):
try:
for i in f:
t = re.findall(match_re, unicode(i.decode(self.encoding)))
if t:
for c in t:
self.push_char(c.encode(self.encoding))
except UnicodeDecodeError as e:
try:
print 'error in decoding %s' % f.name
except:
print 'error in decoding string %s' % f
# re-raise the exception and terminate the building process
raise
def _finish_push(self):
if self._finished_push:
return
self._char_li = zip(self.char_dict.keys(), self.char_dict.values())
self._char_li.sort(key=lambda x:x[1], reverse=True)
self._finished_push = True
#for i in self._char_li:
#print i[0], i[1]
def get_hash_map(self):
self._finish_push()
li = []
for i, k in enumerate(self._char_li):
li.append((k[0], i))
return li
def get_new_font_lib(self):
self._finish_push()
dat = []
for c, f in self._char_li:
dat.extend(self.get_char_data(c))
return dat
def finish(self):
return self.get_hash_map(), self.get_new_font_lib()
class mph_options(object):
'mock object for options'
def __init__(self, verbose=4, delimiter=', ', indent=4, width=80):
self.verbose = verbose
self.delimiter = delimiter
self.indent = indent
self.width = width
def gen_char_mph(font_lib):
template = open(os.path.join(cur_dir, '..', 'common', 'font_mph-tmpl.c'), 'r').read()
opt = mph_options()
hmap, flib = font_lib.finish()
#print 'compact font lib: %d chars included.' % len(hmap)
#for i in hmap:
#print i[0], repr(i[0]), i[1]
code = perfect_hash.generate_code(hmap, template, perfect_hash.Hash2, opt,
extra_subs={
'width':str(font_lib.width),
'height':str(font_lib.height),
'font_data':', '.join([hex(i) for i in flib])})
return code
# {name:[file_name, height, width, encoding, instance]}
_font_map = {'hz16':{'fname':'common/hz16font.c',
'height':16,
'width':16,
'encoding':'GB2312',
'flib':None},
'hz12':{'fname':'common/hz12font.c',
'height':12,
'width':12,
'encoding':'GB2312',
'flib':None}
}
def get_font_lib(name):
if name not in _font_map.keys():
return None
if _font_map[name]['flib'] is None:
_font_map[name]['flib'] = font_lib(open(
os.path.join(cur_dir, '..', _font_map[name]['fname']), 'r'),
_font_map[name]['height'],
_font_map[name]['width'],
_font_map[name]['encoding'])
return _font_map[name]['flib']
def gen_cmp_font_file():
for i in _font_map:
fl = _font_map[i]['flib']
if fl is not None:
code = gen_char_mph(fl)
with open(os.path.join(cur_dir, '..', 'common', 'font_cmp_%s.c' % i), 'w') as f:
f.write(code)
if __name__ == '__main__':
import sys
lib = get_font_lib('hz16')
libn = get_font_lib('hz16')
assert(lib is libn)
lib.push_file(open(sys.argv[1], 'rb'))
hmap, flib = lib.finish()
for i in hmap:
print i[0], i[1]
assert(len(flib) == 32 * len(hmap))
print gen_char_mph(lib)

View File

@ -73,7 +73,7 @@ static void rtgui_box_layout_vertical(struct rtgui_box *box, struct rtgui_rect *
{ {
rtgui_widget_t *widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t *widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
else total_height += widget->mini_height; else total_height += widget->min_height;
} }
/* calculate the height for each spaces */ /* calculate the height for each spaces */
@ -98,8 +98,8 @@ static void rtgui_box_layout_vertical(struct rtgui_box *box, struct rtgui_rect *
/* reset rect */ /* reset rect */
rtgui_rect_moveto(rect, -rect->x1, -rect->y1); rtgui_rect_moveto(rect, -rect->x1, -rect->y1);
rect->x2 = widget->mini_width; rect->x2 = widget->min_width;
rect->y2 = widget->mini_height; rect->y2 = widget->min_height;
/* left in default */ /* left in default */
rtgui_rect_moveto(rect, next_x, next_y); rtgui_rect_moveto(rect, next_x, next_y);
@ -166,7 +166,7 @@ static void rtgui_box_layout_horizontal(struct rtgui_box *box, struct rtgui_rect
{ {
rtgui_widget_t *widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t *widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
else total_width += widget->mini_width; else total_width += widget->min_width;
} }
if (space_count != 0) if (space_count != 0)
@ -191,8 +191,8 @@ static void rtgui_box_layout_horizontal(struct rtgui_box *box, struct rtgui_rect
/* reset rect */ /* reset rect */
rtgui_rect_moveto(rect, -rect->x1, -rect->y1); rtgui_rect_moveto(rect, -rect->x1, -rect->y1);
rect->x2 = widget->mini_width; rect->x2 = widget->min_width;
rect->y2 = widget->mini_height; rect->y2 = widget->min_height;
/* top in default */ /* top in default */
rtgui_rect_moveto(rect, next_x, next_y); rtgui_rect_moveto(rect, next_x, next_y);

View File

@ -104,7 +104,8 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object *object, struct rtgui_e
break; break;
case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_BUTTON:
if (RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; if (RTGUI_WIDGET_IS_HIDE(widget))
return RT_FALSE;
{ {
struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse *)event; struct rtgui_event_mouse *emouse = (struct rtgui_event_mouse *)event;
@ -159,9 +160,6 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object *object, struct rtgui_e
/* need callback */ /* need callback */
rt_bool_t need_cb = RT_FALSE; rt_bool_t need_cb = RT_FALSE;
win = RTGUI_WIN(RTGUI_WIDGET(btn)->toplevel);
win->last_mevent_widget = RTGUI_WIDGET(btn);
/* we need to decide whether the callback will be invoked /* we need to decide whether the callback will be invoked
* before the flag has changed. Moreover, we cannot invoke * before the flag has changed. Moreover, we cannot invoke
* it directly here, because the button might be destroyed * it directly here, because the button might be destroyed
@ -174,14 +172,20 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object *object, struct rtgui_e
need_cb = RT_TRUE; need_cb = RT_TRUE;
} }
/* it's a normal button */ /* if the button will handle the mouse up event here, it
* should not be the last_mevent_widget. Take care that
* don't overwrite other widgets. */
win = RTGUI_WIN(RTGUI_WIDGET(btn)->toplevel);
if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN) if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
{ {
btn->flag |= RTGUI_BUTTON_FLAG_PRESS; btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
win->last_mevent_widget = RTGUI_WIDGET(btn);
} }
else else
{ {
btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS; btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
if (win->last_mevent_widget == RTGUI_WIDGET(btn))
win->last_mevent_widget = RT_NULL;
} }
/* draw button */ /* draw button */

View File

@ -48,7 +48,7 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object *object, struct rtgui_
if (combo->on_selected != RT_NULL) if (combo->on_selected != RT_NULL)
combo->on_selected(RTGUI_OBJECT(combo), RT_NULL); combo->on_selected(RTGUI_OBJECT(combo), RT_NULL);
rtgui_win_hiden(pd_win); rtgui_win_hide(pd_win);
rtgui_widget_update(RTGUI_WIDGET(combo)); rtgui_widget_update(RTGUI_WIDGET(combo));
return RT_FALSE; return RT_FALSE;
@ -56,7 +56,7 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object *object, struct rtgui_
rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_object *object, struct rtgui_event *event) rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_object *object, struct rtgui_event *event)
{ {
rtgui_win_hiden(RTGUI_WIN(object)); rtgui_win_hide(RTGUI_WIN(object));
return RT_TRUE; return RT_TRUE;
} }
@ -226,7 +226,7 @@ rt_bool_t rtgui_combobox_event_handler(struct rtgui_object *object, struct rtgui
if (focused->widget != RT_NULL) if (focused->widget != RT_NULL)
{ {
/* hide pull down window */ /* hide pull down window */
rtgui_win_hiden(RTGUI_WIN(box->pd_win)); rtgui_win_hide(RTGUI_WIN(box->pd_win));
rtgui_combobox_ondraw(box); rtgui_combobox_ondraw(box);
} }
} }
@ -255,7 +255,7 @@ static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_object *object, struc
if (box == RT_NULL) return RT_TRUE; if (box == RT_NULL) return RT_TRUE;
/* hide pull down window */ /* hide pull down window */
rtgui_win_hiden(RTGUI_WIN(box->pd_win)); rtgui_win_hide(RTGUI_WIN(box->pd_win));
/* clear pull down button state */ /* clear pull down button state */
box->pd_pressed = RT_FALSE; box->pd_pressed = RT_FALSE;

View File

@ -0,0 +1,309 @@
/*
* File : digfont.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-12-21 pife first version
*/
#include <rtthread.h>
#include <rtgui/rtgui.h>
#include <rtgui/dc.h>
#include <rtgui/widgets/digfont.h>
#define DIGFONT_V 1
#define DIGFONT_H 0
int rtgui_digitfont_create(struct rtgui_digitfont * font)
{
int i;
int half;
int space;
int seg35_y;
int hight;
struct rtgui_digitfont_data * data, *databuf;
struct rtgui_digitfont_data temp, temp2;;
data= rt_malloc(sizeof(struct rtgui_digitfont_data) * 7 * font->seg1_nr);
if (data== RT_NULL)
{
rt_kprintf("out of memory.\n");
goto __err;
}
databuf = font->data = data;
data = &temp;
half = font->seg1_nr >> 1;
space = font->seg1_hspace;
seg35_y = font->seg1_vspace + font->seg2_len + (half<<1) - font->seg1_vspace;
hight = (font->seg1_vspace << 1) + font->seg2_len + font->seg3_len + (half << 1) - 1;
//seg 1
data->type = DIGFONT_H;
data->x = font->seg1_hspace;
data->y = 0;
data->len = font->seg1_len;
*databuf++ = *data;
for(i=1; i<font->seg1_nr; i++)
{
data->len -= 2;
data->x ++;
data->y ++;
*databuf++ = *data;
}
//seg 2
data->type = DIGFONT_V;
data->x = (font->seg1_hspace << 1) + font->seg1_len -1;
data->y = font->seg1_vspace ;
data->len = font->seg2_len;
*databuf++ = *data;
for(i=1; i<font->seg1_nr; i++)
{
if (i >= half)
{
data->len -= 2;
}
data->x --;
data->y ++;
*databuf++ = *data;
}
//seg 3
data->type = DIGFONT_V;
data->x = (font->seg1_hspace << 1) + font->seg1_len -1;
data->y = seg35_y;
data->len = font->seg3_len;
*databuf++ = *data;
temp2 = *data;
for(i=1; i<font->seg1_nr; i++)
{
if (i < half)
data->y --;
else
{
data->len -= 2;
data->y ++;
}
data->x --;
*databuf++ = *data;
}
// seg4
data->type = DIGFONT_H;
data->x = font->seg1_hspace;
data->y = hight -1;
data->len = font->seg1_len;
*databuf++ = *data;
for(i=1; i<font->seg1_nr; i++)
{
data->len -= 2;
data->x ++;
data->y --;
*databuf++ = *data;
}
//seg5
data->type = DIGFONT_V;
data->x = 0;
data->y = seg35_y;
data->len = font->seg3_len;
*databuf++ = *data;
for(i=1; i<font->seg1_nr; i++)
{
if (i < half)
data->y --;
else
{
data->len -= 2;
data->y ++;
}
data->x ++;
*databuf++ = *data;
}
//seg 6
data->type = DIGFONT_V;
data->x = 0;
data->y = font->seg1_vspace ;
data->len = font->seg2_len;
*databuf++ = *data;
for(i=1; i<font->seg1_nr; i++)
{
if (i >= half)
{
data->len -= 2;
}
data->x ++;
data->y ++;
*databuf++ = *data;
}
//seg7
data->type = DIGFONT_H;
data->x = font->seg1_hspace + half - 1;
data->y = font->seg1_vspace + font->seg2_len + half -1;
data->len = (font->seg1_hspace << 1) + font->seg1_len - \
((font->seg1_hspace + half -1) << 1);
*databuf++ = *data;
temp2 = *data;
for(i=0; i<half; i++)
{
data->x ++;
data->y --;
data->len -= 2;
*databuf++ = *data;
}
*data = temp2;
for (i=0; i<half; i++)
{
data->x ++;
data->y ++;
data->len -= 2;
*databuf++ = *data;
}
return 0;
__err:
return -1;
}
int rtgui_dc_draw_digitfont(struct rtgui_dc *dc, struct rtgui_digitfont * font, rtgui_rect_t * rect)
{
int i, size;
struct rtgui_digitfont_data * data;
size = font->seg1_nr * 7;
data = font->data;
for(i=0; i<size; i++)
{
if (data->type == DIGFONT_H)
rtgui_dc_draw_hline(dc, rect->x1 + data->x, \
rect->x1 + data->x + data->len, rect->y1 + data->y);
else
rtgui_dc_draw_vline(dc, rect->x1 + data->x, rect->y1 + data->y, \
rect->y1 + data->y + data->len);
data++;
}
}
const char digtube_code_table[] =
{ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,};
int rtgui_dc_draw_digitfont_code(struct rtgui_dc *dc, struct rtgui_digitfont * font, rtgui_rect_t * rect, char code)
{
int i,j;
struct rtgui_digitfont_data * data;
rtgui_color_t color;
data = font->data;
color = RTGUI_DC_FC(dc);
for(i=0; i<7; i++)
{
if (code & (1 << i))
RTGUI_DC_FC(dc) = color;
else
RTGUI_DC_FC(dc) = RTGUI_DC_BC(dc);
for (j=0; j<font->seg1_nr; j++)
{
if (data->type == DIGFONT_H)
rtgui_dc_draw_hline(dc, rect->x1 + data->x, \
rect->x1 + data->x + data->len, rect->y1 + data->y);
else
rtgui_dc_draw_vline(dc, rect->x1 + data->x, rect->y1 + data->y, \
rect->y1 + data->y + data->len);
data++;
}
}
RTGUI_DC_FC(dc) = color;
return 0;
}
int rtgui_get_digfont_metrics(struct rtgui_digitfont * font, rtgui_rect_t * rect)
{
int half = font->seg1_nr >> 1;
rect->x1 = 0;
rect->y1 = 0;
rect->x2 = (font->seg1_hspace << 1) + font->seg1_len;
rect->y2 = (font->seg1_vspace << 1) + font->seg2_len + font->seg3_len + (half << 1) - 1;
return 0;
}
/* debug */
struct rtgui_digitfont digitfont_40 =
{
34, //int seg1_len;
3, //int seg1_hspace;
1, //int seg1_vpace;
9, //int seg1_nr; //9
30, //int seg2_len;
30, //int seg3_len;
RT_NULL,
};
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char fontbuf[80];
int digfont_file(char * name, struct rtgui_digitfont * font)
{
int i;
int size;
FILE * file;
struct rtgui_digitfont_data * data;
if (font->data == RT_NULL)
rtgui_digitfont_create(font);
/* create a file to store data */
file = fopen(name, "wb + ");
if (file == RT_NULL)
{
rt_kprintf("open < % s > failed.\n", name);
return -1;
}
data = font->data;
size = font->seg1_nr * 7;
for( i=0; i<size; i++)
{
if ((i % (font->seg1_nr)) == 0)
{
sprintf(fontbuf, "\n/* seg <%d> */\n", i/font->seg1_nr + 1);
fwrite(fontbuf, strlen(fontbuf), 1, file);
}
sprintf(fontbuf, " { % 2d, % 2d, % 2d, % 2d}, \n", data->x, data->y, data->len, data->type);
fwrite(fontbuf, strlen(fontbuf), 1, file);
data ++;
}
fclose(file);
return 0;
}
#if defined(RT_USING_FINSH)
#include <finsh.h>
FINSH_FUNCTION_EXPORT(digfont_file, create the font file of digit font)
#endif
#endif

View File

@ -0,0 +1,174 @@
/*
* File : digfont.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-12-21 pife first version
*/
#include <rtgui/dc.h>
#include <rtgui/widgets/digtube.h>
static void _rtgui_digtube_constructor(struct rtgui_digtube * digtube)
{
RTGUI_WIDGET_TEXTALIGN(digtube) = RTGUI_ALIGN_CENTER;
/* init widget and set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(digtube), rtgui_digtube_event_handler);
}
static void _rtgui_digtube_destructor(struct rtgui_digtube *digtube)
{
#ifndef RTGUI_DIGTUBE_USE_CONST_FONT
/* release font memory */
rt_free(digtube->digitfont.data);
digtube->digitfont.data = RT_NULL;
#endif
}
DEFINE_CLASS_TYPE(digtube, "digtube",
RTGUI_WIDGET_TYPE,
_rtgui_digtube_constructor,
_rtgui_digtube_destructor,
sizeof(struct rtgui_digtube));
rt_bool_t rtgui_digtube_event_handler(struct rtgui_object *object, struct rtgui_event *event)
{
struct rtgui_digtube *digtube;
struct rtgui_dc *dc;
rtgui_rect_t rect;
rtgui_rect_t text_rect;
rtgui_color_t color;
char * disbuf;
char tempbuf[8];
int i;
RTGUI_WIDGET_EVENT_HANDLER_PREPARE
digtube = RTGUI_DIGTUBE(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(object));
if (dc == RT_NULL)
break;
rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect);
rtgui_dc_fill_rect(dc, &rect);
if (! (digtube->tube_style & RTGUI_DIGTUBE_STYLE_NOBACKFONT))
{
color = RTGUI_DC_BC(dc);
RTGUI_DC_BC(dc) = digtube->digit_bc;
}
if (digtube->tube_style & RTGUI_DIGTUBE_STYLE_DISCODES)
disbuf = (char *) (digtube->value);
else
{
const char * format =
digtube->tube_style & RTGUI_DIGTUBE_STYLE_DISHEXNUM ?
"%7x" : "%7d";
disbuf = &tempbuf[0];
rt_snprintf(disbuf, 8, format, digtube->value);
/* */
for (i=0; i<7; i++)
{
if (disbuf[i] == ' ')
disbuf[i] = 0;
else
{
disbuf[i] = (disbuf[i] >= '0' && disbuf[i] <= '9') ? disbuf[i] - '0':
disbuf[i] - 'a' + 10;
disbuf[i] = digtube_code_table[disbuf[i]];
}
}
disbuf = tempbuf + 7 - digtube->tube_count;
}
text_rect.x1 = 0;
text_rect.y1 = 0;
text_rect.x2 = (digtube->digit_width + digtube->digit_space) * digtube->tube_count
-digtube->digit_space;
text_rect.y2 = digtube->digit_hight;
rtgui_rect_moveto_align(&rect, &text_rect, RTGUI_DC_TEXTALIGN(dc));
for (i=0; i<digtube->tube_count; i++)
{
rtgui_dc_draw_digitfont_code(dc, &digtube->digitfont, &text_rect, disbuf[i]);
text_rect.x1 += digtube->digit_width + digtube->digit_space;
}
if (! (digtube->tube_style & RTGUI_DIGTUBE_STYLE_NOBACKFONT))
RTGUI_DC_BC(dc) = color;
rtgui_dc_end_drawing(dc);
break;
default:
return rtgui_widget_event_handler(object, event);
}
return RT_FALSE;
}
rtgui_digtube_t *rtgui_digtube_create(
struct rtgui_digitfont * digitfont,
int count,
void * value,
int style)
{
struct rtgui_digtube *digtube;
rtgui_rect_t rect;
RT_ASSERT(count <= 7 && count > 0)
digtube = (struct rtgui_digtube *) rtgui_widget_create(RTGUI_DIGTUBE_TYPE);
if (digtube == RT_NULL)
return RT_NULL;
/* set field */
if (digitfont == RT_NULL)
digitfont = &digitfont_40;
rt_memcpy(& digtube->digitfont, digitfont, sizeof(struct rtgui_digitfont));
#ifndef RTGUI_DIGTUBE_USE_CONST_FONT
if (digtube->digitfont.data == RT_NULL)
rtgui_digitfont_create(& digtube->digitfont);
#endif
/* set default rect */
rtgui_get_digfont_metrics(&digtube->digitfont, &rect);
digtube->digit_width = rect.x2;
digtube->digit_hight = rect.y2;
digtube->tube_count = count;
digtube->digit_space = RTGUI_DIGTUBE_DEFAULT_SPACE;
rect.x2 = (rect.x2 + digtube->digit_space) * count - digtube->digit_space;
rect.y2 = rect.y2;
RTGUI_WIDGET_BACKGROUND(digtube) = rtgui_theme_default_bc();
RTGUI_WIDGET_FOREGROUND(digtube) = RTGUI_DIGTUBE_DEFAULT_FC;
rtgui_widget_set_rect(RTGUI_WIDGET(digtube), &rect);
/* set display value */
digtube->digit_bc = RTGUI_DIGTUBE_DEFAULT_DIGIT_BC;
digtube->value = value;
digtube->tube_style = style;
return digtube;
}
void rtgui_digtube_destroy(rtgui_digtube_t *digtube)
{
rtgui_widget_destroy(RTGUI_WIDGET(digtube));
}

View File

@ -250,7 +250,7 @@ static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t *object, stru
view = RTGUI_FILELIST_VIEW(menu->user_data); view = RTGUI_FILELIST_VIEW(menu->user_data);
/* hide window */ /* hide window */
rtgui_win_hiden(menu); rtgui_win_hide(menu);
switch (listbox->current_item) switch (listbox->current_item)
{ {

View File

@ -61,7 +61,7 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object *object, struct rtgui_ev
if (!RTGUI_WIDGET_IS_HIDE(menu->sub_menu)) if (!RTGUI_WIDGET_IS_HIDE(menu->sub_menu))
{ {
/* hide this sub menu */ /* hide this sub menu */
rtgui_win_hiden(RTGUI_WIN(menu->sub_menu)); rtgui_win_hide(RTGUI_WIN(menu->sub_menu));
return RT_FALSE; return RT_FALSE;
} }
@ -91,9 +91,9 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object *object, struct rtgui_ev
/* hide sub-menu */ /* hide sub-menu */
if (menu->sub_menu != RT_NULL) if (menu->sub_menu != RT_NULL)
{ {
rtgui_menu_hiden(menu->sub_menu); rtgui_menu_hide(menu->sub_menu);
} }
rtgui_menu_hiden(menu); rtgui_menu_hide(menu);
} }
return RT_FALSE; return RT_FALSE;
} }
@ -183,7 +183,7 @@ static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object *object, rtgui_eve
return RT_TRUE; return RT_TRUE;
} }
rtgui_win_hiden(RTGUI_WIN(menu)); rtgui_win_hide(RTGUI_WIN(menu));
if (menu->on_menuhide != RT_NULL) if (menu->on_menuhide != RT_NULL)
{ {
menu->on_menuhide(RTGUI_OBJECT(menu), RT_NULL); menu->on_menuhide(RTGUI_OBJECT(menu), RT_NULL);
@ -282,13 +282,13 @@ void rtgui_menu_pop(struct rtgui_menu *menu, int x, int y)
rtgui_win_show(RTGUI_WIN(menu), RT_FALSE); rtgui_win_show(RTGUI_WIN(menu), RT_FALSE);
} }
void rtgui_menu_hiden(struct rtgui_menu *menu) void rtgui_menu_hide(struct rtgui_menu *menu)
{ {
rtgui_win_hiden(RTGUI_WIN(menu)); rtgui_win_hide(RTGUI_WIN(menu));
/* un-select item */ /* un-select item */
menu->items_list->current_item = -1; menu->items_list->current_item = -1;
if (menu->parent_menu != RT_NULL) if (menu->parent_menu != RT_NULL)
rtgui_menu_hiden(menu->parent_menu); rtgui_menu_hide(menu->parent_menu);
} }

View File

@ -539,7 +539,8 @@ void rtgui_notebook_set_current_by_index(struct rtgui_notebook *notebook, rt_uin
widget = notebook->childs[notebook->current].widget; widget = notebook->childs[notebook->current].widget;
rtgui_widget_show(widget); rtgui_widget_show(widget);
rtgui_widget_update_clip(widget); rtgui_widget_update_clip(widget);
rtgui_widget_update(widget); /* the whole notebook need an update */
rtgui_widget_update(RTGUI_WIDGET(notebook));
rtgui_widget_focus(widget); rtgui_widget_focus(widget);
} }
} }

View File

@ -228,14 +228,14 @@ void rtgui_radiobox_set_orientation(struct rtgui_radiobox *radiobox, int orienta
if (radiobox->orient == RTGUI_HORIZONTAL) if (radiobox->orient == RTGUI_HORIZONTAL)
{ {
/* HORIZONTAL */ /* HORIZONTAL */
rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); rtgui_widget_set_minheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); rtgui_widget_set_minwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
} }
else else
{ {
/* VERTICAL */ /* VERTICAL */
rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); rtgui_widget_set_minwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); rtgui_widget_set_minheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
} }
#endif #endif
} }

View File

@ -255,14 +255,14 @@ void rtgui_slider_set_orientation(struct rtgui_slider *slider, int orientation)
if (slider->orient == RTGUI_HORIZONTAL) if (slider->orient == RTGUI_HORIZONTAL)
{ {
/* HORIZONTAL */ /* HORIZONTAL */
rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); rtgui_widget_set_minheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); rtgui_widget_set_minwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
} }
else else
{ {
/* VERTICAL */ /* VERTICAL */
rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); rtgui_widget_set_minwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); rtgui_widget_set_minheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
} }
#endif #endif
} }

View File

@ -73,14 +73,14 @@ void rtgui_staticline_set_orientation(rtgui_staticline_t *staticline, int orient
if (orientation == RTGUI_HORIZONTAL) if (orientation == RTGUI_HORIZONTAL)
{ {
/* HORIZONTAL */ /* HORIZONTAL */
rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2); rtgui_widget_set_minheight(RTGUI_WIDGET(staticline), 2);
rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100); rtgui_widget_set_minwidth(RTGUI_WIDGET(staticline), 100);
} }
else else
{ {
/* VERTICAL */ /* VERTICAL */
rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2); rtgui_widget_set_minwidth(RTGUI_WIDGET(staticline), 2);
rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100); rtgui_widget_set_minheight(RTGUI_WIDGET(staticline), 100);
} }
#endif #endif
} }

View File

@ -54,6 +54,14 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
rtgui_textbox_set_mask_char(box, '*'); rtgui_textbox_set_mask_char(box, '*');
rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &rect); rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &rect);
rtgui_widget_set_minheight(RTGUI_WIDGET(box),
rtgui_rect_height(rect) + RTGUI_TEXTBOX_BORDER_WIDTH * 2);
/* at least, we want to display one char. */
rtgui_widget_set_minwidth(RTGUI_WIDGET(box),
rtgui_rect_width(rect) + RTGUI_TEXTBOX_BORDER_WIDTH * 2 \
+ RTGUI_WIDGET_DEFAULT_MARGIN /* there is a margin in the beginning
of the text. */
);
box->font_width = rtgui_rect_width(rect); box->font_width = rtgui_rect_width(rect);
box->on_enter = RT_NULL; box->on_enter = RT_NULL;
box->dis_length = 0; box->dis_length = 0;
@ -531,13 +539,13 @@ void rtgui_textbox_ondraw(rtgui_textbox_t *box)
rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
fc = RTGUI_WIDGET_FOREGROUND(box); fc = RTGUI_WIDGET_FOREGROUND(box);
rtgui_rect_inflate(&rect, -1); rtgui_rect_inflate(&rect, -RTGUI_TEXTBOX_BORDER_WIDTH);
/* fill widget rect with white color */ /* fill widget rect with white color */
RTGUI_WIDGET_BACKGROUND(box) = white; RTGUI_WIDGET_BACKGROUND(box) = white;
rtgui_dc_fill_rect(dc, &rect); rtgui_dc_fill_rect(dc, &rect);
rtgui_rect_inflate(&rect, 1); rtgui_rect_inflate(&rect, RTGUI_TEXTBOX_BORDER_WIDTH);
/* draw border */ /* draw border */
RTGUI_WIDGET_FOREGROUND(box) = RTGUI_RGB(123, 158, 189); RTGUI_WIDGET_FOREGROUND(box) = RTGUI_RGB(123, 158, 189);
rtgui_dc_draw_rect(dc, &rect); rtgui_dc_draw_rect(dc, &rect);
@ -610,29 +618,27 @@ char rtgui_textbox_get_mask_char(rtgui_textbox_t *box)
return box->mask_char; return box->mask_char;
} }
void rtgui_textbox_set_line_length(rtgui_textbox_t *box, rt_size_t length) rt_err_t rtgui_textbox_set_line_length(rtgui_textbox_t *box, rt_size_t length)
{ {
rt_uint8_t *new_line; char *new_line;
RT_ASSERT(box != RT_NULL); RT_ASSERT(box != RT_NULL);
/* invalid length */ /* invalid length */
if (length <= 0) if (length <= 0)
return; return -RT_ERROR;
new_line = rtgui_realloc(box->text, length+1);
if (new_line == RT_NULL)
return -RT_ENOMEM;
new_line = rtgui_malloc(length);
if (length < box->line_length) if (length < box->line_length)
{
rt_memcpy(new_line, box->text, length - 1);
new_line[length] = '\0'; new_line[length] = '\0';
}
else
{
rt_memcpy(new_line, (const char *)box->text, rt_strlen((const char *)box->text));
}
/* set line length */
box->line_length = length; box->line_length = length;
box->text = new_line;
return RT_EOK;
} }
/* get textbox text area */ /* get textbox text area */

View File

@ -135,9 +135,9 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect)
rtgui_container_layout(RTGUI_CONTAINER(widget)); rtgui_container_layout(RTGUI_CONTAINER(widget));
} }
/* reset mini width and height */ /* reset min width and height */
widget->mini_width = rtgui_rect_width(widget->extent); widget->min_width = rtgui_rect_width(widget->extent);
widget->mini_height = rtgui_rect_height(widget->extent); widget->min_height = rtgui_rect_height(widget->extent);
/* it's not empty, fini it */ /* it's not empty, fini it */
if (rtgui_region_not_empty(&(widget->clip))) if (rtgui_region_not_empty(&(widget->clip)))
@ -184,21 +184,29 @@ void rtgui_widget_get_extent(rtgui_widget_t *widget, rtgui_rect_t *rect)
} }
RTM_EXPORT(rtgui_widget_get_extent); RTM_EXPORT(rtgui_widget_get_extent);
void rtgui_widget_set_miniwidth(rtgui_widget_t *widget, int width) void rtgui_widget_set_minsize(rtgui_widget_t *widget, int width, int height)
{
RT_ASSERT(widget != RT_NULL);
widget->min_width = width;
widget->min_height = height;
}
RTM_EXPORT(rtgui_widget_set_minsize);
void rtgui_widget_set_minwidth(rtgui_widget_t *widget, int width)
{ {
RT_ASSERT(widget != RT_NULL); RT_ASSERT(widget != RT_NULL);
widget->mini_width = width; widget->min_width = width;
} }
RTM_EXPORT(rtgui_widget_set_miniwidth); RTM_EXPORT(rtgui_widget_set_minwidth);
void rtgui_widget_set_miniheight(rtgui_widget_t *widget, int height) void rtgui_widget_set_minheight(rtgui_widget_t *widget, int height)
{ {
RT_ASSERT(widget != RT_NULL); RT_ASSERT(widget != RT_NULL);
widget->mini_height = height; widget->min_height = height;
} }
RTM_EXPORT(rtgui_widget_set_miniheight); RTM_EXPORT(rtgui_widget_set_minheight);
/* /*
* This function moves widget and its children to a logic point * This function moves widget and its children to a logic point

View File

@ -178,7 +178,7 @@ static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
return RT_FALSE; return RT_FALSE;
} }
rtgui_win_hiden(win); rtgui_win_hide(win);
win->flag |= RTGUI_WIN_FLAG_CLOSED; win->flag |= RTGUI_WIN_FLAG_CLOSED;
@ -280,7 +280,7 @@ rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal)
/* set main window */ /* set main window */
if (app->main_object == RT_NULL) if (app->main_object == RT_NULL)
rtgui_app_set_main_win(win); rtgui_app_set_main_win(app, win);
if (is_modal == RT_TRUE) if (is_modal == RT_TRUE)
{ {
@ -328,7 +328,7 @@ void rtgui_win_end_modal(struct rtgui_win *win, rtgui_modal_code_t modal_code)
} }
RTM_EXPORT(rtgui_win_end_modal); RTM_EXPORT(rtgui_win_end_modal);
void rtgui_win_hiden(struct rtgui_win *win) void rtgui_win_hide(struct rtgui_win *win)
{ {
RT_ASSERT(win != RT_NULL); RT_ASSERT(win != RT_NULL);
@ -351,7 +351,7 @@ void rtgui_win_hiden(struct rtgui_win *win)
win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE; win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
} }
} }
RTM_EXPORT(rtgui_win_hiden); RTM_EXPORT(rtgui_win_hide);
rt_err_t rtgui_win_activate(struct rtgui_win *win) rt_err_t rtgui_win_activate(struct rtgui_win *win)
{ {
@ -469,7 +469,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
break; break;
case RTGUI_EVENT_WIN_HIDE: case RTGUI_EVENT_WIN_HIDE:
rtgui_win_hiden(win); rtgui_win_hide(win);
break; break;
case RTGUI_EVENT_WIN_CLOSE: case RTGUI_EVENT_WIN_CLOSE:
@ -538,8 +538,26 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
break; break;
case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_BUTTON:
/* check whether has widget which handled mouse event before */ {
if (win->last_mevent_widget != RT_NULL) rt_bool_t res = rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
(struct rtgui_event_mouse *)event);
#ifndef RTGUI_USING_SMALL_SIZE
if (RTGUI_WIDGET(object)->on_mouseclick != RT_NULL)
{
RTGUI_WIDGET(object)->on_mouseclick(object, event);
}
#endif
/* check whether has widget which handled mouse event before.
*
* Note #1: that the widget should have already received mouse down
* event and we should only feed the mouse up event to it here.
*
* Note #2: the widget is responsible to clean up
* last_mevent_widget on mouse up event(but not overwrite other
* widgets). If not, it will receive two mouse up events.
*/
if (((struct rtgui_event_mouse *)event)->button & RTGUI_MOUSE_BUTTON_UP
&& win->last_mevent_widget != RT_NULL)
{ {
RTGUI_OBJECT(win->last_mevent_widget)->event_handler( RTGUI_OBJECT(win->last_mevent_widget)->event_handler(
RTGUI_OBJECT(win->last_mevent_widget), RTGUI_OBJECT(win->last_mevent_widget),
@ -548,17 +566,9 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even
/* clean last mouse event handled widget */ /* clean last mouse event handled widget */
win->last_mevent_widget = RT_NULL; win->last_mevent_widget = RT_NULL;
} }
else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
(struct rtgui_event_mouse *)event) == RT_FALSE) return res;
{
#ifndef RTGUI_USING_SMALL_SIZE
if (RTGUI_WIDGET(object)->on_mouseclick != RT_NULL)
{
return RTGUI_WIDGET(object)->on_mouseclick(object, event);
} }
#endif
}
break;
case RTGUI_EVENT_MOUSE_MOTION: case RTGUI_EVENT_MOUSE_MOTION:
#if 0 #if 0

View File

@ -43,6 +43,7 @@ demo_view_edit.c
demo_view_bmp.c demo_view_bmp.c
demo_plot.c demo_plot.c
mywidget.c mywidget.c
demo_view_digtube.c
""") """)
if GetDepend('RTGUI_USING_FONT_COMPACT'): if GetDepend('RTGUI_USING_FONT_COMPACT'):

View File

@ -33,7 +33,7 @@ static void application_entry(void *parameter)
struct rtgui_app *app; struct rtgui_app *app;
struct rtgui_rect rect; struct rtgui_rect rect;
app = rtgui_app_create(rt_thread_self(), "gui_demo"); app = rtgui_app_create("gui_demo");
if (app == RT_NULL) if (app == RT_NULL)
return; return;
@ -95,6 +95,7 @@ static void application_entry(void *parameter)
demo_view_notebook(); demo_view_notebook();
demo_view_mywidget(); demo_view_mywidget();
demo_plot(); demo_plot();
demo_view_digtube();
#if defined(RTGUI_USING_DFS_FILERW) #if defined(RTGUI_USING_DFS_FILERW)
demo_view_edit(); demo_view_edit();

View File

@ -42,7 +42,7 @@ struct rtgui_container* demo_plot(void)
curve1->min_x = 0; curve1->min_x = 0;
curve1->max_x = sizeof(sin_ydata)/sizeof(sin_ydata[0]); curve1->max_x = sizeof(sin_ydata)/sizeof(sin_ydata[0]);
curve1->min_y = -100; curve1->min_y = -100;
curve1->min_y = 100; curve1->max_y = 100;
curve1->color = red; curve1->color = red;
rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve1), RTGUI_MV_VIEW(plot)); rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve1), RTGUI_MV_VIEW(plot));
@ -51,22 +51,25 @@ struct rtgui_container* demo_plot(void)
RTGUI_MV_MODEL(curve2)->length = sizeof(cos_ydata)/sizeof(cos_ydata[0]); RTGUI_MV_MODEL(curve2)->length = sizeof(cos_ydata)/sizeof(cos_ydata[0]);
curve2->min_x = 0; curve2->min_x = 0;
curve2->max_x = sizeof(cos_ydata)/sizeof(cos_ydata[0]); curve2->max_x = sizeof(cos_ydata)/sizeof(cos_ydata[0]);
curve1->min_y = -50; curve2->min_y = -50;
curve1->min_y = 50; curve2->max_y = 50;
curve2->color = blue; curve2->color = blue;
rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve2), RTGUI_MV_VIEW(plot)); rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve2), RTGUI_MV_VIEW(plot));
curve3 = rtgui_plot_curve_create(); curve3 = rtgui_plot_curve_create();
rtgui_plot_curve_set_x(curve3, cos_ydata); rtgui_plot_curve_set_x(curve3, cos_ydata);
rtgui_plot_curve_set_y(curve3, sin_ydata); rtgui_plot_curve_set_y(curve3, sin_ydata);
curve3->min_x = -50;
curve3->max_x = 50;
curve3->min_y = -100;
curve3->max_y = 100;
RTGUI_MV_MODEL(curve3)->length = sizeof(sin_ydata)/sizeof(sin_ydata[0]); RTGUI_MV_MODEL(curve3)->length = sizeof(sin_ydata)/sizeof(sin_ydata[0]);
curve3->color = black; curve3->color = black;
rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve3), RTGUI_MV_VIEW(plot)); rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve3), RTGUI_MV_VIEW(plot));
rtgui_widget_get_rect(RTGUI_WIDGET(cnt), &rect); rtgui_widget_get_rect(RTGUI_WIDGET(cnt), &rect);
rtgui_widget_set_rect(RTGUI_WIDGET(plot), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(plot), &rect);
rtgui_plot_set_base(plot, rtgui_plot_set_base(plot, -100, -300);
-rtgui_rect_width(rect)/3, rtgui_rect_height(rect)/2);
rtgui_container_add_child(cnt, RTGUI_WIDGET(plot)); rtgui_container_add_child(cnt, RTGUI_WIDGET(plot));

View File

@ -110,7 +110,7 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev
if (running) if (running)
{ {
/* stop */ /* stop */
rtgui_app_set_onidle(RT_NULL); rtgui_app_set_onidle(rtgui_app_self(), RT_NULL);
_draw_default(object, event); _draw_default(object, event);
} }
else else
@ -118,7 +118,7 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev
/* run */ /* run */
ticks = rt_tick_get(); ticks = rt_tick_get();
area = 0; area = 0;
rtgui_app_set_onidle(_onidle); rtgui_app_set_onidle(rtgui_app_self(), _onidle);
} }
running = !running; running = !running;

View File

@ -34,7 +34,7 @@ rtgui_container_t *demo_view_box(void)
button = rtgui_button_create("button 2"); button = rtgui_button_create("button 2");
rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button)); rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button));
rtgui_widget_set_miniheight(RTGUI_WIDGET(button), 25); rtgui_widget_set_minheight(RTGUI_WIDGET(button), 25);
RTGUI_WIDGET_ALIGN(button) = RTGUI_ALIGN_EXPAND; RTGUI_WIDGET_ALIGN(button) = RTGUI_ALIGN_EXPAND;
rtgui_container_layout(RTGUI_CONTAINER(panel)); rtgui_container_layout(RTGUI_CONTAINER(panel));

View File

@ -1,13 +1,13 @@
/* /*
* button控件演示 * button控件演示
* *
* container上添加几个不同类型的button控件 * container上添加几个不同类型的button控件
*/ */
#include "demo_view.h" #include "demo_view.h"
#include <rtgui/widgets/button.h> #include <rtgui/widgets/button.h>
/* 创建用于演示button控件的视图 */ /* 创建用于演示button控件的视图 */
rtgui_container_t *demo_view_button(void) rtgui_container_t *demo_view_button(void)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
@ -15,64 +15,64 @@ rtgui_container_t *demo_view_button(void)
rtgui_button_t *button; rtgui_button_t *button;
rtgui_font_t *font; rtgui_font_t *font;
/* 先创建一个演示用的视图 */ /* 先创建一个演示用的视图 */
container = demo_view("Button View"); container = demo_view("Button View");
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5; rect.y1 += 5;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个button控件 */ /* 创建一个button控件 */
button = rtgui_button_create("Red"); button = rtgui_button_create("Red");
/* 设置label控件的前景色为红色 */ /* 设置label控件的前景色为红色 */
RTGUI_WIDGET_FOREGROUND(button) = red; RTGUI_WIDGET_FOREGROUND(button) = red;
/* 设置button的位置 */ /* 设置button的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_container_add_child(container, RTGUI_WIDGET(button));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25; rect.y1 += 5 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个button控件 */ /* 创建一个button控件 */
button = rtgui_button_create("Blue"); button = rtgui_button_create("Blue");
/* 设置label控件的前景色为蓝色 */ /* 设置label控件的前景色为蓝色 */
RTGUI_WIDGET_FOREGROUND(button) = blue; RTGUI_WIDGET_FOREGROUND(button) = blue;
/* 设置button的位置 */ /* 设置button的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_container_add_child(container, RTGUI_WIDGET(button));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25 + 25; rect.y1 += 5 + 25 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个button控件 */ /* 创建一个button控件 */
button = rtgui_button_create("12 font"); button = rtgui_button_create("12 font");
/* 设置字体为12点阵的asc字体 */ /* 设置字体为12点阵的asc字体 */
font = rtgui_font_refer("asc", 12); font = rtgui_font_refer("asc", 12);
RTGUI_WIDGET_FONT(button) = font; RTGUI_WIDGET_FONT(button) = font;
/* 设置button的位置 */ /* 设置button的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_container_add_child(container, RTGUI_WIDGET(button));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25 + 25 + 25; rect.y1 += 5 + 25 + 25 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个button控件 */ /* 创建一个button控件 */
button = rtgui_button_create("16 font"); button = rtgui_button_create("16 font");
/* 设置字体为16点阵的asc字体 */ /* 设置字体为16点阵的asc字体 */
font = rtgui_font_refer("asc", 16); font = rtgui_font_refer("asc", 16);
RTGUI_WIDGET_FONT(button) = font; RTGUI_WIDGET_FONT(button) = font;
/* 设置button的位置 */ /* 设置button的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_container_add_child(container, RTGUI_WIDGET(button));

View File

@ -1,13 +1,13 @@
/* /*
* checkbox控件演示 * checkbox控件演示
* *
* container上添加几个checkbox控件 * container上添加几个checkbox控件
*/ */
#include "demo_view.h" #include "demo_view.h"
#include <rtgui/widgets/checkbox.h> #include <rtgui/widgets/checkbox.h>
/* 创建用于演示checkbox控件的视图 */ /* 创建用于演示checkbox控件的视图 */
rtgui_container_t *demo_view_checkbox(void) rtgui_container_t *demo_view_checkbox(void)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
@ -15,64 +15,64 @@ rtgui_container_t *demo_view_checkbox(void)
rtgui_checkbox_t *checkbox; rtgui_checkbox_t *checkbox;
rtgui_font_t *font; rtgui_font_t *font;
/* 先创建一个演示用的视图 */ /* 先创建一个演示用的视图 */
container = demo_view("CheckBox View"); container = demo_view("CheckBox View");
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5; rect.y1 += 5;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个checkbox控件 */ /* 创建一个checkbox控件 */
checkbox = rtgui_checkbox_create("Red", RT_TRUE); checkbox = rtgui_checkbox_create("Red", RT_TRUE);
/* 设置前景色为红色 */ /* 设置前景色为红色 */
RTGUI_WIDGET_FOREGROUND(checkbox) = red; RTGUI_WIDGET_FOREGROUND(checkbox) = red;
/* 设置checkbox的位置 */ /* 设置checkbox的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25; rect.y1 += 5 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个checkbox控件 */ /* 创建一个checkbox控件 */
checkbox = rtgui_checkbox_create("Blue", RT_TRUE); checkbox = rtgui_checkbox_create("Blue", RT_TRUE);
/* 设置前景色为蓝色 */ /* 设置前景色为蓝色 */
RTGUI_WIDGET_FOREGROUND(checkbox) = blue; RTGUI_WIDGET_FOREGROUND(checkbox) = blue;
/* 设置checkbox的位置 */ /* 设置checkbox的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25 + 25; rect.y1 += 5 + 25 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个checkbox控件 */ /* 创建一个checkbox控件 */
checkbox = rtgui_checkbox_create("12 font", RT_TRUE); checkbox = rtgui_checkbox_create("12 font", RT_TRUE);
/* 设置字体为12点阵 */ /* 设置字体为12点阵 */
font = rtgui_font_refer("asc", 12); font = rtgui_font_refer("asc", 12);
RTGUI_WIDGET_FONT(checkbox) = font; RTGUI_WIDGET_FONT(checkbox) = font;
/* 设置checkbox的位置 */ /* 设置checkbox的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox));
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 = rect.x1 + 100; rect.x2 = rect.x1 + 100;
rect.y1 += 5 + 25 + 25 + 25; rect.y1 += 5 + 25 + 25 + 25;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个checkbox控件 */ /* 创建一个checkbox控件 */
checkbox = rtgui_checkbox_create("16 font", RT_TRUE); checkbox = rtgui_checkbox_create("16 font", RT_TRUE);
/* 设置字体为16点阵 */ /* 设置字体为16点阵 */
font = rtgui_font_refer("asc", 16); font = rtgui_font_refer("asc", 16);
RTGUI_WIDGET_FONT(checkbox) = font; RTGUI_WIDGET_FONT(checkbox) = font;
/* 设置checkbox的位置 */ /* 设置checkbox的位置 */
rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect);
rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox));

View File

@ -1,7 +1,7 @@
/* /*
* label控件演示 * label控件演示
* *
* container上添加几个不同类型的label控件 * container上添加几个不同类型的label控件
*/ */
#include "demo_view.h" #include "demo_view.h"
#include <rtgui/widgets/combobox.h> #include <rtgui/widgets/combobox.h>
@ -15,25 +15,25 @@ struct rtgui_listbox_item items[] =
{"item 5", RT_NULL}, {"item 5", RT_NULL},
}; };
/* 创建用于演示combobox控件的视图 */ /* 创建用于演示combobox控件的视图 */
rtgui_container_t *demo_view_combobox(void) rtgui_container_t *demo_view_combobox(void)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
rtgui_container_t *container; rtgui_container_t *container;
rtgui_combobox_t *box; rtgui_combobox_t *box;
/* 先创建一个演示用的视图 */ /* 先创建一个演示用的视图 */
container = demo_view("ComboBox View"); container = demo_view("ComboBox View");
/* 获得视图的位置信息 */ /* 获得视图的位置信息 */
demo_view_get_rect(container, &rect); demo_view_get_rect(container, &rect);
rect.x1 += 5; rect.x1 += 5;
rect.x2 -= 5; rect.x2 -= 5;
rect.y1 += 5; rect.y1 += 5;
rect.y2 = rect.y1 + 20; rect.y2 = rect.y1 + 20;
/* 创建一个label控件 */ /* 创建一个label控件 */
box = rtgui_combobox_create(items, sizeof(items) / sizeof(items[0]), &rect); box = rtgui_combobox_create(items, sizeof(items) / sizeof(items[0]), &rect);
/* container是一个container控件调用add_child方法添加这个box控件 */ /* container是一个container控件调用add_child方法添加这个box控件 */
rtgui_container_add_child(container, RTGUI_WIDGET(box)); rtgui_container_add_child(container, RTGUI_WIDGET(box));
return container; return container;

Some files were not shown because too many files have changed in this diff Show More