commit
9400f237b2
|
@ -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 )
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
common/font_cmp_hz*.c
|
||||||
|
doc/doxygened/
|
File diff suppressed because it is too large
Load Diff
|
@ -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'):
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 的
|
||||||
|
价值。
|
|
@ -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 发送事件。使得这个模型适用于线程间同步,也
|
||||||
|
可以在中断上下文里通知事件的发生。
|
||||||
|
*/
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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__ */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
@ -0,0 +1,7 @@
|
||||||
|
# 'animals.txt'
|
||||||
|
Elephant
|
||||||
|
Horse
|
||||||
|
Camel
|
||||||
|
Python
|
||||||
|
Dog
|
||||||
|
Cat
|
|
@ -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
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -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">"Optimal algorithms for minimal perfect hashing"</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 = ["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
|
||||||
|
</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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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>'
|
|
@ -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)
|
|
@ -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'
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
|
@ -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')"
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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()
|
|
@ -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'
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
all:
|
||||||
|
true
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
true
|
||||||
|
|
||||||
|
|
||||||
|
test:
|
||||||
|
./generate_hash.py
|
||||||
|
./PerfHash.py
|
||||||
|
./Graph.py
|
||||||
|
|
|
@ -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'
|
|
@ -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'
|
|
@ -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'
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
/* Return hash value of abbreviation 'abbr' if found, -1 otherwise */
|
||||||
|
int has_key (const char *abbr);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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()
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
../perfect_hash.py ../animals.txt | ./py2dot | neato -Tps -Gstart=100 -o out.ps
|
||||||
|
|
|
@ -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:
|
|
@ -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()
|
|
@ -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
|
|
@ -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)
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
|
@ -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));
|
||||||
|
}
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'):
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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
Loading…
Reference in New Issue