diff --git a/components/external/lzo/README.LZO b/components/external/lzo/README.LZO index e725437827..058eace70a 100644 --- a/components/external/lzo/README.LZO +++ b/components/external/lzo/README.LZO @@ -1,124 +1,124 @@ - - ============================================================================ - miniLZO -- mini subset of the LZO real-time data compression library - ============================================================================ - - Author : Markus Franz Xaver Johannes Oberhumer - - http://www.oberhumer.com/opensource/lzo/ - Version : 2.06 - Date : 12 Aug 2011 - - I've created miniLZO for projects where it is inconvenient to - include (or require) the full LZO source code just because you - want to add a little bit of data compression to your application. - - miniLZO implements the LZO1X-1 compressor and both the standard and - safe LZO1X decompressor. Apart from fast compression it also useful - for situations where you want to use pre-compressed data files (which - must have been compressed with LZO1X-999). - - miniLZO consists of one C source file and three header files: - minilzo.c - minilzo.h, lzoconf.h, lzodefs.h - - To use miniLZO just copy these files into your source directory, add - minilzo.c to your Makefile and #include minilzo.h from your program. - Note: you also must distribute this file ('README.LZO') with your project. - - minilzo.o compiles to about 6 KiB (using gcc or Visual C on an i386), and - the sources are about 30 KiB when packed with zip - so there's no more - excuse that your application doesn't support data compression :-) - - For more information, documentation, example programs and other support - files (like Makefiles and build scripts) please download the full LZO - package from - http://www.oberhumer.com/opensource/lzo/ - - Have fun, - Markus - - - P.S. minilzo.c is generated automatically from the LZO sources and - therefore functionality is completely identical - - - Appendix A: building miniLZO - ---------------------------- - miniLZO is written such a way that it should compile and run - out-of-the-box on most machines. - - If you are running on a very unusual architecture and lzo_init() fails then - you should first recompile with '-DLZO_DEBUG' to see what causes the failure. - The most probable case is something like 'sizeof(void *) != sizeof(size_t)'. - After identifying the problem you can compile by adding some defines - like '-DSIZEOF_VOID_P=8' to your Makefile. - - The best solution is (of course) using Autoconf - if your project uses - Autoconf anyway just add '-DMINILZO_HAVE_CONFIG_H' to your compiler - flags when compiling minilzo.c. See the LZO distribution for an example - how to set up configure.ac. - - - Appendix B: list of public functions available in miniLZO - --------------------------------------------------------- - Library initialization - lzo_init() - - Compression - lzo1x_1_compress() - - Decompression - lzo1x_decompress() - lzo1x_decompress_safe() - - Checksum functions - lzo_adler32() - - Version functions - lzo_version() - lzo_version_string() - lzo_version_date() - - Portable (but slow) string functions - lzo_memcmp() - lzo_memcpy() - lzo_memmove() - lzo_memset() - - - Appendix C: suggested macros for 'configure.ac' when using Autoconf - ------------------------------------------------------------------- - Checks for typedefs and structures - AC_CHECK_TYPE(ptrdiff_t,long) - AC_TYPE_SIZE_T - AC_CHECK_SIZEOF(short) - AC_CHECK_SIZEOF(int) - AC_CHECK_SIZEOF(long) - AC_CHECK_SIZEOF(long long) - AC_CHECK_SIZEOF(__int64) - AC_CHECK_SIZEOF(void *) - AC_CHECK_SIZEOF(size_t) - AC_CHECK_SIZEOF(ptrdiff_t) - - Checks for compiler characteristics - AC_C_CONST - - Checks for library functions - AC_CHECK_FUNCS(memcmp memcpy memmove memset) - - - Appendix D: Copyright - --------------------- - LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 - Markus Franz Xaver Oberhumer . - - LZO and miniLZO are distributed under the terms of the GNU General - Public License (GPL). See the file COPYING. - - Special licenses for commercial and other applications which - are not willing to accept the GNU General Public License - are available by contacting the author. - - + + ============================================================================ + miniLZO -- mini subset of the LZO real-time data compression library + ============================================================================ + + Author : Markus Franz Xaver Johannes Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + Version : 2.06 + Date : 12 Aug 2011 + + I've created miniLZO for projects where it is inconvenient to + include (or require) the full LZO source code just because you + want to add a little bit of data compression to your application. + + miniLZO implements the LZO1X-1 compressor and both the standard and + safe LZO1X decompressor. Apart from fast compression it also useful + for situations where you want to use pre-compressed data files (which + must have been compressed with LZO1X-999). + + miniLZO consists of one C source file and three header files: + minilzo.c + minilzo.h, lzoconf.h, lzodefs.h + + To use miniLZO just copy these files into your source directory, add + minilzo.c to your Makefile and #include minilzo.h from your program. + Note: you also must distribute this file ('README.LZO') with your project. + + minilzo.o compiles to about 6 KiB (using gcc or Visual C on an i386), and + the sources are about 30 KiB when packed with zip - so there's no more + excuse that your application doesn't support data compression :-) + + For more information, documentation, example programs and other support + files (like Makefiles and build scripts) please download the full LZO + package from + http://www.oberhumer.com/opensource/lzo/ + + Have fun, + Markus + + + P.S. minilzo.c is generated automatically from the LZO sources and + therefore functionality is completely identical + + + Appendix A: building miniLZO + ---------------------------- + miniLZO is written such a way that it should compile and run + out-of-the-box on most machines. + + If you are running on a very unusual architecture and lzo_init() fails then + you should first recompile with '-DLZO_DEBUG' to see what causes the failure. + The most probable case is something like 'sizeof(void *) != sizeof(size_t)'. + After identifying the problem you can compile by adding some defines + like '-DSIZEOF_VOID_P=8' to your Makefile. + + The best solution is (of course) using Autoconf - if your project uses + Autoconf anyway just add '-DMINILZO_HAVE_CONFIG_H' to your compiler + flags when compiling minilzo.c. See the LZO distribution for an example + how to set up configure.ac. + + + Appendix B: list of public functions available in miniLZO + --------------------------------------------------------- + Library initialization + lzo_init() + + Compression + lzo1x_1_compress() + + Decompression + lzo1x_decompress() + lzo1x_decompress_safe() + + Checksum functions + lzo_adler32() + + Version functions + lzo_version() + lzo_version_string() + lzo_version_date() + + Portable (but slow) string functions + lzo_memcmp() + lzo_memcpy() + lzo_memmove() + lzo_memset() + + + Appendix C: suggested macros for 'configure.ac' when using Autoconf + ------------------------------------------------------------------- + Checks for typedefs and structures + AC_CHECK_TYPE(ptrdiff_t,long) + AC_TYPE_SIZE_T + AC_CHECK_SIZEOF(short) + AC_CHECK_SIZEOF(int) + AC_CHECK_SIZEOF(long) + AC_CHECK_SIZEOF(long long) + AC_CHECK_SIZEOF(__int64) + AC_CHECK_SIZEOF(void *) + AC_CHECK_SIZEOF(size_t) + AC_CHECK_SIZEOF(ptrdiff_t) + + Checks for compiler characteristics + AC_C_CONST + + Checks for library functions + AC_CHECK_FUNCS(memcmp memcpy memmove memset) + + + Appendix D: Copyright + --------------------- + LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Markus Franz Xaver Oberhumer . + + LZO and miniLZO are distributed under the terms of the GNU General + Public License (GPL). See the file COPYING. + + Special licenses for commercial and other applications which + are not willing to accept the GNU General Public License + are available by contacting the author. + + diff --git a/components/external/lzo/lzo.c b/components/external/lzo/lzo.c index 357cf8c82a..e9c421b256 100644 --- a/components/external/lzo/lzo.c +++ b/components/external/lzo/lzo.c @@ -19,13 +19,8 @@ #ifdef _WIN32 #pragma warning(disable: 4996) -#include -#include -#include -#include -#else -#include #endif +#include /* the worst of allocation */ #define LZO1X_WORST(x) ( (x) + ((x)/16) + 64 + 3 ) diff --git a/components/external/tjpgd1a/SConscript b/components/external/tjpgd1a/SConscript index 8f8200e134..d5db35385f 100644 --- a/components/external/tjpgd1a/SConscript +++ b/components/external/tjpgd1a/SConscript @@ -1,11 +1,13 @@ +Import('RTT_ROOT') +Import('rtconfig') from building import * -cwd = GetCurrentDir() -CPPPATH = [cwd] -src = Split(''' +src = Split(''' tjpgd.c ''') +CPPPATH = [RTT_ROOT + '/components/external/tjpgd1a'] + group = DefineGroup('tjpgd', src, depend = ['RTGUI_IMAGE_TJPGD'], CPPPATH = CPPPATH) Return('group') diff --git a/components/rtgui/.gitignore b/components/rtgui/.gitignore new file mode 100644 index 0000000000..b38864776e --- /dev/null +++ b/components/rtgui/.gitignore @@ -0,0 +1,2 @@ +common/font_cmp_hz*.c +doc/doxygened/ diff --git a/components/rtgui/Doxyfile b/components/rtgui/Doxyfile new file mode 100644 index 0000000000..5c7700759e --- /dev/null +++ b/components/rtgui/Doxyfile @@ -0,0 +1,1826 @@ +# Doxyfile 1.8.1.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "RT-GUI" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/doxygened + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = Chinese + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = utils/perfect_hash + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/components/rtgui/SConscript b/components/rtgui/SConscript index e59a14a664..c68721663c 100644 --- a/components/rtgui/SConscript +++ b/components/rtgui/SConscript @@ -72,6 +72,8 @@ widgets/edit.c widgets/mv_view.c widgets/plot.c widgets/plot_curve.c +widgets/digtube.c +widgets/digfont.c """) if GetDepend('RTGUI_USING_FONT_COMPACT'): diff --git a/components/rtgui/common/asc12font.c b/components/rtgui/common/asc12font.c index 10788e7b96..4aaf82949e 100644 --- a/components/rtgui/common/asc12font.c +++ b/components/rtgui/common/asc12font.c @@ -15,198 +15,101 @@ const rt_uint8_t asc12_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, - 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, - 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, - 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, - 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3c, - 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, - 0xc3, 0xff, 0xff, 0xff, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, - 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, - 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, - 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, - 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x3e, - 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, - 0x18, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, - 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0xc6, 0x60, 0x38, 0x6c, - 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, - 0xfe, 0xfe, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, - 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, - 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x14, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x50, 0x50, 0x00, 0x00, - 0x00, 0x10, 0x38, 0x40, 0x40, 0x38, 0x48, 0x70, 0x10, 0x10, 0x00, 0x00, 0x00, 0x20, 0x50, 0x20, - 0x0c, 0x70, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x20, 0x54, 0x48, - 0x34, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x20, 0x20, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x10, 0x7c, 0x10, 0x28, 0x28, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00, - 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x08, 0x10, 0x20, 0x44, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x14, 0x14, 0x24, 0x44, 0x7c, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x20, 0x20, - 0x38, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x40, 0x78, 0x44, 0x44, 0x44, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, - 0x44, 0x3c, 0x04, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x30, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x10, 0x60, 0x80, 0x60, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x18, 0x04, 0x18, 0x20, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x04, 0x08, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x38, 0x44, 0x44, 0x4c, 0x54, 0x54, 0x4c, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 0x30, 0x10, 0x28, - 0x28, 0x28, 0x7c, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x44, 0x44, 0x78, 0x44, 0x44, 0x44, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0xf0, 0x48, 0x44, 0x44, 0x44, 0x44, 0x48, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x44, 0x50, - 0x70, 0x50, 0x40, 0x44, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x20, 0x28, 0x38, 0x28, 0x20, 0x20, - 0x70, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x4c, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0xec, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x08, 0x08, 0x48, 0x48, 0x48, - 0x30, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x48, 0x50, 0x70, 0x48, 0x44, 0xe4, 0x00, 0x00, 0x00, - 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x24, 0x24, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xec, 0x6c, 0x6c, - 0x54, 0x54, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0xec, 0x64, 0x64, 0x54, 0x54, 0x54, 0x4c, - 0xec, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x78, 0x24, 0x24, 0x24, 0x38, 0x20, 0x20, 0x70, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x38, 0x1c, 0x00, 0x00, 0x00, 0xf8, 0x44, 0x44, 0x44, 0x78, 0x48, 0x44, - 0xe0, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x40, 0x38, 0x04, 0x04, 0x64, 0x58, 0x00, 0x00, 0x00, - 0x00, 0xfc, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, - 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, - 0x10, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x54, 0x54, 0x54, 0x54, 0x28, 0x00, 0x00, 0x00, - 0x00, 0xc4, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0xc4, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x28, - 0x28, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x08, 0x10, 0x10, 0x20, 0x44, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, - 0x00, 0x40, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x38, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 0x00, 0x10, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, - 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x44, 0x3c, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x40, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, - 0x44, 0x7c, 0x40, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x38, 0x00, - 0x00, 0xc0, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0xec, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, - 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x70, 0x00, 0x00, 0xc0, 0x40, 0x5c, 0x48, 0x70, 0x50, 0x48, 0xdc, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, - 0x54, 0x54, 0x54, 0x54, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x64, 0x44, 0x44, 0x44, - 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xd8, 0x64, 0x44, 0x44, 0x44, 0x78, 0x40, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x34, - 0x4c, 0x44, 0x44, 0x44, 0x3c, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x30, 0x20, 0x20, 0x20, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x38, 0x04, 0x44, 0x78, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x20, 0x7c, 0x20, 0x20, 0x20, 0x20, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, - 0x44, 0x44, 0x44, 0x4c, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x44, 0x28, 0x28, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x44, 0x54, 0x54, 0x54, 0x28, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xcc, 0x48, 0x30, 0x30, 0x48, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, - 0x44, 0x24, 0x28, 0x18, 0x10, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x48, 0x10, 0x20, 0x44, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x08, 0x00, - 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, - 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x58, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 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,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00,/*"!",1*/ + 0x00,0x28,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/ + 0x00,0x00,0x28,0x28,0xFC,0x28,0x50,0xFC,0x50,0x50,0x00,0x00,/*"#",3*/ + 0x00,0x20,0x78,0xA8,0xA0,0x60,0x30,0x28,0xA8,0xF0,0x20,0x00,/*"$",4*/ + 0x00,0x00,0x48,0xA8,0xB0,0x50,0x28,0x34,0x54,0x48,0x00,0x00,/*"%",5*/ + 0x00,0x00,0x20,0x50,0x50,0x78,0xA8,0xA8,0x90,0x6C,0x00,0x00,/*"&",6*/ + 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/ + 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x04,0x00,/*"(",8*/ + 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,/*")",9*/ + 0x00,0x00,0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00,0x00,0x00,/*"*",10*/ + 0x00,0x00,0x20,0x20,0x20,0xF8,0x20,0x20,0x20,0x00,0x00,0x00,/*"+",11*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,/*",",12*/ + 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,/*".",14*/ + 0x00,0x08,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00,/*"/",15*/ + 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,/*"0",16*/ + 0x00,0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"1",17*/ + 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x40,0x80,0xF8,0x00,0x00,/*"2",18*/ + 0x00,0x00,0x70,0x88,0x08,0x30,0x08,0x08,0x88,0x70,0x00,0x00,/*"3",19*/ + 0x00,0x00,0x10,0x30,0x50,0x50,0x90,0x78,0x10,0x18,0x00,0x00,/*"4",20*/ + 0x00,0x00,0xF8,0x80,0x80,0xF0,0x08,0x08,0x88,0x70,0x00,0x00,/*"5",21*/ + 0x00,0x00,0x70,0x90,0x80,0xF0,0x88,0x88,0x88,0x70,0x00,0x00,/*"6",22*/ + 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x20,0x20,0x20,0x00,0x00,/*"7",23*/ + 0x00,0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00,/*"8",24*/ + 0x00,0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x48,0x70,0x00,0x00,/*"9",25*/ + 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x20,0x00,0x00,/*":",26*/ + 0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x00,/*";",27*/ + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00,/*"<",28*/ + 0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,/*"=",29*/ + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/ + 0x00,0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00,/*"?",31*/ + 0x00,0x00,0x70,0x88,0x98,0xA8,0xA8,0xB8,0x80,0x78,0x00,0x00,/*"@",32*/ + 0x00,0x00,0x20,0x20,0x30,0x50,0x50,0x78,0x48,0xCC,0x00,0x00,/*"A",33*/ + 0x00,0x00,0xF0,0x48,0x48,0x70,0x48,0x48,0x48,0xF0,0x00,0x00,/*"B",34*/ + 0x00,0x00,0x78,0x88,0x80,0x80,0x80,0x80,0x88,0x70,0x00,0x00,/*"C",35*/ + 0x00,0x00,0xF0,0x48,0x48,0x48,0x48,0x48,0x48,0xF0,0x00,0x00,/*"D",36*/ + 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x48,0xF8,0x00,0x00,/*"E",37*/ + 0x00,0x00,0xF8,0x48,0x50,0x70,0x50,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/ + 0x00,0x00,0x38,0x48,0x80,0x80,0x9C,0x88,0x48,0x30,0x00,0x00,/*"G",39*/ + 0x00,0x00,0xCC,0x48,0x48,0x78,0x48,0x48,0x48,0xCC,0x00,0x00,/*"H",40*/ + 0x00,0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"I",41*/ + 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0xE0,0x00,/*"J",42*/ + 0x00,0x00,0xEC,0x48,0x50,0x60,0x50,0x50,0x48,0xEC,0x00,0x00,/*"K",43*/ + 0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x44,0xFC,0x00,0x00,/*"L",44*/ + 0x00,0x00,0xD8,0xD8,0xD8,0xD8,0xA8,0xA8,0xA8,0xA8,0x00,0x00,/*"M",45*/ + 0x00,0x00,0xDC,0x48,0x68,0x68,0x58,0x58,0x48,0xE8,0x00,0x00,/*"N",46*/ + 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00,/*"O",47*/ + 0x00,0x00,0xF0,0x48,0x48,0x70,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/ + 0x00,0x00,0x70,0x88,0x88,0x88,0x88,0xE8,0x98,0x70,0x18,0x00,/*"Q",49*/ + 0x00,0x00,0xF0,0x48,0x48,0x70,0x50,0x48,0x48,0xEC,0x00,0x00,/*"R",50*/ + 0x00,0x00,0x78,0x88,0x80,0x60,0x10,0x08,0x88,0xF0,0x00,0x00,/*"S",51*/ + 0x00,0x00,0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"T",52*/ + 0x00,0x00,0xCC,0x48,0x48,0x48,0x48,0x48,0x48,0x30,0x00,0x00,/*"U",53*/ + 0x00,0x00,0xCC,0x48,0x48,0x50,0x50,0x30,0x20,0x20,0x00,0x00,/*"V",54*/ + 0x00,0x00,0xA8,0xA8,0xA8,0x70,0x50,0x50,0x50,0x50,0x00,0x00,/*"W",55*/ + 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x50,0x50,0xD8,0x00,0x00,/*"X",56*/ + 0x00,0x00,0xD8,0x50,0x50,0x20,0x20,0x20,0x20,0x70,0x00,0x00,/*"Y",57*/ + 0x00,0x00,0xF8,0x90,0x10,0x20,0x20,0x40,0x48,0xF8,0x00,0x00,/*"Z",58*/ + 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,/*"[",59*/ + 0x00,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x00,0x00,/*"\",60*/ + 0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00,/*"]",61*/ + 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,/*"_",63*/ + 0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/ + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x38,0x48,0x3C,0x00,0x00,/*"a",65*/ + 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00,/*"b",66*/ + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x40,0x40,0x38,0x00,0x00,/*"c",67*/ + 0x00,0x00,0x18,0x08,0x08,0x38,0x48,0x48,0x48,0x3C,0x00,0x00,/*"d",68*/ + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00,/*"e",69*/ + 0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x78,0x00,0x00,/*"f",70*/ + 0x00,0x00,0x00,0x00,0x00,0x3C,0x48,0x30,0x40,0x78,0x44,0x38,/*"g",71*/ + 0x00,0x00,0xC0,0x40,0x40,0x70,0x48,0x48,0x48,0xEC,0x00,0x00,/*"h",72*/ + 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x70,0x00,0x00,/*"i",73*/ + 0x00,0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,/*"j",74*/ + 0x00,0x00,0xC0,0x40,0x40,0x5C,0x50,0x70,0x48,0xEC,0x00,0x00,/*"k",75*/ + 0x00,0x00,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"l",76*/ + 0x00,0x00,0x00,0x00,0x00,0xF0,0xA8,0xA8,0xA8,0xA8,0x00,0x00,/*"m",77*/ + 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0xEC,0x00,0x00,/*"n",78*/ + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00,/*"o",79*/ + 0x00,0x00,0x00,0x00,0x00,0xF0,0x48,0x48,0x48,0x70,0x40,0xE0,/*"p",80*/ + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x1C,/*"q",81*/ + 0x00,0x00,0x00,0x00,0x00,0xD8,0x60,0x40,0x40,0xE0,0x00,0x00,/*"r",82*/ + 0x00,0x00,0x00,0x00,0x00,0x78,0x40,0x30,0x08,0x78,0x00,0x00,/*"s",83*/ + 0x00,0x00,0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x18,0x00,0x00,/*"t",84*/ + 0x00,0x00,0x00,0x00,0x00,0xD8,0x48,0x48,0x48,0x3C,0x00,0x00,/*"u",85*/ + 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x00,0x00,/*"v",86*/ + 0x00,0x00,0x00,0x00,0x00,0xA8,0xA8,0x70,0x50,0x50,0x00,0x00,/*"w",87*/ + 0x00,0x00,0x00,0x00,0x00,0xD8,0x50,0x20,0x50,0xD8,0x00,0x00,/*"x",88*/ + 0x00,0x00,0x00,0x00,0x00,0xEC,0x48,0x50,0x30,0x20,0x20,0xC0,/*"y",89*/ + 0x00,0x00,0x00,0x00,0x00,0x78,0x10,0x20,0x20,0x78,0x00,0x00,/*"z",90*/ + 0x00,0x18,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x18,0x00,/*"{",91*/ + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,/*"|",92*/ + 0x00,0x60,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0x60,0x00,/*"}",93*/ + 0x40,0xA4,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"~",94*/ }; const struct rtgui_font_bitmap asc12 = @@ -216,8 +119,8 @@ const struct rtgui_font_bitmap asc12 = RT_NULL, /* offset for each character */ 6, /* width */ 12, /* height */ - 0, /* first char */ - 255 /* last char */ + 32, /* first char */ + 127 /* last char */ }; struct rtgui_font rtgui_font_asc12 = diff --git a/components/rtgui/common/asc16font.c b/components/rtgui/common/asc16font.c index 4db17e1655..b2de5ab354 100644 --- a/components/rtgui/common/asc16font.c +++ b/components/rtgui/common/asc16font.c @@ -16,262 +16,101 @@ #ifdef RTGUI_USING_FONT16 const unsigned char asc16_font[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 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, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, - 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 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, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*" ",0*/ + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x18,0x18,0x00,0x00,/*"!",1*/ + 0x00,0x12,0x36,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*""",2*/ + 0x00,0x00,0x00,0x24,0x24,0x24,0xFE,0x48,0x48,0x48,0xFE,0x48,0x48,0x48,0x00,0x00,/*"#",3*/ + 0x00,0x00,0x10,0x38,0x54,0x54,0x50,0x30,0x18,0x14,0x14,0x54,0x54,0x38,0x10,0x10,/*"$",4*/ + 0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xA8,0x54,0x1A,0x2A,0x2A,0x2A,0x44,0x00,0x00,/*"%",5*/ + 0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x50,0x6E,0xA4,0x94,0x88,0x89,0x76,0x00,0x00,/*"&",6*/ + 0x00,0x60,0x60,0x20,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"'",7*/ + 0x00,0x02,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x08,0x08,0x04,0x02,0x00,/*"(",8*/ + 0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40,0x00,/*")",9*/ + 0x00,0x00,0x00,0x00,0x10,0x10,0xD6,0x38,0x38,0xD6,0x10,0x10,0x00,0x00,0x00,0x00,/*"*",10*/ + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x10,0x00,0x00,0x00,/*"+",11*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0xC0,/*",",12*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"-",13*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,/*".",14*/ + 0x00,0x00,0x01,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,/*"/",15*/ + 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"0",16*/ + 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"1",17*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,/*"2",18*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"3",19*/ + 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,/*"4",20*/ + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,/*"5",21*/ + 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,/*"6",22*/ + 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,/*"7",23*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,/*"8",24*/ + 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,/*"9",25*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,/*":",26*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x20,/*";",27*/ + 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x02,0x00,0x00,/*"<",28*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,/*"=",29*/ + 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x40,0x00,0x00,/*">",30*/ + 0x00,0x00,0x00,0x3C,0x42,0x42,0x62,0x02,0x04,0x08,0x08,0x00,0x18,0x18,0x00,0x00,/*"?",31*/ + 0x00,0x00,0x00,0x38,0x44,0x5A,0xAA,0xAA,0xAA,0xAA,0xB4,0x42,0x44,0x38,0x00,0x00,/*"@",32*/ + 0x00,0x00,0x00,0x10,0x10,0x18,0x28,0x28,0x24,0x3C,0x44,0x42,0x42,0xE7,0x00,0x00,/*"A",33*/ + 0x00,0x00,0x00,0xF8,0x44,0x44,0x44,0x78,0x44,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"B",34*/ + 0x00,0x00,0x00,0x3E,0x42,0x42,0x80,0x80,0x80,0x80,0x80,0x42,0x44,0x38,0x00,0x00,/*"C",35*/ + 0x00,0x00,0x00,0xF8,0x44,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x44,0xF8,0x00,0x00,/*"D",36*/ + 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x42,0x42,0xFC,0x00,0x00,/*"E",37*/ + 0x00,0x00,0x00,0xFC,0x42,0x48,0x48,0x78,0x48,0x48,0x40,0x40,0x40,0xE0,0x00,0x00,/*"F",38*/ + 0x00,0x00,0x00,0x3C,0x44,0x44,0x80,0x80,0x80,0x8E,0x84,0x44,0x44,0x38,0x00,0x00,/*"G",39*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"H",40*/ + 0x00,0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"I",41*/ + 0x00,0x00,0x00,0x3E,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x88,0xF0,/*"J",42*/ + 0x00,0x00,0x00,0xEE,0x44,0x48,0x50,0x70,0x50,0x48,0x48,0x44,0x44,0xEE,0x00,0x00,/*"K",43*/ + 0x00,0x00,0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0xFE,0x00,0x00,/*"L",44*/ + 0x00,0x00,0x00,0xEE,0x6C,0x6C,0x6C,0x6C,0x54,0x54,0x54,0x54,0x54,0xD6,0x00,0x00,/*"M",45*/ + 0x00,0x00,0x00,0xC7,0x62,0x62,0x52,0x52,0x4A,0x4A,0x4A,0x46,0x46,0xE2,0x00,0x00,/*"N",46*/ + 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0x44,0x38,0x00,0x00,/*"O",47*/ + 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0xE0,0x00,0x00,/*"P",48*/ + 0x00,0x00,0x00,0x38,0x44,0x82,0x82,0x82,0x82,0x82,0xB2,0xCA,0x4C,0x38,0x06,0x00,/*"Q",49*/ + 0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x7C,0x48,0x48,0x44,0x44,0x42,0xE3,0x00,0x00,/*"R",50*/ + 0x00,0x00,0x00,0x3E,0x42,0x42,0x40,0x20,0x18,0x04,0x02,0x42,0x42,0x7C,0x00,0x00,/*"S",51*/ + 0x00,0x00,0x00,0xFE,0x92,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"T",52*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"U",53*/ + 0x00,0x00,0x00,0xE7,0x42,0x42,0x44,0x24,0x24,0x28,0x28,0x18,0x10,0x10,0x00,0x00,/*"V",54*/ + 0x00,0x00,0x00,0xD6,0x92,0x92,0x92,0x92,0xAA,0xAA,0x6C,0x44,0x44,0x44,0x00,0x00,/*"W",55*/ + 0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x18,0x18,0x18,0x24,0x24,0x42,0xE7,0x00,0x00,/*"X",56*/ + 0x00,0x00,0x00,0xEE,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,/*"Y",57*/ + 0x00,0x00,0x00,0x7E,0x84,0x04,0x08,0x08,0x10,0x20,0x20,0x42,0x42,0xFC,0x00,0x00,/*"Z",58*/ + 0x00,0x1E,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1E,0x00,/*"[",59*/ + 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x02,/*"\",60*/ + 0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78,0x00,/*"]",61*/ + 0x00,0x1C,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"^",62*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,/*"_",63*/ + 0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"`",64*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x1E,0x22,0x42,0x42,0x3F,0x00,0x00,/*"a",65*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x64,0x58,0x00,0x00,/*"b",66*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,/*"c",67*/ + 0x00,0x00,0x00,0x06,0x02,0x02,0x02,0x1E,0x22,0x42,0x42,0x42,0x26,0x1B,0x00,0x00,/*"d",68*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x7E,0x40,0x40,0x42,0x3C,0x00,0x00,/*"e",69*/ + 0x00,0x00,0x00,0x0F,0x11,0x10,0x10,0x7E,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"f",70*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x44,0x44,0x38,0x40,0x3C,0x42,0x42,0x3C,/*"g",71*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"h",72*/ + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"i",73*/ + 0x00,0x00,0x00,0x0C,0x0C,0x00,0x00,0x1C,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x78,/*"j",74*/ + 0x00,0x00,0x00,0xC0,0x40,0x40,0x40,0x4E,0x48,0x50,0x68,0x48,0x44,0xEE,0x00,0x00,/*"k",75*/ + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,/*"l",76*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x49,0x49,0x49,0x49,0x49,0xED,0x00,0x00,/*"m",77*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x62,0x42,0x42,0x42,0x42,0xE7,0x00,0x00,/*"n",78*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,/*"o",79*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x64,0x42,0x42,0x42,0x44,0x78,0x40,0xE0,/*"p",80*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x22,0x42,0x42,0x42,0x22,0x1E,0x02,0x07,/*"q",81*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0x32,0x20,0x20,0x20,0x20,0xF8,0x00,0x00,/*"r",82*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x40,0x3C,0x02,0x42,0x7C,0x00,0x00,/*"s",83*/ + 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,0x00,/*"t",84*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x46,0x3B,0x00,0x00,/*"u",85*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x10,0x10,0x00,0x00,/*"v",86*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD7,0x92,0x92,0xAA,0xAA,0x44,0x44,0x00,0x00,/*"w",87*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x24,0x18,0x18,0x18,0x24,0x76,0x00,0x00,/*"x",88*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x42,0x24,0x24,0x28,0x18,0x10,0x10,0xE0,/*"y",89*/ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x44,0x08,0x10,0x10,0x22,0x7E,0x00,0x00,/*"z",90*/ + 0x00,0x03,0x04,0x04,0x04,0x04,0x04,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x03,0x00,/*"{",91*/ + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,/*"|",92*/ + 0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x60,0x00,/*"}",93*/ + 0x30,0x4C,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"~",94*/ }; struct rtgui_font_bitmap asc16 = @@ -281,8 +120,8 @@ struct rtgui_font_bitmap asc16 = RT_NULL, /* offset for each character */ 8, /* width */ 16, /* height */ - 0, /* first char */ - 255 /* last char */ + 32, /* first char */ + 127 /* last char */ }; struct rtgui_font rtgui_font_asc16 = @@ -294,5 +133,4 @@ struct rtgui_font rtgui_font_asc16 = &asc16, /* font private data */ }; -/* size = 4096 bytes */ #endif diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c index 02413a7a0f..c9dc711a47 100644 --- a/components/rtgui/common/dc_hw.c +++ b/components/rtgui/common/dc_hw.c @@ -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 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 = { rtgui_dc_hw_draw_point, diff --git a/components/rtgui/common/font_bmp.c b/components/rtgui/common/font_bmp.c index 264a822401..e4c0ab1646 100644 --- a/components/rtgui/common/font_bmp.c +++ b/components/rtgui/common/font_bmp.c @@ -59,11 +59,12 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap *font, struct rtgui_dc 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; for (j = 0; j < w; j++) { - if (j % 8 == 0)chr = *ptr++; + if (j % 8 == 0) + chr = *ptr++; if (chr & 0x80) rtgui_dc_draw_point(dc, j + x, i + y); else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) diff --git a/components/rtgui/common/image_jpg.c b/components/rtgui/common/image_jpg.c index 67164c7372..c5fe5da384 100644 --- a/components/rtgui/common/image_jpg.c +++ b/components/rtgui/common/image_jpg.c @@ -351,6 +351,7 @@ static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image *image, struct rtgui_f { /* no memory */ jpeg_finish_decompress(&jpeg->cinfo); + jpeg_destroy_decompress(&jpeg->cinfo); rt_free(jpeg); return RT_FALSE; @@ -381,6 +382,7 @@ static void rtgui_image_jpeg_unload(struct rtgui_image *image) rtgui_filerw_close(jpeg->filerw); jpeg_finish_decompress(&jpeg->cinfo); } + jpeg_destroy_decompress(&jpeg->cinfo); rt_free(jpeg); } } diff --git a/components/rtgui/common/region.c b/components/rtgui/common/region.c index a4bf2f2ed1..47a4b862f2 100644 --- a/components/rtgui/common/region.c +++ b/components/rtgui/common/region.c @@ -2274,3 +2274,13 @@ rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect) 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; +} + diff --git a/components/rtgui/common/rtgui_app.c b/components/rtgui/common/rtgui_app.c index 186a1cca4c..7f76d76288 100644 --- a/components/rtgui/common/rtgui_app.c +++ b/components/rtgui/common/rtgui_app.c @@ -30,7 +30,6 @@ static void _rtgui_app_constructor(struct rtgui_app *app) app->ref_count = 0; app->exit_code = 0; app->tid = RT_NULL; - app->server = RT_NULL; app->mq = RT_NULL; app->modal_object = RT_NULL; app->main_object = RT_NULL; @@ -51,13 +50,13 @@ DEFINE_CLASS_TYPE(application, "application", _rtgui_app_destructor, sizeof(struct rtgui_app)); -struct rtgui_app *rtgui_app_create( - rt_thread_t tid, - const char *title) +struct rtgui_app *rtgui_app_create(const char *title) { - rt_thread_t srv_tid; + rt_thread_t tid = rt_thread_self(); struct rtgui_app *app; + struct rtgui_app *srv_app; struct rtgui_event_application event; + char mq_name[RT_NAME_MAX]; RT_ASSERT(tid != 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 */ RT_ASSERT(tid->user_data == 0); 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) { rt_kprintf("create msgq failed.\n"); @@ -85,31 +83,30 @@ struct rtgui_app *rtgui_app_create( if (app->name == RT_NULL) goto __err; - /* send a message to notify rtgui server */ - srv_tid = rtgui_get_server(); - if (srv_tid == RT_NULL) + /* the first app should be the server */ + srv_app = rtgui_get_server(); + if (srv_app == RT_NULL) { - rt_kprintf("gui server is not running.\n"); - goto __err; - } - - /* create the rtgui server application */ - if (srv_tid == rt_thread_self()) + /* set user thread */ + tid->user_data = (rt_uint32_t)app; + rt_kprintf("RTGUI: creating the server app %p.\n", app); return app; + } RTGUI_EVENT_APP_CREATE_INIT(&event); event.app = app; /* 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; } __err: __mq_err: rtgui_object_destroy(RTGUI_OBJECT(app)); - tid->user_data = 0; return RT_NULL; } RTM_EXPORT(rtgui_app_create); @@ -124,7 +121,7 @@ RTM_EXPORT(rtgui_app_create); void rtgui_app_destroy(struct rtgui_app *app) { - rt_thread_t srv_tid; + struct rtgui_app *srv_app; _rtgui_application_check(app); 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 */ - srv_tid = rtgui_get_server(); - if (srv_tid != rt_thread_self()) /* must not the server thread */ + srv_app = rtgui_get_server(); + if (srv_app != rtgui_app_self()) { struct rtgui_event_application event; RTGUI_EVENT_APP_DESTROY_INIT(&event); 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"); return ; @@ -168,25 +165,18 @@ struct rtgui_app *rtgui_app_self(void) } 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; - - app = rtgui_app_self(); - if (app != RT_NULL) - app->on_idle = onidle; + _rtgui_application_check(app); + app->on_idle = 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(); - if (app != RT_NULL) - return app->on_idle; - else - return RT_NULL; + _rtgui_application_check(app); + return app->on_idle; } RTM_EXPORT(rtgui_app_get_onidle); @@ -369,7 +359,7 @@ void rtgui_app_activate(struct rtgui_app *app) RTGUI_EVENT_APP_ACTIVATE_INIT(&event); 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); @@ -380,28 +370,28 @@ void rtgui_app_close(struct rtgui_app *app) RTGUI_EVENT_APP_DESTROY_INIT(&event); 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); /** * 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_app *app; - srv_tid = rtgui_get_server(); - app = rtgui_app_self(); - if (app != RT_NULL && srv_tid != RT_NULL) + _rtgui_application_check(app); + + srv_app = rtgui_get_server(); + if (srv_app != RT_NULL) { /* notify rtgui server, this is a window manager */ RTGUI_EVENT_SET_WM_INIT(&event); 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; } @@ -409,15 +399,11 @@ rt_err_t rtgui_app_set_as_wm(void) } 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(); - if (app != RT_NULL) - { - app->main_object = RTGUI_OBJECT(win); - } + _rtgui_application_check(app); + app->main_object = RTGUI_OBJECT(win); } RTM_EXPORT(rtgui_app_set_main_win); diff --git a/components/rtgui/common/rtgui_mv_model.c b/components/rtgui/common/rtgui_mv_model.c index c32fce3001..e10976b14c 100644 --- a/components/rtgui/common/rtgui_mv_model.c +++ b/components/rtgui/common/rtgui_mv_model.c @@ -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_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->view = view; return rtgui_send(target, (struct rtgui_event *)emodel, sizeof(*emodel)); diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c index 576655dadf..781b25adc5 100644 --- a/components/rtgui/common/rtgui_system.c +++ b/components/rtgui/common/rtgui_system.c @@ -70,7 +70,7 @@ static void rtgui_time_out(void *parameter) 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) @@ -78,7 +78,7 @@ rtgui_timer_t *rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeou rtgui_timer_t *timer; timer = (rtgui_timer_t *) rtgui_malloc(sizeof(rtgui_timer_t)); - timer->tid = rt_thread_self(); + timer->app = rtgui_app_self(); timer->timeout = timeout; timer->user_data = parameter; @@ -371,7 +371,7 @@ const char *event_string[] = #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)"; @@ -389,12 +389,12 @@ static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t *event) 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 ; } 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) @@ -545,88 +545,68 @@ static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t *event) } #else #define DBG_MSG(x) -#define rtgui_event_dump(tid, event) +#define rtgui_event_dump(app, event) #endif /************************************************************************/ /* 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; - struct rtgui_app *app; - RT_ASSERT(tid != RT_NULL); + RT_ASSERT(app != RT_NULL); RT_ASSERT(event != RT_NULL); RT_ASSERT(event_size != 0); - rtgui_event_dump(tid, event); - - /* find struct rtgui_application */ - app = (struct rtgui_app *)(tid->user_data); - if (app == RT_NULL) - return -RT_ERROR; + rtgui_event_dump(app, event); result = rt_mq_send(app->mq, event, event_size); if (result != RT_EOK) { 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; } 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; - struct rtgui_app *app; - RT_ASSERT(tid != RT_NULL); + RT_ASSERT(app != RT_NULL); RT_ASSERT(event != RT_NULL); RT_ASSERT(event_size != 0); - rtgui_event_dump(tid, event); - - /* find rtgui_application */ - app = (struct rtgui_app *)(tid->user_data); - if (app == RT_NULL) - return -RT_ERROR; + rtgui_event_dump(app, event); result = rt_mq_urgent(app->mq, event, event_size); if (result != RT_EOK) - rt_kprintf("send ergent event failed\n"); + rt_kprintf("send ergent event to %s failed\n", app->name); return result; } 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; - struct rtgui_app *app; rt_int32_t ack_buffer, ack_status; struct rt_mailbox ack_mb; - RT_ASSERT(tid != RT_NULL); + RT_ASSERT(app != RT_NULL); RT_ASSERT(event != RT_NULL); RT_ASSERT(event_size != 0); - rtgui_event_dump(tid, event); + rtgui_event_dump(app, event); /* init ack mailbox */ r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0); if (r != RT_EOK) goto __return; - app = (struct rtgui_app *)(tid->user_data); - if (app == RT_NULL) - { - r = -RT_ERROR; - goto __return; - } - event->ack = &ack_mb; r = rt_mq_send(app->mq, event, event_size); 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); -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) { _mainwin_rect = *rect; diff --git a/components/rtgui/common/rtgui_theme.c b/components/rtgui/common/rtgui_theme.c index a1e8b119b5..e7576c4558 100644 --- a/components/rtgui/common/rtgui_theme.c +++ b/components/rtgui/common/rtgui_theme.c @@ -96,31 +96,34 @@ void rtgui_theme_draw_win(struct rtgui_topwin *win) if (!(win->flag & WINTITLE_NO)) { 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) { - r = 10; - g = 36; - b = 106; - delta = 150 / (float)(rect.x2 - rect.x1); + r = 10 << RGB_FACTOR; + g = 36 << RGB_FACTOR; + b = 106 << RGB_FACTOR; + delta = (150 << RGB_FACTOR) / (rect.x2 - rect.x1); } else { - r = 128; - g = 128; - b = 128; - delta = 64 / (float)(rect.x2 - rect.x1); + r = 128 << RGB_FACTOR; + g = 128 << RGB_FACTOR; + b = 128 << RGB_FACTOR; + 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 ++) { + 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); r += delta; g += delta; b += delta; } +#undef RGB_FACTOR if (win->flag & WINTITLE_ACTIVATE) { diff --git a/components/rtgui/doc/ANNOUNCE.0.6.md b/components/rtgui/doc/ANNOUNCE.0.6.md new file mode 100644 index 0000000000..8d65c0a812 --- /dev/null +++ b/components/rtgui/doc/ANNOUNCE.0.6.md @@ -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 的 +价值。 diff --git a/components/rtgui/doc/road_map.txt b/components/rtgui/doc/historical/road_map.txt similarity index 100% rename from components/rtgui/doc/road_map.txt rename to components/rtgui/doc/historical/road_map.txt diff --git a/components/rtgui/doc/mv-model.dox b/components/rtgui/doc/mv-model.dox new file mode 100644 index 0000000000..15975c4625 --- /dev/null +++ b/components/rtgui/doc/mv-model.dox @@ -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 发送事件。使得这个模型适用于线程间同步,也 + 可以在中断上下文里通知事件的发生。 +*/ diff --git a/components/rtgui/include/rtgui/dc.h b/components/rtgui/include/rtgui/dc.h index 7ee7f6dd93..4a36465e89 100644 --- a/components/rtgui/include/rtgui/dc.h +++ b/components/rtgui/include/rtgui/dc.h @@ -60,6 +60,14 @@ struct rtgui_dc 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_BC(dc) (rtgui_dc_get_gc(dc)->background) #define RTGUI_DC_FONT(dc) (rtgui_dc_get_gc(dc)->font) diff --git a/components/rtgui/include/rtgui/driver.h b/components/rtgui/include/rtgui/driver.h index 6b77aa804f..2259853448 100644 --- a/components/rtgui/include/rtgui/driver.h +++ b/components/rtgui/include/rtgui/driver.h @@ -17,6 +17,7 @@ #include #include +/* graphic driver operations */ struct rtgui_graphic_driver_ops { /* 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); }; +/* 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 { /* pixel format and byte per pixel */ @@ -43,11 +60,11 @@ struct rtgui_graphic_driver /* framebuffer address and ops */ volatile rt_uint8_t *framebuffer; - rt_device_t device; - const struct rtgui_graphic_driver_ops *ops; -}; + struct rt_device* device; -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); @@ -64,5 +81,19 @@ rt_inline struct rtgui_graphic_driver *rtgui_graphic_get_device() 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 diff --git a/components/rtgui/include/rtgui/event.h b/components/rtgui/include/rtgui/event.h index c0f4e5b7bf..cb83fdb85b 100644 --- a/components/rtgui/include/rtgui/event.h +++ b/components/rtgui/include/rtgui/event.h @@ -90,7 +90,7 @@ struct rtgui_event rt_uint16_t user; /* the event sender */ - rt_thread_t sender; + struct rtgui_app *sender; /* mailbox to acknowledge request */ rt_mailbox_t ack; @@ -98,11 +98,13 @@ struct rtgui_event typedef struct rtgui_event rtgui_event_t; #define RTGUI_EVENT(e) ((struct rtgui_event*)(e)) +extern struct rtgui_app* rtgui_app_self(void); + #define RTGUI_EVENT_INIT(e, t) do \ { \ (e)->type = (t); \ (e)->user = 0; \ - (e)->sender = rt_thread_self(); \ + (e)->sender = rtgui_app_self(); \ (e)->ack = RT_NULL; \ } while (0) diff --git a/components/rtgui/include/rtgui/region.h b/components/rtgui/include/rtgui/region.h index 42a78b8da4..ab36acccfb 100644 --- a/components/rtgui/include/rtgui/region.h +++ b/components/rtgui/include/rtgui/region.h @@ -20,81 +20,82 @@ extern "C" { #endif - typedef struct rtgui_region_data rtgui_region_data_t; +typedef struct rtgui_region_data rtgui_region_data_t; - struct rtgui_region_data - { - rt_uint32_t size; - rt_uint32_t numRects; - /* XXX: And why, exactly, do we have this bogus struct definition? */ - /* rtgui_rect_t rects[size]; in memory but not explicitly declared */ - }; +struct rtgui_region_data +{ + rt_uint32_t size; + rt_uint32_t numRects; + /* XXX: And why, exactly, do we have this bogus struct definition? */ + /* rtgui_rect_t rects[size]; in memory but not explicitly declared */ +}; - typedef struct rtgui_region - { - rtgui_rect_t extents; - rtgui_region_data_t *data; - } rtgui_region_t; +typedef struct rtgui_region +{ + rtgui_rect_t extents; + rtgui_region_data_t *data; +} rtgui_region_t; - typedef enum - { - RTGUI_REGION_STATUS_FAILURE, - RTGUI_REGION_STATUS_SUCCESS - } rtgui_region_status_t; +typedef enum +{ + RTGUI_REGION_STATUS_FAILURE, + RTGUI_REGION_STATUS_SUCCESS +} rtgui_region_status_t; - /* creation/destruction */ +/* creation/destruction */ - void rtgui_region_init(rtgui_region_t *region); - void rtgui_region_init_rect(rtgui_region_t *region, - int x, int y, unsigned int width, unsigned int height); - void rtgui_region_init_with_extents(rtgui_region_t *region, const rtgui_rect_t *extents); - void rtgui_region_fini(rtgui_region_t *region); +void rtgui_region_init(rtgui_region_t *region); +void rtgui_region_init_rect(rtgui_region_t *region, + int x, int y, unsigned int width, unsigned int height); +void rtgui_region_init_with_extents(rtgui_region_t *region, const rtgui_rect_t *extents); +void rtgui_region_fini(rtgui_region_t *region); - void rtgui_region_translate(rtgui_region_t *region, int x, int y); +void rtgui_region_translate(rtgui_region_t *region, int x, int y); - rtgui_region_status_t rtgui_region_copy(rtgui_region_t *dest, rtgui_region_t *source); +rtgui_region_status_t rtgui_region_copy(rtgui_region_t *dest, rtgui_region_t *source); - rtgui_region_status_t rtgui_region_intersect(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_region_t *reg2); - rtgui_region_status_t rtgui_region_intersect_rect(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_rect_t *rect); - rtgui_region_status_t rtgui_region_union(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_region_t *reg2); - rtgui_region_status_t rtgui_region_union_rect(rtgui_region_t *dest, rtgui_region_t *source, rtgui_rect_t *rect); - rtgui_region_status_t rtgui_region_subtract(rtgui_region_t *regD, rtgui_region_t *regM, rtgui_region_t *regS); - rtgui_region_status_t rtgui_region_subtract_rect(rtgui_region_t *regD, rtgui_region_t *regM, rtgui_rect_t *rect); - rtgui_region_status_t rtgui_region_inverse(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_rect_t *invRect); +rtgui_region_status_t rtgui_region_intersect(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_region_t *reg2); +rtgui_region_status_t rtgui_region_intersect_rect(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_rect_t *rect); +rtgui_region_status_t rtgui_region_union(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_region_t *reg2); +rtgui_region_status_t rtgui_region_union_rect(rtgui_region_t *dest, rtgui_region_t *source, rtgui_rect_t *rect); +rtgui_region_status_t rtgui_region_subtract(rtgui_region_t *regD, rtgui_region_t *regM, rtgui_region_t *regS); +rtgui_region_status_t rtgui_region_subtract_rect(rtgui_region_t *regD, rtgui_region_t *regM, rtgui_rect_t *rect); +rtgui_region_status_t rtgui_region_inverse(rtgui_region_t *newReg, rtgui_region_t *reg1, rtgui_rect_t *invRect); - int rtgui_region_num_rects(rtgui_region_t *region); +int rtgui_region_num_rects(rtgui_region_t *region); - rtgui_rect_t *rtgui_region_rects(rtgui_region_t *region); +rtgui_rect_t *rtgui_region_rects(rtgui_region_t *region); #define RTGUI_REGION_OUT 0 #define RTGUI_REGION_IN 1 #define RTGUI_REGION_PART 2 - int rtgui_region_contains_point(rtgui_region_t *region, int x, int y, rtgui_rect_t *box); - int rtgui_region_contains_rectangle(rtgui_region_t *rtgui_region_t, rtgui_rect_t *prect); +int rtgui_region_contains_point(rtgui_region_t *region, int x, int y, rtgui_rect_t *box); +int rtgui_region_contains_rectangle(rtgui_region_t *rtgui_region_t, rtgui_rect_t *prect); - int rtgui_region_not_empty(rtgui_region_t *region); - rtgui_rect_t *rtgui_region_extents(rtgui_region_t *region); +int rtgui_region_not_empty(rtgui_region_t *region); +rtgui_rect_t *rtgui_region_extents(rtgui_region_t *region); - rtgui_region_status_t rtgui_region_append(rtgui_region_t *dest, rtgui_region_t *region); - rtgui_region_status_t rtgui_region_validate(rtgui_region_t *badreg, int *pOverlap); +rtgui_region_status_t rtgui_region_append(rtgui_region_t *dest, rtgui_region_t *region); +rtgui_region_status_t rtgui_region_validate(rtgui_region_t *badreg, int *pOverlap); - void rtgui_region_reset(rtgui_region_t *region, rtgui_rect_t *rect); - void rtgui_region_empty(rtgui_region_t *region); - void rtgui_region_dump(rtgui_region_t *region); - int rtgui_region_is_flat(rtgui_region_t *region); +void rtgui_region_reset(rtgui_region_t *region, rtgui_rect_t *rect); +void rtgui_region_empty(rtgui_region_t *region); +void rtgui_region_dump(rtgui_region_t *region); +int rtgui_region_is_flat(rtgui_region_t *region); - /* rect functions */ - extern rtgui_rect_t rtgui_empty_rect; +/* rect functions */ +extern rtgui_rect_t rtgui_empty_rect; - void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y); - void rtgui_rect_moveto_align(rtgui_rect_t *rect, rtgui_rect_t *to, int align); - void rtgui_rect_inflate(rtgui_rect_t *rect, int d); - void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest); - 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_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); - rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect); +void rtgui_rect_moveto(rtgui_rect_t *rect, int x, int y); +void rtgui_rect_moveto_align(rtgui_rect_t *rect, rtgui_rect_t *to, int align); +void rtgui_rect_inflate(rtgui_rect_t *rect, int d); +void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest); +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_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); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/components/rtgui/include/rtgui/rtgui.h b/components/rtgui/include/rtgui/rtgui.h index 066262d34c..fc00d4559f 100644 --- a/components/rtgui/include/rtgui/rtgui.h +++ b/components/rtgui/include/rtgui/rtgui.h @@ -17,6 +17,11 @@ #include #include +#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_MIN (-RT_INT16_MAX-1) #define RTGUI_NOT_FOUND (-1) diff --git a/components/rtgui/include/rtgui/rtgui_app.h b/components/rtgui/include/rtgui/rtgui_app.h index 50087e07a2..67f5e0ae4c 100644 --- a/components/rtgui/include/rtgui/rtgui_app.h +++ b/components/rtgui/include/rtgui/rtgui_app.h @@ -52,9 +52,6 @@ struct rtgui_app /* the thread id */ rt_thread_t tid; - /* the RTGUI server id */ - rt_thread_t server; - /* the message queue of thread */ rt_mq_t mq; /* 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); 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_close(struct rtgui_app *app); -void rtgui_app_set_onidle(rtgui_idle_func_t onidle); -rtgui_idle_func_t rtgui_app_get_onidle(void); +void rtgui_app_set_onidle(struct rtgui_app *app, rtgui_idle_func_t onidle); +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); -rt_err_t rtgui_app_set_as_wm(void); -void rtgui_app_set_main_win(struct rtgui_win *win); +rt_err_t rtgui_app_set_as_wm(struct rtgui_app *app); +void rtgui_app_set_main_win(struct rtgui_app *app, struct rtgui_win *win); #endif /* end of include guard: __RTGUI_APP_H__ */ diff --git a/components/rtgui/include/rtgui/rtgui_server.h b/components/rtgui/include/rtgui/rtgui_server.h index 9914a5b8ef..de459bf29e 100644 --- a/components/rtgui/include/rtgui/rtgui_server.h +++ b/components/rtgui/include/rtgui/rtgui_server.h @@ -56,8 +56,8 @@ struct rtgui_topwin /* the window id */ struct rtgui_win *wid; - /* the thread id */ - rt_thread_t tid; + /* which app I belong */ + struct rtgui_app *app; /* the extent information */ rtgui_rect_t extent; diff --git a/components/rtgui/include/rtgui/rtgui_system.h b/components/rtgui/include/rtgui/rtgui_system.h index 975b1e0be5..8f8edaaacc 100644 --- a/components/rtgui/include/rtgui/rtgui_system.h +++ b/components/rtgui/include/rtgui/rtgui_system.h @@ -26,8 +26,8 @@ typedef void (*rtgui_timeout_func)(struct rtgui_timer *timer, void *parameter); struct rtgui_timer { - /* context thread id */ - rt_thread_t tid; + /* the rtgui application it runs on */ + struct rtgui_app* app; /* rt 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 #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_get_mainwin_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); 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_urgent(rt_thread_t tid, 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(struct rtgui_app* app, 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(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_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); diff --git a/components/rtgui/include/rtgui/widgets/digfont.h b/components/rtgui/include/rtgui/widgets/digfont.h new file mode 100644 index 0000000000..6765ed06c3 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/digfont.h @@ -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 \ No newline at end of file diff --git a/components/rtgui/include/rtgui/widgets/digtube.h b/components/rtgui/include/rtgui/widgets/digtube.h new file mode 100644 index 0000000000..c29a907f48 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/digtube.h @@ -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 +#include +#include +#include + +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 \ No newline at end of file diff --git a/components/rtgui/include/rtgui/widgets/menu.h b/components/rtgui/include/rtgui/widgets/menu.h index 0a40890b0f..1a6e85b387 100644 --- a/components/rtgui/include/rtgui/widgets/menu.h +++ b/components/rtgui/include/rtgui/widgets/menu.h @@ -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_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 diff --git a/components/rtgui/include/rtgui/widgets/textbox.h b/components/rtgui/include/rtgui/widgets/textbox.h index e6c1d008ab..989c170efb 100644 --- a/components/rtgui/include/rtgui/widgets/textbox.h +++ b/components/rtgui/include/rtgui/widgets/textbox.h @@ -34,6 +34,8 @@ DECLARE_CLASS_TYPE(textbox); #define RTGUI_TEXTBOX_DEFAULT_WIDTH 80 #define RTGUI_TEXTBOX_DEFAULT_HEIGHT 20 +#define RTGUI_TEXTBOX_BORDER_WIDTH 1 + #define RTGUI_TEXTBOX_SINGLE 0x00 #define RTGUI_TEXTBOX_MULTI 0x01 /* multiline */ #define RTGUI_TEXTBOX_MASK 0x02 /* ciphertext */ @@ -52,10 +54,13 @@ struct rtgui_textbox rt_uint32_t flag; /* 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 first_pos; char mask_char; + /** a NULL terminated string that the textbox is holding */ char *text; 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); void rtgui_textbox_set_mask_char(rtgui_textbox_t *box, const char ch); 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); diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index 7dd65898c4..60d388cc1a 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -62,139 +62,138 @@ extern "C" { #define RTGUI_WIDGET_DC_SET_UNVISIBLE(w) RTGUI_WIDGET_FLAG(w) &= ~RTGUI_WIDGET_FLAG_DC_VISIBLE #define RTGUI_WIDGET_DC(w) ((struct rtgui_dc*)&((w)->dc_type)) - DECLARE_CLASS_TYPE(widget); +DECLARE_CLASS_TYPE(widget); - /** Gets the type of a widget */ +/** Gets the type of a widget */ #define RTGUI_WIDGET_TYPE (RTGUI_TYPE(widget)) - /** Casts the object to a rtgui_widget */ +/** Casts the object to a rtgui_widget */ #define RTGUI_WIDGET(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_WIDGET_TYPE, rtgui_widget_t)) - /** Check if the object is a rtgui_widget */ +/** Check if the object is a rtgui_widget */ #define RTGUI_IS_WIDGET(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WIDGET_TYPE)) - /* - * the base widget object - */ - struct rtgui_widget - { - /* inherit from rtgui_object */ - struct rtgui_object object; +/* + * the base widget object + */ +struct rtgui_widget +{ + /* inherit from rtgui_object */ + struct rtgui_object object; - /* the widget that contains this widget */ - struct rtgui_widget *parent; - /* the window that contains this widget */ - struct rtgui_win *toplevel; - /* the widget children and sibling */ - rtgui_list_t sibling; + /* the widget that contains this widget */ + struct rtgui_widget *parent; + /* the window that contains this widget */ + struct rtgui_win *toplevel; + /* the widget children and sibling */ + rtgui_list_t sibling; - /* widget flag */ - rt_int32_t flag; + /* widget flag */ + rt_int32_t flag; - /* hardware device context */ - rt_uint32_t dc_type; - const struct rtgui_dc_engine *dc_engine; + /* hardware device context */ + rt_uint32_t dc_type; + const struct rtgui_dc_engine *dc_engine; - /* the graphic context of widget */ - rtgui_gc_t gc; + /* the graphic context of widget */ + rtgui_gc_t gc; - /* the widget extent */ - rtgui_rect_t extent; + /* the widget extent */ + rtgui_rect_t extent; - /* minimal width and height of widget */ - rt_int16_t mini_width, mini_height; - /* widget align */ - rt_int32_t align; - rt_uint16_t border; - rt_uint16_t border_style; - /* the rect clip */ - rtgui_region_t clip; + /* minimal width and height of widget */ + rt_int16_t min_width, min_height; + /* widget align */ + rt_int32_t align; + rt_uint16_t border; + rt_uint16_t border_style; + /* the rect clip */ + rtgui_region_t clip; - /* call back */ - rt_bool_t (*on_focus_in)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_focus_out)(struct rtgui_object *widget, struct rtgui_event *event); + /* call back */ + rt_bool_t (*on_focus_in)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_focus_out)(struct rtgui_object *widget, struct rtgui_event *event); #ifndef RTGUI_USING_SMALL_SIZE - rt_bool_t (*on_draw)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_mouseclick)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_key)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_size)(struct rtgui_object *widget, struct rtgui_event *event); - rt_bool_t (*on_command)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_draw)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_mouseclick)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_key)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_size)(struct rtgui_object *widget, struct rtgui_event *event); + rt_bool_t (*on_command)(struct rtgui_object *widget, struct rtgui_event *event); #endif - /* user private data */ - rt_uint32_t user_data; - }; - typedef struct rtgui_widget rtgui_widget_t; + /* user private data */ + rt_uint32_t user_data; +}; +typedef struct rtgui_widget rtgui_widget_t; - rtgui_widget_t *rtgui_widget_create(rtgui_type_t *widget_type); - void rtgui_widget_destroy(rtgui_widget_t *widget); +rtgui_widget_t *rtgui_widget_create(rtgui_type_t *widget_type); +void rtgui_widget_destroy(rtgui_widget_t *widget); - rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t *event); +rt_bool_t rtgui_widget_event_handler(struct rtgui_object *object, rtgui_event_t *event); - /* focus and unfocus */ - void rtgui_widget_focus(rtgui_widget_t *widget); - void rtgui_widget_unfocus(rtgui_widget_t *widget); +/* focus and unfocus */ +void rtgui_widget_focus(rtgui_widget_t *widget); +void rtgui_widget_unfocus(rtgui_widget_t *widget); - /* event handler for each command */ - void rtgui_widget_set_onfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); - void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +/* event handler for each command */ +void rtgui_widget_set_onfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_onunfocus(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); #ifndef RTGUI_USING_SMALL_SIZE - void rtgui_widget_set_ondraw(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); - void rtgui_widget_set_onmouseclick(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); - void rtgui_widget_set_onkey(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); - void rtgui_widget_set_onsize(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); - void rtgui_widget_set_oncommand(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_ondraw(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_onmouseclick(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_onkey(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_onsize(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); +void rtgui_widget_set_oncommand(rtgui_widget_t *widget, rtgui_event_handler_ptr handler); #endif - /* get and set rect of widget */ - void rtgui_widget_get_rect(rtgui_widget_t *widget, rtgui_rect_t *rect); - void rtgui_widget_set_border(rtgui_widget_t *widget, rt_uint32_t style); - void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect); - 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); +/* get and set rect of widget */ +void rtgui_widget_get_rect(rtgui_widget_t *widget, rtgui_rect_t *rect); +void rtgui_widget_set_border(rtgui_widget_t *widget, rt_uint32_t style); +void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect); +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); -#ifndef RTGUI_USING_SMALL_SIZE - void rtgui_widget_set_miniwidth(rtgui_widget_t *widget, int width); - void rtgui_widget_set_miniheight(rtgui_widget_t *widget, int height); -#endif +void rtgui_widget_set_minsize(rtgui_widget_t *widget, int width, int height); +void rtgui_widget_set_minwidth(rtgui_widget_t *widget, int width); +void rtgui_widget_set_minheight(rtgui_widget_t *widget, int height); - 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); - /* get the physical position of a logic point on widget */ - void rtgui_widget_point_to_device(rtgui_widget_t *widget, rtgui_point_t *point); - /* get the physical position of a logic rect on widget */ - void rtgui_widget_rect_to_device(rtgui_widget_t *widget, rtgui_rect_t *rect); +/* get the physical position of a logic point on widget */ +void rtgui_widget_point_to_device(rtgui_widget_t *widget, rtgui_point_t *point); +/* get the physical position of a logic rect on widget */ +void rtgui_widget_rect_to_device(rtgui_widget_t *widget, rtgui_rect_t *rect); - /* get the logic position of a physical point on widget */ - void rtgui_widget_point_to_logic(rtgui_widget_t *widget, rtgui_point_t *point); - /* get the logic position of a physical rect on widget */ - void rtgui_widget_rect_to_logic(rtgui_widget_t *widget, rtgui_rect_t *rect); +/* get the logic position of a physical point on widget */ +void rtgui_widget_point_to_logic(rtgui_widget_t *widget, rtgui_point_t *point); +/* get the logic position of a physical rect on widget */ +void rtgui_widget_rect_to_logic(rtgui_widget_t *widget, rtgui_rect_t *rect); - /* move widget and its children to a logic point */ - void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy); +/* move widget and its children to a logic point */ +void rtgui_widget_move_to_logic(rtgui_widget_t *widget, int dx, int dy); - /* update the clip info of widget */ - void rtgui_widget_update_clip(rtgui_widget_t *widget); +/* update the clip info of widget */ +void rtgui_widget_update_clip(rtgui_widget_t *widget); - /* get the toplevel widget of widget */ - struct rtgui_win *rtgui_widget_get_toplevel(rtgui_widget_t *widget); - rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui_event *event); +/* get the toplevel widget of widget */ +struct rtgui_win *rtgui_widget_get_toplevel(rtgui_widget_t *widget); +rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui_event *event); - void rtgui_widget_show(rtgui_widget_t *widget); - rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event); - void rtgui_widget_hide(rtgui_widget_t *widget); - rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event); - void rtgui_widget_update(rtgui_widget_t *widget); +void rtgui_widget_show(rtgui_widget_t *widget); +rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event); +void rtgui_widget_hide(rtgui_widget_t *widget); +rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event); +void rtgui_widget_update(rtgui_widget_t *widget); - /* get parent color */ - rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t *widget); - rtgui_color_t rtgui_widget_get_parent_background(rtgui_widget_t *widget); +/* get parent color */ +rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t *widget); +rtgui_color_t rtgui_widget_get_parent_background(rtgui_widget_t *widget); - /* get the next sibling of widget */ - rtgui_widget_t *rtgui_widget_get_next_sibling(rtgui_widget_t *widget); - /* get the prev sibling of widget */ - rtgui_widget_t *rtgui_widget_get_prev_sibling(rtgui_widget_t *widget); +/* get the next sibling of widget */ +rtgui_widget_t *rtgui_widget_get_next_sibling(rtgui_widget_t *widget); +/* get the prev sibling of widget */ +rtgui_widget_t *rtgui_widget_get_prev_sibling(rtgui_widget_t *widget); - /* dump widget information */ - void rtgui_widget_dump(rtgui_widget_t *widget); +/* dump widget information */ +void rtgui_widget_dump(rtgui_widget_t *widget); #ifdef __cplusplus } diff --git a/components/rtgui/include/rtgui/widgets/window.h b/components/rtgui/include/rtgui/widgets/window.h index 6c8a37cf7f..f0642004a0 100644 --- a/components/rtgui/include/rtgui/widgets/window.h +++ b/components/rtgui/include/rtgui/widgets/window.h @@ -130,7 +130,7 @@ void rtgui_win_destroy(rtgui_win_t *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); -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); rt_err_t rtgui_win_activate(struct rtgui_win *win); rt_bool_t rtgui_win_is_activated(struct rtgui_win *win); diff --git a/components/rtgui/server/driver.c b/components/rtgui/server/driver.c index 2fe19347b5..dd441afb88 100644 --- a/components/rtgui/server/driver.c +++ b/components/rtgui/server/driver.c @@ -41,6 +41,7 @@ rt_err_t rtgui_graphic_set_device(rt_device_t device) { rt_err_t result; struct rt_device_graphic_info info; + struct rtgui_graphic_ext_ops *ext_ops; /* get framebuffer address */ 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.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) { /* 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); } +#ifdef RTGUI_USING_HW_CURSOR + /* set default cursor image */ + rtgui_cursor_set_image(RTGUI_CURSOR_ARROW); +#endif + return RT_EOK; } 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); +#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 + diff --git a/components/rtgui/server/mouse.c b/components/rtgui/server/mouse.c index 27972af2b2..0fff8f101c 100644 --- a/components/rtgui/server/mouse.c +++ b/components/rtgui/server/mouse.c @@ -255,6 +255,10 @@ void rtgui_mouse_moveto(int x, int y) rtgui_mouse_show_cursor(); #endif } + +#ifdef RTGUI_USING_HW_CURSOR + rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy); +#endif } #ifdef RTGUI_USING_MOUSE_CURSOR @@ -262,6 +266,17 @@ void rtgui_mouse_moveto(int x, int y) #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 void rtgui_mouse_set_cursor_enable(rt_bool_t enable) { diff --git a/components/rtgui/server/mouse.h b/components/rtgui/server/mouse.h index 7b8c4f5990..dd62596efe 100644 --- a/components/rtgui/server/mouse.h +++ b/components/rtgui/server/mouse.h @@ -31,6 +31,8 @@ typedef struct rtgui_mouse_monitor rtgui_mouse_monitor_t; void rtgui_mouse_init(void); void rtgui_mouse_fini(void); 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(rtgui_image_t *cursor); diff --git a/components/rtgui/server/server.c b/components/rtgui/server/server.c index ea0fbc44c8..8728a5ed44 100644 --- a/components/rtgui/server/server.c +++ b/components/rtgui/server/server.c @@ -22,9 +22,7 @@ #include "mouse.h" #include "topwin.h" -static struct rt_thread *rtgui_server_tid; - -static struct rtgui_app *rtgui_server_application = RT_NULL; +static struct rtgui_app *rtgui_server_app = RT_NULL; static struct rtgui_app *rtgui_wm_application = RT_NULL; 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 */ RTGUI_EVENT_MOUSE_BUTTON_INIT(event); + /* set cursor position */ + rtgui_mouse_set_position(event->x, event->y); + #ifdef RTGUI_USING_WINMOVE if (rtgui_winrect_is_moved() && 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 */ - rtgui_send(topwin->tid, &(ewin.parent), sizeof(ewin)); + rtgui_send(topwin->app, &(ewin.parent), sizeof(ewin)); return; } @@ -100,9 +101,10 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event) { 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); } @@ -114,7 +116,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse *event) else { /* 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 ; } @@ -146,7 +148,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse *event) { event->wid = last_monitor_topwin->wid; /* 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) @@ -157,7 +159,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse *event) event->wid = last_monitor_topwin->wid; /* 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; /* 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; } @@ -207,7 +209,7 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, if (rtgui_wm_application != RT_NULL) { /* 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 { @@ -349,12 +351,12 @@ static void rtgui_server_entry(void *parameter) #endif /* create rtgui server application */ - rtgui_server_application = rtgui_app_create(rtgui_server_tid, - "rtgui"); - if (rtgui_server_application == RT_NULL) + rtgui_server_app = rtgui_app_create("rtgui"); + rt_kprintf("RTGUI: create server: %p", rtgui_server_app); + if (rtgui_server_app == RT_NULL) 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); /* init mouse and show */ rtgui_mouse_init(); @@ -362,24 +364,24 @@ static void rtgui_server_entry(void *parameter) rtgui_mouse_show_cursor(); #endif - rtgui_app_run(rtgui_server_application); + rtgui_app_run(rtgui_server_app); - rtgui_app_destroy(rtgui_server_application); - rtgui_server_application = RT_NULL; + rtgui_app_destroy(rtgui_server_app); + rtgui_server_app = RT_NULL; } void rtgui_server_post_event(struct rtgui_event *event, rt_size_t size) { - if (rtgui_server_tid != RT_NULL) - rtgui_send(rtgui_server_tid, event, size); + if (rtgui_server_app != RT_NULL) + rtgui_send(rtgui_server_app, event, size); else 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) { - if (rtgui_server_tid != RT_NULL) - return rtgui_send_sync(rtgui_server_tid, event, size); + if (rtgui_server_app != RT_NULL) + return rtgui_send_sync(rtgui_server_app, event, size); else { 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) { - if (rtgui_server_tid != RT_NULL) - return; + rt_thread_t tid; - rtgui_server_tid = rt_thread_create("rtgui", - rtgui_server_entry, RT_NULL, - RTGUI_SVR_THREAD_STACK_SIZE, - RTGUI_SVR_THREAD_PRIORITY, - RTGUI_SVR_THREAD_TIMESLICE); + tid = rt_thread_create("rtgui", + rtgui_server_entry, RT_NULL, + RTGUI_SVR_THREAD_STACK_SIZE, + RTGUI_SVR_THREAD_PRIORITY, + RTGUI_SVR_THREAD_TIMESLICE); /* start rtgui server thread */ - if (rtgui_server_tid != RT_NULL) - rt_thread_startup(rtgui_server_tid); + if (tid != RT_NULL) + rt_thread_startup(tid); } diff --git a/components/rtgui/server/topwin.c b/components/rtgui/server/topwin.c index abb69d717d..d052e00071 100644 --- a/components/rtgui/server/topwin.c +++ b/components/rtgui/server/topwin.c @@ -102,7 +102,7 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create *event) #else topwin->extent = event->extent; #endif - topwin->tid = event->parent.sender; + topwin->app = event->parent.sender; if (event->parent_window == RT_NULL) { @@ -337,7 +337,7 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin) topwin->flag |= WINTITLE_ACTIVATE; 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 */ if (topwin->title != RT_NULL) @@ -366,11 +366,11 @@ static void _rtgui_topwin_deactivate(struct rtgui_topwin *topwin) struct rtgui_event_win event; RT_ASSERT(topwin != RT_NULL); - RT_ASSERT(topwin->tid != RT_NULL); + RT_ASSERT(topwin->app != RT_NULL); RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event); event.wid = topwin->wid; - rtgui_send(topwin->tid, + rtgui_send(topwin->app, &event.parent, sizeof(struct rtgui_event_win)); 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; - 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) { @@ -748,7 +748,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move *event) struct rtgui_event_paint epaint; RTGUI_EVENT_PAINT_INIT(&epaint); epaint.wid = topwin->wid; - rtgui_send(topwin->tid, &(epaint.parent), sizeof(epaint)); + rtgui_send(topwin->app, &(epaint.parent), sizeof(epaint)); } return RT_EOK; @@ -945,7 +945,7 @@ static void rtgui_topwin_update_clip(void) /* send clip event to destination window */ 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 */ 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) { epaint->wid = topwin->wid; - rtgui_send(topwin->tid, &(epaint->parent), sizeof(*epaint)); + rtgui_send(topwin->app, &(epaint->parent), sizeof(*epaint)); /* draw title */ 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) { /* 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; } @@ -1098,7 +1098,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin *win, struct rtgui_event_mou /* send close event to window */ RTGUI_EVENT_WIN_CLOSE_INIT(&event); 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)); } } } diff --git a/components/rtgui/utils/perfect_hash/README b/components/rtgui/utils/perfect_hash/README new file mode 100644 index 0000000000..fa798c1d3c --- /dev/null +++ b/components/rtgui/utils/perfect_hash/README @@ -0,0 +1,49 @@ + +perfect_hash.py + +Ilan Schnell , 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. diff --git a/components/rtgui/utils/perfect_hash/__init__.py b/components/rtgui/utils/perfect_hash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/components/rtgui/utils/perfect_hash/animals.txt b/components/rtgui/utils/perfect_hash/animals.txt new file mode 100644 index 0000000000..ac29563736 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/animals.txt @@ -0,0 +1,7 @@ +# 'animals.txt' +Elephant +Horse +Camel +Python +Dog +Cat diff --git a/components/rtgui/utils/perfect_hash/doc/Makefile b/components/rtgui/utils/perfect_hash/doc/Makefile new file mode 100644 index 0000000000..6a456a5b97 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/Makefile @@ -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,
table
,m4_include(\`table.html')," | \ + m4 -P >doc.html + rm table.html + + +doc.txt: doc.in parameters.txt + sed doc.txt + + +clean: + rm doc.html doc.txt + + diff --git a/components/rtgui/utils/perfect_hash/doc/czech92optimal.pdf b/components/rtgui/utils/perfect_hash/doc/czech92optimal.pdf new file mode 100644 index 0000000000..08825a1315 Binary files /dev/null and b/components/rtgui/utils/perfect_hash/doc/czech92optimal.pdf differ diff --git a/components/rtgui/utils/perfect_hash/doc/doc.html b/components/rtgui/utils/perfect_hash/doc/doc.html new file mode 100644 index 0000000000..3abb399f32 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/doc.html @@ -0,0 +1,136 @@ + + +

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. +

+ +

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", + Z. J. Czech, G. Havas and B.S. Majewski. +

+

I tried to illustrate the algorithm and explain how it works on + this page. +

+ +

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: +

+ + + + + + + + + + + +
stringexpands to
$NSthe length of S1 and S2
$S1array of integers S1
$S2array of integers S2
$NGlength of array G
$Garray of integers G
$NKthe number of keys, i.e. length of array K and H
$Karray with the quoted keys
$Harray 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 +

+ + diff --git a/components/rtgui/utils/perfect_hash/doc/doc.in b/components/rtgui/utils/perfect_hash/doc/doc.in new file mode 100644 index 0000000000..1bcce9a961 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/doc.in @@ -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 diff --git a/components/rtgui/utils/perfect_hash/doc/doc.txt b/components/rtgui/utils/perfect_hash/doc/doc.txt new file mode 100644 index 0000000000..f28dda0ed2 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/doc.txt @@ -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 diff --git a/components/rtgui/utils/perfect_hash/doc/mktable.py b/components/rtgui/utils/perfect_hash/doc/mktable.py new file mode 100644 index 0000000000..ef304ed673 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/mktable.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +import re + +def convert(line, head = False): + pat = re.compile(r'([$]\S*)') + line = pat.sub(r'\1', line) + + row = [x.strip() for x in line.split('|')] + fmt = ' %s%s' + if head: + fmt = fmt.replace('td', 'th') + print fmt % tuple(row) + + +f = file('parameters.txt') + +print '' +convert(f.readline(), head = True) +f.readline() +for line in f: + convert(line) +print '
' diff --git a/components/rtgui/utils/perfect_hash/doc/parameters.txt b/components/rtgui/utils/perfect_hash/doc/parameters.txt new file mode 100644 index 0000000000..b853492659 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/doc/parameters.txt @@ -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) diff --git a/components/rtgui/utils/perfect_hash/example-C++/Makefile b/components/rtgui/utils/perfect_hash/example-C++/Makefile new file mode 100644 index 0000000000..de525f5d5d --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/Makefile @@ -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' diff --git a/components/rtgui/utils/perfect_hash/example-C++/main.cc b/components/rtgui/utils/perfect_hash/example-C++/main.cc new file mode 100644 index 0000000000..9d724a7872 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/main.cc @@ -0,0 +1,24 @@ + +#include +#include +using namespace std; + +#include "states-code.hh" + + +int main (int argc, char *argv[]) +{ + if (argc != 2) { + printf ("Usage: %s \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; +} diff --git a/components/rtgui/utils/perfect_hash/example-C++/mk_header.py b/components/rtgui/utils/perfect_hash/example-C++/mk_header.py new file mode 100644 index 0000000000..646c0787be --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/mk_header.py @@ -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 diff --git a/components/rtgui/utils/perfect_hash/example-C++/states-code.hh b/components/rtgui/utils/perfect_hash/example-C++/states-code.hh new file mode 100644 index 0000000000..964d8bf8a5 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/states-code.hh @@ -0,0 +1,19 @@ + + +#include +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; +}; + diff --git a/components/rtgui/utils/perfect_hash/example-C++/states-tmpl.cc b/components/rtgui/utils/perfect_hash/example-C++/states-tmpl.cc new file mode 100644 index 0000000000..ab94be31f6 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/states-tmpl.cc @@ -0,0 +1,55 @@ + +#include + +#include + +#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"; + } +} diff --git a/components/rtgui/utils/perfect_hash/example-C++/states.dat b/components/rtgui/utils/perfect_hash/example-C++/states.dat new file mode 100644 index 0000000000..5538309450 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-C++/states.dat @@ -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 diff --git a/components/rtgui/utils/perfect_hash/example-PyModule/Makefile b/components/rtgui/utils/perfect_hash/example-PyModule/Makefile new file mode 100644 index 0000000000..662ff78442 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-PyModule/Makefile @@ -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')" + + diff --git a/components/rtgui/utils/perfect_hash/example-PyModule/stations-tmpl.h b/components/rtgui/utils/perfect_hash/example-PyModule/stations-tmpl.h new file mode 100644 index 0000000000..b77e6320b3 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-PyModule/stations-tmpl.h @@ -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 }; + diff --git a/components/rtgui/utils/perfect_hash/example-PyModule/stations.dat b/components/rtgui/utils/perfect_hash/example-PyModule/stations.dat new file mode 100644 index 0000000000..5358120c34 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-PyModule/stations.dat @@ -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 diff --git a/components/rtgui/utils/perfect_hash/example-PyModule/stationsmodule.c b/components/rtgui/utils/perfect_hash/example-PyModule/stationsmodule.c new file mode 100644 index 0000000000..bf14e1bbee --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-PyModule/stationsmodule.c @@ -0,0 +1,69 @@ + +#include + +#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); +} diff --git a/components/rtgui/utils/perfect_hash/example-PyModule/test.py b/components/rtgui/utils/perfect_hash/example-PyModule/test.py new file mode 100644 index 0000000000..02c06b6926 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-PyModule/test.py @@ -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() diff --git a/components/rtgui/utils/perfect_hash/example-Python/Graph.py b/components/rtgui/utils/perfect_hash/example-Python/Graph.py new file mode 100644 index 0000000000..f2927719b4 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-Python/Graph.py @@ -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' diff --git a/components/rtgui/utils/perfect_hash/example-Python/Makefile b/components/rtgui/utils/perfect_hash/example-Python/Makefile new file mode 100644 index 0000000000..4f6dd13850 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-Python/Makefile @@ -0,0 +1,15 @@ + + +all: + true + + +clean: + true + + +test: + ./generate_hash.py + ./PerfHash.py + ./Graph.py + diff --git a/components/rtgui/utils/perfect_hash/example-Python/PerfHash.py b/components/rtgui/utils/perfect_hash/example-Python/PerfHash.py new file mode 100644 index 0000000000..49131c2b63 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-Python/PerfHash.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' diff --git a/components/rtgui/utils/perfect_hash/example-Python/generate_hash.py b/components/rtgui/utils/perfect_hash/example-Python/generate_hash.py new file mode 100644 index 0000000000..dfe9f92186 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example-Python/generate_hash.py @@ -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' diff --git a/components/rtgui/utils/perfect_hash/example1-C/Makefile b/components/rtgui/utils/perfect_hash/example1-C/Makefile new file mode 100644 index 0000000000..59b7ef0d67 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/Makefile @@ -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' diff --git a/components/rtgui/utils/perfect_hash/example1-C/main.c b/components/rtgui/utils/perfect_hash/example1-C/main.c new file mode 100644 index 0000000000..0d36bcea45 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/main.c @@ -0,0 +1,33 @@ + +#include + +#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 \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; +} diff --git a/components/rtgui/utils/perfect_hash/example1-C/mk_header.py b/components/rtgui/utils/perfect_hash/example1-C/mk_header.py new file mode 100644 index 0000000000..646c0787be --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/mk_header.py @@ -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 diff --git a/components/rtgui/utils/perfect_hash/example1-C/states-code.h b/components/rtgui/utils/perfect_hash/example1-C/states-code.h new file mode 100644 index 0000000000..5717b92d32 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/states-code.h @@ -0,0 +1,6 @@ + + +/* Return hash value of abbreviation 'abbr' if found, -1 otherwise */ +int has_key (const char *abbr); + + diff --git a/components/rtgui/utils/perfect_hash/example1-C/states-tmpl.c b/components/rtgui/utils/perfect_hash/example1-C/states-tmpl.c new file mode 100644 index 0000000000..001ca6e5ce --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/states-tmpl.c @@ -0,0 +1,42 @@ + +#include + +#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; +} diff --git a/components/rtgui/utils/perfect_hash/example1-C/states.dat b/components/rtgui/utils/perfect_hash/example1-C/states.dat new file mode 100644 index 0000000000..5538309450 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example1-C/states.dat @@ -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 diff --git a/components/rtgui/utils/perfect_hash/example2-C/Makefile b/components/rtgui/utils/perfect_hash/example2-C/Makefile new file mode 100644 index 0000000000..865e8cf7eb --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example2-C/Makefile @@ -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 + diff --git a/components/rtgui/utils/perfect_hash/example2-C/keys.tmpl.h b/components/rtgui/utils/perfect_hash/example2-C/keys.tmpl.h new file mode 100644 index 0000000000..550bdb089d --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example2-C/keys.tmpl.h @@ -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 }; + diff --git a/components/rtgui/utils/perfect_hash/example2-C/main.c b/components/rtgui/utils/perfect_hash/example2-C/main.c new file mode 100644 index 0000000000..c19db892b8 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example2-C/main.c @@ -0,0 +1,51 @@ + +#include +#include +#include +#include + +#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; +} diff --git a/components/rtgui/utils/perfect_hash/example2-C/mk_rnd_keys.py b/components/rtgui/utils/perfect_hash/example2-C/mk_rnd_keys.py new file mode 100644 index 0000000000..81f964e9ff --- /dev/null +++ b/components/rtgui/utils/perfect_hash/example2-C/mk_rnd_keys.py @@ -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() diff --git a/components/rtgui/utils/perfect_hash/graph/Makefile b/components/rtgui/utils/perfect_hash/graph/Makefile new file mode 100644 index 0000000000..dc84f85fdb --- /dev/null +++ b/components/rtgui/utils/perfect_hash/graph/Makefile @@ -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 + + diff --git a/components/rtgui/utils/perfect_hash/graph/example-pipeline b/components/rtgui/utils/perfect_hash/graph/example-pipeline new file mode 100644 index 0000000000..86f58cdb38 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/graph/example-pipeline @@ -0,0 +1,4 @@ +#!/bin/bash + +../perfect_hash.py ../animals.txt | ./py2dot | neato -Tps -Gstart=100 -o out.ps + diff --git a/components/rtgui/utils/perfect_hash/graph/py2dot b/components/rtgui/utils/perfect_hash/graph/py2dot new file mode 100644 index 0000000000..920c70386a --- /dev/null +++ b/components/rtgui/utils/perfect_hash/graph/py2dot @@ -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: diff --git a/components/rtgui/utils/perfect_hash/perfect_hash.py b/components/rtgui/utils/perfect_hash/perfect_hash.py new file mode 100644 index 0000000000..e981877634 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/perfect_hash.py @@ -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 , 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() diff --git a/components/rtgui/utils/perfect_hash/run b/components/rtgui/utils/perfect_hash/run new file mode 100644 index 0000000000..c7fe1f22e2 --- /dev/null +++ b/components/rtgui/utils/perfect_hash/run @@ -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 diff --git a/components/rtgui/utils/stract_cjk.py b/components/rtgui/utils/stract_cjk.py new file mode 100644 index 0000000000..afea09897c --- /dev/null +++ b/components/rtgui/utils/stract_cjk.py @@ -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) diff --git a/components/rtgui/widgets/box.c b/components/rtgui/widgets/box.c index 47c704b7c9..448f47ea36 100644 --- a/components/rtgui/widgets/box.c +++ b/components/rtgui/widgets/box.c @@ -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); 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 */ @@ -98,8 +98,8 @@ static void rtgui_box_layout_vertical(struct rtgui_box *box, struct rtgui_rect * /* reset rect */ rtgui_rect_moveto(rect, -rect->x1, -rect->y1); - rect->x2 = widget->mini_width; - rect->y2 = widget->mini_height; + rect->x2 = widget->min_width; + rect->y2 = widget->min_height; /* left in default */ 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); if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; - else total_width += widget->mini_width; + else total_width += widget->min_width; } if (space_count != 0) @@ -191,8 +191,8 @@ static void rtgui_box_layout_horizontal(struct rtgui_box *box, struct rtgui_rect /* reset rect */ rtgui_rect_moveto(rect, -rect->x1, -rect->y1); - rect->x2 = widget->mini_width; - rect->y2 = widget->mini_height; + rect->x2 = widget->min_width; + rect->y2 = widget->min_height; /* top in default */ rtgui_rect_moveto(rect, next_x, next_y); diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c index ca15acb89a..ceca58f008 100644 --- a/components/rtgui/widgets/button.c +++ b/components/rtgui/widgets/button.c @@ -104,7 +104,8 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object *object, struct rtgui_e break; 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; @@ -159,9 +160,6 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object *object, struct rtgui_e /* need callback */ 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 * before the flag has changed. Moreover, we cannot invoke * 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; } - /* 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) { btn->flag |= RTGUI_BUTTON_FLAG_PRESS; + win->last_mevent_widget = RTGUI_WIDGET(btn); } else { btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS; + if (win->last_mevent_widget == RTGUI_WIDGET(btn)) + win->last_mevent_widget = RT_NULL; } /* draw button */ diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c index 50cac173b1..ece6cb2e1b 100644 --- a/components/rtgui/widgets/combobox.c +++ b/components/rtgui/widgets/combobox.c @@ -48,7 +48,7 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object *object, struct rtgui_ if (combo->on_selected != 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)); 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) { - rtgui_win_hiden(RTGUI_WIN(object)); + rtgui_win_hide(RTGUI_WIN(object)); 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) { /* hide pull down window */ - rtgui_win_hiden(RTGUI_WIN(box->pd_win)); + rtgui_win_hide(RTGUI_WIN(box->pd_win)); 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; /* 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 */ box->pd_pressed = RT_FALSE; diff --git a/components/rtgui/widgets/digfont.c b/components/rtgui/widgets/digfont.c new file mode 100644 index 0000000000..0d081f94ad --- /dev/null +++ b/components/rtgui/widgets/digfont.c @@ -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 +#include +#include +#include + +#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; iseg1_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; iseg1_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; iseg1_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; iseg1_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; iseg1_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; iseg1_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; ix ++; + data->y --; + data->len -= 2; + *databuf++ = *data; + } + + *data = temp2; + for (i=0; ix ++; + 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; itype == 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; jseg1_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 +#include +#include +#include +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; iseg1_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_FUNCTION_EXPORT(digfont_file, create the font file of digit font) +#endif + +#endif \ No newline at end of file diff --git a/components/rtgui/widgets/digtube.c b/components/rtgui/widgets/digtube.c new file mode 100644 index 0000000000..e5ce5484ea --- /dev/null +++ b/components/rtgui/widgets/digtube.c @@ -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 +#include + +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; itube_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)); +} \ No newline at end of file diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c index effb42c251..78d05c68d0 100644 --- a/components/rtgui/widgets/filelist_view.c +++ b/components/rtgui/widgets/filelist_view.c @@ -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); /* hide window */ - rtgui_win_hiden(menu); + rtgui_win_hide(menu); switch (listbox->current_item) { diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c index 07a3a4dd15..ce6f719120 100644 --- a/components/rtgui/widgets/menu.c +++ b/components/rtgui/widgets/menu.c @@ -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)) { /* hide this sub menu */ - rtgui_win_hiden(RTGUI_WIN(menu->sub_menu)); + rtgui_win_hide(RTGUI_WIN(menu->sub_menu)); return RT_FALSE; } @@ -91,9 +91,9 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object *object, struct rtgui_ev /* hide sub-menu */ 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; } @@ -183,7 +183,7 @@ static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object *object, rtgui_eve return RT_TRUE; } - rtgui_win_hiden(RTGUI_WIN(menu)); + rtgui_win_hide(RTGUI_WIN(menu)); if (menu->on_menuhide != 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); } -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 */ menu->items_list->current_item = -1; if (menu->parent_menu != RT_NULL) - rtgui_menu_hiden(menu->parent_menu); + rtgui_menu_hide(menu->parent_menu); } diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c index b0d1846e65..f3a6da232c 100644 --- a/components/rtgui/widgets/notebook.c +++ b/components/rtgui/widgets/notebook.c @@ -539,7 +539,8 @@ void rtgui_notebook_set_current_by_index(struct rtgui_notebook *notebook, rt_uin widget = notebook->childs[notebook->current].widget; rtgui_widget_show(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); } } diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c index 47dc92e9db..4eeb620221 100644 --- a/components/rtgui/widgets/radiobox.c +++ b/components/rtgui/widgets/radiobox.c @@ -228,14 +228,14 @@ void rtgui_radiobox_set_orientation(struct rtgui_radiobox *radiobox, int orienta if (radiobox->orient == RTGUI_HORIZONTAL) { /* HORIZONTAL */ - rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); - rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); + rtgui_widget_set_minheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); + rtgui_widget_set_minwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); } else { /* VERTICAL */ - rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); - rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); + rtgui_widget_set_minwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT); + rtgui_widget_set_minheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH); } #endif } diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c index e592183f07..01ef2a340b 100644 --- a/components/rtgui/widgets/slider.c +++ b/components/rtgui/widgets/slider.c @@ -255,14 +255,14 @@ void rtgui_slider_set_orientation(struct rtgui_slider *slider, int orientation) if (slider->orient == RTGUI_HORIZONTAL) { /* HORIZONTAL */ - rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); - rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); + rtgui_widget_set_minheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); + rtgui_widget_set_minwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); } else { /* VERTICAL */ - rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); - rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); + rtgui_widget_set_minwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT); + rtgui_widget_set_minheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH); } #endif } diff --git a/components/rtgui/widgets/staticline.c b/components/rtgui/widgets/staticline.c index 2187f0131c..b3ee043f0d 100644 --- a/components/rtgui/widgets/staticline.c +++ b/components/rtgui/widgets/staticline.c @@ -73,14 +73,14 @@ void rtgui_staticline_set_orientation(rtgui_staticline_t *staticline, int orient if (orientation == RTGUI_HORIZONTAL) { /* HORIZONTAL */ - rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2); - rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100); + rtgui_widget_set_minheight(RTGUI_WIDGET(staticline), 2); + rtgui_widget_set_minwidth(RTGUI_WIDGET(staticline), 100); } else { /* VERTICAL */ - rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2); - rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100); + rtgui_widget_set_minwidth(RTGUI_WIDGET(staticline), 2); + rtgui_widget_set_minheight(RTGUI_WIDGET(staticline), 100); } #endif } diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c index 53642aeed3..6cc46e05f4 100644 --- a/components/rtgui/widgets/textbox.c +++ b/components/rtgui/widgets/textbox.c @@ -54,6 +54,14 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box) rtgui_textbox_set_mask_char(box, '*'); 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->on_enter = RT_NULL; box->dis_length = 0; @@ -531,13 +539,13 @@ void rtgui_textbox_ondraw(rtgui_textbox_t *box) rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); fc = RTGUI_WIDGET_FOREGROUND(box); - rtgui_rect_inflate(&rect, -1); + rtgui_rect_inflate(&rect, -RTGUI_TEXTBOX_BORDER_WIDTH); /* fill widget rect with white color */ RTGUI_WIDGET_BACKGROUND(box) = white; rtgui_dc_fill_rect(dc, &rect); - rtgui_rect_inflate(&rect, 1); + rtgui_rect_inflate(&rect, RTGUI_TEXTBOX_BORDER_WIDTH); /* draw border */ RTGUI_WIDGET_FOREGROUND(box) = RTGUI_RGB(123, 158, 189); rtgui_dc_draw_rect(dc, &rect); @@ -610,29 +618,27 @@ char rtgui_textbox_get_mask_char(rtgui_textbox_t *box) 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 */ - if (length <= 0) - return; + /* invalid length */ + if (length <= 0) + return -RT_ERROR; - new_line = rtgui_malloc(length); - if (length < box->line_length) - { - rt_memcpy(new_line, box->text, length - 1); - new_line[length] = '\0'; - } - else - { - rt_memcpy(new_line, (const char *)box->text, rt_strlen((const char *)box->text)); - } + new_line = rtgui_realloc(box->text, length+1); + if (new_line == RT_NULL) + return -RT_ENOMEM; - /* set line length */ - box->line_length = length; + if (length < box->line_length) + new_line[length] = '\0'; + + box->line_length = length; + box->text = new_line; + + return RT_EOK; } /* get textbox text area */ diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index 83c87ba1b9..9340a5394a 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -135,9 +135,9 @@ void rtgui_widget_set_rect(rtgui_widget_t *widget, const rtgui_rect_t *rect) rtgui_container_layout(RTGUI_CONTAINER(widget)); } - /* reset mini width and height */ - widget->mini_width = rtgui_rect_width(widget->extent); - widget->mini_height = rtgui_rect_height(widget->extent); + /* reset min width and height */ + widget->min_width = rtgui_rect_width(widget->extent); + widget->min_height = rtgui_rect_height(widget->extent); /* it's not empty, fini it */ 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); -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); - 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); - 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 diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index cb93ee9e92..78971a4649 100644 --- a/components/rtgui/widgets/window.c +++ b/components/rtgui/widgets/window.c @@ -178,7 +178,7 @@ static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, return RT_FALSE; } - rtgui_win_hiden(win); + rtgui_win_hide(win); 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 */ if (app->main_object == RT_NULL) - rtgui_app_set_main_win(win); + rtgui_app_set_main_win(app, win); 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); -void rtgui_win_hiden(struct rtgui_win *win) +void rtgui_win_hide(struct rtgui_win *win) { RT_ASSERT(win != RT_NULL); @@ -351,7 +351,7 @@ void rtgui_win_hiden(struct rtgui_win *win) 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) { @@ -469,7 +469,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even break; case RTGUI_EVENT_WIN_HIDE: - rtgui_win_hiden(win); + rtgui_win_hide(win); break; case RTGUI_EVENT_WIN_CLOSE: @@ -538,27 +538,37 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even break; case RTGUI_EVENT_MOUSE_BUTTON: - /* check whether has widget which handled mouse event before */ - if (win->last_mevent_widget != RT_NULL) - { - RTGUI_OBJECT(win->last_mevent_widget)->event_handler( - RTGUI_OBJECT(win->last_mevent_widget), - event); - - /* clean last mouse event handled widget */ - win->last_mevent_widget = RT_NULL; - } - else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win), - (struct rtgui_event_mouse *)event) == RT_FALSE) { + 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) { - return RTGUI_WIDGET(object)->on_mouseclick(object, event); + 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); + + /* clean last mouse event handled widget */ + win->last_mevent_widget = RT_NULL; + } + + return res; } - break; case RTGUI_EVENT_MOUSE_MOTION: #if 0 @@ -623,7 +633,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object *object, struct rtgui_even return RT_TRUE; break; - default : + default: return rtgui_container_event_handler(object, event); } diff --git a/examples/gui/SConscript b/examples/gui/SConscript index b4d2e952f8..1d82cccdb0 100644 --- a/examples/gui/SConscript +++ b/examples/gui/SConscript @@ -43,6 +43,7 @@ demo_view_edit.c demo_view_bmp.c demo_plot.c mywidget.c +demo_view_digtube.c """) if GetDepend('RTGUI_USING_FONT_COMPACT'): diff --git a/examples/gui/demo_application.c b/examples/gui/demo_application.c index d57987943b..45ce95251a 100644 --- a/examples/gui/demo_application.c +++ b/examples/gui/demo_application.c @@ -33,7 +33,7 @@ static void application_entry(void *parameter) struct rtgui_app *app; struct rtgui_rect rect; - app = rtgui_app_create(rt_thread_self(), "gui_demo"); + app = rtgui_app_create("gui_demo"); if (app == RT_NULL) return; @@ -95,6 +95,7 @@ static void application_entry(void *parameter) demo_view_notebook(); demo_view_mywidget(); demo_plot(); + demo_view_digtube(); #if defined(RTGUI_USING_DFS_FILERW) demo_view_edit(); diff --git a/examples/gui/demo_plot.c b/examples/gui/demo_plot.c index fa524aefa7..14595cb1e9 100644 --- a/examples/gui/demo_plot.c +++ b/examples/gui/demo_plot.c @@ -42,7 +42,7 @@ struct rtgui_container* demo_plot(void) curve1->min_x = 0; curve1->max_x = sizeof(sin_ydata)/sizeof(sin_ydata[0]); curve1->min_y = -100; - curve1->min_y = 100; + curve1->max_y = 100; curve1->color = red; 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]); curve2->min_x = 0; curve2->max_x = sizeof(cos_ydata)/sizeof(cos_ydata[0]); - curve1->min_y = -50; - curve1->min_y = 50; + curve2->min_y = -50; + curve2->max_y = 50; curve2->color = blue; rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve2), RTGUI_MV_VIEW(plot)); curve3 = rtgui_plot_curve_create(); rtgui_plot_curve_set_x(curve3, cos_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]); curve3->color = black; rtgui_mv_model_add_view(RTGUI_MV_MODEL(curve3), RTGUI_MV_VIEW(plot)); rtgui_widget_get_rect(RTGUI_WIDGET(cnt), &rect); rtgui_widget_set_rect(RTGUI_WIDGET(plot), &rect); - rtgui_plot_set_base(plot, - -rtgui_rect_width(rect)/3, rtgui_rect_height(rect)/2); + rtgui_plot_set_base(plot, -100, -300); rtgui_container_add_child(cnt, RTGUI_WIDGET(plot)); diff --git a/examples/gui/demo_view_benchmark.c b/examples/gui/demo_view_benchmark.c index 005db4799f..8664759b5c 100644 --- a/examples/gui/demo_view_benchmark.c +++ b/examples/gui/demo_view_benchmark.c @@ -110,7 +110,7 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev if (running) { /* stop */ - rtgui_app_set_onidle(RT_NULL); + rtgui_app_set_onidle(rtgui_app_self(), RT_NULL); _draw_default(object, event); } else @@ -118,7 +118,7 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev /* run */ ticks = rt_tick_get(); area = 0; - rtgui_app_set_onidle(_onidle); + rtgui_app_set_onidle(rtgui_app_self(), _onidle); } running = !running; diff --git a/examples/gui/demo_view_box.c b/examples/gui/demo_view_box.c index f2ab96baa9..51e264aefe 100644 --- a/examples/gui/demo_view_box.c +++ b/examples/gui/demo_view_box.c @@ -34,7 +34,7 @@ rtgui_container_t *demo_view_box(void) button = rtgui_button_create("button 2"); 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_container_layout(RTGUI_CONTAINER(panel)); diff --git a/examples/gui/demo_view_button.c b/examples/gui/demo_view_button.c index 45c688cfac..2fc73727bb 100644 --- a/examples/gui/demo_view_button.c +++ b/examples/gui/demo_view_button.c @@ -1,13 +1,13 @@ /* - * 程序清单:button控件演示 + * 嵥buttonؼʾ * - * 这个例子会在创建出的container上添加几个不同类型的button控件 + * ӻڴcontainerӼͬ͵buttonؼ */ #include "demo_view.h" #include -/* 创建用于演示button控件的视图 */ +/* ʾbuttonؼͼ */ rtgui_container_t *demo_view_button(void) { rtgui_rect_t rect; @@ -15,64 +15,64 @@ rtgui_container_t *demo_view_button(void) rtgui_button_t *button; rtgui_font_t *font; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("Button View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个button控件 */ + /* һbuttonؼ */ button = rtgui_button_create("Red"); - /* 设置label控件的前景色为红色 */ + /* labelؼǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(button) = red; - /* 设置button的位置 */ + /* buttonλ */ rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个button控件 */ + /* һbuttonؼ */ button = rtgui_button_create("Blue"); - /* 设置label控件的前景色为蓝色 */ + /* labelؼǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(button) = blue; - /* 设置button的位置 */ + /* buttonλ */ rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个button控件 */ + /* һbuttonؼ */ button = rtgui_button_create("12 font"); - /* 设置字体为12点阵的asc字体 */ + /* Ϊ12asc */ font = rtgui_font_refer("asc", 12); RTGUI_WIDGET_FONT(button) = font; - /* 设置button的位置 */ + /* buttonλ */ rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个button控件 */ + /* һbuttonؼ */ button = rtgui_button_create("16 font"); - /* 设置字体为16点阵的asc字体 */ + /* Ϊ16asc */ font = rtgui_font_refer("asc", 16); RTGUI_WIDGET_FONT(button) = font; - /* 设置button的位置 */ + /* buttonλ */ rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); diff --git a/examples/gui/demo_view_checkbox.c b/examples/gui/demo_view_checkbox.c index 8e4e118681..0dc3c751dc 100644 --- a/examples/gui/demo_view_checkbox.c +++ b/examples/gui/demo_view_checkbox.c @@ -1,13 +1,13 @@ /* - * 程序清单:checkbox控件演示 + * 嵥checkboxؼʾ * - * 这个例子会在创建出的container上添加几个checkbox控件 + * ӻڴcontainerӼcheckboxؼ */ #include "demo_view.h" #include -/* 创建用于演示checkbox控件的视图 */ +/* ʾcheckboxؼͼ */ rtgui_container_t *demo_view_checkbox(void) { rtgui_rect_t rect; @@ -15,64 +15,64 @@ rtgui_container_t *demo_view_checkbox(void) rtgui_checkbox_t *checkbox; rtgui_font_t *font; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("CheckBox View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个checkbox控件 */ + /* һcheckboxؼ */ checkbox = rtgui_checkbox_create("Red", RT_TRUE); - /* 设置前景色为红色 */ + /* ǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(checkbox) = red; - /* 设置checkbox的位置 */ + /* checkboxλ */ rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个checkbox控件 */ + /* һcheckboxؼ */ checkbox = rtgui_checkbox_create("Blue", RT_TRUE); - /* 设置前景色为蓝色 */ + /* ǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(checkbox) = blue; - /* 设置checkbox的位置 */ + /* checkboxλ */ rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个checkbox控件 */ + /* һcheckboxؼ */ checkbox = rtgui_checkbox_create("12 font", RT_TRUE); - /* 设置字体为12点阵 */ + /* Ϊ12 */ font = rtgui_font_refer("asc", 12); RTGUI_WIDGET_FONT(checkbox) = font; - /* 设置checkbox的位置 */ + /* checkboxλ */ rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5 + 25 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个checkbox控件 */ + /* һcheckboxؼ */ checkbox = rtgui_checkbox_create("16 font", RT_TRUE); - /* 设置字体为16点阵 */ + /* Ϊ16 */ font = rtgui_font_refer("asc", 16); RTGUI_WIDGET_FONT(checkbox) = font; - /* 设置checkbox的位置 */ + /* checkboxλ */ rtgui_widget_set_rect(RTGUI_WIDGET(checkbox), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(checkbox)); diff --git a/examples/gui/demo_view_combobox.c b/examples/gui/demo_view_combobox.c index 7542131e7e..4d57a175e0 100644 --- a/examples/gui/demo_view_combobox.c +++ b/examples/gui/demo_view_combobox.c @@ -1,7 +1,7 @@ /* - * 程序清单:label控件演示 + * 嵥labelؼʾ * - * 这个例子会在创建出的container上添加几个不同类型的label控件 + * ӻڴcontainerӼͬ͵labelؼ */ #include "demo_view.h" #include @@ -15,25 +15,25 @@ struct rtgui_listbox_item items[] = {"item 5", RT_NULL}, }; -/* 创建用于演示combobox控件的视图 */ +/* ʾcomboboxؼͼ */ rtgui_container_t *demo_view_combobox(void) { rtgui_rect_t rect; rtgui_container_t *container; rtgui_combobox_t *box; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("ComboBox View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ box = rtgui_combobox_create(items, sizeof(items) / sizeof(items[0]), &rect); - /* container是一个container控件,调用add_child方法添加这个box控件 */ + /* containerһcontainerؼadd_childboxؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(box)); return container; diff --git a/examples/gui/demo_view_digtube.c b/examples/gui/demo_view_digtube.c new file mode 100644 index 0000000000..cff1d34f5e --- /dev/null +++ b/examples/gui/demo_view_digtube.c @@ -0,0 +1,56 @@ +#include "demo_view.h" +#include + +/* digit tube codes: "ERROR" */ +static char digitbuf[5] = {0x79, 0x77, 0x77, 0x3F, 0x77}; + +rtgui_container_t * demo_view_digtube(void) +{ + struct rtgui_rect rect; + rtgui_container_t *container; + struct rtgui_digtube * digtube; + struct rtgui_digitfont digitfont; + + container = demo_view("Digit Tube View"); + /* add digtube 1: use the default digit font */ + digtube = rtgui_digtube_create(RT_NULL, 5, (void *)4213, 0); + rtgui_container_add_child(container, RTGUI_WIDGET(digtube)); + + demo_view_get_rect(container, &rect); + rect.y2 = rect.y1 + 80; + rtgui_widget_set_rect(RTGUI_WIDGET(digtube), &rect); + + /* add digtube 2: show hex */ + digitfont.seg1_len = 20; + digitfont.seg1_hspace = 4; + digitfont.seg1_nr = 3; + digitfont.seg2_len = 20; + digitfont.seg3_len = 20; + digitfont.seg1_vspace = 1; + digitfont.data = RT_NULL; + + digtube = rtgui_digtube_create(&digitfont, 5, (void *)0xABC, RTGUI_DIGTUBE_STYLE_NOBACKFONT | RTGUI_DIGTUBE_STYLE_DISHEXNUM); + rtgui_container_add_child(container, RTGUI_WIDGET(digtube)); + rect.y1 = rect.y2 + 10;; + rect.y2 = rect.y1 + 60; + rtgui_widget_set_rect(RTGUI_WIDGET(digtube), &rect); + + /* add digtube 3: show custom codes table */ + digitfont.seg1_len = 25; + digitfont.seg1_hspace = 5; + digitfont.seg1_nr = 5; + digitfont.seg2_len = 25; + digitfont.seg3_len = 25; + digitfont.seg1_vspace = 1; + digitfont.data = RT_NULL; + digtube = rtgui_digtube_create(&digitfont, 5, (void *)digitbuf, RTGUI_DIGTUBE_STYLE_DISCODES); + rtgui_container_add_child(container, RTGUI_WIDGET(digtube)); + rect.y1 = rect.y2 + 5; + rect.y2 = rect.y1 + 80; + rtgui_widget_set_rect(RTGUI_WIDGET(digtube), &rect); + RTGUI_WIDGET_BACKGROUND(digtube) = RTGUI_RGB(0x00, 0x00, 0x00); + RTGUI_WIDGET_FOREGROUND(digtube) = RTGUI_RGB(0x00, 0xFF, 0x00); + digtube->digit_bc = RTGUI_RGB(0x00, 0xFF, 0xFF); + + return container; +} \ No newline at end of file diff --git a/examples/gui/demo_view_edit.c b/examples/gui/demo_view_edit.c index 3ee31b7994..fd3f81e949 100644 --- a/examples/gui/demo_view_edit.c +++ b/examples/gui/demo_view_edit.c @@ -1,7 +1,7 @@ /* - * 程序清单:edit控件演示 + * 嵥editؼʾ * - * 这个例子会在conatiner上进行edit控件的演示 + * ӻconatinerϽeditؼʾ */ #include "demo_view.h" @@ -22,14 +22,14 @@ void demo_edit_readin_file(struct rtgui_object *object, struct rtgui_event *even RT_ASSERT(object != RT_NULL); button = RTGUI_BUTTON(object); - /* 取得edit指针 */ + /* ȡeditָ */ edit = RTGUI_EDIT(RTGUI_WIDGET(button)->user_data); - /* 判断文件是否存在 */ + /* жļǷ */ file = rtgui_filerw_create_file(filename, "rb"); if (file == RT_NULL) { - /* 不存在存在,则创建它 */ + /* ڴ,򴴽 */ rt_kprintf("file:\"%s\" does not exist!\n", filename); return; @@ -49,15 +49,15 @@ void demo_edit_saveas_file(struct rtgui_object *object, struct rtgui_event *even RT_ASSERT(object != RT_NULL); button = RTGUI_BUTTON(object); - /* 取得edit指针 */ + /* ȡeditָ */ edit = RTGUI_EDIT(RTGUI_WIDGET(button)->user_data); - /* 判断文件是否存在, 如果存在则删除之 */ + /* жļǷ, ɾ֮ */ file = rtgui_filerw_create_file(filename, "rb"); if (file != RT_NULL) { rtgui_filerw_close(file); - /* 如果是在win32中调试, 请手工删除该文件吧, NT中文件是只读的,unlink删除不掉 */ + /* win32е, ֹɾļ, NTļֻ,unlinkɾ */ if (rtgui_filerw_unlink(filename) == -1) rt_kprintf("Could not delete %s\n", filename); } @@ -95,7 +95,7 @@ rt_bool_t demo_edit_event_handler(struct rtgui_object* object, struct rtgui_even return result; } -/* 创建用于演示edit控件的视图 */ +/* ʾeditؼͼ */ rtgui_container_t *demo_view_edit(void) { rtgui_rect_t rect; @@ -104,7 +104,7 @@ rtgui_container_t *demo_view_edit(void) struct rtgui_label *label; struct rtgui_button *button; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("Edit View"); edit = rtgui_edit_create(container, 10, 35, 220, 200); @@ -117,14 +117,14 @@ rtgui_container_t *demo_view_edit(void) "rtgui_edit_insert_line\n" "rtgui_edit_delete_line\n" "rtgui_edit_connect_line\n" - "双字节测试\n" + "˫ֽڲ\n" "a\n" "b\n" "c\n" "d\n" "1234567890\n"); - /* 创建一个按钮, 读取某个文件 */ + /* һť, ȡijļ */ demo_view_get_rect(container, &rect); rect.x1 += 10; rect.x2 = rect.x1 + 100; @@ -134,10 +134,10 @@ rtgui_container_t *demo_view_edit(void) rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_button_set_onbutton(button, demo_edit_readin_file); - /* 使用user_data传递edit指针 */ + /* ʹuser_dataeditָ */ RTGUI_WIDGET(button)->user_data = (rt_uint32_t)edit; - /* 创建一个按钮, 保存为某个文件 */ + /* һť, Ϊijļ */ demo_view_get_rect(container, &rect); rect.x1 += 130; rect.x2 = rect.x1 + 100; @@ -147,10 +147,10 @@ rtgui_container_t *demo_view_edit(void) rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_button_set_onbutton(button, demo_edit_saveas_file); - /* 使用user_data传递edit指针 */ + /* ʹuser_dataeditָ */ RTGUI_WIDGET(button)->user_data = (rt_uint32_t)edit; - /* 创建一个标签, 显示EDIT的主要参数 */ + /* һǩ, ʾEDITҪ */ demo_view_get_rect(container, &rect); rect.x1 += 10; rect.x2 = rect.x1 + 220; @@ -165,7 +165,7 @@ rtgui_container_t *demo_view_edit(void) RTGUI_WIDGET(edit)->user_data = (rt_uint32_t)label; rtgui_object_set_event_handler(RTGUI_OBJECT(edit), demo_edit_event_handler); - /* 创建一个按钮, 读取EDIT的内存消耗 */ + /* һť, ȡEDITڴ */ demo_view_get_rect(container, &rect); rect.x1 += 150; rect.x2 = rect.x1 + 80; diff --git a/examples/gui/demo_view_label.c b/examples/gui/demo_view_label.c index a8e87142d6..7355cca648 100644 --- a/examples/gui/demo_view_label.c +++ b/examples/gui/demo_view_label.c @@ -1,12 +1,12 @@ /* - * 程序清单:label控件演示 + * 嵥labelؼʾ * - * 这个例子会在创建出的container上添加几个不同类型的label控件 + * ӻڴcontainerӼͬ͵labelؼ */ #include "demo_view.h" #include -/* 创建用于演示label控件的视图 */ +/* ʾlabelؼͼ */ rtgui_container_t *demo_view_label(void) { rtgui_rect_t rect; @@ -14,89 +14,89 @@ rtgui_container_t *demo_view_label(void) rtgui_label_t *label; rtgui_font_t *font; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("Label View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("Red Left"); - /* 设置label控件上的文本对齐方式为:左对齐 */ + /* labelؼϵı뷽ʽΪ */ RTGUI_WIDGET_TEXTALIGN(label) = RTGUI_ALIGN_LEFT; - /* 设置label控件的前景色为红色 */ + /* labelؼǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(label) = red; - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("Blue Right"); - /* 设置label控件上的文本对齐方式为:右对齐 */ + /* labelؼϵı뷽ʽΪҶ */ RTGUI_WIDGET_TEXTALIGN(label) = RTGUI_ALIGN_RIGHT; - /* 设置label控件的前景色为蓝色 */ + /* labelؼǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(label) = blue; - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("Green Center"); - /* 设置label控件的前景色为绿色 */ + /* labelؼǰɫΪɫ */ RTGUI_WIDGET_FOREGROUND(label) = green; - /* 设置label控件上的文本对齐方式为:右对齐 */ + /* labelؼϵı뷽ʽΪҶ */ RTGUI_WIDGET_TEXTALIGN(label) = RTGUI_ALIGN_CENTER_HORIZONTAL; - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5 + 25 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("12 font"); - /* 设置字体为12点阵的asc字体 */ + /* Ϊ12asc */ font = rtgui_font_refer("asc", 12); RTGUI_WIDGET_FONT(label) = font; - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.y1 += 5 + 25 + 25 + 25 + 25; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("16 font"); - /* 设置字体为16点阵的asc字体 */ + /* Ϊ16asc */ font = rtgui_font_refer("asc", 16); RTGUI_WIDGET_FONT(label) = font; - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); return container; diff --git a/examples/gui/demo_view_listbox.c b/examples/gui/demo_view_listbox.c index 1829c81fb0..9b7f4ed302 100644 --- a/examples/gui/demo_view_listbox.c +++ b/examples/gui/demo_view_listbox.c @@ -1,7 +1,7 @@ /* - * 程序清单:label控件演示 + * 嵥labelؼʾ * - * 这个例子会在创建出的container上添加几个不同类型的label控件 + * ӻڴcontainerӼͬ͵labelؼ */ #include "demo_view.h" #include @@ -149,13 +149,13 @@ static rt_bool_t on_items(struct rtgui_object *object, struct rtgui_event *event /* get listbox */ box = RTGUI_LISTBOX(object); - /* 打印当前的项 */ + /* ӡǰ */ rt_kprintf("current item: %d\n", box->current_item); return RT_TRUE; } -/* 创建用于演示label控件的视图 */ +/* ʾlabelؼͼ */ rtgui_container_t *demo_view_listbox(void) { rtgui_rect_t rect; @@ -163,7 +163,7 @@ rtgui_container_t *demo_view_listbox(void) rtgui_label_t *label; rtgui_listbox_t *box; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("ListBox Demo"); if (item_icon == RT_NULL) @@ -171,24 +171,24 @@ rtgui_container_t *demo_view_listbox(void) (const rt_uint8_t *)image_xpm, sizeof(image_xpm), RT_TRUE); items[1].image = item_icon; - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个label控件 */ + /* һlabelؼ */ label = rtgui_label_create("listbox: "); - /* 设置label的位置 */ + /* labelλ */ rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect); - /* container是一个container控件,调用add_child方法添加这个label控件 */ + /* containerһcontainerؼadd_childlabelؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(label)); rect.y1 = rect.y2 + 3; rect.y2 = 250; box = rtgui_listbox_create(items, sizeof(items) / sizeof(struct rtgui_listbox_item), &rect); rtgui_listbox_set_onitem(box, on_items); - /* container是一个container控件,调用add_child方法添加这个listbox控件 */ + /* containerһcontainerؼadd_childlistboxؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(box)); return container; diff --git a/examples/gui/demo_view_menu.c b/examples/gui/demo_view_menu.c index 45a170999f..e49ceca239 100644 --- a/examples/gui/demo_view_menu.c +++ b/examples/gui/demo_view_menu.c @@ -1,7 +1,7 @@ /* - * 程序清单:menu控件演示 + * 嵥menuؼʾ * - * 这个例子会在创建出的container上添加几个不同类型的label控件 + * ӻڴcontainerӼͬ͵labelؼ */ #include "demo_view.h" #include @@ -46,27 +46,27 @@ static rt_bool_t _onmenu(struct rtgui_object *object, struct rtgui_event *event) return RT_TRUE; } -/* 创建用于演示menu控件的视图 */ +/* ʾmenuؼͼ */ rtgui_container_t *demo_view_menu(void) { rtgui_rect_t rect; rtgui_container_t *container; rtgui_button_t *button; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("MENU View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.x1 + 100; rect.y1 += 5; rect.y2 = rect.y1 + 20; - /* 创建一个button控件 */ + /* һbuttonؼ */ button = rtgui_button_create("Pop Menu"); - /* 设置button的位置 */ + /* buttonλ */ rtgui_widget_set_rect(RTGUI_WIDGET(button), &rect); - /* container是一个container控件,调用add_child方法添加这个button控件 */ + /* containerһcontainerؼadd_childbuttonؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(button)); rtgui_button_set_onbutton(button, _onmenu); diff --git a/examples/gui/demo_view_mywidget.c b/examples/gui/demo_view_mywidget.c index effe4d3507..622cc5a5bd 100644 --- a/examples/gui/demo_view_mywidget.c +++ b/examples/gui/demo_view_mywidget.c @@ -1,41 +1,41 @@ /* - * 程序清单:自定义控件演示 + * 嵥Զؼʾ * - * 这个例子会在创建出的container上添加两个自定义控件 + * ӻڴcontainerԶؼ */ #include "demo_view.h" #include "mywidget.h" -/* 创建用于演示自定义控件的视图 */ +/* ʾԶؼͼ */ rtgui_container_t *demo_view_mywidget(void) { rtgui_container_t *container; rtgui_rect_t rect; rtgui_mywidget_t *mywidget; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("MyWidget View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 = rect.y1 + 80; rect.y1 += 5; rect.y2 = rect.y1 + 80; - /* 创建一个自定义控件 */ + /* һԶؼ */ mywidget = rtgui_mywidget_create(&rect); - /* container是一个container控件,调用add_child方法添加这个自控件 */ + /* containerһcontainerؼadd_childԿؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(mywidget)); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 25; rect.x2 = rect.y1 + 40; rect.y1 += 5 + 100; rect.y2 = rect.y1 + 40; - /* 创建一个自定义控件 */ + /* һԶؼ */ mywidget = rtgui_mywidget_create(&rect); - /* container是一个container控件,调用add_child方法添加这个自控件 */ + /* containerһcontainerؼadd_childԿؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(mywidget)); return container; diff --git a/examples/gui/demo_view_notebook.c b/examples/gui/demo_view_notebook.c index 0573b3ac05..07bc84c966 100644 --- a/examples/gui/demo_view_notebook.c +++ b/examples/gui/demo_view_notebook.c @@ -1,7 +1,7 @@ /* - * 程序清单:notebook控件演示 + * 嵥notebookؼʾ * - * 这个例子会在创建出的container上演示notebook控件 + * ӻڴcontainerʾnotebookؼ */ #include "demo_view.h" @@ -25,7 +25,7 @@ const static struct rtgui_listbox_item items2[] = {"new list #2", RT_NULL}, }; -/* 创建用于演示notebook控件的视图 */ +/* ʾnotebookؼͼ */ rtgui_container_t *demo_view_notebook(void) { rtgui_rect_t rect; @@ -33,14 +33,14 @@ rtgui_container_t *demo_view_notebook(void) struct rtgui_notebook *notebook; rtgui_listbox_t *box; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("Notebook View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); notebook = rtgui_notebook_create(&rect, RTGUI_NOTEBOOK_BOTTOM); - /* container是一个container控件,调用add_child方法添加这个notebook控件 */ + /* containerһcontainerؼadd_childnotebookؼ */ rtgui_container_add_child(container, RTGUI_WIDGET(notebook)); box = rtgui_listbox_create(items, sizeof(items) / sizeof(struct rtgui_listbox_item), &rect); diff --git a/examples/gui/demo_view_radiobox.c b/examples/gui/demo_view_radiobox.c index 45fe343a5a..7d72d550a6 100644 --- a/examples/gui/demo_view_radiobox.c +++ b/examples/gui/demo_view_radiobox.c @@ -1,13 +1,13 @@ /* - * 程序清单:radiobox控件演示 + * 嵥radioboxؼʾ * - * 这个例子会在创建出的container上添加两个不同方向的radiobox控件 + * ӻڴcontainerͬradioboxؼ */ #include "demo_view.h" #include -/* 用于显示垂直方向的radio文本项数组 */ +/* ʾֱradioı */ static char *radio_item_v[5] = { "one", @@ -17,52 +17,52 @@ static char *radio_item_v[5] = "item 2" }; -/* 用于显示水平方向的radio文本项数组 */ +/* ʾˮƽradioı */ static char *radio_item_h[3] = { "one", "two", "three" }; -/* 创建用于演示radiobox控件的视图 */ +/* ʾradioboxؼͼ */ rtgui_container_t *demo_view_radiobox(void) { rtgui_rect_t rect; rtgui_container_t *container; rtgui_radiobox_t *radiobox; - /* 先创建一个演示用的视图 */ + /* ȴһʾõͼ */ container = demo_view("RadioBox View"); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5; rect.y2 = rect.y1 + 5 * 25; - /* 创建一个垂直方向显示的radiobox控件,文本项是radio_item_v数组,共5个项 */ + /* һֱʾradioboxؼıradio_item_v飬5 */ radiobox = rtgui_radiobox_create("Radio Box", RTGUI_VERTICAL, radio_item_v, 5); - /* 设置当前选择的数组是第0项 */ + /* õǰѡǵ0 */ rtgui_radiobox_set_selection(radiobox, 0); - /* 添加radiobox控件到视图中 */ + /* radioboxؼͼ */ rtgui_container_add_child(container, RTGUI_WIDGET(radiobox)); - /* 设置radiobox控件的位置信息 */ + /* radioboxؼλϢ */ rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect); - /* 获得视图的位置信息 */ + /* ͼλϢ */ demo_view_get_rect(container, &rect); rect.x1 += 5; rect.x2 -= 5; rect.y1 += 5 + 5 * 25; rect.y2 = rect.y1 + 60; - /* 创建一个水平方向显示的radiobox控件,文本项是radio_item_h数组,共3个项 */ + /* һˮƽʾradioboxؼıradio_item_h飬3 */ radiobox = rtgui_radiobox_create("Radio Box", RTGUI_HORIZONTAL, radio_item_h, 3); - /* 设置当前选择的数组是第0项 */ + /* õǰѡǵ0 */ rtgui_radiobox_set_selection(radiobox, 0); - /* 添加radiobox控件到视图中 */ + /* radioboxؼͼ */ rtgui_container_add_child(container, RTGUI_WIDGET(radiobox)); - /* 设置radiobox控件的位置信息 */ + /* radioboxؼλϢ */ rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect); return container;