GUI_Paint.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. /******************************************************************************
  2. * | File : GUI_Paint.c
  3. * | Author : Waveshare electronics
  4. * | Function : Achieve drawing: draw points, lines, boxes, circles and
  5. * their size, solid dotted line, solid rectangle hollow
  6. * rectangle, solid circle hollow circle.
  7. * | Info :
  8. * Achieve display characters: Display a single character, string, number
  9. * Achieve time display: adaptive size display time minutes and seconds
  10. *----------------
  11. * | This version: V3.1
  12. * | Date : 2020-07-08
  13. * | Info :
  14. * -----------------------------------------------------------------------------
  15. * V3.1(2020-07-08):
  16. * 1.Change: Paint_SetScale(UBYTE scale)
  17. * Add scale 7 for 5.65f e-Parper
  18. * 2.Change: Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color)
  19. * Add the branch for scale 7
  20. * 3.Change: Paint_Clear(UWORD Color)
  21. * Add the branch for scale 7
  22. *
  23. * -----------------------------------------------------------------------------
  24. * V3.0(2019-04-18):
  25. * 1.Change:
  26. * Paint_DrawPoint(..., DOT_STYLE DOT_STYLE)
  27. * => Paint_DrawPoint(..., DOT_STYLE Dot_Style)
  28. * Paint_DrawLine(..., LINE_STYLE Line_Style, DOT_PIXEL Dot_Pixel)
  29. * => Paint_DrawLine(..., DOT_PIXEL Line_width, LINE_STYLE Line_Style)
  30. * Paint_DrawRectangle(..., DRAW_FILL Filled, DOT_PIXEL Dot_Pixel)
  31. * => Paint_DrawRectangle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Fill)
  32. * Paint_DrawCircle(..., DRAW_FILL Draw_Fill, DOT_PIXEL Dot_Pixel)
  33. * => Paint_DrawCircle(..., DOT_PIXEL Line_width, DRAW_FILL Draw_Filll)
  34. *
  35. * -----------------------------------------------------------------------------
  36. * V2.0(2018-11-15):
  37. * 1.add: Paint_NewImage()
  38. * Create an image's properties
  39. * 2.add: Paint_SelectImage()
  40. * Select the picture to be drawn
  41. * 3.add: Paint_SetRotate()
  42. * Set the direction of the cache
  43. * 4.add: Paint_RotateImage()
  44. * Can flip the picture, Support 0-360 degrees,
  45. * but only 90.180.270 rotation is better
  46. * 4.add: Paint_SetMirroring()
  47. * Can Mirroring the picture, horizontal, vertical, origin
  48. * 5.add: Paint_DrawString_CN()
  49. * Can display Chinese(GB1312)
  50. *
  51. * -----------------------------------------------------------------------------
  52. * V1.0(2018-07-17):
  53. * Create library
  54. *
  55. * Permission is hereby granted, free of charge, to any person obtaining a copy
  56. * of this software and associated documnetation files (the "Software"), to deal
  57. * in the Software without restriction, including without limitation the rights
  58. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  59. * copies of the Software, and to permit persons to whom the Software is
  60. * furished to do so, subject to the following conditions:
  61. *
  62. * The above copyright notice and this permission notice shall be included in
  63. * all copies or substantial portions of the Software.
  64. *
  65. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  66. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  67. * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  68. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  69. * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  70. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  71. * THE SOFTWARE.
  72. *
  73. ******************************************************************************/
  74. #include "GUI_Paint.h"
  75. // #include "DEV_Config.h"
  76. #include "esp_log.h"
  77. #include <stdint.h>
  78. #include <stdlib.h>
  79. #include <string.h> //memset()
  80. #include <math.h>
  81. #include "GT5DL32A3W.h"
  82. static const char *LOG_TAG = "GUI_PAINT";
  83. PAINT Paint_info;
  84. PAINT_TIME Paint_time_info;
  85. FONT_TYPE_T ascii_type_5x7 = {"ascii_type_5x7",ASCII_5X7,5,7,};
  86. FONT_TYPE_T ascii_type_7x8 ={"ascii_type_7x8",ASCII_7X8,7,8,};
  87. FONT_TYPE_T ascii_type_6x12 ={"ascii_type_6x12",ASCII_6X12,6,12,};
  88. FONT_TYPE_T ascii_type_8x16 ={"ascii_type_8x16",ASCII_8X16,8,16,};
  89. FONT_TYPE_T ascii_type_12x24 ={"ascii_type_12x24",ASCII_12X24,12,24,};
  90. FONT_TYPE_T ascii_type_12x24_b ={"ascii_type_12x24_b",ASCII_12X24_B,12,24,};
  91. FONT_TYPE_T ascii_type_16x32 ={"ascii_type_16x32",ASCII_16X32,16,32,};
  92. FONT_TYPE_T chinese_type_12 ={"chinese_type_12", 0,12,12,};
  93. FONT_TYPE_T chinese_type_16 = {"chinese_type_16", 0,16,16,};
  94. FONT_TYPE_T chinese_type_24 = {"chinese_type_24", 0,24,24,};
  95. FONT_TYPE_T chinese_type_32 = {"chinese_type_32", 0,32,32,};
  96. /******************************************************************************
  97. function: Create Image
  98. parameter:
  99. image : Pointer to the image cache
  100. width : The width of the picture
  101. Height : The height of the picture
  102. Color : Whether the picture is inverted
  103. ******************************************************************************/
  104. void Paint_NewImage(UBYTE *image, UWORD Width, UWORD Height, UWORD Rotate, UWORD Color)
  105. {
  106. memset(&Paint_info,0,sizeof(Paint_info));
  107. Paint_info.Image = NULL;
  108. Paint_info.Image = image;
  109. Paint_info.WidthMemory = Width;
  110. Paint_info.HeightMemory = Height;
  111. Paint_info.Color = Color;
  112. Paint_info.Scale = 2;
  113. Paint_info.WidthByte = (Width % 8 == 0)? (Width / 8 ): (Width / 8 + 1);
  114. Paint_info.HeightByte = Height;
  115. // printf("WidthByte = %d, HeightByte = %d\r\n", Paint.WidthByte, Paint.HeightByte);
  116. // printf(" EPD_WIDTH / 8 = %d\r\n", 122 / 8);
  117. Paint_info.Rotate = Rotate;
  118. Paint_info.Mirror = MIRROR_NONE;//MIRROR_NONE;
  119. if(Rotate == ROTATE_0 || Rotate == ROTATE_180) {
  120. Paint_info.Width = Width;
  121. Paint_info.Height = Height;
  122. } else {
  123. Paint_info.Width = Height;
  124. Paint_info.Height = Width;
  125. }
  126. }
  127. /******************************************************************************
  128. function: Select Image
  129. parameter:
  130. image : Pointer to the image cache
  131. ******************************************************************************/
  132. void Paint_SelectImage(UBYTE *image)
  133. {
  134. Paint_info.Image = image;
  135. }
  136. /******************************************************************************
  137. function: Select Image Rotate
  138. parameter:
  139. Rotate : 0,90,180,270
  140. ******************************************************************************/
  141. void Paint_SetRotate(UWORD Rotate)
  142. {
  143. if(Rotate == ROTATE_0 || Rotate == ROTATE_90 || Rotate == ROTATE_180 || Rotate == ROTATE_270) {
  144. Debug("Set image Rotate %d\r\n", Rotate);
  145. Paint_info.Rotate = Rotate;
  146. } else {
  147. Debug("rotate = 0, 90, 180, 270\r\n");
  148. }
  149. }
  150. void Paint_SetScale(UBYTE scale)
  151. {
  152. if(scale == 2){
  153. Paint_info.Scale = scale;
  154. Paint_info.WidthByte = (Paint_info.WidthMemory % 8 == 0)? (Paint_info.WidthMemory / 8 ): (Paint_info.WidthMemory / 8 + 1);
  155. }else if(scale == 4){
  156. Paint_info.Scale = scale;
  157. Paint_info.WidthByte = (Paint_info.WidthMemory % 4 == 0)? (Paint_info.WidthMemory / 4 ): (Paint_info.WidthMemory / 4 + 1);
  158. }else if(scale == 7){//Only applicable with 5in65 e-Paper
  159. Paint_info.Scale = scale;
  160. Paint_info.WidthByte = (Paint_info.WidthMemory % 2 == 0)? (Paint_info.WidthMemory / 2 ): (Paint_info.WidthMemory / 2 + 1);;
  161. }else{
  162. Debug("Set Scale Input parameter error\r\n");
  163. Debug("Scale Only support: 2 4 7\r\n");
  164. }
  165. }
  166. /******************************************************************************
  167. function: Select Image mirror
  168. parameter:
  169. mirror :Not mirror,Horizontal mirror,Vertical mirror,Origin mirror
  170. ******************************************************************************/
  171. void Paint_SetMirroring(UBYTE mirror)
  172. {
  173. if(mirror == MIRROR_NONE || mirror == MIRROR_HORIZONTAL ||
  174. mirror == MIRROR_VERTICAL || mirror == MIRROR_ORIGIN) {
  175. Debug("mirror image x:%s, y:%s\r\n",(mirror & 0x01)? "mirror":"none", ((mirror >> 1) & 0x01)? "mirror":"none");
  176. Paint_info.Mirror = mirror;
  177. } else {
  178. Debug("mirror should be MIRROR_NONE, MIRROR_HORIZONTAL, \
  179. MIRROR_VERTICAL or MIRROR_ORIGIN\r\n");
  180. }
  181. }
  182. /******************************************************************************
  183. function: Draw Pixels
  184. parameter:
  185. Xpoint : At point X
  186. Ypoint : At point Y
  187. Color : Painted colors
  188. ******************************************************************************/
  189. void Paint_SetPixel(UWORD Xpoint, UWORD Ypoint, UWORD Color )
  190. {
  191. if(Xpoint > Paint_info.Width || Ypoint > Paint_info.Height){
  192. Debug("Exceeding display boundaries\r\n");
  193. return;
  194. }
  195. UWORD X, Y;
  196. switch(Paint_info.Rotate) {
  197. case 0:
  198. X = Xpoint;
  199. Y = Ypoint;
  200. break;
  201. case 90:
  202. X = Paint_info.WidthMemory - Ypoint - 1;
  203. Y = Xpoint;
  204. break;
  205. case 180:
  206. X = Paint_info.WidthMemory - Xpoint - 1;
  207. Y = Paint_info.HeightMemory - Ypoint - 1;
  208. break;
  209. case 270:
  210. X = Ypoint;
  211. Y = Paint_info.HeightMemory - Xpoint - 1;
  212. break;
  213. default:
  214. return;
  215. }
  216. switch(Paint_info.Mirror) {
  217. case MIRROR_NONE:
  218. break;
  219. case MIRROR_HORIZONTAL:
  220. X = Paint_info.WidthMemory - X - 1;
  221. break;
  222. case MIRROR_VERTICAL:
  223. Y = Paint_info.HeightMemory - Y - 1;
  224. break;
  225. case MIRROR_ORIGIN:
  226. X = Paint_info.WidthMemory - X - 1;
  227. Y = Paint_info.HeightMemory - Y - 1;
  228. break;
  229. default:
  230. return;
  231. }
  232. if(X > Paint_info.WidthMemory || Y > Paint_info.HeightMemory){
  233. Debug("Exceeding display boundaries\r\n");
  234. return;
  235. }
  236. if(Paint_info.Scale == 2){
  237. UDOUBLE Addr = X / 8 + Y * Paint_info.WidthByte;
  238. if(Addr>(Paint_info.WidthMemory*Paint_info.HeightMemory)){
  239. printf("------数组溢出-----------\n");
  240. return;
  241. }
  242. UBYTE Rdata = Paint_info.Image[Addr];
  243. if(Color == BLACK)
  244. Paint_info.Image[Addr] = Rdata & ~(0x80 >> (X % 8));
  245. else
  246. Paint_info.Image[Addr] = Rdata | (0x80 >> (X % 8));
  247. }else if(Paint_info.Scale == 4){
  248. UDOUBLE Addr = X / 4 + Y * Paint_info.WidthByte;
  249. Color = Color % 4;//Guaranteed color scale is 4 --- 0~3
  250. UBYTE Rdata = Paint_info.Image[Addr];
  251. Rdata = Rdata & (~(0xC0 >> ((X % 4)*2)));
  252. Paint_info.Image[Addr] = Rdata | ((Color << 6) >> ((X % 4)*2));
  253. }else if(Paint_info.Scale == 7){
  254. UDOUBLE Addr = X / 2 + Y * Paint_info.WidthByte;
  255. UBYTE Rdata = Paint_info.Image[Addr];
  256. Rdata = Rdata & (~(0xF0 >> ((X % 2)*4)));//Clear first, then set value
  257. Paint_info.Image[Addr] = Rdata | ((Color << 4) >> ((X % 2)*4));
  258. //printf("Add = %d ,data = %d\r\n",Addr,Rdata);
  259. }
  260. }
  261. /******************************************************************************
  262. function: Clear the color of the picture
  263. parameter:
  264. Color : Painted colors
  265. ******************************************************************************/
  266. void Paint_Clear(UWORD Color )
  267. {
  268. if(Paint_info.Scale == 2) {
  269. for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) {
  270. for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) {//8 pixel = 1 byte
  271. UDOUBLE Addr = X + Y*Paint_info.WidthByte;
  272. Paint_info.Image[Addr] = Color;
  273. }
  274. }
  275. }else if(Paint_info.Scale == 4) {
  276. for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) {
  277. for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) {
  278. UDOUBLE Addr = X + Y*Paint_info.WidthByte;
  279. Paint_info.Image[Addr] = (Color<<6)|(Color<<4)|(Color<<2)|Color;
  280. }
  281. }
  282. }else if(Paint_info.Scale == 7) {
  283. for (UWORD Y = 0; Y < Paint_info.HeightByte; Y++) {
  284. for (UWORD X = 0; X < Paint_info.WidthByte; X++ ) {
  285. UDOUBLE Addr = X + Y*Paint_info.WidthByte;
  286. Paint_info.Image[Addr] = (Color<<4)|Color;
  287. }
  288. }
  289. }
  290. }
  291. /******************************************************************************
  292. function: Clear the color of a window
  293. parameter:
  294. Xstart : x starting point
  295. Ystart : Y starting point
  296. Xend : x end point
  297. Yend : y end point
  298. Color : Painted colors
  299. ******************************************************************************/
  300. void Paint_ClearWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD Color )
  301. {
  302. UWORD X, Y;
  303. for (Y = Ystart; Y < Yend; Y++) {
  304. for (X = Xstart; X < Xend; X++) {//8 pixel = 1 byte
  305. Paint_SetPixel(X, Y, Color );
  306. }
  307. }
  308. }
  309. /******************************************************************************
  310. function: Draw Point(Xpoint, Ypoint) Fill the color
  311. parameter:
  312. Xpoint : The Xpoint coordinate of the point
  313. Ypoint : The Ypoint coordinate of the point
  314. Color : Painted color
  315. Dot_Pixel : point size
  316. Dot_Style : point Style
  317. ******************************************************************************/
  318. void Paint_DrawPoint(UWORD Xpoint, UWORD Ypoint, UWORD Color,
  319. DOT_PIXEL Dot_Pixel, DOT_STYLE Dot_Style )
  320. {
  321. if (Xpoint > Paint_info.Width || Ypoint > Paint_info.Height) {
  322. Debug("Paint_DrawPoint Input exceeds the normal display range\r\n");
  323. // printf("Xpoint = %d , Paint_info.Width = %d \r\n ",Xpoint .Width);
  324. // printf("Ypoint = %d , Paint_info.Height = %d \r\n ",Ypoint .Height);
  325. return;
  326. }
  327. int16_t XDir_Num , YDir_Num;
  328. if (Dot_Style == DOT_FILL_AROUND) {
  329. for (XDir_Num = 0; XDir_Num < 2 * Dot_Pixel - 1; XDir_Num++) {
  330. for (YDir_Num = 0; YDir_Num < 2 * Dot_Pixel - 1; YDir_Num++) {
  331. if((Xpoint + XDir_Num - Dot_Pixel) < 0 || (Ypoint + YDir_Num - Dot_Pixel) < 0)
  332. break;
  333. // printf("x = %d, y = %d\r\n", Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel);
  334. Paint_SetPixel(Xpoint + XDir_Num - Dot_Pixel, Ypoint + YDir_Num - Dot_Pixel, Color );
  335. }
  336. }
  337. } else {
  338. for (XDir_Num = 0; XDir_Num < Dot_Pixel; XDir_Num++) {
  339. for (YDir_Num = 0; YDir_Num < Dot_Pixel; YDir_Num++) {
  340. Paint_SetPixel(Xpoint + XDir_Num - 1, Ypoint + YDir_Num - 1, Color );
  341. }
  342. }
  343. }
  344. }
  345. /******************************************************************************
  346. function: Draw a line of arbitrary slope
  347. parameter:
  348. Xstart :Starting Xpoint point coordinates
  349. Ystart :Starting Xpoint point coordinates
  350. Xend :End point Xpoint coordinate
  351. Yend :End point Ypoint coordinate
  352. Color :The color of the line segment
  353. Line_width : Line width
  354. Line_Style: Solid and dotted lines
  355. ******************************************************************************/
  356. void Paint_DrawLine(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
  357. UWORD Color_Background, DOT_PIXEL Line_width, LINE_STYLE Line_Style )
  358. {
  359. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height ||
  360. Xend > Paint_info.Width || Yend > Paint_info.Height) {
  361. Debug("Paint_DrawLine Input exceeds the normal display range\r\n");
  362. return;
  363. }
  364. UWORD Xpoint = Xstart;
  365. UWORD Ypoint = Ystart;
  366. int dx = (int)Xend - (int)Xstart >= 0 ? Xend - Xstart : Xstart - Xend;
  367. int dy = (int)Yend - (int)Ystart <= 0 ? Yend - Ystart : Ystart - Yend;
  368. // Increment direction, 1 is positive, -1 is counter;
  369. int XAddway = Xstart < Xend ? 1 : -1;
  370. int YAddway = Ystart < Yend ? 1 : -1;
  371. //Cumulative error
  372. int Esp = dx + dy;
  373. char Dotted_Len = 0;
  374. for (;;) {
  375. Dotted_Len++;
  376. //Painted dotted line, 2 point is really virtual
  377. if (Line_Style == LINE_STYLE_DOTTED && Dotted_Len % 3 == 0) {
  378. //Debug("LINE_DOTTED\r\n");
  379. Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT );
  380. Dotted_Len = 0;
  381. }
  382. else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 4 == 0)
  383. {
  384. Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT );
  385. }
  386. else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 5 == 0)
  387. {
  388. Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT );
  389. }
  390. else if(Line_Style == LINE_STYLE_DOTTED_2 && Dotted_Len % 6 == 0)
  391. {
  392. Paint_DrawPoint(Xpoint, Ypoint, 0xff, Line_width, DOT_STYLE_DFT );
  393. Dotted_Len = 0;
  394. }
  395. else {
  396. Paint_DrawPoint(Xpoint, Ypoint, Color_Background, Line_width, DOT_STYLE_DFT );
  397. }
  398. if (2 * Esp >= dy) {
  399. if (Xpoint == Xend)
  400. break;
  401. Esp += dy;
  402. Xpoint += XAddway;
  403. }
  404. if (2 * Esp <= dx) {
  405. if (Ypoint == Yend)
  406. break;
  407. Esp += dx;
  408. Ypoint += YAddway;
  409. }
  410. }
  411. }
  412. /******************************************************************************
  413. function: Draw a rectangle
  414. parameter:
  415. Xstart :Rectangular Starting Xpoint point coordinates
  416. Ystart :Rectangular Starting Xpoint point coordinates
  417. Xend :Rectangular End point Xpoint coordinate
  418. Yend :Rectangular End point Ypoint coordinate
  419. Color :The color of the Rectangular segment
  420. Line_width: Line width
  421. Draw_Fill : Whether to fill the inside of the rectangle
  422. ******************************************************************************/
  423. void Paint_DrawRectangle(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend,
  424. UWORD Color_Background, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill )
  425. {
  426. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height ||
  427. Xend > Paint_info.Width || Yend > Paint_info.Height) {
  428. Debug("Input exceeds the normal display range\r\n");
  429. return;
  430. }
  431. if (Draw_Fill) {
  432. UWORD Ypoint;
  433. for(Ypoint = Ystart; Ypoint < Yend; Ypoint++) {
  434. Paint_DrawLine(Xstart, Ypoint, Xend, Ypoint, Color_Background , Line_width, LINE_STYLE_SOLID );
  435. }
  436. } else {
  437. Paint_DrawLine(Xstart, Ystart, Xend, Ystart, Color_Background, Line_width, LINE_STYLE_SOLID );
  438. Paint_DrawLine(Xstart, Ystart, Xstart, Yend, Color_Background, Line_width, LINE_STYLE_SOLID );
  439. Paint_DrawLine(Xend, Yend, Xend, Ystart, Color_Background, Line_width, LINE_STYLE_SOLID );
  440. Paint_DrawLine(Xend, Yend, Xstart, Yend, Color_Background, Line_width, LINE_STYLE_SOLID );
  441. }
  442. }
  443. /******************************************************************************
  444. function: Use the 8-point method to draw a circle of the
  445. specified size at the specified position->
  446. parameter:
  447. X_Center :Center X coordinate
  448. Y_Center :Center Y coordinate
  449. Radius :circle Radius
  450. Color :The color of the :circle segment
  451. Line_width: Line width
  452. Draw_Fill : Whether to fill the inside of the Circle
  453. ******************************************************************************/
  454. void Paint_DrawCircle(UWORD X_Center, UWORD Y_Center, UWORD Radius,
  455. UWORD Color_Background, DOT_PIXEL Line_width, DRAW_FILL Draw_Fill )
  456. {
  457. if (X_Center > Paint_info.Width || Y_Center >= Paint_info.Height) {
  458. Debug("Paint_DrawCircle Input exceeds the normal display range\r\n");
  459. return;
  460. }
  461. //Draw a circle from(0, R) as a starting point
  462. int16_t XCurrent, YCurrent;
  463. XCurrent = 0;
  464. YCurrent = Radius;
  465. //Cumulative error,judge the next point of the logo
  466. int16_t Esp = 3 - (Radius << 1 );
  467. int16_t sCountY;
  468. if (Draw_Fill == DRAW_FILL_FULL) {
  469. while (XCurrent <= YCurrent ) { //Realistic circles
  470. for (sCountY = XCurrent; sCountY <= YCurrent; sCountY ++ ) {
  471. Paint_DrawPoint(X_Center + XCurrent, Y_Center + sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//1
  472. Paint_DrawPoint(X_Center - XCurrent, Y_Center + sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//2
  473. Paint_DrawPoint(X_Center - sCountY, Y_Center + XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//3
  474. Paint_DrawPoint(X_Center - sCountY, Y_Center - XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//4
  475. Paint_DrawPoint(X_Center - XCurrent, Y_Center - sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//5
  476. Paint_DrawPoint(X_Center + XCurrent, Y_Center - sCountY, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//6
  477. Paint_DrawPoint(X_Center + sCountY, Y_Center - XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );//7
  478. Paint_DrawPoint(X_Center + sCountY, Y_Center + XCurrent, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT );
  479. }
  480. if (Esp < 0 )
  481. Esp += 4 * XCurrent + 6;
  482. else {
  483. Esp += 10 + 4 * (XCurrent - YCurrent );
  484. YCurrent --;
  485. }
  486. XCurrent ++;
  487. }
  488. } else { //Draw a hollow circle
  489. while (XCurrent <= YCurrent ) {
  490. Paint_DrawPoint(X_Center + XCurrent, Y_Center + YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//1
  491. Paint_DrawPoint(X_Center - XCurrent, Y_Center + YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//2
  492. Paint_DrawPoint(X_Center - YCurrent, Y_Center + XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//3
  493. Paint_DrawPoint(X_Center - YCurrent, Y_Center - XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//4
  494. Paint_DrawPoint(X_Center - XCurrent, Y_Center - YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//5
  495. Paint_DrawPoint(X_Center + XCurrent, Y_Center - YCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//6
  496. Paint_DrawPoint(X_Center + YCurrent, Y_Center - XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//7
  497. Paint_DrawPoint(X_Center + YCurrent, Y_Center + XCurrent, Color_Background, Line_width, DOT_STYLE_DFT );//0
  498. if (Esp < 0 )
  499. Esp += 4 * XCurrent + 6;
  500. else {
  501. Esp += 10 + 4 * (XCurrent - YCurrent );
  502. YCurrent --;
  503. }
  504. XCurrent ++;
  505. }
  506. }
  507. }
  508. //whc set start
  509. void Paint_DrawChar(UWORD Xpoint, UWORD Ypoint, const char Acsii_Char,FONT_TYPE_T* Ascii_type,
  510. UWORD Color_Foreground, UWORD Color_Background )
  511. {
  512. //ESP_LOGE(LOG_TAG,"DRAW");
  513. UWORD Page = 0, Column = 0;
  514. int font_width = 0,font_height = 0;//xpos_offset,ypos_offset,
  515. font_width = Ascii_type->Font_Width;
  516. font_height = Ascii_type->Font_Height;
  517. // switch (Ascii_type)
  518. // {
  519. // case 1: font_width = 5; font_height = 7; break;
  520. // case 2: font_width = 7; font_height = 8;break;
  521. // case 3: font_width = 6; font_height = 12;break;
  522. // case 4: font_width = 8; font_height = 16;break;
  523. // case 5: font_width = 12; font_height =24;break;
  524. // case 6: font_width = 12; font_height =24;break;
  525. // case 7: font_width = 16; font_height =32;break;
  526. // // case 8: font_width = 0; font_height =12;break;
  527. // // case 9: font_width = 0; font_height =16;break;
  528. // // case 10:font_width = 0; font_height =24;break;
  529. // // case 11:font_width = 0; font_height =32;break;
  530. // default:
  531. // break;
  532. // }
  533. unsigned char get_data_buf[50] = {};
  534. if (Xpoint > Paint_info.Width || Ypoint > Paint_info.Height) {
  535. ESP_LOGE(LOG_TAG,"Paint_DrawChar Input exceeds the normal display range");
  536. return;
  537. }
  538. ASCII_GetData(Acsii_Char,Ascii_type->Font_lib_type,get_data_buf);
  539. const unsigned char *ptr = get_data_buf;
  540. // for(int i = 0;i<50;i++)
  541. // {ESP_LOGE(LOG_TAG,"%x",ptr[i]);}
  542. // ESP_LOGE(LOG_TAG,"P");
  543. for (Page = 0; Page < font_height; Page ++ ) {
  544. for (Column = 0; Column < font_width; Column ++ ) {
  545. //To determine whether the font background color and screen background color is consistent
  546. if (FONT_BACKGROUND == Color_Foreground) { //this process is to speed up the scan
  547. if (*ptr & (0x80 >> (Column % 8)))
  548. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background );
  549. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  550. } else {
  551. if (*ptr & (0x80 >> (Column % 8))) {
  552. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background );
  553. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  554. } else {
  555. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground );
  556. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  557. }
  558. }
  559. //One pixel is 8 bits
  560. if (Column % 8 == 7)
  561. ptr++;
  562. }// Write a line
  563. if (font_width% 8 != 0)
  564. ptr++;
  565. }// Write all
  566. }
  567. void Paint_DrawString_EN(UWORD Xstart, UWORD Ystart, const char * pString,
  568. FONT_TYPE_T* Ascii_type, UWORD Color_Foreground, UWORD Color_Background )
  569. {
  570. UWORD Xpoint = Xstart;
  571. UWORD Ypoint = Ystart;
  572. int font_width = 0,font_height = 0;
  573. font_width = Ascii_type->Font_Width;
  574. font_height = Ascii_type->Font_Height;
  575. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) {
  576. Debug("Paint_DrawString_EN Input exceeds the normal display range\r\n");
  577. return;
  578. }
  579. while (* pString != '\0') {
  580. //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
  581. if ((Xpoint + font_width ) > Paint_info.Width ) {
  582. Xpoint = Xstart;
  583. Ypoint += font_height;
  584. }
  585. // If the Y direction is full, reposition to(Xstart, Ystart)
  586. if ((Ypoint + font_height ) > Paint_info.Height ) {
  587. Xpoint = Xstart;
  588. Ypoint = Ystart;
  589. }
  590. Paint_DrawChar(Xpoint, Ypoint, * pString, Ascii_type, Color_Foreground, Color_Background );
  591. //The next character of the address
  592. pString ++;
  593. //The next word of the abscissa increases the font of the broadband
  594. Xpoint += font_width;
  595. }
  596. }
  597. void Paint_DrawChar_CN48(UWORD Xstart, UWORD Ystart, const char * pString )
  598. {
  599. #define FONT_SIZE_24 24
  600. // 放大后的64x64点阵字库
  601. #define ENLARGED_FONT_SIZE_48 48
  602. const char* p_text = pString;
  603. unsigned char enlarged_font[48*48/8] = {};
  604. unsigned char font[24*24/8] = {};
  605. //ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2);
  606. if(*pString>0x80)
  607. {
  608. GBK_24_GetData(*p_text, *(p_text+1), font);
  609. }
  610. else
  611. {
  612. ASCII_GetData(*(p_text),ASCII_24_N,font);
  613. }
  614. double scale = (double)ENLARGED_FONT_SIZE_48 / FONT_SIZE_24;
  615. for (int y = 0; y < ENLARGED_FONT_SIZE_48; y++) {
  616. for (int x = 0; x < ENLARGED_FONT_SIZE_48; x++) {
  617. double x0 = x / scale;
  618. double y0 = y / scale;
  619. int x1 = (int)x0;
  620. int y1 = (int)y0;
  621. int x2 = x1 + 1;
  622. int y2 = y1 + 1;
  623. if (x2 >= FONT_SIZE_24) x2 = FONT_SIZE_24 - 1;
  624. if (y2 >= FONT_SIZE_24) y2 = FONT_SIZE_24 - 1;
  625. double dx = x0 - x1;
  626. double dy = y0 - y1;
  627. unsigned char q11 = (font[y1 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  628. unsigned char q21 = (font[y1 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  629. unsigned char q12 = (font[y2 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  630. unsigned char q22 = (font[y2 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  631. double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 +
  632. (1 - dx) * dy * q12 + dx * dy * q22;
  633. int index = y * ENLARGED_FONT_SIZE_48 + x;
  634. if (interpolated_value >= 0.5) {
  635. enlarged_font[index / 8] |= (1 << (7 - (index % 8)));
  636. } else {
  637. enlarged_font[index / 8] &= ~(1 << (7 - (index % 8)));
  638. }
  639. }
  640. }
  641. int Xpoint = Xstart, Ypoint = Ystart;
  642. const unsigned char *ptr = enlarged_font;
  643. UWORD Page = 0, Column = 0;
  644. for (Page = 0; Page < ENLARGED_FONT_SIZE_48; Page ++ ) {
  645. for (Column = 0; Column < ENLARGED_FONT_SIZE_48; Column ++ ) {
  646. //To determine whether the font background color and screen background color is consistent
  647. if (FONT_BACKGROUND == WHITE) { //this process is to speed up the scan
  648. if (*ptr & (0x80 >> (Column % 8)))
  649. Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK );
  650. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  651. } else {
  652. if (*ptr & (0x80 >> (Column % 8))) {
  653. Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK );
  654. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  655. } else {
  656. Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE );
  657. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  658. }
  659. }
  660. //One pixel is 8 bits
  661. if (Column % 8 == 7)
  662. ptr++;
  663. }// Write a line
  664. if (ENLARGED_FONT_SIZE_48% 8 != 0)
  665. ptr++;
  666. }// Write all
  667. }
  668. void Paint_DrawChar_CN48_black(UWORD Xstart, UWORD Ystart, const char * pString )//原来扩大是黑底白字Paint_DrawChar_CN48_black为白底黑字
  669. {
  670. #define FONT_SIZE_24 24
  671. // 放大后的64x64点阵字库
  672. #define ENLARGED_FONT_SIZE_48 48
  673. const char* p_text = pString;
  674. unsigned char enlarged_font[48*48/8] = {};
  675. unsigned char font[24*24/8] = {};
  676. //ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2);
  677. if(*pString>0x80)
  678. {
  679. GBK_24_GetData(*p_text, *(p_text+1), font);
  680. }
  681. else
  682. {
  683. ASCII_GetData(*(p_text),ASCII_24_N,font);
  684. }
  685. double scale = (double)ENLARGED_FONT_SIZE_48 / FONT_SIZE_24;
  686. for (int y = 0; y < ENLARGED_FONT_SIZE_48; y++) {
  687. for (int x = 0; x < ENLARGED_FONT_SIZE_48; x++) {
  688. double x0 = x / scale;
  689. double y0 = y / scale;
  690. int x1 = (int)x0;
  691. int y1 = (int)y0;
  692. int x2 = x1 + 1;
  693. int y2 = y1 + 1;
  694. if (x2 >= FONT_SIZE_24) x2 = FONT_SIZE_24 - 1;
  695. if (y2 >= FONT_SIZE_24) y2 = FONT_SIZE_24 - 1;
  696. double dx = x0 - x1;
  697. double dy = y0 - y1;
  698. unsigned char q11 = (font[y1 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  699. unsigned char q21 = (font[y1 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  700. unsigned char q12 = (font[y2 * (FONT_SIZE_24 / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  701. unsigned char q22 = (font[y2 * (FONT_SIZE_24 / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  702. double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 +
  703. (1 - dx) * dy * q12 + dx * dy * q22;
  704. int index = y * ENLARGED_FONT_SIZE_48 + x;
  705. if (interpolated_value >= 0.5) {
  706. enlarged_font[index / 8] |= (1 << (7 - (index % 8)));
  707. } else {
  708. enlarged_font[index / 8] &= ~(1 << (7 - (index % 8)));
  709. }
  710. }
  711. }
  712. int Xpoint = Xstart, Ypoint = Ystart;
  713. const unsigned char *ptr = enlarged_font;
  714. UWORD Page = 0, Column = 0;
  715. for (Page = 0; Page < ENLARGED_FONT_SIZE_48; Page ++ ) {
  716. for (Column = 0; Column < ENLARGED_FONT_SIZE_48; Column ++ ) {
  717. //To determine whether the font background color and screen background color is consistent
  718. if (FONT_BACKGROUND == BLACK) { //this process is to speed up the scan
  719. if (*ptr & (0x80 >> (Column % 8)))
  720. Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE );
  721. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  722. } else {
  723. if (*ptr & (0x80 >> (Column % 8))) {
  724. Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE );
  725. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  726. } else {
  727. Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK );
  728. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  729. }
  730. }
  731. //One pixel is 8 bits
  732. if (Column % 8 == 7)
  733. ptr++;
  734. }// Write a line
  735. if (ENLARGED_FONT_SIZE_48% 8 != 0)
  736. ptr++;
  737. }// Write all
  738. }
  739. void Paint_DrawChar_CN64(UWORD Xstart, UWORD Ystart, const char * pString )
  740. {
  741. #define FONT_SIZE 32
  742. // 放大后的64x64点阵字库
  743. #define ENLARGED_FONT_SIZE 64
  744. const char* p_text = pString;
  745. unsigned char enlarged_font[64*64/8] = {};
  746. unsigned char font[32*32/8] = {};
  747. // ESP_LOG_BUFFER_HEX(LOG_TAG,pString,2);
  748. if(*pString>0x80)
  749. {
  750. //ESP_LOGW(LOG_TAG,"汉字");
  751. GBK_32_GetData(*p_text, *(p_text+1), font);
  752. }
  753. else
  754. {
  755. //ESP_LOGW(LOG_TAG,"ASCII");
  756. ASCII_GetData(*(p_text),ASCII_32_N,font);
  757. }
  758. double scale = (double)ENLARGED_FONT_SIZE / FONT_SIZE;
  759. for (int y = 0; y < ENLARGED_FONT_SIZE; y++) {
  760. for (int x = 0; x < ENLARGED_FONT_SIZE; x++) {
  761. double x0 = x / scale;
  762. double y0 = y / scale;
  763. int x1 = (int)x0;
  764. int y1 = (int)y0;
  765. int x2 = x1 + 1;
  766. int y2 = y1 + 1;
  767. if (x2 >= FONT_SIZE) x2 = FONT_SIZE - 1;
  768. if (y2 >= FONT_SIZE) y2 = FONT_SIZE - 1;
  769. double dx = x0 - x1;
  770. double dy = y0 - y1;
  771. unsigned char q11 = (font[y1 * (FONT_SIZE / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  772. unsigned char q21 = (font[y1 * (FONT_SIZE / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  773. unsigned char q12 = (font[y2 * (FONT_SIZE / 8) + (x1 / 8)] >> (7 - (x1 % 8))) & 1;
  774. unsigned char q22 = (font[y2 * (FONT_SIZE / 8) + (x2 / 8)] >> (7 - (x2 % 8))) & 1;
  775. double interpolated_value = (1 - dx) * (1 - dy) * q11 + dx * (1 - dy) * q21 +
  776. (1 - dx) * dy * q12 + dx * dy * q22;
  777. int index = y * ENLARGED_FONT_SIZE + x;
  778. if (interpolated_value >= 0.5) {
  779. enlarged_font[index / 8] |= (1 << (7 - (index % 8)));
  780. } else {
  781. enlarged_font[index / 8] &= ~(1 << (7 - (index % 8)));
  782. }
  783. }
  784. }
  785. int Xpoint = Xstart, Ypoint = Ystart;
  786. const unsigned char *ptr = enlarged_font;
  787. UWORD Page = 0, Column = 0;
  788. for (Page = 0; Page < ENLARGED_FONT_SIZE; Page ++ ) {
  789. for (Column = 0; Column < ENLARGED_FONT_SIZE; Column ++ ) {
  790. //To determine whether the font background color and screen background color is consistent
  791. if (FONT_BACKGROUND == WHITE) { //this process is to speed up the scan
  792. if (*ptr & (0x80 >> (Column % 8)))
  793. Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK );
  794. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  795. } else {
  796. if (*ptr & (0x80 >> (Column % 8))) {
  797. Paint_SetPixel(Xpoint + Column, Ypoint + Page, BLACK );
  798. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Foreground, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  799. } else {
  800. Paint_SetPixel(Xpoint + Column, Ypoint + Page, WHITE );
  801. // Paint_DrawPoint(Xpoint + Column, Ypoint + Page, Color_Background, DOT_PIXEL_DFT, DOT_STYLE_DFT);
  802. }
  803. }
  804. //One pixel is 8 bits
  805. if (Column % 8 == 7)
  806. ptr++;
  807. }// Write a line
  808. if (ENLARGED_FONT_SIZE% 8 != 0)
  809. ptr++;
  810. }// Write all
  811. }
  812. void Paint_DrawChar_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T* chinese_type,
  813. UWORD Color_Foreground, UWORD Color_Background )
  814. {
  815. const char* p_text = pString;
  816. int Xpoint = Xstart, Ypoint = Ystart;
  817. int font_width = 0,font_height = 0;
  818. unsigned char get_chinese_data_buf[32*4] = {};
  819. font_width = chinese_type->Font_Width;
  820. font_height = chinese_type->Font_Height;
  821. switch (chinese_type->Font_Width)
  822. {
  823. //case CHINESE_TYPE_12: font_width = 12; font_height = 12; break;
  824. case 16:
  825. {
  826. GB2312_16_GetData(*p_text, *(p_text+1), get_chinese_data_buf);
  827. }break;
  828. case 24:
  829. {
  830. GBK_24_GetData(*p_text, *(p_text+1), get_chinese_data_buf);
  831. }break;
  832. case 32:
  833. {
  834. GBK_32_GetData(*p_text, *(p_text+1), get_chinese_data_buf);
  835. }break;
  836. default:
  837. break;
  838. }
  839. // for(int i=0;i<32*4;i++)
  840. // {
  841. // printf("%02x ",get_chinese_data_buf[i]);
  842. // }
  843. // printf("\n-------------------------\n");
  844. const unsigned char *ptr = get_chinese_data_buf;
  845. UWORD Page = 0, Column = 0;
  846. for (Page = 0; Page < font_height; Page ++ ) {
  847. for (Column = 0; Column < font_width; Column ++ ) {
  848. //To determine whether the font background color and screen background color is consistent
  849. if (FONT_BACKGROUND == Color_Foreground) { //this process is to speed up the scan
  850. if (*ptr & (0x80 >> (Column % 8)))
  851. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background );
  852. } else {
  853. if (*ptr & (0x80 >> (Column % 8))) {
  854. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Background );
  855. } else {
  856. Paint_SetPixel(Xpoint + Column, Ypoint + Page, Color_Foreground );
  857. }
  858. }
  859. //One pixel is 8 bits
  860. if (Column % 8 == 7)
  861. ptr++;
  862. }// Write a line
  863. if (font_width% 8 != 0)
  864. ptr++;
  865. }// Write all
  866. }
  867. void Paint_DrawString_CN48(UWORD Xstart, UWORD Ystart, const char * pString , int is_black)
  868. {
  869. UWORD Xpoint = Xstart;
  870. UWORD Ypoint = Ystart;
  871. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) {
  872. Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n");
  873. return;
  874. }
  875. //ESP_LOGW(LOG_TAG,"------CN64--len =%d --:%s--",strlen(pString),pString);
  876. // while (((* pString != '\0')&&(* (pString + 1) != '\0'))||((* pString == '\0')&&(* (pString + 1) != '\0'))){
  877. while (* pString != '\0'){
  878. //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
  879. if ((Xpoint + 48 ) > Paint_info.Width ) {
  880. Xpoint = Xstart;
  881. Ypoint += 48;
  882. }
  883. //ESP_LOGW(LOG_TAG,"------6464------");
  884. // If the Y direction is full, reposition to(Xstart, Ystart)
  885. if ((Ypoint + 48 ) > Paint_info.Height ) {
  886. Xpoint = Xstart;
  887. Ypoint = Ystart;
  888. }
  889. if(*pString >0x80)
  890. {
  891. if(!is_black)
  892. Paint_DrawChar_CN48(Xpoint, Ypoint, pString);
  893. else
  894. Paint_DrawChar_CN48_black(Xpoint, Ypoint, pString);
  895. //The next character of the address
  896. pString ++;
  897. pString ++;
  898. //The next word of the abscissa increases the font of the broadband
  899. Xpoint += 48;
  900. }
  901. else//ascii
  902. {
  903. if(!is_black)
  904. Paint_DrawChar_CN48(Xpoint, Ypoint, pString);
  905. else
  906. Paint_DrawChar_CN48_black(Xpoint, Ypoint, pString);
  907. //The next character of the address
  908. pString ++;
  909. //The next word of the abscissa increases the font of the broadband
  910. Xpoint += 48;
  911. }
  912. }
  913. }
  914. void Paint_DrawString_CN64(UWORD Xstart, UWORD Ystart, const char * pString )
  915. {
  916. UWORD Xpoint = Xstart;
  917. UWORD Ypoint = Ystart;
  918. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) {
  919. Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n");
  920. return;
  921. }
  922. //ESP_LOGW(LOG_TAG,"------CN64--len =%d --:%s--",strlen(pString),pString);
  923. // while (((* pString != '\0')&&(* (pString + 1) != '\0'))||((* pString == '\0')&&(* (pString + 1) != '\0'))){
  924. while (* pString != '\0'){
  925. //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
  926. if ((Xpoint + 64 ) > Paint_info.Width ) {
  927. Xpoint = Xstart;
  928. Ypoint += 64;
  929. }
  930. //ESP_LOGW(LOG_TAG,"------6464------");
  931. // If the Y direction is full, reposition to(Xstart, Ystart)
  932. if ((Ypoint + 64 ) > Paint_info.Height ) {
  933. Xpoint = Xstart;
  934. Ypoint = Ystart;
  935. }
  936. if(*pString >0x80)
  937. {
  938. Paint_DrawChar_CN64(Xpoint, Ypoint, pString );
  939. //The next character of the address
  940. pString ++;
  941. pString ++;
  942. //The next word of the abscissa increases the font of the broadband
  943. Xpoint += 64;
  944. }
  945. else//ascii
  946. {
  947. Paint_DrawChar_CN64(Xpoint, Ypoint, pString );
  948. //The next character of the address
  949. pString ++;
  950. //The next word of the abscissa increases the font of the broadband
  951. Xpoint += 64;
  952. }
  953. }
  954. }
  955. void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T* chinese_type,
  956. UWORD Color_Foreground, UWORD Color_Background )
  957. {
  958. UWORD Xpoint = Xstart;
  959. UWORD Ypoint = Ystart;
  960. int font_width = 0,font_height = 0;
  961. font_width = chinese_type->Font_Width;
  962. font_height = chinese_type->Font_Height;
  963. if (Xstart > Paint_info.Width || Ystart > Paint_info.Height) {
  964. Debug("Paint_DrawString_CN Input exceeds the normal display range\r\n");
  965. return;
  966. }
  967. while ((* pString != '\0') || (* (pString+1) != '\0')) {
  968. //if X direction filled , reposition to(Xstart,Ypoint),Ypoint is Y direction plus the Height of the character
  969. if ((Xpoint + font_width ) > Paint_info.Width ) {
  970. Xpoint = Xstart;
  971. Ypoint += font_height;
  972. }
  973. // If the Y direction is full, reposition to(Xstart, Ystart)
  974. if ((Ypoint + font_height ) > Paint_info.Height ) {
  975. Xpoint = Xstart;
  976. Ypoint = Ystart;
  977. }
  978. #if 0
  979. if(((*(pString +1))== '\0') && ((* pString)<0x80))
  980. #else
  981. if(((* pString)<0x80))
  982. #endif
  983. {
  984. font_width = chinese_type->Font_Width;
  985. font_height = chinese_type->Font_Height;
  986. #if 0
  987. FONT_TYPE_T ascii_type_5x7 = {"ascii_type_5x7",ASCII_5X7,5,7,};
  988. FONT_TYPE_T ascii_type_7x8 ={"ascii_type_7x8",ASCII_7X8,7,8,};
  989. FONT_TYPE_T ascii_type_6x12 ={"ascii_type_6x12",ASCII_6X12,6,12,};
  990. FONT_TYPE_T ascii_type_8x16 ={"ascii_type_8x16",ASCII_8X16,8,16,};
  991. FONT_TYPE_T ascii_type_12x24 ={"ascii_type_12x24",ASCII_12X24,12,24,};
  992. FONT_TYPE_T ascii_type_12x24_b ={"ascii_type_12x24_b",ASCII_12X24_B,12,24,};
  993. FONT_TYPE_T ascii_type_16x32 ={"ascii_type_16x32",ASCII_16X32,16,32,};
  994. #endif
  995. switch(font_height)
  996. {
  997. case 8:
  998. Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_7x8, Color_Foreground, Color_Background);
  999. break;
  1000. case 16:
  1001. Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_8x16, Color_Foreground, Color_Background);
  1002. break;
  1003. case 24:
  1004. //printf("");
  1005. Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_12x24, Color_Foreground, Color_Background);
  1006. break;
  1007. case 32:
  1008. Paint_DrawString_EN(Xpoint, Ypoint, (pString), &ascii_type_16x32, Color_Foreground, Color_Background);
  1009. break;
  1010. }
  1011. Xpoint += font_width/2;
  1012. pString ++;
  1013. }
  1014. else
  1015. {
  1016. Paint_DrawChar_CN(Xpoint, Ypoint, pString, chinese_type, Color_Foreground, Color_Background);
  1017. Xpoint += font_width;
  1018. //The next character of the address
  1019. pString ++;
  1020. pString ++;
  1021. }
  1022. //The next word of the abscissa increases the font of the broadband
  1023. }
  1024. }
  1025. // void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char * pString, FONT_TYPE_T chinese_type,
  1026. // UWORD Color_Foreground, UWORD Color_Background)
  1027. // {
  1028. // }
  1029. //whc set end
  1030. /******************************************************************************
  1031. function: Display time
  1032. parameter:
  1033. Xstart :X coordinate
  1034. Ystart : Y coordinate
  1035. pTime : Time-related structures
  1036. Font :A structure pointer that displays a character size
  1037. Color_Foreground : Select the foreground color
  1038. Color_Background : Select the background color
  1039. ******************************************************************************/
  1040. void Paint_DrawTime(UWORD Xstart, UWORD Ystart, PAINT_TIME *pTime, FONT_TYPE_T* Font_type,
  1041. UWORD Color_Foreground, UWORD Color_Background )
  1042. {
  1043. uint8_t value[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
  1044. UWORD Dx = Font_type->Font_Width;
  1045. //Write data into the cache
  1046. // Paint_DrawChar(Xstart , Ystart, value[pTime->Hour / 10], Font_type, Color_Foreground, Color_Background );
  1047. // Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->Hour % 10], Font_type, Color_Foreground, Color_Background );
  1048. // Paint_DrawChar(Xstart + Dx + Dx / 4 + Dx / 2 , Ystart, ':' , Font_type, Color_Foreground, Color_Background );
  1049. // Paint_DrawChar(Xstart + Dx * 2 + Dx / 2 , Ystart, value[pTime->Min / 10] , Font_type, Color_Foreground, Color_Background );
  1050. // Paint_DrawChar(Xstart + Dx * 3 + Dx / 2 , Ystart, value[pTime->Min % 10] , Font_type, Color_Foreground, Color_Background );
  1051. // Paint_DrawChar(Xstart + Dx * 4 + Dx / 2 - Dx / 4, Ystart, ':' , Font_type, Color_Foreground, Color_Background );
  1052. // Paint_DrawChar(Xstart + Dx * 5 , Ystart, value[pTime->Sec / 10] , Font_type, Color_Foreground, Color_Background );
  1053. // Paint_DrawChar(Xstart + Dx * 6 , Ystart, value[pTime->Sec % 10] , Font_type, Color_Foreground, Color_Background );
  1054. Paint_DrawChar(Xstart , Ystart, value[pTime->Hour / 10], Font_type, Color_Foreground, Color_Background );
  1055. Paint_DrawChar(Xstart + Dx , Ystart, value[pTime->Hour % 10], Font_type, Color_Foreground, Color_Background );
  1056. Paint_DrawChar(Xstart + Dx * 2 , Ystart, ':' , Font_type, Color_Foreground, Color_Background );
  1057. Paint_DrawChar(Xstart + Dx * 3 , Ystart, value[pTime->Min / 10] , Font_type, Color_Foreground, Color_Background );
  1058. Paint_DrawChar(Xstart + Dx * 4 , Ystart, value[pTime->Min % 10] , Font_type, Color_Foreground, Color_Background );
  1059. Paint_DrawChar(Xstart + Dx * 5 , Ystart, ':' , Font_type, Color_Foreground, Color_Background );
  1060. Paint_DrawChar(Xstart + Dx * 6 , Ystart, value[pTime->Sec / 10] , Font_type, Color_Foreground, Color_Background );
  1061. Paint_DrawChar(Xstart + Dx * 7 , Ystart, value[pTime->Sec % 10] , Font_type, Color_Foreground, Color_Background );
  1062. }
  1063. /******************************************************************************
  1064. function: Display monochrome bitmap
  1065. parameter:
  1066. image_buffer :A picture data converted to a bitmap
  1067. info:
  1068. Use a computer to convert the image into a corresponding array,
  1069. and then embed the array directly into Imagedata.cpp as a .c file.
  1070. ******************************************************************************/
  1071. void Paint_DrawBitMap(const unsigned char* image_buffer )
  1072. {
  1073. UWORD x, y;
  1074. UDOUBLE Addr = 0;
  1075. for (y = 0; y < Paint_info.HeightByte; y++) {
  1076. for (x = 0; x < Paint_info.WidthByte; x++) {//8 pixel = 1 byte
  1077. Addr = x + y * Paint_info.WidthByte;
  1078. Paint_info.Image[Addr] = (unsigned char)image_buffer[Addr];
  1079. }
  1080. }
  1081. }
  1082. /******************************************************************************
  1083. function: Paint_DrawBitMap_Vertical 垂直对称显示背景图片
  1084. parameter:
  1085. image_buffer :A picture data converted to a bitmap
  1086. info:
  1087. Use a computer to convert the image into a corresponding array,
  1088. and then embed the array directly into Imagedata.cpp as a .c file.
  1089. ******************************************************************************/
  1090. void Paint_DrawBitMap_Vertical(const unsigned char* image_buffer )
  1091. {
  1092. uint8_t temp_buffer[648/8]={0};
  1093. UWORD x, y;
  1094. for(y = 0; y < Paint_info.HeightByte; y++) {
  1095. memcpy(temp_buffer,(unsigned char*)&image_buffer[(Paint_info.HeightByte - y)*Paint_info.WidthByte],648/8);
  1096. //Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
  1097. memcpy(&Paint_info.Image[y*Paint_info.WidthByte],temp_buffer,648/8);
  1098. }
  1099. }
  1100. /******************************************************************************
  1101. function: paste monochrome bitmap to a frame buff
  1102. parameter:
  1103. image_buffer :A picture data converted to a bitmap
  1104. xStart: The starting x coordinate
  1105. yStart: The starting y coordinate
  1106. imageWidth: Original image width
  1107. imageHeight: Original image height
  1108. flipColor: Whether the color is reversed
  1109. info:
  1110. Use this function to paste image data into a buffer
  1111. ******************************************************************************/
  1112. void Paint_DrawBitMap_Paste(const unsigned char* image_buffer, UWORD xStart, UWORD yStart, UWORD imageWidth,
  1113. UWORD imageHeight, UBYTE flipColor )
  1114. {
  1115. UBYTE color, srcImage;
  1116. UWORD x, y;
  1117. UWORD width = (imageWidth%8==0 ? imageWidth/8 : imageWidth/8+1);
  1118. for (y = 0; y < imageHeight; y++) {
  1119. for (x = 0; x < imageWidth; x++) {
  1120. srcImage = image_buffer[y*width + x/8];
  1121. if(flipColor)
  1122. color = (((srcImage<<(x%8) & 0x80) == 0) ? 0xff : 0x00);
  1123. else
  1124. color = (((srcImage<<(x%8) & 0x80) == 0) ? 0 : 0xff);
  1125. Paint_SetPixel(x+xStart, y+yStart, color );
  1126. }
  1127. }
  1128. }
  1129. void Paint_DrawBitMap_Paste_t(const unsigned char* image_buffer, UWORD xStart, UWORD yStart, UWORD imageWidth,
  1130. UWORD imageHeight, UBYTE flipColor )
  1131. {
  1132. int i=0;
  1133. UBYTE color, srcImage;
  1134. UWORD x, y;
  1135. UWORD width = (imageWidth%8==0 ? imageWidth/8 : imageWidth/8+1);
  1136. for (y = 0; y < imageHeight; y++) {
  1137. for (x = 0; x < imageWidth; x++) {
  1138. srcImage = image_buffer[y*width + x/8];
  1139. if(flipColor)
  1140. color = (((srcImage<<(x%8) & 0x80) == 0) ? 0xff : 0x00);
  1141. else
  1142. color = (((srcImage<<(x%8) & 0x80) == 0) ? 0 : 0xff);
  1143. printf("%02x ",color);
  1144. i++;
  1145. Paint_SetPixel(x+xStart, y+yStart, color );
  1146. }
  1147. }
  1148. printf("[%d]\n",i);
  1149. }
  1150. ///******************************************************************************
  1151. //function: SDisplay half of monochrome bitmap
  1152. //parameter:
  1153. // Region : 1 Upper half
  1154. // 2 Lower half
  1155. //info:
  1156. //******************************************************************************/
  1157. //void Paint_DrawBitMap_Half(const unsigned char* image_buffer, UBYTE Region)
  1158. //{
  1159. // UWORD x, y;
  1160. // UDOUBLE Addr = 0;
  1161. //
  1162. // if(Region == 1){
  1163. // for (y = 0; y < Paint.HeightByte; y++) {
  1164. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1165. // Addr = x + y * Paint.WidthByte;
  1166. // Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
  1167. // }
  1168. // }
  1169. // }else{
  1170. // for (y = 0; y < Paint.HeightByte; y++) {
  1171. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1172. // Addr = x + y * Paint.WidthByte ;
  1173. // Paint.Image[Addr] =
  1174. // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte];
  1175. // }
  1176. // }
  1177. // }
  1178. //}
  1179. ///******************************************************************************
  1180. //function: SDisplay half of monochrome bitmap
  1181. //parameter:
  1182. // Region : 1 Upper half
  1183. // 2 Lower half
  1184. //info:
  1185. //******************************************************************************/
  1186. //void Paint_DrawBitMap_OneQuarter(const unsigned char* image_buffer, UBYTE Region)
  1187. //{
  1188. // UWORD x, y;
  1189. // UDOUBLE Addr = 0;
  1190. //
  1191. // if(Region == 1){
  1192. // for (y = 0; y < Paint.HeightByte; y++) {
  1193. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1194. // Addr = x + y * Paint.WidthByte;
  1195. // Paint.Image[Addr] = (unsigned char)image_buffer[Addr];
  1196. // }
  1197. // }
  1198. // }else if(Region == 2){
  1199. // for (y = 0; y < Paint.HeightByte; y++) {
  1200. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1201. // Addr = x + y * Paint.WidthByte ;
  1202. // Paint.Image[Addr] =
  1203. // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte];
  1204. // }
  1205. // }
  1206. // }else if(Region == 3){
  1207. // for (y = 0; y < Paint.HeightByte; y++) {
  1208. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1209. // Addr = x + y * Paint.WidthByte ;
  1210. // Paint.Image[Addr] =
  1211. // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*2];
  1212. // }
  1213. // }
  1214. // }else if(Region == 4){
  1215. // for (y = 0; y < Paint.HeightByte; y++) {
  1216. // for (x = 0; x < Paint.WidthByte; x++) {//8 pixel = 1 byte
  1217. // Addr = x + y * Paint.WidthByte ;
  1218. // Paint.Image[Addr] =
  1219. // (unsigned char)image_buffer[Addr+ (Paint.HeightByte)*Paint.WidthByte*3];
  1220. // }
  1221. // }
  1222. // }
  1223. //}
  1224. void Paint_DrawBitMap_Block(const unsigned char* image_buffer, UBYTE Region )
  1225. {
  1226. UWORD x, y;
  1227. UDOUBLE Addr = 0;
  1228. for (y = 0; y < Paint_info.HeightByte; y++) {
  1229. for (x = 0; x < Paint_info.WidthByte; x++) {//8 pixel = 1 byte
  1230. Addr = x + y * Paint_info.WidthByte ;
  1231. Paint_info.Image[Addr] = \
  1232. (unsigned char)image_buffer[Addr+ (Paint_info.HeightByte)*Paint_info.WidthByte*(Region - 1)];
  1233. }
  1234. }
  1235. }
  1236. void drawQuadraticBezierCurve(uint8_t* framebuffer, int width, int height,
  1237. int x0, int y0, int x1, int y1, int x2, int y2,
  1238. uint8_t color, int thickness) {
  1239. // 使用二次贝塞尔曲线算法计算曲线上的点并绘制
  1240. for (double t = 0; t <= 1.0; t += 0.01) {
  1241. double u = 1.0 - t;
  1242. double tt = t * t;
  1243. double uu = u * u;
  1244. double ut = u * t;
  1245. int x = (int)(uu * x0 + 2 * ut * x1 + tt * x2);
  1246. int y = (int)(uu * y0 + 2 * ut * y1 + tt * y2);
  1247. // 绘制线条
  1248. for (int i = -thickness / 2; i <= thickness / 2; i++) {
  1249. for (int j = -thickness / 2; j <= thickness / 2; j++) {
  1250. int currentX = x + i;
  1251. int currentY = y + j;
  1252. // 检查点是否在屏幕范围内
  1253. if (currentX >= 0 && currentX < width && currentY >= 0 && currentY < height) {
  1254. // 计算帧缓冲中的字节和位偏移
  1255. int byteOffset = (currentY * width + currentX) / 8;
  1256. int bitOffset = (currentY * width + currentX) % 8;
  1257. // 根据颜色设置像素值
  1258. if (color) {
  1259. framebuffer[byteOffset] |= (0x80 >> bitOffset);
  1260. } else {
  1261. framebuffer[byteOffset] &= ~(0x80 >> bitOffset);
  1262. }
  1263. }
  1264. }
  1265. }
  1266. }
  1267. }
  1268. #include "math.h"
  1269. void drawQuadraticBezierCurve_do(uint8_t* framebuffer, int width, int height,
  1270. int x0, int y0, int x1, int y1, int x2, int y2,
  1271. uint8_t color, int thickness) {
  1272. // 使用二次贝塞尔曲线算法计算曲线上的点并绘制
  1273. for (double t = 0; t <= 1.0; t += 0.01) {
  1274. double u = 1.0 - t;
  1275. double tt = t * t;
  1276. double uu = u * u;
  1277. double ut = u * t;
  1278. int x = (int)(uu * x0 + 2 * ut * x1 + tt * x2);
  1279. int y = (int)(uu * y0 + 2 * ut * y1 + tt * y2);
  1280. // 绘制线条
  1281. for (int i = -thickness / 2; i <= thickness / 2; i++) {
  1282. for (int j = -thickness / 2; j <= thickness / 2; j++) {
  1283. int currentX = x + i;
  1284. int currentY = y + j;
  1285. // 检查点是否在屏幕范围内
  1286. if (currentX >= 0 && currentX < width && currentY >= 0 && currentY < height) {
  1287. // 计算帧缓冲中的字节和位偏移
  1288. int byteOffset = (currentY * width + currentX) / 8;
  1289. int bitOffset = (currentY * width + currentX) % 8;
  1290. // 根据颜色设置像素值
  1291. if (color) {
  1292. framebuffer[byteOffset] |= (0x80 >> bitOffset);
  1293. } else {
  1294. framebuffer[byteOffset] &= ~(0x80 >> bitOffset);
  1295. }
  1296. if (abs(x - (uu * x0 + 2 * ut * x1 + tt * x2)) > 1 || abs(y - (uu * y0 + 2 * ut * y1 + tt * y2)) > 1) {
  1297. ESP_LOGW(LOG_TAG,"---abs");
  1298. int byteOffset = (y * width + x) / 8;
  1299. int bitOffset = (y * width + x) % 8;
  1300. if (color) {
  1301. framebuffer[byteOffset] &= ~(0x80 >> bitOffset);
  1302. } else {
  1303. framebuffer[byteOffset] |= (0x80 >> bitOffset);
  1304. }
  1305. }
  1306. }
  1307. }
  1308. }
  1309. }
  1310. }