Zlggui is a simple gui. It took half a day to experiment with it. I personally think it is quite good to use this UI in a simple UI embedded system, which is easy to transplant, easy to modify. It implements basic draw lines, draw rectangles, draw circles/ovans, draw arcs, curves, fill, 5*7 \ 8*8 characters \ 24*32 ASCII characters, simple forms, menus, buttons. During the experiment, a bug was modified and several functions were added to output the gb2312 font. The following is a detailed description.
Logical Link Structure of each function part in the source program:
Top layer: font_24_32 font5_7 font8_8 menu spline windows loadbit
Middle Layer: gui_basic gui_stockc convertcolor
Underlying layer: the LCD driver needs to be written by the user based on the hardware and must comply with the middle-layer function declaration requirements.
Configuration layer: gui_config.h. In addition, you must provide a global configuration file (data type, etc)
During the porting process, you only need to design four files (the file name is customized, and the number of files is also determined, as long as the function is implemented): LCD _driver.h LCD _driver.c config. h. The LCD _driver.c, LCD _driver.h, and config. h must be provided by the user. In addition to the function definitions required by gui_basic.h in the middle layer, two macros (functions): gui_cmpcolor and gui_copycolor must be defined in LCD _driver.c/h, note that the two macros must be defined based on the LCD display type. The monochrome screen and the color screen are different.
Some examples in LCD _driver.h:
// These two macros vary based on the number of pixels in the LCD. They are defined as colored screens.
# Define gui_cmpcolor (color1, color2) (color1) = (color2 ))
# Define gui_copycolor (color1, color2) (* color1) = (color2 ))
// Definition of monochrome screen
# Define gui_cmpcolor (color1, color2) (color1 & 0x01) = (color2 & 0x01 ))
# Define gui_copycolor (color1, color2) (* color1) = (color2 & 0x01 ))
// Define some color values
# Define red 0x001f
# Define blue 0xf800
# Define green 0x07e0
# Define black 0x0000
============================================
Some examples in LCD _driver.c:
In this driver file, you need to define several functions: Draw a point, take a point, draw a horizontal line, draw a vertical line, draw any two-point line four functions, and must be consistent with the function declaration in gui_basic.h. In my porting, I used macros to contact these functions in LCD _driver.h, so that I don't need to change the function name in LCD _driver.c, as shown below:
# Define gui_point set_pixel
# Define gui_hline draw_hline
# Define gui_rline draw_vline
# Define gui_readpoint get_pixel
Some examples in config. h:
Typedef unsigned char uint8;/* unsigned 8-bit integer variable */
Typedef signed Char int8;/* signed 8-bit integer variable */
Typedef unsigned short uint16;/* unsigned 16-bit integer variable */
Typedef signed short int16;/* signed 16-bit integer variable */
Typedef unsigned int uint32;/* unsigned 32-bit integer variable */
Typedef signed int int32;/* signed 32-bit integer variable */
Typedef unsigned short tcolor;
// Contains files, which are included according to the project environment
# Include "gui_basic.h"
# Include "font5_7.h"
# Include "font24_32.h"
# Include "font8_8.h"
# Include "font_macro.h"
# Include "windows. H"
A bug in zlggui was found during the porting process. In font_24_32.c, The gui_putchar24_32 function is incorrectly designed, leading to incorrect output of font data. According to my understanding logic, the modifications are as follows:
Uint8 gui_putchar24_32 (uint32 X, uint32 y, uint8 ch)
{Uint8 font_dat;
Uint8 I, J, K;
Tcolor BAKC;
/* Parameter filtering */
If (x> (GUI_LCM_XMAX-32) Return (0 );
If (Y> (GUI_LCM_YMAX-32) Return (0 );
For (I = 0; I <14; I ++)
{If (font24x32_tab [I] = CH) break;
}
Ch = I;
For (I = 0; I <32; I ++) // display 32 rows in total
{
For (j = 0; j <3; j ++) // each row contains 3 bytes.
{
Font_dat = font24x32 [CH] [I * 3 + J];
/* Set the corresponding vertex to color or back_color */
For (k = 0; k <8; k ++)
{
If (font_dat & dcb2hex_tab [k]) = 0)
Gui_copycolor (& BAKC, back_color );
Else
Gui_copycolor (& BAKC, disp_color );
Gui_point (X, Y, BAKC );
X ++;
}
}
Y ++;
// Point to the next row
X-= 24;
// Restore x
}
Return (1 );
}
========================================================== ============================
Original function:
Uint8 gui_putchar24_32 (uint32 X, uint32 y, uint8 ch)
{Uint8 font_dat;
Uint8 I, J;
Tcolor BAKC;
/* Parameter filtering */
If (x> (GUI_LCM_XMAX-32) Return (0 );
If (Y> (GUI_LCM_YMAX-32) Return (0 );
For (I = 0; I <14; I ++)
{If (font24x32_tab [I] = CH) break;
}
Ch = I;
For (I = 0; I <32; I ++) // display 32 rows in total
{
For (j = 0; j <24; j ++) // 24 points in total for each row
{/* If the current vertex is 0, 8, or 16, read the dot matrix data */
If (J & 0x07) = 0) font_dat = font24x32 [CH] [I * 3 + j> 3];
/* Set the corresponding vertex to color or back_color */
F (font_dat & dcb2hex_tab [J]) = 0) gui_copycolor (& BAKC, back_color );
Else gui_copycolor (& BAKC, disp_color );
Gui_point (X, Y, BAKC );
X ++;
}
Y ++;
// Point to the next row
X-= 24;
// Restore x
}
Return (1 );
}
========================================================== ========
// In addition, I designed a function that can output 24*32 strings, as shown below:
Uint8 gui_putstring24_32 (uint32 X, uint32 y, uint8 * Str)
{
While (1)
{If (* Str) = '\ 0') break;
If (gui_putchar24_32 (X, Y, * STR ++) = 0) break;
X + = 24;
// The Position of the next character, Y unchanged (that is, no line break)
}
Return 1;
}
========================================================== ========================================================== ====================================
========================================================== ========================================================== ====================================
Display gb2312 Chinese characters. The font library is generated by the tool provided by MiniGUI. I generated a 16*16 font library. In practice, the displayed font may be 12*12, 16*16, or 24*32. Therefore, a general font data output function must be designed to automatically identify font parameters, such as height and width. In loadbit. C, there is a function _ gui_puthz that can be used to display Chinese characters. Using this function, I have designed several functions to output the gb2312 font with different widths and heights. Description:
// This function can display font data of any height or width. Hz_addr = (uint8 *) hz_font_addr is the word
The starting address of the database. Hz_addr = (uint8 *) hz_font_addr + 128 * hz_bytes1 is the starting address of Chinese characters.
Important: TMP = (* CHR) * hz_bytes1 and TMP = (* (CHR)-0xa0-1) * 94 + (* (CHR + 1)-0xa0-1) * hz_bytes2
The starting offset of the dot matrix data of Chinese characters is calculated based on the gb2312 encoding rules and the parameters of the generated font,
Hz_bytes1 indicates the number of bytes required for a word in the Spanish font; hz_bytes2 indicates the Chinese font
The number of bytes required for a word. 94 indicates the area code of the font. You can refer to the gpb2312 rule for understanding.
Void gui_puthz (uint32 X, uint32 y, uint8 * CHR)
{
Uint32 TMP;
If (! Font_lib_valid_flag) // whether the font is valid
Return;
If (* CHR <128)
{
Hz_addr = (uint8 *) hz_font_addr;
TMP = (* CHR) * hz_bytes1; // the offset of the West text.
_ Gui_puthz (X, Y, hz_addr + TMP, hz_width1, hz_height); // output the West text
}
Else
{
Hz_addr = (uint8 *) hz_font_addr + 128 * hz_bytes1;
TMP = (* (CHR)-0xa0-1) * 94 + (* (CHR + 1)-0xa0-1) * hz_bytes2; // text offset
_ Gui_puthz (X, Y, hz_addr + TMP, hz_wid2, hz_height); // output text
}
}
// This function is used to display the horizontal output of Chinese character strings. It can be used to output both Chinese and ASCII characters and automatically recognize the font width.
// Call example: gui_puthzstringh ");
// Gui_puthzstringh (0,100, "abcdef 1234 ");
Void gui_puthzstringh (uint32 X, uint32 y, uint8 * Str)
{
If (! Font_lib_valid_flag) // whether the font is valid
Return;
While (1)
{If (* Str) = '\ 0') break;
If (* STR> 127)
{
Gui_puthz (X, Y, STR );
STR + = 2; // each text consists of two bytes of data
X + = hz_wid2; // Chinese font
}
Else
{
Gui_puthz (X, Y, STR );
STR + = 1;
X + = hz_width1; // Spanish font
}
}
}
// This function is used to display vertical output Chinese character strings. It can be used to output Chinese and ASCII characters in combination and automatically recognize the font width.
// Call example: gui_puthzstringv ");
// Gui_puthzstringv (0,100, "abcdef 1234 ");
Void gui_puthzstringv (uint32 X, uint32 y, uint8 * Str)
{
If (! Font_lib_valid_flag) // whether the font is valid
Return;
While (1)
{If (* Str) = '\ 0') break;
If (* STR> 127)
{
Gui_puthz (X, Y, STR );
STR + = 2;
Y + = hz_height; // Chinese font
}
Else
{
Gui_puthz (X, Y, STR );
STR + = 1;
Y + = hz_height; // Spanish font
}
}
}
// Read and process font parameters: Uniform font height, Western font width, Chinese font width, encoding method, and validation of byte data
// Before outputting the gb2312 font data, you must call this function only once. The parameters used to read the font are as follows: uniform font height, width, encoding method (output function only supports gb2312), verification, and so on.
Void gui_hzparameterinit (void)
{
Uint8 TMP;
Hz_addr = (uint8 *) hz_font_addr;
Hz_height = * hz_addr; // unified font height
Hz_width1 = * (hz_addr + 1); // specifies the width of the Spanish font.
Hz_wid2= * (hz_addr + 2); // Chinese font width
Hz_code_mode = * (hz_addr + 3); // font encoding method
TMP = ~ (Hz_height + hz_width1 + hz_wid2+ hz_code_mode); // calculate the verification code.
If (* (hz_addr + 4) = TMP) // check whether the result is valid.
{
Font_lib_valid_flag = 0xff;
Hz_bytes1 = (hz_width1% 8 )? Hz_width1/8 + 1: hz_width1/8)
* Hz_height; // calculates the number of Spanish font bytes.
Hz_bytes2 = (hz_wid2% 8 )? Hz_wid2/ 8 + 1: hz_wid2/ 8)
* Hz_height; // calculates the number of Chinese font bytes.
}
Else
Font_lib_valid_flag = 0x00; // invalid Font Library
}
// Some variables used
# Define hz_font_addr 0x26000 // The starting address for storing the font, which can be handled according to the actual situation.
Uint8 * hz_addr; // access the data address pointer of the font library
Uint8 hz_width1, hz_wid2; // The width of the Chinese text and the width of the Chinese text.
Uint8 hz_height;/unified font height
Uint8 hz_code_mode; // encoding method
Uint8 hz_bytes1, hz_bytes2; // number of bytes occupied by the West text, in the text
Uint8 font_lib_valid_flag; // font Validity
// Some other functions called
/*************************************** *************************************
* Name: gui_loadline ()
* Function: outputs a line of data for a monochrome image.
* Entry parameter: X indicates the display position and X coordinate.
* Y indicates the display position and Y coordinate.
* Data to be output by dat.
* No number of vertices for this row
* Exit parameter: If the return value is 1, the operation is successful. If the return value is 0, the operation fails.
* Description: The operation fails because the specified address is out of the valid range.
**************************************** ************************************/
Uint8 gui_loadline (uint32 X, uint32 y, uint8 * dat, uint32 No)
{Uint8 bit_dat;
Uint8 I;
Tcolor BAKC;
/* Parameter filtering */
If (x> = gui_lcm_xmax) Return (0 );
If (Y> = gui_lcm_ymax) Return (0 );
For (I = 0; I <no; I ++)
{/* Determine whether to read the dot matrix data */
If (I % 8) = 0) bit_dat = * dat ++;
/* Set the corresponding vertex to color or back_color */
If (bit_dat & dcb2hex_tab [I & 0x07]) = 0) gui_copycolor (& BAKC, back_color );
Else gui_copycolor (& BAKC, disp_color );
Gui_point (X, Y, BAKC );
If (++ X)> = gui_lcm_xmax) Return (0 );
}
Return (1 );
}
/*************************************** *************************************
* Name: _ gui_puthz ()
* Function: display Chinese characters.
* Entry parameter: X indicates the display position and X coordinate.
* Y indicates the display position and Y coordinate.
* Dat outputs the dot matrix data of Chinese characters to be displayed.
* HNO: displays the number of vertices in a row.
* LNO: Number of vertices in the column to be displayed
* Exit parameter: None
* Description: The operation fails because the specified address is out of the valid range.
**************************************** ************************************/
// I changed the name of this function. _ gui_puthz is used to output the font lattice data, and gui_puthz is used to output
Chinese characters
Void _ gui_puthz (uint32 X, uint32 y, uint8 * dat, uint8 HNO, uint8 LNO)
{Uint8 I;
For (I = 0; I <LNO; I ++)
{Gui_loadline (X, Y, dat, HNO );
// Output a row of data
Y ++;
// Display the next row
DAT + = (HNO> 3 );
// Calculate the data of the next row
If (HNO & 0x07 )! = 0) DAT ++;
}
}
==========================================
About the storage of the gb2312 font. A kb storage space is required for the 16*16 gb2312 font. You can
In the SD card, External Flash, or internal flash. I am using lpc1768, a total
KB Internal flash space, so it is stored in the second half of the Internal flash space. How to burn it
What should I do? There are several methods: first, generate a bind file for the font, and then use the recorder to burn it into the specified space; second
It is to design a program for burning the font library in the main program, and use IAP to burn the Library to the specified space. The third is to first download the font file
Compile with the main program, define the font library to the specified space, burn it once, and then remove the font file from the main program
In the future, the program compilation and burning will only compile and burn the main program (this can speed up compilation and burning)
Note that the requirement space of the main program cannot cover the font space. I used the last one for learning verification.
Method, the key of the method is to compile the font to the specified space: const unsigned char font [263744]
_ Attribute _ (at (0x26000). This is the starting address of the font space I used. The starting point of the font library
The address is 0x26000. Font data is generally not stored in the Internal flash space, which is an extreme wave
Fee (unless there is more than enough space ). In actual products, font libraries are generally stored in SD cards or external flash.
========================================================== ======================================
For the gb2312 encoding rules, extract some important information on the internet as follows:
In GB 2312, "partition" is performed on the received Chinese characters. Each partition contains 94 Chinese characters/symbols. This representation is also called
The location code.
The 01-09 area is a special symbol.
Areas 16-55 are top-level Chinese characters sorted by pinyin.
Area 56-87 contains second-level Chinese characters, which are sorted by the beginning or strokes.
Areas 10-15 and 8-94 are not encoded.
For example, the word "ah" is the first Chinese Character in gb2312, and its location code is 1601.
Each Chinese Character and symbol is expressed in two bytes.
The first byte is referred to as "high byte" (also called zone byte), and the second byte is referred to as "low Byte" (also called bit byte ).
"High Byte" uses 0xa1-0xf7 (add the area code of area 01-87 with 0xa0), "low Byte" uses 0xa1-0xfe (
Add 01-94 with 0xa0 ).
The range of the "high byte" in the Chinese character area is 0xb0-0xf7 and "low Byte" since the first-level Chinese character starts in the 16-area.
It is 0xa1-0xfe, and the occupied code bit is 72*94 = 6768. Five of them are D7FA-D7FE.
For example, in most programs, the word "ah" takes two bytes, 0xb0 (first byte) 0xa1 (second byte)
Storage. Location code = byte + byte (compared with the location code: 0xb0 = 0xa0 + 16, 0xa1 = 0xa0 + 1 ).
========================================================== ======================================
========================================================== ======================================== End