Displaying text description is essential for many applications. This section is to explain how developers may utilize LT768x to display graphic font coded by Unicode.
Just follow the simple steps listed below:
Step 1: Select and setup a desired font, and convert it into a bin file.
Step 2: Program the bin file to the flash connected to LT768x
Step 3: Call LT768x functions to "draw" the designated text, and display it onto the TFT panel.
Levetop provides, BWFont.exe, a powerful tool that can help developers generate a graphic font, and convert the font into a bin file. Each symbol/character is depicted in the form of PNG picture, and the picture data are stored in a consecutive order in the bin file.
(For more information about the convertion tool, please contact: Levetop Semiconductor)
The generated bin file also has a header that lists the related information of the font, as shown below:
Byte order | Content of the byte | Explanation |
---|---|---|
byte0 | 'U' -- 0x55 | |
byte1 | 'N' -- 0x4E | |
byte2 | Width of the font | |
byte3 | Height of the font | |
byte4 | StartCode & 0xFF | LSB |
byte5 | (StartCode<<8) & 0xFF | MSB |
byte6 | EndCode & 0xFF | LSB |
byte7 | (EndCode<<8) & 0xFF | MSB |
byte8 | Grayscale of pixel: 0 -- 1bit 1 -- 2bits 2 -- 4bits 3 -- 8bits | |
byte9~103 | Width of each ASCII code(0x20~0x7E) | |
byte104 ~ byte(104+W*H*95/bitsData-1) | ASCII Graphic Data | 1bit: bitData=8 2bits: bitsData=4 4bits: bitsData=2 8bits: bitsData=1 |
byte(104+W*H*95/bitsData) ~ | Unicode Font Graphic Data |
Users may develope their own functions by decoding the bin file based on the above table.
Related functions:
void LT768_Draw_16bit // To draw one symbol/character (PNG picture)
(
unsigned char SCS // Select SPI device 0: SPI0, 1: SPI1
,unsigned char Clk // SPI Clock - System Clock /{(Clk+1)*2}
,unsigned short X1 // X start coordinate of the destination
,unsigned short Y1 // Y start coordinate of the destination
,unsigned short X_W // Data width
,unsigned short Y_H // Data height
,unsigned short P_W // Picture width
,unsigned long F_Color // Font color
,unsigned long B_Color // Background color
,unsigned short transparent // 1: remove background 0: show background color
,unsigned short pixel_format // Options: 1/2/4 bits
,unsigned long Addr // Starting address to retrieve data from flash
,unsigned long lay0 // SDRAM layer address to write to
,unsigned short canvas_w // Layer width
)
void LT768_Print_Font_Unicode // To print out a unicode string
(
unsigned long FlashAddr // Font address in the Flash
,unsigned short x // x coordinate to start displaying unicode
,unsigned short y // y coordinate to start displaying unicode
,unsigned short w // String display length (in pixel)
,unsigned long FontColor // Font color
,unsigned long BackGroundColor // Background color
,unsigned short transparent // Flag for removing background
,unsigned short String_Length // String length - the amonunt of the code (unit: byte)
,char *c // Starting address of the string
)
Demo code is listed below:
/*---------------------------------------------------------------------------------------*/
/* Function: LT768_Draw_16bit */
/* */
/* Parameters: */
/* SCS: Select SPI device 0: SPI0, 1: SPI1 */
/* Clk: SPI Clock - System Clock /{(Clk+1)*2} */
/* X1: X start coordinate of the destination */
/* Y1: Y start coordinate of the destination */
/* X_W: Data width */
/* Y_H: Data height */
/* P_W: Picture width */
/* F_Color: Font color */
/* B_Color: Background color */
/* transparent: 1: remove background 0: show background color */
/* pixel_format: Options: 1/2/4 bits */
/* Addr: Starting address to retrieve data from flash */
/* lay0: SDRAM layer address to write to */
/* canvas_w: Layer width */
/* Returns: None */
/* Description: To draw one unicode symbol/character (PNG picture) */
/*---------------------------------------------------------------------------------------*/
u8 cSetb[8] = {cSetb0, cSetb1, cSetb2, cSetb3, cSetb4, cSetb5, cSetb6, cSetb7};
u8 cSetb_2bit[4] = {0xc0, 0x30, 0x0c, 0x03};
u8 cSetb_4bit[2] = {0xF0, 0x0F};
void LT768_Draw_16bit
(
unsigned char SCS
,unsigned char Clk
,unsigned short X1
,unsigned short Y1
,unsigned short X_W
,unsigned short Y_H
,unsigned short P_W
,unsigned long F_Color
,unsigned long B_Color
,unsigned short transparent
,unsigned short pixel_format
,unsigned long Addr
,unsigned long lay0
,unsigned short canvas_w
)
{
unsigned short a, b, c, d;
u16 color_temp , bcolor_temp;
u16 temp;
u8 fdata[8 * 128 * 2];
LT768_SPI_Init(SCS, Clk); // Intialize selected SPI (for Flash)
LT_ReadFlash(fdata, Addr, X_W * Y_H ); // Retrieve data from SPI Flash
if (F_Color == 0)
F_Color += 1;
if (B_Color == 0)
B_Color += 1;
if(transparent == 1) bcolor_temp = 0;
else if(transparent == 0)
{
bcolor_temp = B_Color;
}
Graphic_Mode();
Canvas_Image_Start_address(lay0);
Canvas_image_width(canvas_w);
Active_Window_XY(X1, Y1);
Active_Window_WH(P_W, Y_H);
Goto_Pixel_XY(X1, Y1);
LCD_CmdWrite(0x04);
SS_RESET;
SPI2_ReadWriteByte(0x80);
if(pixel_format == 1) // For 1bit unicode font
{
for (a = 0; a < Y_H; a++)
{
for (c = 0; c < X_W; c++)
{
for (b = 0; b < 8; b++)
{
if (fdata[X_W * a + c] & cSetb[7 - b])
{
SPI2_ReadWriteByte(F_Color);
SPI2_ReadWriteByte(F_Color >> 8);
}
else
{
SPI2_ReadWriteByte(bcolor_temp);
SPI2_ReadWriteByte(bcolor_temp >> 8);
}
}
}
}
}
else if(pixel_format == 2) // for 2bits unicode font
{
for (a = 0; a < Y_H; a++)
{
for (c = 0; c < X_W/2; c++)
{
for (d = 0; d < 2; d++)
{
for (b = 0; b < 4; b++)
{
temp = (fdata[X_W * a + c * 2 + d] & cSetb_2bit[b]);
if( b == 0) temp = temp >> 6 ;
else if( b == 1) temp = temp >> 4 ;
else if( b == 2) temp = temp >> 2 ;
if (temp>0)
{
if(temp == 1) color_temp = F_Color | (0x04<<12) ;
else if(temp == 2) color_temp = F_Color | (0x08<<12) ;
else if(temp == 3) color_temp = F_Color | (0x0F<<12) ;
SPI2_ReadWriteByte(color_temp);
SPI2_ReadWriteByte(color_temp >> 8);
}
else
{
SPI2_ReadWriteByte(bcolor_temp);
SPI2_ReadWriteByte(bcolor_temp >> 8);
}
}
}
}
}
}
else if(pixel_format == 4) // for 4bits unicode font
{
for (a = 0; a < Y_H; a++)
{
for (c = 0; c < X_W/4; c++)
{
for (d = 0; d < 4; d++)
{
for (b = 0; b < 2; b++)
{
temp = (fdata[X_W * a + c * 4 + d] & cSetb_4bit[b]);
if( b == 0) temp = temp >> 4 ;
if (temp>0)
{
color_temp = F_Color | (temp<<12) ;
SPI2_ReadWriteByte(color_temp);
SPI2_ReadWriteByte(color_temp >> 8);
}
else
{
SPI2_ReadWriteByte(bcolor_temp);
SPI2_ReadWriteByte(bcolor_temp >> 8);
}
}
}
}
}
}
SS_SET;
}
/*---------------------------------------------------------------------------------------*/
/* Function: LT768_Print_Font_Unicode */
/* */
/* Parameters: */
/* FlashAddr: Font address in the Flash */
/* x: x coordinate to start displaying unicode */
/* y: y coordinate to start displaying unicode */
/* w: String display length */
/* FontColor: Font color */
/* BackGroundColor: Background color */
/* transparent: Flag for removing background */
/* String_Length: String length - the amount of the code (unit: byte) */
/* *c: Starting address of the string */
/* Returns: None */
/* Description: Print out unicode fonts */
/*---------------------------------------------------------------------------------------*/
u8 ASCII_W[95] = {0}; // For decoding bin file's header
void LT768_Print_Font_Unicode
(
unsigned long FlashAddr
,unsigned short x
,unsigned short y
,unsigned short w
,unsigned long FontColor
,unsigned long BackGroundColor
,unsigned short transparent
,unsigned short String_Length
,char *c
)
{
unsigned short temp = 0; // For Unicode index
unsigned long i = 0; // For input string index
unsigned short width_Hor = 0; // For actual width of the unicode
u16 size_w,size_h; // For original font width and height
u16 unicode = 0; // For unicode
u16 start_code = 0, end_code = 0; // For the start/end code of the Unicode
u16 temp_x = x; // The x coordinate to print out the font
u16 temp_y = y; // The y coordinate to print out the font
u8 Ascii_temp; // Ascii code index
u8 gray = 0; // Grayscale
u8 temp_pixel; // Pixel amount per bit
u8 pixel_format; // Represent 1/2/4bits grayscale
/*************************** Unicode Header List ***************************
byte0 'U'--0x55
byte1 'N'--0x4E
byte2 Font width
byte3 Font height
byte4 StartCode & 0xFF LSB
byte5 (StartCode<<8) & 0xFF MSB
byte6 EndCode & 0xFF LSB
byte7 (EndCode<<8) & 0xFF MSB
----------------------------------------------------------------------------
byte8 Grayscale of pixel
0 -- 1bit
1 -- 2bits
2 -- 4bits
3 -- 8bits
----------------------------------------------------------------------------
byte9~103 Width of each Ascii code
(0x20~0x7E)
----------------------------------------------------------------------------
byte104 ASCII graphic data 1bit: bitsData=8
to 2bits:bitsData=4
byte(104+W*H*95/bitsData-1) 4bits:bitsData=2
8bits:bitsData=1
----------------------------------------------------------------------------
byte(104+W*H*95/bitsData)~ Unicode Font graphic data
(start position)
*****************************************************************************/
LT768_SPI_Init(1,1); // Initialzie & enable SPI Flash
LT_ReadFlash(ASCII_W , FlashAddr + 2 , 7); // Retrieve byte2 ~ 8 from flash
size_w = ASCII_W[0]; // byte2: font width
size_h = ASCII_W[1]; // byte3: font height
start_code = ASCII_W[2] + (ASCII_W[3] << 8); // byte4 and byte 5: Start code of the unicode
end_code = ASCII_W[4] + (ASCII_W[5] << 8); // byte6 and byte 7: End code of the unicode
gray = ASCII_W[6]; // byte8: Grayscale of pixel
if(gray == 0) { temp_pixel = 8; pixel_format = 1;} // pixel_format -> 1/2/4 bits (Grayscale)
else if(gray == 1) { temp_pixel = 4; pixel_format = 2;}
else if(gray == 2) { temp_pixel = 2; pixel_format = 4;}
if ( size_w%8 != 0)
width_Hor = size_w / temp_pixel + 1;
else
width_Hor = size_w / temp_pixel;
LT_ReadFlash(ASCII_W, FlashAddr + 9, 95); // Retrieve Ascii code widths and store them to ASCII_W array
while(String_Length)
{
unicode = (c[i]<<8) + c[i+1]; // Reassemble the code
if (unicode < 128 && unicode > 0x00) // Print ASCII
{
Ascii_temp = unicode - 0x20; // Ascii code index
// Draw Ascii by its png data
LT768_Draw_16bit(1, 0, temp_x, temp_y, width_Hor, size_h, width_Hor * temp_pixel, FontColor, BackGroundColor, transparent, pixel_format, FlashAddr + 104 + Ascii_temp * width_Hor * size_h, LAYER_0, LCD_XSIZE_TFT);
i += 2;
String_Length -= 2;
temp_x = temp_x + ASCII_W[Ascii_temp] + 1; // ASCII_W[Ascii_temp] = the width of the current Ascii code ->
// This line is to calculate the x coordinate of the next Ascii code
}
else if (unicode >= start_code && unicode <= end_code) // Print Unicode
{
temp = unicode - start_code; // Unicode index start with start_code
// Draw Unicode by its png data
LT768_Draw_16bit(1, 0, temp_x, temp_y, width_Hor, size_h, width_Hor * temp_pixel, FontColor, BackGroundColor, transparent, pixel_format, FlashAddr + 104+ (temp + 95) * width_Hor * size_h, LAYER_0, LCD_XSIZE_TFT);
i += 2;
String_Length -= 2;
temp_x = temp_x + size_w; // size_w = the width of each Unicode character ->
// This line is to calculate the x coordinate of the next Unicode
}
else
{
break;
}
}
}
void Print_Unicode(void)
{
// 風のリズムで推理が冴える,
char L1[26] = {0x98,0xA8,0x30,0x6E,0x30,0xEA,0x30,0xBA,0x30,0xE0,0x30,0x67,
0x63,0xA8,0x74,0x06,0x30,0x4C,0x51,0xB4,0x30,0x48,0x30,0x8B,
0x30,0x01};
// 黒い鏡もほぐれて見える!
char L2[24] = {0x9E,0xD2,0x30,0x44,0x93,0xE1,0x30,0x82,0x30,0x7B,0x30,0x50,
0x30,0x8C,0x30,0x66,0x89,0x8B,0x30,0x48,0x30,0x8B,0x00,0x21};
// たった一つの真実見抜く,
char L3[38] = {0x30,0x5F,0x30,0x63,0x30,0x5F,0x4E,0x00,0x30,0x64,0x30,0x6E,
0x77,0x1F,0x5B,0x9F,0x89,0x8B,0x62,0x9C,0x30,0x4F,0x30,0x01};
// 見た目は子供,ずのうはおとな,
char L4[40] = {0x89,0x8B,0x30,0x5F,0x76,0xEE,0x30,0x6F,0x5B,0x50,0x4F,0x9B,
0x30,0x01,0x30,0x5A,0x30,0x6E,0x30,0x46,0x30,0x6F,0x30,0x4A,
0x30,0x68,0x30,0x6A,0x30,0x01};
// その名は,名探偵コナン!
char L5[24] = {0x30,0x5D,0x30,0x6E,0x54,0x0D,0x30,0x6F,0x00,0x2C,0x54,0x0D,
0x63,0xA2,0x50,0x75,0x30,0xB3,0x30,0xCA,0x30,0xF3,0x00,0x21};
Select_Main_Window_16bpp(); // Set main window color depth
Main_Image_Start_Address(LAYER_0); // Set main window start address - Display layer
Main_Image_Width(LCD_XSIZE_TFT); // Set main window width
Main_Window_Start_XY(0,0); // Set main window start coordinate
Canvas_Image_Start_address(LAYER_0); // Set canvas start address
Canvas_image_width(LCD_XSIZE_TFT); // Set canvas width
Active_Window_XY(0,0); // Set active window start coordinate
Active_Window_WH(LCD_XSIZE_TFT,LCD_YSIZE_TFT); // Set active window area
// Load the background picture to display layer
LT768_DMA_24bit_Block(1,0,0,0,LCD_XSIZE_TFT,LCD_YSIZE_TFT,LCD_XSIZE_TFT,0);
// Print the font - 0x000BB800 is the starting address (flash) of the 32x32 unicode font
LT768_Print_Font_Unicode(0x000BB800, 100, 124, 26/2*32, Yellow, Red, 1, 26, L1); delay_ms(500);
LT768_Print_Font_Unicode(0x000BB800, 260, 180, 24/2*32, Yellow, Red, 1, 24, L2); delay_ms(500);
LT768_Print_Font_Unicode(0x000BB800, 100, 234, 38/2*32, Yellow, Red, 1, 38, L3); delay_ms(500);
LT768_Print_Font_Unicode(0x000BB800, 260, 290, 40/2*32, Yellow, Red, 1, 40, L4); delay_ms(500);
LT768_Print_Font_Unicode(0x000BB800, 220, 360, 24/2*32, White, Red, 1, 24, L5);
}
In the demo code, "Print_Unicode" is the main function which sets the arrays containing the unicode of the text to be displayed, and then it calls "LT768_Print_Font_Unicode" to decode the text bin file, and then call "LT768_Draw_16bit" to draw the designated Japanese characters.
Running result is shown below: