#include "mywin_inc.h" uint32_t WIN_SetLcdColor(uint32_t color) { WIN_Struct *ewin = WIN_GetWinStruct(); uint32_t co = ewin->lcd->getLcdColor(); uint32_t ret = COLOR565TO888(co); ewin->lcd->setLcdColor(COLOR888TO565(color)); return ret; } uint32_t WIN_SetLcdBkColor(uint32_t color) { WIN_Struct *ewin = WIN_GetWinStruct(); uint32_t co = ewin->lcd->getLcdBkColor(); uint32_t ret = COLOR565TO888(co); ewin->lcd->setLcdBkColor(COLOR888TO565(color)); return ret; } uint16_t WIN_GetLcdColor16(void) { return WIN_GetWinStruct()->lcd->getLcdColor(); } void WIN_DrawPointSafe(int x, int y, int mode) { WIN_Struct *ewin = WIN_GetWinStruct(); if (POS_InRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size, x, y)) { // if (mode) // LCD_DrawPointSafe (x,y,1); // else // LCD_DrawPointSafe (x,y,0); ewin->lcd->drawPoint(x, y, mode); } } void WIN_DrawPointNormal(int x, int y, int mode) { WIN_Struct *ewin = WIN_GetWinStruct(); ewin->lcd->drawPoint(x, y, mode); } void WIN_DrawPointColorSafe(int x, int y, uint32_t color) { WIN_Struct *ewin = WIN_GetWinStruct(); if (POS_InRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size, x, y)) { ewin->lcd->drawPointColor(x, y, color); } } void WIN_DrawPointColorNormal(int x, int y, uint32_t color) { WIN_Struct *ewin = WIN_GetWinStruct(); ewin->lcd->drawPointColor(x, y, color); } void WIN_DrawPointSafeColorAlpha(int x, int y, uint16_t color, uint8_t alpha) { WIN_Struct *ewin = WIN_GetWinStruct(); if (POS_InRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size, x, y)) { ewin->lcd->drawPointColorAlpha(x, y, color, alpha); } } // 绘制一个英文字符,内部调用 // 返回字符的宽度 static uint32_t WIN_DrawCharAt(char c, int x, int y) { WIN_Struct *ewin = WIN_GetWinStruct(); if (ewin->font.drawChar) return ewin->font.drawChar(c, x, y); else return 0; } // 显示一个汉字,内部调用,返回汉字的宽度 static uint32_t WIN_DrawWordAt(char *c, int x, int y) { WIN_Struct *ewin = WIN_GetWinStruct(); if (ewin->font.drawWord) return ewin->font.drawWord(c, x, y); else return 0; } // 在指定位置显示字符串 void WIN_DrawTxtAt(char *txt, int x, int y) { if (txt == 0) return; while (*txt) { if ((*txt & 0x80) == 0) { x += WIN_DrawCharAt(*txt, x, y); txt++; } else { x += WIN_DrawWordAt(txt, x, y); txt += 2; } } } // 在指定矩形中显示字符串,支持换行符\n void WIN_DrawTxtAtRect(char *txt, int x, int y, int x_size, int y_size) { int x_s = x; int y_s = y; if (txt == 0) return; while (*txt) { if ((*txt & 0x80) == 0) { if ((x_s - x > x_size - 1 - WIN_GetFontWidth() / 2) || (*txt == '\n')) { x_s = x; y_s += WIN_GetFontHight(); if (*txt == '\n') { txt++; continue; } } x_s += WIN_DrawCharAt(*txt, x_s, y_s); txt++; } else { if (x_s - x > x_size - 1 - WIN_GetFontWidth()) { x_s = x; y_s += WIN_GetFontHight(); } x_s += WIN_DrawWordAt(txt, x_s, y_s); txt += 2; } if (y_s - y > y_size - 1 - WIN_GetFontHight()) return; } } // 在指定矩形居中显示字符串,支持换行符\n void WIN_DrawTxtCenterAtRect(char *txt, int x, int y, int x_size, int y_size) { int line_max = y_size / WIN_GetFontHight(); // 计算可以显示多少行 int char_max = x_size / (WIN_GetFontWidth() / 2); // 计算每行可以显示多少个字符 int x_s = x; int line_i = 0; char *txtbuff = mymalloc(line_max * (char_max + 1)); char *txt_ptr = txtbuff; while (*txt) { if (line_i >= line_max) { line_i--; break; } if ((*txt & 0x80) == 0) { if ((x_s - x > x_size - WIN_GetFontWidth() / 2) || (*txt == '\n')) { *txt_ptr = 0; line_i++; txt_ptr = txtbuff + (char_max + 1) * line_i; x_s = x; if (*txt == '\n') { txt++; } continue; } x_s += WIN_GetFontWidth() / 2; *txt_ptr = *txt; txt_ptr++; txt++; } else { if (x_s - x > x_size - WIN_GetFontWidth()) { *txt_ptr = 0; line_i++; txt_ptr = txtbuff + (char_max + 1) * line_i; x_s = x; continue; } x_s += WIN_GetFontWidth(); *txt_ptr = *txt; txt_ptr++; txt++; *txt_ptr = *txt; txt_ptr++; txt++; } } *txt_ptr = 0; // 最后一个字符串添加结尾 int y_s = y + (y_size - (line_i + 1) * WIN_GetFontHight()) / 2; // y方向上居中 txt_ptr = txtbuff; for (int i = 0; i < line_i + 1; i++) { WIN_DrawTxtHCenterAt(txt_ptr, x + x_size / 2, y_s); y_s += WIN_GetFontHight(); txt_ptr += char_max + 1; } myfree(txtbuff); } // 在指定位置居中显示字符串 void WIN_DrawTxtHCenterAt(char *txt, int x, int y) { int str_len = strlen(txt); int str_x_size = WIN_GetWinStruct()->font.TxtW / 2 * str_len; WIN_DrawTxtAt(txt, x - str_x_size / 2, y); } void WIN_DrawHLine(int x_s, int y, int x_e) { for (int i = x_s; i <= x_e; i++) { WIN_DrawPointSafe(i, y, 1); } } // 有透明度的划线,dis=0,正方向,dis=1,反方向 void WIN_DrawHLineAlpha(int x_s, int y, int x_e, uint16_t color, uint8_t dis) { uint8_t step = (x_e - x_s + 1); if (dis) { for (int i = x_s; i <= x_e; i++) { WIN_DrawPointSafeColorAlpha(i, y, color, (i - x_s) * 32 / step); } } else { for (int i = x_s; i <= x_e; i++) { WIN_DrawPointSafeColorAlpha(i, y, color, (x_e - i) * 32 / step); } } } void WIN_DrawVLine(int x, int y_s, int y_e) { for (int i = y_s; i <= y_e; i++) { WIN_DrawPointSafe(x, i, 1); } } // 画线 x1,y1:起点坐标 x2,y2:终点坐标 void WIN_DrawLine(int x1, int y1, int x2, int y2) { int t; int xerr = 0, yerr = 0, delta_x, delta_y, distance; int incx, incy, uRow, uCol; delta_x = x2 - x1; // 计算坐标增量 delta_y = y2 - y1; uRow = x1; uCol = y1; if (delta_x > 0) incx = 1; // 设置单步方向 else if (delta_x == 0) incx = 0; // 垂直线 else { incx = -1; delta_x = -delta_x; } if (delta_y > 0) incy = 1; else if (delta_y == 0) incy = 0; // 水平线 else { incy = -1; delta_y = -delta_y; } if (delta_x > delta_y) distance = delta_x; // 选取基本增量坐标轴 else distance = delta_y; for (t = 0; t <= distance + 1; t++) // 画线输出 { // WIN_GetWinStruct()->drawPoint (uRow,uCol,1); WIN_DrawPointSafe(uRow, uCol, 1); xerr += delta_x; yerr += delta_y; if (xerr > distance) { xerr -= distance; uRow += incx; } if (yerr > distance) { yerr -= distance; uCol += incy; } } } // 在指定位置画一个指定大小的圆 (x,y):中心点 r :半径 void WIN_DrawCircle(int x0, int y0, int r) { int a, b; int di; int c_x = 0; int c_y = 0; a = 0; b = r; di = 3 - (r << 1); // 判断下个点位置的标志 while (a <= b) { // 只绘制无效窗口内的屏幕 c_x = x0 + a; c_y = y0 - b; // WIN_GetWinStruct()->drawPoint (c_x,c_y,1); WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 + b; c_y = y0 - a; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 + b; c_y = y0 + a; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 + a; c_y = y0 + b; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 - a; c_y = y0 + b; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 - b; c_y = y0 + a; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 - a; c_y = y0 - b; WIN_DrawPointSafe(c_x, c_y, 1); c_x = x0 - b; c_y = y0 - a; WIN_DrawPointSafe(c_x, c_y, 1); a++; // 使用Bresenham算法画圆 if (di < 0) di += 4 * a + 6; else { di += 10 + 4 * (a - b); b--; } } } // 绘制连续线段 void WIN_DrawLines(POINT_Struct *Points, int PointCount) { for (int i = 0; i < PointCount - 1; i++) { WIN_DrawLine(Points[i].x, Points[i].y, Points[i + 1].x, Points[i + 1].y); } } // 绘制多边形 void WIN_DrawPolygon(POINT_Struct *Points, int PointCount) { int16_t X = 0, Y = 0; if (PointCount < 2) { return; } WIN_DrawLine(Points->x, Points->y, (Points + PointCount - 1)->x, (Points + PointCount - 1)->y); while (--PointCount) { X = Points->x; Y = Points->y; Points++; WIN_DrawLine(X, Y, Points->x, Points->y); } } // 绘制空心矩形 void WIN_DrawRect(int x, int y, int x_size, int y_size) { WIN_DrawHLine(x, y, x + x_size - 1); WIN_DrawHLine(x, y + y_size - 1, x + x_size - 1); WIN_DrawVLine(x, y, y + y_size - 1); WIN_DrawVLine(x + x_size - 1, y, y + y_size - 1); } // 创建一个抗锯齿绘图平面 WIN_PlaneAAStruct *WIN_CreatPlaneAA(int x, int y, int x_size, int y_size, int accuracy) { WIN_PlaneAAStruct *ret = mymalloc(sizeof(WIN_PlaneAAStruct) + x_size * y_size); if (ret) { ret->x = x; ret->y = y; ret->x_size = x_size; ret->y_size = y_size; ret->accuracy = accuracy; ret->avr = ret->accuracy * ret->accuracy; mymemset(ret->alpha, 0, x_size * y_size); } return ret; } // 删除一个抗锯齿平面 void WIN_DeletePlaneAA(WIN_PlaneAAStruct *p) { if (p == 0) return; myfree(p); } // 绘制一个抗锯齿绘图平面 void WIN_DrawPlaneAA(WIN_PlaneAAStruct *p) { if (p == 0) return; uint16_t color = WIN_GetLcdColor16(); uint8_t *alpha = 0; for (int y = 0; y < p->y_size; y++) { alpha = &p->alpha[y * p->x_size]; for (int x = 0; x < p->x_size; x++) { if (*alpha > 0x7) WIN_DrawPointSafeColorAlpha(x + p->x, y + p->y, color, *alpha >> 3); alpha++; } } } // 在平面内绘制抗锯齿点 // 这里的x,y是实际值乘以p->accuracy的值 void WIN_DrawPointAA(WIN_PlaneAAStruct *p, int x, int y) { if (p == 0) return; int x_s = x / p->accuracy; int y_s = y / p->accuracy; int x_e = x_s + 1; int y_e = y_s + 1; if (x_s < p->x || x_s > p->x + p->x_size - 1) return; if (y_s < p->y || y_s > p->y + p->y_size - 1) return; // 每个像素的细分程度,除以一个p->accuracy是这个虚拟像素在实际像素里的分量 // 再除以一个p->accuracy是因为上层步进值 int accuracy = p->accuracy; //*p->accuracy; int alpha_x = 16 - (x % p->accuracy) * 16 / p->accuracy; int alpha_y = 16 - (y % p->accuracy) * 16 / p->accuracy; uint8_t *point = 0; int point_ = 0; point = &p->alpha[p->x_size * (y_s - p->y) + (x_s - p->x)]; point_ = *point + alpha_x * alpha_y / accuracy; if (point_ > 0xff) point_ = 0xff; *point = point_; if (x_e < p->x + p->x_size) { point = &p->alpha[p->x_size * (y_s - p->y) + (x_e - p->x)]; point_ = *point + (16 - alpha_x) * alpha_y / accuracy; if (point_ > 0xff) point_ = 0xff; *point = point_; } if ((y_e < p->y + p->y_size) && (x_e < p->x + p->x_size)) { point = &p->alpha[p->x_size * (y_e - p->y) + (x_e - p->x)]; point_ = *point + (16 - alpha_x) * (16 - alpha_y) / accuracy; if (point_ > 0xff) point_ = 0xff; *point = point_; } if (y_e < p->y + p->y_size) { point = &p->alpha[p->x_size * (y_e - p->y) + (x_s - p->x)]; point_ = *point + alpha_x * (16 - alpha_y) / accuracy; if (point_ > 0xff) point_ = 0xff; *point = point_; } } // 在平面内画线 x1,y1:起点坐标 x2,y2:终点坐标 static void WIN_PlaneDrawLine(WIN_PlaneAAStruct *p, int x1, int y1, int x2, int y2) { if (p == 0) return; int t; int xerr = 0, yerr = 0, delta_x, delta_y, distance; int incx, incy, uRow, uCol; delta_x = x2 - x1; // 计算坐标增量 delta_y = y2 - y1; uRow = x1; uCol = y1; if (delta_x > 0) incx = 1; // 设置单步方向 else if (delta_x == 0) incx = 0; // 垂直线 else { incx = -1; delta_x = -delta_x; } if (delta_y > 0) incy = 1; else if (delta_y == 0) incy = 0; // 水平线 else { incy = -1; delta_y = -delta_y; } if (delta_x > delta_y) distance = delta_x; // 选取基本增量坐标轴 else distance = delta_y; for (t = 0; t <= distance + 1; t++) // 画线输出 { WIN_DrawPointAA(p, uRow, uCol); xerr += delta_x; yerr += delta_y; if (xerr > distance) { xerr -= distance; uRow += incx; } if (yerr > distance) { yerr -= distance; uCol += incy; } } } // 抗锯齿画线 void WIN_DrawLineAA(int x1, int y1, int x2, int y2, int accuracy) { int x = x1; if (x > x2) x = x2; int y = y1; if (y > y2) y = y2; int x_size = x1 - x2; if (x_size < 0) x_size = -x_size; int y_size = y1 - y2; if (y_size < 0) y_size = -y_size; x_size++; y_size++; WIN_PlaneAAStruct *p = WIN_CreatPlaneAA(x, y, x_size, y_size, 4); if (p) { x1 *= p->accuracy; y1 *= p->accuracy; x2 *= p->accuracy; y2 *= p->accuracy; WIN_PlaneDrawLine(p, x1, y1, x2, y2); WIN_DrawPlaneAA(p); WIN_DeletePlaneAA(p); } } // 用纯色填充矩形 void WIN_FillRectByColor(int x, int y, int x_size, int y_size) { RECT_Struct r1; RECT_Struct r2; RECT_Struct ret; r1.x = x; r1.x_size = x_size; r1.y = y; r1.y_size = y_size; r2.x = WIN_GetWinStruct()->Invalid_x; r2.x_size = WIN_GetWinStruct()->Invalid_x_size; r2.y = WIN_GetWinStruct()->Invalid_y; r2.y_size = WIN_GetWinStruct()->Invalid_y_size; // 绘制新矩形 if (POS_RectIntersection(&ret, &r1, &r2)) { // LCD_FillRectByColor (ret.x,ret.y,ret.x_size,ret.y_size); WIN_GetWinStruct()->lcd->fillRectByColor(ret.x, ret.y, ret.x_size, ret.y_size); } } // 用纯色和透明度填充矩形 void WIN_FillRectByColorAlpha(int x, int y, int x_size, int y_size, uint8_t alpha) { RECT_Struct r1; RECT_Struct r2; RECT_Struct ret; r1.x = x; r1.x_size = x_size; r1.y = y; r1.y_size = y_size; r2.x = WIN_GetWinStruct()->Invalid_x; r2.x_size = WIN_GetWinStruct()->Invalid_x_size; r2.y = WIN_GetWinStruct()->Invalid_y; r2.y_size = WIN_GetWinStruct()->Invalid_y_size; // 绘制新矩形 if (POS_RectIntersection(&ret, &r1, &r2)) { // LCD_FillRectByColorAlpha (ret.x,ret.y,ret.x_size,ret.y_size,alpha); WIN_GetWinStruct()->lcd->fillRectByColorAlpha(ret.x, ret.y, ret.x_size, ret.y_size, alpha); } } // 用背景图片填充矩形 void WIN_FillRect(int x, int y, int x_size, int y_size, uint16_t *buff, uint16_t pic_x, uint16_t pic_y, uint16_t pic_xsize, uint16_t pic_ysize) { RECT_Struct r1; RECT_Struct r2; RECT_Struct ret; r1.x = x; r1.x_size = x_size; r1.y = y; r1.y_size = y_size; r2.x = WIN_GetWinStruct()->Invalid_x; r2.x_size = WIN_GetWinStruct()->Invalid_x_size; r2.y = WIN_GetWinStruct()->Invalid_y; r2.y_size = WIN_GetWinStruct()->Invalid_y_size; // 绘制新矩形 if (POS_RectIntersection(&ret, &r1, &r2)) { // 把图片偏移到绘制区 pic_x += ret.x - x; pic_y += ret.y - y; WIN_GetWinStruct()->lcd->fillRectOffAt(ret.x, ret.y, ret.x_size, ret.y_size, buff, pic_x, pic_y, pic_xsize, pic_ysize); } } // 用带透明度的图片填充矩形 void WIN_FillRectAlpha(int x, int y, int x_size, int y_size, void *buff, uint16_t pic_x, uint16_t pic_y, uint16_t pic_xsize, uint16_t pic_ysize) { RECT_Struct r1; RECT_Struct r2; RECT_Struct ret; r1.x = x; r1.x_size = x_size; r1.y = y; r1.y_size = y_size; r2.x = WIN_GetWinStruct()->Invalid_x; r2.x_size = WIN_GetWinStruct()->Invalid_x_size; r2.y = WIN_GetWinStruct()->Invalid_y; r2.y_size = WIN_GetWinStruct()->Invalid_y_size; // 绘制新矩形 if (POS_RectIntersection(&ret, &r1, &r2)) { // 把图片偏移到绘制区 pic_x += ret.x - x; pic_y += ret.y - y; WIN_GetWinStruct()->lcd->fillRectOffAtAlpha(ret.x, ret.y, ret.x_size, ret.y_size, buff, pic_x, pic_y, pic_xsize, pic_ysize); } } // 填充三角形 #define ABS(X) ((X) > 0 ? (X) : -(X)) void WIN_FillTriangle(int x1, int x2, int x3, int y1, int y2, int y3) { int deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, curpixel = 0; deltax = ABS(x2 - x1); /* The difference between the x's */ deltay = ABS(y2 - y1); /* The difference between the y's */ x = x1; /* Start x off at the first pixel */ y = y1; /* Start y off at the first pixel */ if (x2 >= x1) /* The x-values are increasing */ { xinc1 = 1; xinc2 = 1; } else /* The x-values are decreasing */ { xinc1 = -1; xinc2 = -1; } if (y2 >= y1) /* The y-values are increasing */ { yinc1 = 1; yinc2 = 1; } else /* The y-values are decreasing */ { yinc1 = -1; yinc2 = -1; } if (deltax >= deltay) /* There is at least one x-value for every y-value */ { xinc1 = 0; /* Don't change the x when numerator >= denominator */ yinc2 = 0; /* Don't change the y for every iteration */ den = deltax; num = deltax / 2; numadd = deltay; numpixels = deltax; /* There are more x-values than y-values */ } else /* There is at least one y-value for every x-value */ { xinc2 = 0; /* Don't change the x for every iteration */ yinc1 = 0; /* Don't change the y when numerator >= denominator */ den = deltay; num = deltay / 2; numadd = deltax; numpixels = deltay; /* There are more y-values than x-values */ } for (curpixel = 0; curpixel <= numpixels; curpixel++) { WIN_DrawLine(x, y, x3, y3); num += numadd; /* Increase the numerator by the top of the fraction */ if (num >= den) /* Check if numerator >= denominator */ { num -= den; /* Calculate the new numerator value */ x += xinc1; /* Change the x as appropriate */ y += yinc1; /* Change the y as appropriate */ } x += xinc2; /* Change the x as appropriate */ y += yinc2; /* Change the y as appropriate */ } } // 填充多边形 #define POLY_X(Z) ((int32_t)((Points + (Z))->x)) #define POLY_Y(Z) ((int32_t)((Points + (Z))->y)) void WIN_FillPolygon(POINT_Struct *Points, int PointCount) { int X = 0, Y = 0, X2 = 0, Y2 = 0, X_center = 0, Y_center = 0, X_first = 0, Y_first = 0, pixelX = 0, pixelY = 0, counter = 0; int IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0; IMAGE_LEFT = IMAGE_RIGHT = Points->x; IMAGE_TOP = IMAGE_BOTTOM = Points->y; for (counter = 1; counter < PointCount; counter++) { pixelX = POLY_X(counter); if (pixelX < IMAGE_LEFT) { IMAGE_LEFT = pixelX; } if (pixelX > IMAGE_RIGHT) { IMAGE_RIGHT = pixelX; } pixelY = POLY_Y(counter); if (pixelY < IMAGE_TOP) { IMAGE_TOP = pixelY; } if (pixelY > IMAGE_BOTTOM) { IMAGE_BOTTOM = pixelY; } } if (PointCount < 2) { return; } X_center = (IMAGE_LEFT + IMAGE_RIGHT) / 2; Y_center = (IMAGE_BOTTOM + IMAGE_TOP) / 2; X_first = Points->x; Y_first = Points->y; while (--PointCount) { X = Points->x; Y = Points->y; Points++; X2 = Points->x; Y2 = Points->y; WIN_FillTriangle(X, X2, X_center, Y, Y2, Y_center); WIN_FillTriangle(X, X_center, X2, Y, Y_center, Y2); WIN_FillTriangle(X_center, X2, X, Y_center, Y2, Y); } WIN_FillTriangle(X_first, X2, X_center, Y_first, Y2, Y_center); WIN_FillTriangle(X_first, X_center, X2, Y_first, Y_center, Y2); WIN_FillTriangle(X_center, X2, X_first, Y_center, Y2, Y_first); } // 绘制图标,图标使用const数组编译在程序里,其本身已经附带了大小等参数 // 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数 void WIN_DrawImag(int x, int y, int xsize, int ysize, const uint8_t *buff) { if (buff == 0) return; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) || (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b)) return; uint16_t *imag = (uint16_t *)(buff + 8); if (xsize > w) xsize = w; if (ysize > h) ysize = h; for (int j = y; j < y + ysize; j++) { for (int i = 0; i < xsize; i++) { // WIN_GetWinStruct()->drawPointColor(i+x,j,imag[i]); WIN_DrawPointColorSafe(i + x, j, imag[i]); } imag += w; } } // 绘制图标,但是不绘制指定颜色 void WIN_DrawImagButColor(int x, int y, int xsize, int ysize, const uint8_t *buff, uint16_t color) { if (buff == 0) return; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) || (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b)) return; uint16_t *imag = (uint16_t *)(buff + 8); if (xsize > w) xsize = w; if (ysize > h) ysize = h; for (int j = y; j < y + ysize; j++) { for (int i = 0; i < xsize; i++) { if (imag[i] != color) // WIN_GetWinStruct()->drawPointColor (i+x,j,imag[i]); WIN_DrawPointColorSafe(i + x, j, imag[i]); } imag += w; } } // 绘制图标,把图像的有效部分绘制为指定颜色 // 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数 void WIN_DrawImagByColor(int x, int y, int xsize, int ysize, const uint8_t *buff, uint16_t color) { if (buff == 0) return; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) || (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b)) return; uint16_t *imag = (uint16_t *)(buff + 8); if (xsize > w) xsize = w; if (ysize > h) ysize = h; for (int j = y; j < y + ysize; j++) { for (int i = 0; i < xsize; i++) { if ((imag[i] != 0x0000) && (imag[i] != 0xffff)) // WIN_GetWinStruct()->drawPointColor (i+x,j,color); WIN_DrawPointColorSafe(i + x, j, color); } imag += w; } } // 绘制图标,把原图像转化为透明度,用指定颜色来绘制 // 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数 void WIN_DrawImagByAlpha(int x, int y, int xsize, int ysize, const uint8_t *buff, uint16_t color) { if (buff == 0) return; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) || (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b)) return; uint16_t *imag = (uint16_t *)(buff + 8); uint8_t r, g, b; uint8_t alpha = 0; if (xsize > w) xsize = w; if (ysize > h) ysize = h; for (int j = y; j < y + ysize; j++) { for (int i = 0; i < xsize; i++) { // 只绘制无效窗口内的屏幕 WIN_Struct *ewin = WIN_GetWinStruct(); if (POS_InRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size, i + x, j)) { // 白色全透明不绘制,加快速度 if ((imag[i] != 0x0000) && (imag[i] != 0xffff)) { // WIN_GetWinStruct()->drawPointColorAlpha // (i+x,j,color,31-(imag[i]>>11)); WIN_DrawPointSafeColorAlpha(i + x, j, color, 31 - (imag[i] >> 11)); } else if (imag[i] == 0x0000) { // 不透明直接画原来的颜色 // WIN_GetWinStruct()->drawPointColor (i+x,j,color); WIN_DrawPointColorSafe(i + x, j, color); } } } imag += w; } } // 绘制图标,把原图像转化为透明度,用指定颜色来绘制 // 此函数效率比较低,只用于绘制小图标,绘制图片使用矩形填充函数 void WIN_DrawImagByAlphaAnti(int x, int y, int xsize, int ysize, const uint8_t *buff, uint16_t color) { if (buff == 0) return; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) || (h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b)) return; uint16_t *imag = (uint16_t *)(buff + 8); uint8_t r, g, b; uint8_t alpha = 0; if (xsize > w) xsize = w; if (ysize > h) ysize = h; for (int j = y; j < y + ysize; j++) { for (int i = 0; i < xsize; i++) { // 只绘制无效窗口内的屏幕 WIN_Struct *ewin = WIN_GetWinStruct(); if (POS_InRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size, i + x, j)) { // 白色全透明不绘制,加快速度 if ((imag[i] != 0x0000) && (imag[i] != 0xffff)) { // WIN_GetWinStruct()->drawPointColorAlpha // (i+x,j,color,31-(imag[i]>>11)); WIN_DrawPointSafeColorAlpha(i + x, j, color, (imag[i] >> 11)); } else if (imag[i] == 0xffff) { // 不透明直接画原来的颜色 // WIN_GetWinStruct()->drawPointColor (i+x,j,color); WIN_DrawPointColorSafe(i + x, j, color); } } } imag += w; } } // 清空显示 void WIN_Clear(void) { WIN_Struct *ewin = WIN_GetWinStruct(); // LCD_ClearRect // (ewin->Invalid_x,ewin->Invalid_y,ewin->Invalid_x_size,ewin->Invalid_y_size); ewin->lcd->clearRect(ewin->Invalid_x, ewin->Invalid_y, ewin->Invalid_x_size, ewin->Invalid_y_size); } // 获得文字的矩形大小 void WIN_GetTxtRectSize(char *txt, int *x_size, int *y_size) { int font_h = WIN_GetFontHight(); int font_w = WIN_GetFontWidth() / 2; int max_num = 0; int now_num = 0; int line = 1; // 这里没有定义i=0;程序在优化之后产生总线错误 2020.2.26 for (int i = 0; txt[i]; i++) { if (txt[i] != '\n') { now_num++; } else { if (now_num > max_num) { max_num = now_num; now_num = 0; } line++; } } if (max_num < now_num + 1) max_num = now_num + 1; // 最后一行 *x_size = max_num * font_w; *y_size = line * font_h; } // 获得图像数据的尺寸,返回0,成功,非0,失败 int WIN_GetImageSize(uint8_t *buff, int *xsize, int *ysize) { if (buff == 0) return -1; uint8_t scan = buff[0]; uint8_t gray = buff[1]; uint16_t w = *((uint16_t *)&buff[2]); uint16_t h = *((uint16_t *)&buff[4]); uint8_t is565 = buff[6]; uint8_t rgb = buff[7]; // 必须所有参数都符合要求 if ((scan != 0x00) || (gray != 0x10) || (is565 != 0x01) || (rgb != 0x1b)) return -1; *xsize = w; *ysize = h; return 0; }