991 lines
26 KiB
C
991 lines
26 KiB
C
#include "mywin_inc.h"
|
||
|
||
u32 WIN_SetLcdColor(u32 color) {
|
||
WIN_Struct *ewin = WIN_GetWinStruct();
|
||
u32 co = ewin->lcd->getLcdColor();
|
||
u32 ret = COLOR565TO888(co);
|
||
ewin->lcd->setLcdColor(COLOR888TO565(color));
|
||
return ret;
|
||
}
|
||
|
||
u32 WIN_SetLcdBkColor(u32 color) {
|
||
WIN_Struct *ewin = WIN_GetWinStruct();
|
||
u32 co = ewin->lcd->getLcdBkColor();
|
||
u32 ret = COLOR565TO888(co);
|
||
ewin->lcd->setLcdBkColor(COLOR888TO565(color));
|
||
return ret;
|
||
}
|
||
|
||
u16 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, u32 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, u32 color) {
|
||
WIN_Struct *ewin = WIN_GetWinStruct();
|
||
ewin->lcd->drawPointColor(x, y, color);
|
||
}
|
||
|
||
void WIN_DrawPointSafeColorAlpha(int x, int y, u16 color, u8 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 u32 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 u32 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, u16 color, u8 dis) {
|
||
u8 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;
|
||
u16 color = WIN_GetLcdColor16();
|
||
u8 *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;
|
||
if (p->alpha == 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;
|
||
|
||
u8 *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, u8 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, u16 *buff, u16 pic_x,
|
||
u16 pic_y, u16 pic_xsize, u16 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,
|
||
u16 pic_x, u16 pic_y, u16 pic_xsize, u16 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 u8 *buff) {
|
||
|
||
if (buff == 0)
|
||
return;
|
||
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
|
||
(h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return;
|
||
|
||
u16 *imag = (u16 *)(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 u8 *buff,
|
||
u16 color) {
|
||
|
||
if (buff == 0)
|
||
return;
|
||
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
|
||
(h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return;
|
||
|
||
u16 *imag = (u16 *)(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 u8 *buff,
|
||
u16 color) {
|
||
|
||
if (buff == 0)
|
||
return;
|
||
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
|
||
(h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return;
|
||
|
||
u16 *imag = (u16 *)(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 u8 *buff,
|
||
u16 color) {
|
||
|
||
if (buff == 0)
|
||
return;
|
||
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
|
||
(h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return;
|
||
|
||
u16 *imag = (u16 *)(buff + 8);
|
||
u8 r, g, b;
|
||
u8 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 u8 *buff,
|
||
u16 color) {
|
||
|
||
if (buff == 0)
|
||
return;
|
||
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (w > WIN_IMAGE_MAXSIZE) ||
|
||
(h > WIN_IMAGE_MAXSIZE) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return;
|
||
|
||
u16 *imag = (u16 *)(buff + 8);
|
||
u8 r, g, b;
|
||
u8 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(u8 *buff, int *xsize, int *ysize) {
|
||
|
||
if (buff == 0)
|
||
return -1;
|
||
u8 scan = buff[0];
|
||
u8 gray = buff[1];
|
||
u16 w = *((u16 *)&buff[2]);
|
||
u16 h = *((u16 *)&buff[4]);
|
||
u8 is565 = buff[6];
|
||
u8 rgb = buff[7];
|
||
|
||
// 必须所有参数都符合要求
|
||
if ((scan != 0x00) || (gray != 0x10) || (is565 != 0x01) || (rgb != 0x1b))
|
||
return -1;
|
||
|
||
*xsize = w;
|
||
*ysize = h;
|
||
return 0;
|
||
}
|