/****************************************************************************** * | File : GUI_Paint.c * | Author : Waveshare electronics * | Function : Achieve drawing: draw points, lines, boxes, circles and * their size, solid dotted line, solid rectangle hollow * rectangle, solid circle hollow circle. * | Info : * Achieve display characters: Display a single character, string, number * Achieve time display: adaptive size display time minutes and seconds *---------------- * | This version: V3.1 * | Date : 2020-07-08 * | Info : * ----------------------------------------------------------------------------- * V3.1(2020-07-08): * 1.Change: Paint_SetScale(UBYTE scale) * Add scale 7 for 5.65f e-Parper * 2.Change: Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color) * Add the branch for scale 7 * 3.Change: Paint_Clear(UWORD Color) * Add the branch for scale 7 * * ----------------------------------------------------------------------------- * V3.0(2019-04-18): * 1.Change: * Paint_DrawPoint(..., DOT_STYLE DOT_STYLE) * => Paint_DrawPoint(..., DOT_STYLE Dot_Style) * Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel) * => Paint_DrawLine(..., DOT_PIXEL Line_width, LINE_STYLE Line_Style) * Paint_DrawRectangle(..., DRAW_FILL Filled, DOT_PIXEL Dot_Pixel) * => Paint_DrawRectangle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Fill) * Paint_DrawCircle(..., DRAW_FILL Draw_Fill, DOT_PIXEL Dot_Pixel) * => Paint_DrawCircle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Filll) * * ----------------------------------------------------------------------------- * V2.0(2018-11-15): * 1.add: Paint_NewImage() * Create an image's properties * 2.add: Paint_SelectImage() * Select the picture to be drawn * 3.add: Paint_SetRotate() * Set the direction of the cache * 4.add: Paint_RotateImage() * Can flip the picture, Support 0-360 degrees, * but only 90.180.270 rotation is better * 4.add: Paint_SetMirroring() * Can Mirroring the picture, horizontal, vertical, origin * 5.add: Paint_DrawString_CN() * Can display Chinese(GB1312) * * ----------------------------------------------------------------------------- * V1.0(2018-07-17): * Create library * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documnetation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * ******************************************************************************/ #include "GUI_Paint.h" // #include "DEV_Config.h" #include "esp_log.h" #include #include #include //memset() #include #include "GT5DL32A3W.h" static const char *LOG_TAG = "GUI_PAINT"; PAINT Paint_info; PAINT_TIME Paint_time_info; FONT_TYPE_T ascii_type_5x7 = {"ascii_type_5x7",ASCII_5X7,5,7,}; FONT_TYPE_T ascii_type_7x8 ={"ascii_type_7x8",ASCII_7X8,7,8,}; FONT_TYPE_T ascii_type_6x12 ={"ascii_type_6x12",ASCII_6X12,6,12,}; FONT_TYPE_T ascii_type_8x16 ={"ascii_type_8x16",ASCII_8X16,8,16,}; FONT_TYPE_T ascii_type_12x24 ={"ascii_type_12x24",ASCII_12X24,12,24,}; FONT_TYPE_T ascii_type_12x24_b ={"ascii_type_12x24_b",ASCII_12X24_B,12,24,}; FONT_TYPE_T ascii_type_16x32 ={"ascii_type_16x32",ASCII_16X32,16,32,}; FONT_TYPE_T chinese_type_12 ={"chinese_type_12", 0,12,12,}; FONT_TYPE_T chinese_type_16 = {"chinese_type_16", 0,16,16,}; FONT_TYPE_T chinese_type_24 = {"chinese_type_24", 0,24,24,}; FONT_TYPE_T chinese_type_32 = {"chinese_type_32", 0,32,32,}; /****************************************************************************** function: Create Image parameter: image : Pointer to the image cache width : The width of the picture Height : The height of the picture Color : Whether the picture is inverted ******************************************************************************/ void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color) { memset(&Paint_info,0,sizeof(Paint_info)); Paint_info.Image = NULL; Paint_info.Image = image; Paint_info.WidthMemory = Width; Paint_info.HeightMemory = Height; Paint_info.Color = Color; Paint_info.Scale = 2; Paint_info.WidthByte = (Width % 8 == 0)? (Width / 8 ): (Width / 8 + 1); Paint_info.HeightByte = Height; // printf("WidthByte = %d, HeightByte = %d\r\n", Paint.WidthByte, Paint.HeightByte); // printf(" EPD_WIDTH / 8 = %d\r\n", 122 / 8); Paint_info.Rotate = Rotate; Paint_info.Mirror = MIRROR_NONE;//MIRROR_NONE; if(Rotate == ROTATE_0 || Rotate == ROTATE_180) { Paint_info.Width = Width; Paint_info.Height = Height; } else { Paint_info.Width = Height; Paint_info.Height = Width; } } /****************************************************************************** function: Select Image parameter: image : Pointer to the image cache ******************************************************************************/ void Paint_SelectImage(UBYTE *image) { Paint_info.Image = image; } /****************************************************************************** function: Select Image Rotate parameter: Rotate : 0,90,180,270 ******************************************************************************/ void Paint_SetRotate(UWORD Rotate) { if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) { Debug("Set image Rotate %d\r\n", Rotate); Paint_info.Rotate = Rotate; } else { Debug("rotate = 0, 90, 180, 270\r\n"); } } void Paint_SetScale(UBYTE scale) { if(scale == 2){ Paint_info.Scale = scale; Paint_info.WidthByte = (Paint_info.WidthMemory % 8 == 0)? (Paint_info.WidthMemory / 8 ): (Paint_info.WidthMemory / 8 + 1); }else if(scale == 4){ Paint_info.Scale = scale; Paint_info.WidthByte = (Paint_info.WidthMemory % 4 == 0)? (Paint_info.WidthMemory / 4 ): (Paint_info.WidthMemory / 4 + 1); }else if(scale == 7){//Only applicable with 5in65 e-Paper Paint_info.Scale = scale; Paint_info.WidthByte = (Paint_info.WidthMemory % 2 == 0)? (Paint_info.WidthMemory / 2 ): (Paint_info.WidthMemory / 2 + 1);; }else{ Debug("Set Scale Input parameter error\r\n"); Debug("Scale Only support: 2 4 7\r\n"); } } /****************************************************************************** function: Select Image mirror parameter: mirror :Not mirror,Horizontal mirror,Vertical mirror,Origin mirror ******************************************************************************/ void Paint_SetMirroring(UBYTE mirror) { if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL || mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) { Debug("mirror image x:%s, y:%s\r\n",(mirror & 0x01)? "mirror":"none", ((mirror >> 1) & 0x01)? "mirror":"none"); Paint_info.Mirror = mirror; } else { Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \ MIRROR_VERTICAL or MIRROR_ORIGIN\r\n"); } } /****************************************************************************** function: Draw Pixels parameter: Xpoint : At point X Ypoint : At point Y Color : Painted colors ******************************************************************************/ void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color ) { if(Xpoint > Paint_info.Width || Ypoint > Paint_info.Height){ Debug("Exceeding display boundaries\r\n"); return; } UWORD X, Y; switch(Paint_info.Rotate) { case 0: X = Xpoint; Y = Ypoint; break; case 90: X = Paint_info.WidthMemory - Ypoint - 1; Y = Xpoint; break; case 180: X = Paint_info.WidthMemory - Xpoint - 1; Y = Paint_info.HeightMemory - Ypoint - 1; break; case 270: X = Ypoint; Y = Paint_info.HeightMemory - Xpoint - 1; break; default: return; } switch(Paint_info.Mirror) { case MIRROR_NONE: break; case MIRROR_HORIZONTAL: X = Paint_info.WidthMemory - X - 1; break; case MIRROR_VERTICAL: Y = Paint_info.HeightMemory - Y - 1; break; case MIRROR_ORIGIN: X = Paint_info.WidthMemory - X - 1; Y = Paint_info.HeightMemory - Y - 1; break; default: return; } if(X > Paint_info.WidthMemory || Y > Paint_info.HeightMemory){ Debug("Exceeding display boundaries\r\n"); return; } if(Paint_info.Scale == 2){ UDOUBLE Addr = X / 8 + Y * Paint_info.WidthByte; if(Addr>(Paint_info.WidthMemory*Paint_info.HeightMemory)){ printf("------数组溢出-----------\n"); return; } UBYTE Rdata = Paint_info.Image[Addr]; if(Color == BLACK) Paint_info.Image[Addr] = Rdata & ~(0x80 >> (X % 8)); else Paint_info.Image[Addr] = Rdata | (0x80 >> (X % 8)); }else if(Paint_info.Scale == 4){ UDOUBLE Addr = X / 4 + Y * Paint_info.WidthByte; Color = Color % 4;//Guaranteed color scale is 4 --- 0~3 UBYTE Rdata = Paint_info.Image[Addr]; Rdata = Rdata & (~(0xC0 >> ((X % 4)*2))); Paint_info.Image[Addr] = Rdata | ((Color << 6) >> ((X % 4)*2)); }else if(Paint_info.Scale == 7){ UDOUBLE Addr = X / 2 + Y * Paint_info.WidthByte; UBYTE Rdata = Paint_info.Image[Addr]; Rdata = Rdata & (~(0xF0 >> ((X % 2)*4)));//Clear first, then set value Paint_info.Image[Addr] = Rdata | ((Color << 4) >> ((X % 2)*4)); //printf("Add = %d ,data = %d\r\n",Addr,Rdata); } } /****************************************************************************** function: Clear the color of the picture parameter: Color : Painted colors ******************************************************************************/ void Paint_Clear(UWORD Color ) { if(Paint_info.Scale == 2) { for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) { for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) {//8 pixel = 1 byte UDOUBLE Addr = X + Y*Paint_info.WidthByte; Paint_info.Image[Addr] = Color; } } }else if(Paint_info.Scale == 4) { for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) { for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) { UDOUBLE Addr = X + Y*Paint_info.WidthByte; Paint_info.Image[Addr] = (Color<<6)|(Color<<4)|(Color<<2)|Color; } } }else if(Paint_info.Scale == 7) { for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) { for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) { UDOUBLE Addr = X + Y*Paint_info.WidthByte; Paint_info.Image[Addr] = (Color<<4)|Color; } } } } /****************************************************************************** function: Clear the color of a window parameter: Xstart : x starting point Ystart : Y starting point Xend : x end point Yend : y end point Color : Painted colors ******************************************************************************/ void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color ) { UWORD X, Y; for (Y = Ystart; Y < Yend; Y++) { for (X = Xstart; X < Xend; X++) {//8 pixel = 1 byte Paint_SetPixel(X, Y, Color ); } } } /****************************************************************************** function: Draw Point(Xpoint, Ypoint) Fill the color parameter: Xpoint : The Xpoint coordinate of the point Ypoint : The Ypoint coordinate of the point Color : Painted color Dot_Pixel : point size Dot_Style : point Style ******************************************************************************/ void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color, DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style ) { if (Xpoint > Paint_info.Width || Ypoint > Paint_info.Height) { Debug("Paint_DrawPoint Input exceeds the normal display range\r\n"); // printf("Xpoint = %d , Paint_info.Width = %d \r\n ",Xpoint .Width); // printf("Ypoint = %d , Paint_info.Height = %d \r\n ",Ypoint .Height); return; } int16_t XDir_Num , YDir_Num; if (Dot_Style == DOT_FILL_AROUND) { for (XDir_Num = 0; XDir_Num < 2 * Dot_Pixel - 1; XDir_Num++) { for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) { if((Xpoint + XDir_Num - Dot_Pixel) < 0 || (Ypoint + YDir_Num - Dot_Pixel) < 0) break; // printf("x = %d, y = %d\r\n", Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel); Paint_SetPixel(Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel, Color ); } } } else { for (XDir_Num = 0; XDir_Num < Dot_Pixel; XDir_Num++) { for (YDir_Num = 0; YDir_Num < Dot_Pixel; YDir_Num++) { Paint_SetPixel(Xpoint + XDir_Num - 1, Ypoint + YDir_Num - 1, Color ); } } } } /****************************************************************************** function: Draw a line of arbitrary slope parameter: Xstart :Starting Xpoint point coordinates Ystart :Starting Xpoint point coordinates Xend :End point Xpoint coordinate Yend :End point Ypoint coordinate Color :The color of the line segment Line_width : Line width Line_Style: Solid and dotted lines ******************************************************************************/ void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color_Background, DOT_PIXEL Line_width, LINE_STYLE Line_Style ) { if (Xstart > Paint_info.Width || Ystart > Paint_info.Height || Xend > Paint_info.Width || Yend > Paint_info.Height) { Debug("Paint_DrawLine Input exceeds the normal display range\r\n"); return; } UWORD Xpoint = Xstart; UWORD Ypoint = Ystart; int dx = (int)Xend - (int)Xstart >= 0 ? Xend - Xstart : Xstart - Xend; int dy = (int)Yend - (int)Ystart <= 0 ? Yend - Ystart : Ystart - Yend; // Increment direction, 1 is positive, -1 is counter; int XAddway = Xstart < Xend ? 1 : -1; int YAddway = Ystart < Yend ? 1 : -1; //Cumulative error int Esp = dx + dy; char Dotted_Len = 0; for (;;) { Dotted_Len++; //Painted dotted line, 2 point is really virtual if (Line_Style == LINE_STYLE_DOTTED && Dotted_Len % 3 == 0) { //Debug("LINE_DOTTED\r\n"); Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT ); Dotted_Len = 0; } else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 4 == 0) { Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT ); } else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 5 == 0) { Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT ); } else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 6 == 0) { Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT ); Dotted_Len = 0; } else { Paint_DrawPoint(Xpoint, Ypoint, Color_Background, Line_width, DOT_STYLE_DFT ); } if (2 * Esp >= dy) { if (Xpoint == Xend) break; Esp += dy; Xpoint += XAddway; } if (2 * Esp <= dx) { if (Ypoint == Yend) break; Esp += dx; Ypoint += YAddway; } } } /****************************************************************************** function: Draw a rectangle parameter: Xstart :Rectangular Starting Xpoint point coordinates Ystart :Rectangular Starting Xpoint point coordinates Xend :Rectangular End point Xpoint coordinate Yend :Rectangular End point Ypoint coordinate Color :The color of the Rectangular segment Line_width: Line width Draw_Fill : Whether to fill the inside of the rectangle ******************************************************************************/ void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color_Background, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill ) { if (Xstart > Paint_info.Width || Ystart > Paint_info.Height || Xend > Paint_info.Width || Yend > Paint_info.Height) { Debug("Input exceeds the normal display range\r\n"); return; } if (Draw_Fill) { UWORD Ypoint; for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) { Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color_Background , Line_width, LINE_STYLE_SOLID ); } } else { Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color_Background, Line_width, LINE_STYLE_SOLID ); Paint_DrawLine(Xstart, Ystart, Xstart, Yend, Color_Background, Line_width, LINE_STYLE_SOLID ); Paint_DrawLine(Xend, Yend, Xend, Ystart, Color_Background, Line_width, LINE_STYLE_SOLID ); Paint_DrawLine(Xend, Yend, Xstart, Yend, Color_Background, Line_width, LINE_STYLE_SOLID ); } } /****************************************************************************** function: Use the 8-point method to draw a circle of the specified size at the specified position-> parameter: X_Center :Center X coordinate Y_Center :Center Y coordinate Radius :circle Radius Color :The color of the :circle segment Line_width: Line width Draw_Fill : Whether to fill the inside of the Circle ******************************************************************************/ void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius, UWORD Color_Background, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill ) { if (X_Center > Paint_info.Width || Y_Center >= Paint_info.Height) { Debug("Paint_DrawCircle Input exceeds the normal display range\r\n"); return; } //Draw a circle from(0, R) as a starting point int16_t XCurrent, YCurrent; XCurrent = 0; YCurrent = Radius; //Cumulative error,judge the next point of the logo int16_t Esp = 3 - (Radius << 1 ); int16_t sCountY; if (Draw_Fill == DRAW_FILL_FULL) { while (XCurrent <= YCurrent ) { //Realistic circles for (sCountY = XCurrent; sCountY <= YCurrent; sCountY ++ ) { Paint_DrawPoint(X_Center + XCurrent, Y_Center + sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//1 Paint_DrawPoint(X_Center - XCurrent, Y_Center + sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//2 Paint_DrawPoint(X_Center - sCountY, Y_Center + XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//3 Paint_DrawPoint(X_Center - sCountY, Y_Center - XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//4 Paint_DrawPoint(X_Center - XCurrent, Y_Center - sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//5 Paint_DrawPoint(X_Center + XCurrent, Y_Center - sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//6 Paint_DrawPoint(X_Center + sCountY, Y_Center - XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//7 Paint_DrawPoint(X_Center + sCountY, Y_Center + XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT ); } if (Esp < 0 ) Esp += 4 * XCurrent + 6; else { Esp += 10 + 4 * (XCurrent - YCurrent ); YCurrent --; } XCurrent ++; } } else { //Draw a hollow circle while (XCurrent <= YCurrent ) { Paint_DrawPoint(X_Center + XCurrent, Y_Center + YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//1 Paint_DrawPoint(X_Center - XCurrent, Y_Center + YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//2 Paint_DrawPoint(X_Center - YCurrent, Y_Center + XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//3 Paint_DrawPoint(X_Center - YCurrent, Y_Center - XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//4 Paint_DrawPoint(X_Center - XCurrent, Y_Center - YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//5 Paint_DrawPoint(X_Center + XCurrent, Y_Center - YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//6 Paint_DrawPoint(X_Center + YCurrent, Y_Center - XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//7 Paint_DrawPoint(X_Center + YCurrent, Y_Center + XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//0 if (Esp < 0 ) Esp += 4 * XCurrent + 6; else { Esp += 10 + 4 * (XCurrent - YCurrent ); YCurrent --; } XCurrent ++; } } } //whc set start void Paint_DrawChar(UWORD Xpoint, UWORD Ypoint, const char Acsii_Char,FONT_TYPE_T* Ascii_type, UWORD Color_Foreground, UWORD Color_Background ) { //ESP_LOGE(LOG_TAG,"DRAW"); UWORD Page = 0, Column = 0; int font_width = 0,font_height = 0;//xpos_offset,ypos_offset, font_width = Ascii_type->Font_Width; font_height = Ascii_type->Font_Height; // switch (Ascii_type) // { // case 1: font_width = 5; font_height = 7; break; // case 2: font_width = 7; font_height = 8;break; // case 3: font_width = 6; font_height = 12;break; // case 4: font_width = 8; font_height = 16;break; // case 5: font_width = 12; font_height =24;break; // case 6: font_width = 12; font_height =24;break; // case 7: font_width = 16; font_height =32;break; // // case 8: font_width = 0; font_height =12;break; // // case 9: font_width = 0; font_height =16;break; // // case 10:font_width = 0; font_height =24;break; // // case 11:font_width = 0; font_height =32;break; // default: // break; // } unsigned char get_data_buf[50] = {}; if (Xpoint > Paint_info.Width || Ypoint > Paint_info.Height) { ESP_LOGE(LOG_TAG,"Paint_DrawChar Input exceeds the normal display range"); return; } ASCII_GetData(Acsii_Char,Ascii_type->Font_lib_type,get_data_buf); const unsigned char *ptr = get_data_buf; // for(int i = 0;i<50;i++) // {ESP_LOGE(LOG_TAG,"%x",ptr[i]);} // ESP_LOGE(LOG_TAG,"P"); for (Page = 0; Page < font_height; Page ++ ) { for (Column = 0; Column < font_width; Column ++ ) { //To determine whether the font background color and screen background color is consistent if (FONT_BACKGROUND == Color_Foreground) { //this process is to speed up the scan if (*ptr & (0x80 >> (Column % 8))) Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { if (*ptr & (0x80 >> (Column % 8))) { Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT); } } //One pixel is 8 bits if (Column % 8 == 7) ptr++; }// Write a line if (font_width% 8 != 0) ptr++; }// Write all } void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T* Ascii_type, UWORD Color_Foreground, UWORD Color_Background ) { UWORD Xpoint = Xstart; UWORD Ypoint = Ystart; int font_width = 0,font_height = 0; font_width = Ascii_type->Font_Width; font_height = Ascii_type->Font_Height; if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) { Debug("Paint_DrawString_EN Input exceeds the normal display range\r\n"); return; } while (* pString != '\0') { //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character if ((Xpoint + font_width ) > Paint_info.Width ) { Xpoint = Xstart; Ypoint += font_height; } // If the Y direction is full, reposition to(Xstart, Ystart) if ((Ypoint + font_height ) > Paint_info.Height ) { Xpoint = Xstart; Ypoint = Ystart; } Paint_DrawChar(Xpoint, Ypoint, * pString, Ascii_type, Color_Foreground, Color_Background ); //The next character of the address pString ++; //The next word of the abscissa increases the font of the broadband Xpoint += font_width; } } void Paint_DrawChar_CN48(UWORD Xstart, UWORD Ystart, const char * pString ) { #define FONT_SIZE_24 24 // 放大后的64x64点阵字库 #define ENLARGED_FONT_SIZE_48 48 const char* p_text = pString; unsigned char enlarged_font[48*48/8] = {}; unsigned char font[24*24/8] = {}; //ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2); if(*pString>0x80) { GBK_24_GetData(*p_text, *(p_text+1), font); } else { ASCII_GetData(*(p_text),ASCII_24_N,font); } double scale = (double)ENLARGED_FONT_SIZE_48 / FONT_SIZE_24; for (int y = 0; y < ENLARGED_FONT_SIZE_48; y++) { for (int x = 0; x < ENLARGED_FONT_SIZE_48; x++) { double x0 = x / scale; double y0 = y / scale; int x1 = (int)x0; int y1 = (int)y0; int x2 = x1 + 1; int y2 = y1 + 1; if (x2 >= FONT_SIZE_24) x2 = FONT_SIZE_24 - 1; if (y2 >= FONT_SIZE_24) y2 = FONT_SIZE_24 - 1; double dx = x0 - x1; double dy = y0 - y1; unsigned char q11 = (font[y1 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q21 = (font[y1 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; unsigned char q12 = (font[y2 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q22 = (font[y2 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 + (1 - dx) * dy * q12 + dx * dy * q22; int index = y * ENLARGED_FONT_SIZE_48 + x; if (interpolated_value >= 0.5) { enlarged_font[index / 8] |= (1 << (7 - (index % 8))); } else { enlarged_font[index / 8] &= ~(1 << (7 - (index % 8))); } } } int Xpoint = Xstart, Ypoint = Ystart; const unsigned char *ptr = enlarged_font; UWORD Page = 0, Column = 0; for (Page = 0; Page < ENLARGED_FONT_SIZE_48; Page ++ ) { for (Column = 0; Column < ENLARGED_FONT_SIZE_48; Column ++ ) { //To determine whether the font background color and screen background color is consistent if (FONT_BACKGROUND == WHITE) { //this process is to speed up the scan if (*ptr & (0x80 >> (Column % 8))) Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { if (*ptr & (0x80 >> (Column % 8))) { Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT); } } //One pixel is 8 bits if (Column % 8 == 7) ptr++; }// Write a line if (ENLARGED_FONT_SIZE_48% 8 != 0) ptr++; }// Write all } void Paint_DrawChar_CN48_black(UWORD Xstart, UWORD Ystart, const char * pString )//原来扩大是黑底白字Paint_DrawChar_CN48_black为白底黑字 { #define FONT_SIZE_24 24 // 放大后的64x64点阵字库 #define ENLARGED_FONT_SIZE_48 48 const char* p_text = pString; unsigned char enlarged_font[48*48/8] = {}; unsigned char font[24*24/8] = {}; //ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2); if(*pString>0x80) { GBK_24_GetData(*p_text, *(p_text+1), font); } else { ASCII_GetData(*(p_text),ASCII_24_N,font); } double scale = (double)ENLARGED_FONT_SIZE_48 / FONT_SIZE_24; for (int y = 0; y < ENLARGED_FONT_SIZE_48; y++) { for (int x = 0; x < ENLARGED_FONT_SIZE_48; x++) { double x0 = x / scale; double y0 = y / scale; int x1 = (int)x0; int y1 = (int)y0; int x2 = x1 + 1; int y2 = y1 + 1; if (x2 >= FONT_SIZE_24) x2 = FONT_SIZE_24 - 1; if (y2 >= FONT_SIZE_24) y2 = FONT_SIZE_24 - 1; double dx = x0 - x1; double dy = y0 - y1; unsigned char q11 = (font[y1 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q21 = (font[y1 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; unsigned char q12 = (font[y2 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q22 = (font[y2 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 + (1 - dx) * dy * q12 + dx * dy * q22; int index = y * ENLARGED_FONT_SIZE_48 + x; if (interpolated_value >= 0.5) { enlarged_font[index / 8] |= (1 << (7 - (index % 8))); } else { enlarged_font[index / 8] &= ~(1 << (7 - (index % 8))); } } } int Xpoint = Xstart, Ypoint = Ystart; const unsigned char *ptr = enlarged_font; UWORD Page = 0, Column = 0; for (Page = 0; Page < ENLARGED_FONT_SIZE_48; Page ++ ) { for (Column = 0; Column < ENLARGED_FONT_SIZE_48; Column ++ ) { //To determine whether the font background color and screen background color is consistent if (FONT_BACKGROUND == BLACK) { //this process is to speed up the scan if (*ptr & (0x80 >> (Column % 8))) Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { if (*ptr & (0x80 >> (Column % 8))) { Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT); } } //One pixel is 8 bits if (Column % 8 == 7) ptr++; }// Write a line if (ENLARGED_FONT_SIZE_48% 8 != 0) ptr++; }// Write all } void Paint_DrawChar_CN64(UWORD Xstart, UWORD Ystart, const char * pString ) { #define FONT_SIZE 32 // 放大后的64x64点阵字库 #define ENLARGED_FONT_SIZE 64 const char* p_text = pString; unsigned char enlarged_font[64*64/8] = {}; unsigned char font[32*32/8] = {}; // ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2); if(*pString>0x80) { //ESP_LOGW(LOG_TAG,"汉字"); GBK_32_GetData(*p_text, *(p_text+1), font); } else { //ESP_LOGW(LOG_TAG,"ASCII"); ASCII_GetData(*(p_text),ASCII_32_N,font); } double scale = (double)ENLARGED_FONT_SIZE / FONT_SIZE; for (int y = 0; y < ENLARGED_FONT_SIZE; y++) { for (int x = 0; x < ENLARGED_FONT_SIZE; x++) { double x0 = x / scale; double y0 = y / scale; int x1 = (int)x0; int y1 = (int)y0; int x2 = x1 + 1; int y2 = y1 + 1; if (x2 >= FONT_SIZE) x2 = FONT_SIZE - 1; if (y2 >= FONT_SIZE) y2 = FONT_SIZE - 1; double dx = x0 - x1; double dy = y0 - y1; unsigned char q11 = (font[y1 * (FONT_SIZE / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q21 = (font[y1 * (FONT_SIZE / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; unsigned char q12 = (font[y2 * (FONT_SIZE / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1; unsigned char q22 = (font[y2 * (FONT_SIZE / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1; double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 + (1 - dx) * dy * q12 + dx * dy * q22; int index = y * ENLARGED_FONT_SIZE + x; if (interpolated_value >= 0.5) { enlarged_font[index / 8] |= (1 << (7 - (index % 8))); } else { enlarged_font[index / 8] &= ~(1 << (7 - (index % 8))); } } } int Xpoint = Xstart, Ypoint = Ystart; const unsigned char *ptr = enlarged_font; UWORD Page = 0, Column = 0; for (Page = 0; Page < ENLARGED_FONT_SIZE; Page ++ ) { for (Column = 0; Column < ENLARGED_FONT_SIZE; Column ++ ) { //To determine whether the font background color and screen background color is consistent if (FONT_BACKGROUND == WHITE) { //this process is to speed up the scan if (*ptr & (0x80 >> (Column % 8))) Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { if (*ptr & (0x80 >> (Column % 8))) { Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT); } else { Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE ); // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT); } } //One pixel is 8 bits if (Column % 8 == 7) ptr++; }// Write a line if (ENLARGED_FONT_SIZE% 8 != 0) ptr++; }// Write all } void Paint_DrawChar_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T* chinese_type, UWORD Color_Foreground, UWORD Color_Background ) { const char* p_text = pString; int Xpoint = Xstart, Ypoint = Ystart; int font_width = 0,font_height = 0; unsigned char get_chinese_data_buf[32*4] = {}; font_width = chinese_type->Font_Width; font_height = chinese_type->Font_Height; switch (chinese_type->Font_Width) { //case CHINESE_TYPE_12: font_width = 12; font_height = 12; break; case 16: { GB2312_16_GetData(*p_text, *(p_text+1), get_chinese_data_buf); }break; case 24: { GBK_24_GetData(*p_text, *(p_text+1), get_chinese_data_buf); }break; case 32: { GBK_32_GetData(*p_text, *(p_text+1), get_chinese_data_buf); }break; default: break; } // for(int i=0;i<32*4;i++) // { // printf("%02x ",get_chinese_data_buf[i]); // } // printf("\n-------------------------\n"); const unsigned char *ptr = get_chinese_data_buf; UWORD Page = 0, Column = 0; for (Page = 0; Page < font_height; Page ++ ) { for (Column = 0; Column < font_width; Column ++ ) { //To determine whether the font background color and screen background color is consistent if (FONT_BACKGROUND == Color_Foreground) { //this process is to speed up the scan if (*ptr & (0x80 >> (Column % 8))) Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background ); } else { if (*ptr & (0x80 >> (Column % 8))) { Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background ); } else { Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground ); } } //One pixel is 8 bits if (Column % 8 == 7) ptr++; }// Write a line if (font_width% 8 != 0) ptr++; }// Write all } void Paint_DrawString_CN48(UWORD Xstart, UWORD Ystart, const char * pString , int is_black) { UWORD Xpoint = Xstart; UWORD Ypoint = Ystart; if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) { Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n"); return; } //ESP_LOGW(LOG_TAG,"------CN64--len =%d --:%s--",strlen(pString),pString); // while (((* pString != '\0')&&(* (pString + 1) != '\0'))||((* pString == '\0')&&(* (pString + 1) != '\0'))){ while (* pString != '\0'){ //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character if ((Xpoint + 48 ) > Paint_info.Width ) { Xpoint = Xstart; Ypoint += 48; } //ESP_LOGW(LOG_TAG,"------6464------"); // If the Y direction is full, reposition to(Xstart, Ystart) if ((Ypoint + 48 ) > Paint_info.Height ) { Xpoint = Xstart; Ypoint = Ystart; } if(*pString >0x80) { if(!is_black) Paint_DrawChar_CN48(Xpoint, Ypoint, pString); else Paint_DrawChar_CN48_black(Xpoint, Ypoint, pString); //The next character of the address pString ++; pString ++; //The next word of the abscissa increases the font of the broadband Xpoint += 48; } else//ascii { if(!is_black) Paint_DrawChar_CN48(Xpoint, Ypoint, pString); else Paint_DrawChar_CN48_black(Xpoint, Ypoint, pString); //The next character of the address pString ++; //The next word of the abscissa increases the font of the broadband Xpoint += 48; } } } void Paint_DrawString_CN64(UWORD Xstart, UWORD Ystart, const char * pString ) { UWORD Xpoint = Xstart; UWORD Ypoint = Ystart; if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) { Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n"); return; } //ESP_LOGW(LOG_TAG,"------CN64--len =%d --:%s--",strlen(pString),pString); // while (((* pString != '\0')&&(* (pString + 1) != '\0'))||((* pString == '\0')&&(* (pString + 1) != '\0'))){ while (* pString != '\0'){ //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character if ((Xpoint + 64 ) > Paint_info.Width ) { Xpoint = Xstart; Ypoint += 64; } //ESP_LOGW(LOG_TAG,"------6464------"); // If the Y direction is full, reposition to(Xstart, Ystart) if ((Ypoint + 64 ) > Paint_info.Height ) { Xpoint = Xstart; Ypoint = Ystart; } if(*pString >0x80) { Paint_DrawChar_CN64(Xpoint, Ypoint, pString ); //The next character of the address pString ++; pString ++; //The next word of the abscissa increases the font of the broadband Xpoint += 64; } else//ascii { Paint_DrawChar_CN64(Xpoint, Ypoint, pString ); //The next character of the address pString ++; //The next word of the abscissa increases the font of the broadband Xpoint += 64; } } } void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T* chinese_type, UWORD Color_Foreground, UWORD Color_Background ) { UWORD Xpoint = Xstart; UWORD Ypoint = Ystart; int font_width = 0,font_height = 0; font_width = chinese_type->Font_Width; font_height = chinese_type->Font_Height; if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) { Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n"); return; } while ((* pString != '\0') || (* (pString+1) != '\0')) { //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character if ((Xpoint + font_width ) > Paint_info.Width ) { Xpoint = Xstart; Ypoint += font_height; } // If the Y direction is full, reposition to(Xstart, Ystart) if ((Ypoint + font_height ) > Paint_info.Height ) { Xpoint = Xstart; Ypoint = Ystart; } #if 0 if(((*(pString +1))== '\0') && ((* pString)<0x80)) #else if(((* pString)<0x80)) #endif { font_width = chinese_type->Font_Width; font_height = chinese_type->Font_Height; #if 0 FONT_TYPE_T ascii_type_5x7 = {"ascii_type_5x7",ASCII_5X7,5,7,}; FONT_TYPE_T ascii_type_7x8 ={"ascii_type_7x8",ASCII_7X8,7,8,}; FONT_TYPE_T ascii_type_6x12 ={"ascii_type_6x12",ASCII_6X12,6,12,}; FONT_TYPE_T ascii_type_8x16 ={"ascii_type_8x16",ASCII_8X16,8,16,}; FONT_TYPE_T ascii_type_12x24 ={"ascii_type_12x24",ASCII_12X24,12,24,}; FONT_TYPE_T ascii_type_12x24_b ={"ascii_type_12x24_b",ASCII_12X24_B,12,24,}; FONT_TYPE_T ascii_type_16x32 ={"ascii_type_16x32",ASCII_16X32,16,32,}; #endif switch(font_height) { case 8: Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_7x8, Color_Foreground, Color_Background); break; case 16: Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_8x16, Color_Foreground, Color_Background); break; case 24: //printf(""); Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_12x24, Color_Foreground, Color_Background); break; case 32: Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_16x32, Color_Foreground, Color_Background); break; } Xpoint += font_width/2; pString ++; } else { Paint_DrawChar_CN(Xpoint, Ypoint, pString, chinese_type, Color_Foreground, Color_Background); Xpoint += font_width; //The next character of the address pString ++; pString ++; } //The next word of the abscissa increases the font of the broadband } } // void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T chinese_type, // UWORD Color_Foreground, UWORD Color_Background) // { // } //whc set end /****************************************************************************** function: Display time parameter: Xstart :X coordinate Ystart : Y coordinate pTime : Time-related structures Font :A structure pointer that displays a character size Color_Foreground : Select the foreground color Color_Background : Select the background color ******************************************************************************/ void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, FONT_TYPE_T* Font_type, UWORD Color_Foreground, UWORD Color_Background ) { uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; UWORD Dx = Font_type->Font_Width; //Write data into the cache // Paint_DrawChar(Xstart , Ystart, value[pTime->Hour / 10], Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->Hour % 10], Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx + Dx / 4 + Dx / 2 , Ystart, ':' , Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx * 2 + Dx / 2 , Ystart, value[pTime->Min / 10] , Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx * 3 + Dx / 2 , Ystart, value[pTime->Min % 10] , Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx * 4 + Dx / 2 - Dx / 4, Ystart, ':' , Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx * 5 , Ystart, value[pTime->Sec / 10] , Font_type, Color_Foreground, Color_Background ); // Paint_DrawChar(Xstart + Dx * 6 , Ystart, value[pTime->Sec % 10] , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart , Ystart, value[pTime->Hour / 10], Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->Hour % 10], Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 2 , Ystart, ':' , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 3 , Ystart, value[pTime->Min / 10] , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 4 , Ystart, value[pTime->Min % 10] , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 5 , Ystart, ':' , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 6 , Ystart, value[pTime->Sec / 10] , Font_type, Color_Foreground, Color_Background ); Paint_DrawChar(Xstart + Dx * 7 , Ystart, value[pTime->Sec % 10] , Font_type, Color_Foreground, Color_Background ); } /****************************************************************************** function: Display monochrome bitmap parameter: image_buffer :A picture data converted to a bitmap info: Use a computer to convert the image into a corresponding array, and then embed the array directly into Imagedata.cpp as a .c file. ******************************************************************************/ void Paint_DrawBitMap(const unsigned char* image_buffer ) { UWORD x, y; UDOUBLE Addr = 0; for (y = 0; y < Paint_info.HeightByte; y++) { for (x = 0; x < Paint_info.WidthByte; x++) {//8 pixel = 1 byte Addr = x + y * Paint_info.WidthByte; Paint_info.Image[Addr] = (unsigned char)image_buffer[Addr]; } } } /****************************************************************************** function: Paint_DrawBitMap_Vertical 垂直对称显示背景图片 parameter: image_buffer :A picture data converted to a bitmap info: Use a computer to convert the image into a corresponding array, and then embed the array directly into Imagedata.cpp as a .c file. ******************************************************************************/ void Paint_DrawBitMap_Vertical(const unsigned char* image_buffer ) { uint8_t temp_buffer[648/8]={0}; UWORD x, y; for(y = 0; y < Paint_info.HeightByte; y++) { memcpy(temp_buffer,(unsigned char*)&image_buffer[(Paint_info.HeightByte - y)*Paint_info.WidthByte],648/8); //Paint.Image[Addr] = (unsigned char)image_buffer[Addr]; memcpy(&Paint_info.Image[y*Paint_info.WidthByte],temp_buffer,648/8); } } /****************************************************************************** function: paste monochrome bitmap to a frame buff parameter: image_buffer :A picture data converted to a bitmap xStart: The starting x coordinate yStart: The starting y coordinate imageWidth: Original image width imageHeight: Original image height flipColor: Whether the color is reversed info: Use this function to paste image data into a buffer ******************************************************************************/ void Paint_DrawBitMap_Paste(const unsigned char* image_buffer, UWORD xStart, UWORD yStart, UWORD imageWidth, UWORD imageHeight, UBYTE flipColor ) { UBYTE color, srcImage; UWORD x, y; UWORD width = (imageWidth%8==0 ? imageWidth/8 : imageWidth/8+1); for (y = 0; y < imageHeight; y++) { for (x = 0; x < imageWidth; x++) { srcImage = image_buffer[y*width + x/8]; if(flipColor) color = (((srcImage<<(x%8) & 0x80) == 0) ? 0xff : 0x00); else color = (((srcImage<<(x%8) & 0x80) == 0) ? 0 : 0xff); Paint_SetPixel(x+xStart, y+yStart, color ); } } } void Paint_DrawBitMap_Paste_t(const unsigned char* image_buffer, UWORD xStart, UWORD yStart, UWORD imageWidth, UWORD imageHeight, UBYTE flipColor ) { int i=0; UBYTE color, srcImage; UWORD x, y; UWORD width = (imageWidth%8==0 ? imageWidth/8 : imageWidth/8+1); for (y = 0; y < imageHeight; y++) { for (x = 0; x < imageWidth; x++) { srcImage = image_buffer[y*width + x/8]; if(flipColor) color = (((srcImage<<(x%8) & 0x80) == 0) ? 0xff : 0x00); else color = (((srcImage<<(x%8) & 0x80) == 0) ? 0 : 0xff); printf("%02x ",color); i++; Paint_SetPixel(x+xStart, y+yStart, color ); } } printf("[%d]\n",i); } ///****************************************************************************** //function: SDisplay half of monochrome bitmap //parameter: // Region : 1 Upper half // 2 Lower half //info: //******************************************************************************/ //void Paint_DrawBitMap_Half(const unsigned char* image_buffer, UBYTE Region) //{ // UWORD x, y; // UDOUBLE Addr = 0; // // if(Region == 1){ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte; // Paint.Image[Addr] = (unsigned char)image_buffer[Addr]; // } // } // }else{ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte ; // Paint.Image[Addr] = // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte]; // } // } // } //} ///****************************************************************************** //function: SDisplay half of monochrome bitmap //parameter: // Region : 1 Upper half // 2 Lower half //info: //******************************************************************************/ //void Paint_DrawBitMap_OneQuarter(const unsigned char* image_buffer, UBYTE Region) //{ // UWORD x, y; // UDOUBLE Addr = 0; // // if(Region == 1){ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte; // Paint.Image[Addr] = (unsigned char)image_buffer[Addr]; // } // } // }else if(Region == 2){ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte ; // Paint.Image[Addr] = // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte]; // } // } // }else if(Region == 3){ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte ; // Paint.Image[Addr] = // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*2]; // } // } // }else if(Region == 4){ // for (y = 0; y < Paint.HeightByte; y++) { // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte // Addr = x + y * Paint.WidthByte ; // Paint.Image[Addr] = // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*3]; // } // } // } //} void Paint_DrawBitMap_Block(const unsigned char* image_buffer, UBYTE Region ) { UWORD x, y; UDOUBLE Addr = 0; for (y = 0; y < Paint_info.HeightByte; y++) { for (x = 0; x < Paint_info.WidthByte; x++) {//8 pixel = 1 byte Addr = x + y * Paint_info.WidthByte ; Paint_info.Image[Addr] = \ (unsigned char)image_buffer[Addr+ (Paint_info.HeightByte)*Paint_info.WidthByte*(Region - 1)]; } } } void drawQuadraticBezierCurve(uint8_t* framebuffer, int width, int height, int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, int thickness) { // 使用二次贝塞尔曲线算法计算曲线上的点并绘制 for (double t = 0; t <= 1.0; t += 0.01) { double u = 1.0 - t; double tt = t * t; double uu = u * u; double ut = u * t; int x = (int)(uu * x0 + 2 * ut * x1 + tt * x2); int y = (int)(uu * y0 + 2 * ut * y1 + tt * y2); // 绘制线条 for (int i = -thickness / 2; i <= thickness / 2; i++) { for (int j = -thickness / 2; j <= thickness / 2; j++) { int currentX = x + i; int currentY = y + j; // 检查点是否在屏幕范围内 if (currentX >= 0 && currentX < width && currentY >= 0 && currentY < height) { // 计算帧缓冲中的字节和位偏移 int byteOffset = (currentY * width + currentX) / 8; int bitOffset = (currentY * width + currentX) % 8; // 根据颜色设置像素值 if (color) { framebuffer[byteOffset] |= (0x80 >> bitOffset); } else { framebuffer[byteOffset] &= ~(0x80 >> bitOffset); } } } } } } #include "math.h" void drawQuadraticBezierCurve_do(uint8_t* framebuffer, int width, int height, int x0, int y0, int x1, int y1, int x2, int y2, uint8_t color, int thickness) { // 使用二次贝塞尔曲线算法计算曲线上的点并绘制 for (double t = 0; t <= 1.0; t += 0.01) { double u = 1.0 - t; double tt = t * t; double uu = u * u; double ut = u * t; int x = (int)(uu * x0 + 2 * ut * x1 + tt * x2); int y = (int)(uu * y0 + 2 * ut * y1 + tt * y2); // 绘制线条 for (int i = -thickness / 2; i <= thickness / 2; i++) { for (int j = -thickness / 2; j <= thickness / 2; j++) { int currentX = x + i; int currentY = y + j; // 检查点是否在屏幕范围内 if (currentX >= 0 && currentX < width && currentY >= 0 && currentY < height) { // 计算帧缓冲中的字节和位偏移 int byteOffset = (currentY * width + currentX) / 8; int bitOffset = (currentY * width + currentX) % 8; // 根据颜色设置像素值 if (color) { framebuffer[byteOffset] |= (0x80 >> bitOffset); } else { framebuffer[byteOffset] &= ~(0x80 >> bitOffset); } if (abs(x - (uu * x0 + 2 * ut * x1 + tt * x2)) > 1 || abs(y - (uu * y0 + 2 * ut * y1 + tt * y2)) > 1) { ESP_LOGW(LOG_TAG,"---abs"); int byteOffset = (y * width + x) / 8; int bitOffset = (y * width + x) % 8; if (color) { framebuffer[byteOffset] &= ~(0x80 >> bitOffset); } else { framebuffer[byteOffset] |= (0x80 >> bitOffset); } } } } } } }