186 lines
4.2 KiB
C++
186 lines
4.2 KiB
C++
// Anti-aliased functions - for test purposes only
|
|
// TODO: optimise and incorporate in TFT_eSPI
|
|
|
|
// Support
|
|
#define iround(X) ((uint16_t)(((float)(X))+0.5))
|
|
|
|
// Alphablend specified color with sprite background pixel and plot in sprite at x,y
|
|
void plotPixel(int16_t x, int16_t y, uint16_t color, float alpha) {
|
|
if (alpha > 0.996) { face.drawPixel(x, y, color); return; }
|
|
alpha = alpha * ALPHA_GAIN;
|
|
// Clip alpha
|
|
if (alpha > 255) alpha = 255;
|
|
//Blend color with background and plot
|
|
face.drawPixel(x, y, face.alphaBlend((uint8_t)alpha, color, face.readPixel(x, y)));
|
|
}
|
|
|
|
// AA circle outline
|
|
void drawCircleAA( int16_t x, int16_t y, int16_t radius, uint16_t color ) {
|
|
drawRoundRectangleAntialiased(x - radius, y - radius, radius << 1, radius << 1, radius, radius, color);
|
|
}
|
|
|
|
// AA filled circle
|
|
void fillCircleAA( int16_t x, int16_t y, int16_t radius, uint16_t color ) {
|
|
drawRoundRectangleAntialiased(x - radius, y - radius, radius << 1, radius << 1, radius, radius, color);
|
|
face.fillCircle(x, y, radius, color);
|
|
}
|
|
|
|
// AA circle and rounded rectangle support
|
|
void drawRoundRectangleAntialiased(int16_t x, int16_t y, int16_t width, int16_t height, int16_t rx, int16_t ry, uint16_t color) {
|
|
|
|
int16_t i;
|
|
int32_t a2, b2, ds, dt, dxt, t, s, d;
|
|
int16_t xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2;
|
|
float cp;
|
|
float sab;
|
|
float weight, iweight;
|
|
|
|
if ((rx < 0) || (ry < 0)) {
|
|
return;
|
|
}
|
|
|
|
// Temporary - should really draw a box if corner radius is zero...
|
|
if (rx == 0) {
|
|
face.drawFastVLine(x, y - ry, y + ry, color);
|
|
return;
|
|
}
|
|
|
|
if (ry == 0) {
|
|
face.drawFastHLine(x - rx, y, x + rx, color);
|
|
return;
|
|
}
|
|
|
|
a2 = rx * rx;
|
|
b2 = ry * ry;
|
|
|
|
ds = a2 << 1;
|
|
dt = b2 << 1;
|
|
|
|
xc2 = x << 1;
|
|
yc2 = y << 1;
|
|
|
|
sab = sqrt((float)(a2 + b2));
|
|
od = (int)iround(sab * 0.01) + 1;
|
|
dxt = (int)iround((float)a2 / sab) + od;
|
|
|
|
t = 0;
|
|
s = -2 * a2 * ry;
|
|
d = 0;
|
|
|
|
xp = x + rx;
|
|
yp = y;
|
|
|
|
// Sides - may need to reduce color brightness to visually match anti-aliased corners
|
|
face.drawFastHLine(x + rx, y + height, 2 * rx - width + 1, color);
|
|
face.drawFastHLine(x + rx, y, 2 * rx - width + 1, color);
|
|
face.drawFastVLine(x + width, y + ry, 2 * ry - height + 1, color);
|
|
face.drawFastVLine(x, y + ry, 2 * ry - height + 1, color);
|
|
|
|
for (i = 1; i <= dxt; i++) {
|
|
xp--;
|
|
d += t - b2;
|
|
|
|
if (d >= 0) {
|
|
ys = yp - 1;
|
|
} else if ((d - s - a2) > 0) {
|
|
if (((d << 1) - s - a2) >= 0) {
|
|
ys = yp + 1;
|
|
} else {
|
|
ys = yp;
|
|
yp++;
|
|
d -= s + a2;
|
|
s += ds;
|
|
}
|
|
} else {
|
|
yp++;
|
|
ys = yp + 1;
|
|
d -= s + a2;
|
|
s += ds;
|
|
}
|
|
|
|
t -= dt;
|
|
|
|
if (s != 0) {
|
|
cp = (float) abs(d) / (float) abs(s);
|
|
if (cp > 1.0) {
|
|
cp = 1.0f;
|
|
}
|
|
} else {
|
|
cp = 1.0f;
|
|
}
|
|
|
|
weight = cp;
|
|
iweight = 1 - weight;
|
|
|
|
|
|
xx = xc2 - xp;
|
|
plotPixel(xp, yp, color, iweight);
|
|
plotPixel(xx + width, yp, color, iweight);
|
|
|
|
plotPixel(xp, ys, color, weight);
|
|
plotPixel(xx + width, ys, color, weight);
|
|
|
|
yy = yc2 - yp;
|
|
plotPixel(xp, yy + height, color, iweight);
|
|
plotPixel(xx + width, yy + height, color, iweight);
|
|
|
|
yy = yc2 - ys;
|
|
plotPixel(xp, yy + height, color, weight);
|
|
plotPixel(xx + width, yy + height, color, weight);
|
|
}
|
|
|
|
dyt = (int)iround((float)b2 / sab ) + od;
|
|
|
|
for (i = 1; i <= dyt; i++) {
|
|
yp++;
|
|
d -= s + a2;
|
|
|
|
if (d <= 0) {
|
|
xs = xp + 1;
|
|
} else if ((d + t - b2) < 0) {
|
|
if (((d << 1) + t - b2) <= 0) {
|
|
xs = xp - 1;
|
|
} else {
|
|
xs = xp;
|
|
xp--;
|
|
d += t - b2;
|
|
t -= dt;
|
|
}
|
|
} else {
|
|
xp--;
|
|
xs = xp - 1;
|
|
d += t - b2;
|
|
t -= dt;
|
|
}
|
|
|
|
s += ds;
|
|
|
|
if (t != 0) {
|
|
cp = (float) abs(d) / (float) abs(t);
|
|
if (cp > 1.0) {
|
|
cp = 1.0f;
|
|
}
|
|
} else {
|
|
cp = 1.0f;
|
|
}
|
|
|
|
weight = cp;
|
|
iweight = 1 - weight;
|
|
|
|
xx = xc2 - xp;
|
|
yy = yc2 - yp;
|
|
plotPixel(xp, yp, color, iweight);
|
|
plotPixel(xx + width, yp, color, iweight);
|
|
|
|
plotPixel(xp, yy + height, color, iweight);
|
|
plotPixel(xx + width, yy + height, color, iweight);
|
|
|
|
xx = xc2 - xs;
|
|
plotPixel(xs, yp, color, weight);
|
|
plotPixel(xx + width, yp, color, weight);
|
|
|
|
plotPixel(xs, yy + height, color, weight);
|
|
plotPixel(xx + width, yy + height, color, weight);
|
|
}
|
|
}
|