| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456 | /******************************************************************************* | 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 <stdint.h>#include <stdlib.h>#include <string.h> //memset()#include <math.h>#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 Imageparameter:    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 Imageparameter:    image : Pointer to the image cache******************************************************************************/void Paint_SelectImage(UBYTE *image){    Paint_info.Image = image;}/******************************************************************************function: Select Image Rotateparameter:    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 mirrorparameter:    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 Pixelsparameter:    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 pictureparameter:    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 windowparameter:    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 colorparameter:    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 slopeparameter:    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 rectangleparameter:    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 0FONT_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 timeparameter:    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 bitmapparameter:    image_buffer :A picture data converted to a bitmapinfo:    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 bitmapinfo:    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 buffparameter:    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 reversedinfo:    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);                          }                      }                }            }        }    }}
 |