feat: 全量同步 254 个常用的 Arduino 扩展库文件
This commit is contained in:
@@ -0,0 +1,686 @@
|
||||
#include "M5Display.h"
|
||||
|
||||
#ifdef M5Stack_M5Core2
|
||||
#include <M5Touch.h>
|
||||
#endif /* M5Stack_M5Core2 */
|
||||
|
||||
#define BLK_PWM_CHANNEL 7 // LEDC_CHANNEL_7
|
||||
|
||||
// So we can use this instance without including all of M5Core2 / M5Stack
|
||||
M5Display* M5Display::instance;
|
||||
|
||||
M5Display::M5Display() : TFT_eSPI() {
|
||||
if (!instance) instance = this;
|
||||
}
|
||||
|
||||
void M5Display::begin() {
|
||||
TFT_eSPI::begin();
|
||||
setRotation(1);
|
||||
fillScreen(0);
|
||||
|
||||
// Init the back-light LED PWM
|
||||
ledcSetup(BLK_PWM_CHANNEL, 44100, 8);
|
||||
ledcAttachPin(TFT_BL, BLK_PWM_CHANNEL);
|
||||
ledcWrite(BLK_PWM_CHANNEL, 80);
|
||||
}
|
||||
|
||||
void M5Display::sleep() {
|
||||
startWrite();
|
||||
writecommand(ILI9341_SLPIN); // Software reset
|
||||
endWrite();
|
||||
}
|
||||
|
||||
void M5Display::wakeup() {
|
||||
startWrite();
|
||||
writecommand(ILI9341_SLPOUT);
|
||||
endWrite();
|
||||
}
|
||||
|
||||
void M5Display::setBrightness(uint8_t brightness) {
|
||||
ledcWrite(BLK_PWM_CHANNEL, brightness);
|
||||
}
|
||||
|
||||
void M5Display::drawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, const uint16_t *data) {
|
||||
bool swap = getSwapBytes();
|
||||
setSwapBytes(true);
|
||||
pushImage((int32_t)x0, (int32_t)y0, (uint32_t)w, (uint32_t)h, data);
|
||||
setSwapBytes(swap);
|
||||
}
|
||||
|
||||
void M5Display::drawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, uint16_t *data) {
|
||||
bool swap = getSwapBytes();
|
||||
setSwapBytes(true);
|
||||
pushImage((int32_t)x0, (int32_t)y0, (uint32_t)w, (uint32_t)h, data);
|
||||
setSwapBytes(swap);
|
||||
}
|
||||
|
||||
void M5Display::drawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, const uint16_t *data, uint16_t transparent) {
|
||||
bool swap = getSwapBytes();
|
||||
setSwapBytes(true);
|
||||
pushImage((int32_t)x0, (int32_t)y0, (uint32_t)w, (uint32_t)h, data, transparent);
|
||||
setSwapBytes(swap);
|
||||
}
|
||||
|
||||
void M5Display::drawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, const uint8_t *data) {
|
||||
bool swap = getSwapBytes();
|
||||
setSwapBytes(true);
|
||||
pushImage((int32_t)x0, (int32_t)y0, (uint32_t)w, (uint32_t)h, (const uint16_t*)data);
|
||||
setSwapBytes(swap);
|
||||
}
|
||||
|
||||
void M5Display::drawBitmap(int16_t x0, int16_t y0, int16_t w, int16_t h, uint8_t *data) {
|
||||
bool swap = getSwapBytes();
|
||||
setSwapBytes(true);
|
||||
pushImage((int32_t)x0, (int32_t)y0, (uint32_t)w, (uint32_t)h, (uint16_t*)data);
|
||||
setSwapBytes(swap);
|
||||
}
|
||||
|
||||
void M5Display::progressBar(int x, int y, int w, int h, uint8_t val) {
|
||||
drawRect(x, y, w, h, 0x09F1);
|
||||
fillRect(x + 1, y + 1, w * (((float)val) / 100.0), h - 1, 0x09F1);
|
||||
}
|
||||
|
||||
#include "utility/qrcode.h"
|
||||
void M5Display::qrcode(const char *string, uint16_t x, uint16_t y, uint8_t width, uint8_t version) {
|
||||
|
||||
// Create the QR code
|
||||
QRCode qrcode;
|
||||
uint8_t qrcodeData[qrcode_getBufferSize(version)];
|
||||
qrcode_initText(&qrcode, qrcodeData, version, 0, string);
|
||||
|
||||
// Top quiet zone
|
||||
uint8_t thickness = width / qrcode.size;
|
||||
uint16_t lineLength = qrcode.size * thickness;
|
||||
uint8_t xOffset = x + (width-lineLength)/2;
|
||||
uint8_t yOffset = y + (width-lineLength)/2;
|
||||
fillRect(x, y, width, width, TFT_WHITE);
|
||||
|
||||
for (uint8_t y = 0; y < qrcode.size; y++) {
|
||||
for (uint8_t x = 0; x < qrcode.size; x++) {
|
||||
uint8_t q = qrcode_getModule(&qrcode, x, y);
|
||||
if (q) fillRect(x * thickness + xOffset, y * thickness + yOffset, thickness, thickness, TFT_BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void M5Display::qrcode(const String &string, uint16_t x, uint16_t y, uint8_t width, uint8_t version) {
|
||||
int16_t len = string.length() + 2;
|
||||
char buffer[len];
|
||||
string.toCharArray(buffer, len);
|
||||
qrcode(buffer, x, y, width, version);
|
||||
}
|
||||
|
||||
// These read 16- and 32-bit types from the SD card file.
|
||||
// BMP data is stored little-endian, Arduino is little-endian too.
|
||||
// May need to reverse subscript order if porting elsewhere.
|
||||
|
||||
uint16_t read16(fs::File &f) {
|
||||
uint16_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t read32(fs::File &f) {
|
||||
uint32_t result;
|
||||
((uint8_t *)&result)[0] = f.read(); // LSB
|
||||
((uint8_t *)&result)[1] = f.read();
|
||||
((uint8_t *)&result)[2] = f.read();
|
||||
((uint8_t *)&result)[3] = f.read(); // MSB
|
||||
return result;
|
||||
}
|
||||
|
||||
// Bodmers BMP image rendering function
|
||||
void M5Display::drawBmpFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y) {
|
||||
if ((x >= width()) || (y >= height())) return;
|
||||
|
||||
// Open requested file on SD card
|
||||
File bmpFS = fs.open(path, "r");
|
||||
|
||||
if (!bmpFS) {
|
||||
Serial.print("File not found");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t seekOffset;
|
||||
uint16_t w, h, row, col;
|
||||
uint8_t r, g, b;
|
||||
|
||||
uint32_t startTime = millis();
|
||||
|
||||
if (read16(bmpFS) == 0x4D42) {
|
||||
read32(bmpFS);
|
||||
read32(bmpFS);
|
||||
seekOffset = read32(bmpFS);
|
||||
read32(bmpFS);
|
||||
w = read32(bmpFS);
|
||||
h = read32(bmpFS);
|
||||
|
||||
if ((read16(bmpFS) == 1) && (read16(bmpFS) == 24) && (read32(bmpFS) == 0)) {
|
||||
y += h - 1;
|
||||
|
||||
setSwapBytes(true);
|
||||
bmpFS.seek(seekOffset);
|
||||
|
||||
uint16_t padding = (4 - ((w * 3) & 3)) & 3;
|
||||
uint8_t lineBuffer[w * 3 + padding];
|
||||
|
||||
for (row = 0; row < h; row++) {
|
||||
bmpFS.read(lineBuffer, sizeof(lineBuffer));
|
||||
uint8_t* bptr = lineBuffer;
|
||||
uint16_t* tptr = (uint16_t*)lineBuffer;
|
||||
// Convert 24 to 16 bit colours
|
||||
for (col = 0; col < w; col++) {
|
||||
b = *bptr++;
|
||||
g = *bptr++;
|
||||
r = *bptr++;
|
||||
*tptr++ = ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
|
||||
}
|
||||
|
||||
// Push the pixel row to screen, pushImage will crop the line if needed
|
||||
// y is decremented as the BMP image is drawn bottom up
|
||||
pushImage(x, y--, w, 1, (uint16_t*)lineBuffer);
|
||||
}
|
||||
Serial.print("Loaded in "); Serial.print(millis() - startTime);
|
||||
Serial.println(" ms");
|
||||
}
|
||||
else Serial.println("BMP format not recognized.");
|
||||
}
|
||||
bmpFS.close();
|
||||
}
|
||||
|
||||
// void M5Display::drawBmp(fs::FS &fs, const char *path, uint16_t x, uint16_t y) {
|
||||
// drawBmpFile(fs, path, x, y);
|
||||
// }
|
||||
/***************************************************
|
||||
This library is written to be compatible with Adafruit's ILI9341
|
||||
library and automatically detects the display type on ESP_WROVER_KITs
|
||||
Earlier WROVERs had ILI9341, while newer releases have ST7789V
|
||||
|
||||
MIT license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
/*
|
||||
* JPEG
|
||||
*/
|
||||
|
||||
#include "rom/tjpgd.h"
|
||||
|
||||
#define jpgColor(c) \
|
||||
(((uint16_t)(((uint8_t *)(c))[0] & 0xF8) << 8) | \
|
||||
((uint16_t)(((uint8_t *)(c))[1] & 0xFC) << 3) | \
|
||||
((((uint8_t *)(c))[2] & 0xF8) >> 3))
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
|
||||
const char *jd_errors[] = {"Succeeded",
|
||||
"Interrupted by output function",
|
||||
"Device error or wrong termination of input stream",
|
||||
"Insufficient memory pool for the image",
|
||||
"Insufficient stream input buffer",
|
||||
"Parameter error",
|
||||
"Data format error",
|
||||
"Right format but not supported",
|
||||
"Not supported JPEG standard"};
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t maxWidth;
|
||||
uint16_t maxHeight;
|
||||
uint16_t offX;
|
||||
uint16_t offY;
|
||||
jpeg_div_t scale;
|
||||
const void *src;
|
||||
size_t len;
|
||||
size_t index;
|
||||
M5Display *tft;
|
||||
uint16_t outWidth;
|
||||
uint16_t outHeight;
|
||||
} jpg_file_decoder_t;
|
||||
|
||||
static uint32_t jpgReadFile(JDEC *decoder, uint8_t *buf, uint32_t len) {
|
||||
jpg_file_decoder_t *jpeg = (jpg_file_decoder_t *)decoder->device;
|
||||
File *file = (File *)jpeg->src;
|
||||
if (buf) {
|
||||
return file->read(buf, len);
|
||||
} else {
|
||||
file->seek(len, SeekCur);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static uint32_t jpgRead(JDEC *decoder, uint8_t *buf, uint32_t len) {
|
||||
jpg_file_decoder_t *jpeg = (jpg_file_decoder_t *)decoder->device;
|
||||
if (buf) {
|
||||
memcpy(buf, (const uint8_t *)jpeg->src + jpeg->index, len);
|
||||
}
|
||||
jpeg->index += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
static uint32_t jpgWrite(JDEC *decoder, void *bitmap, JRECT *rect) {
|
||||
jpg_file_decoder_t *jpeg = (jpg_file_decoder_t *)decoder->device;
|
||||
uint16_t x = rect->left;
|
||||
uint16_t y = rect->top;
|
||||
uint16_t w = rect->right + 1 - x;
|
||||
uint16_t h = rect->bottom + 1 - y;
|
||||
uint16_t oL = 0, oR = 0;
|
||||
uint8_t *data = (uint8_t *)bitmap;
|
||||
|
||||
if (rect->right < jpeg->offX) {
|
||||
return 1;
|
||||
}
|
||||
if (rect->left >= (jpeg->offX + jpeg->outWidth)) {
|
||||
return 1;
|
||||
}
|
||||
if (rect->bottom < jpeg->offY) {
|
||||
return 1;
|
||||
}
|
||||
if (rect->top >= (jpeg->offY + jpeg->outHeight)) {
|
||||
return 1;
|
||||
}
|
||||
if (rect->top < jpeg->offY) {
|
||||
uint16_t linesToSkip = jpeg->offY - rect->top;
|
||||
data += linesToSkip * w * 3;
|
||||
h -= linesToSkip;
|
||||
y += linesToSkip;
|
||||
}
|
||||
if (rect->bottom >= (jpeg->offY + jpeg->outHeight)) {
|
||||
uint16_t linesToSkip = (rect->bottom + 1) - (jpeg->offY + jpeg->outHeight);
|
||||
h -= linesToSkip;
|
||||
}
|
||||
if (rect->left < jpeg->offX) {
|
||||
oL = jpeg->offX - rect->left;
|
||||
}
|
||||
if (rect->right >= (jpeg->offX + jpeg->outWidth)) {
|
||||
oR = (rect->right + 1) - (jpeg->offX + jpeg->outWidth);
|
||||
}
|
||||
|
||||
uint16_t pixBuf[32];
|
||||
uint8_t pixIndex = 0;
|
||||
uint16_t line;
|
||||
|
||||
jpeg->tft->startWrite();
|
||||
// jpeg->tft->setAddrWindow(x - jpeg->offX + jpeg->x + oL, y - jpeg->offY +
|
||||
// jpeg->y, w - (oL + oR), h);
|
||||
jpeg->tft->setWindow(x - jpeg->offX + jpeg->x + oL,
|
||||
y - jpeg->offY + jpeg->y,
|
||||
x - jpeg->offX + jpeg->x + oL + w - (oL + oR) - 1,
|
||||
y - jpeg->offY + jpeg->y + h - 1);
|
||||
|
||||
while (h--) {
|
||||
data += 3 * oL;
|
||||
line = w - (oL + oR);
|
||||
while (line--) {
|
||||
pixBuf[pixIndex++] = jpgColor(data);
|
||||
data += 3;
|
||||
if (pixIndex == 32) {
|
||||
jpeg->tft->writePixels(pixBuf, 32);
|
||||
// SPI.writePixels((uint8_t *)pixBuf, 64);
|
||||
pixIndex = 0;
|
||||
}
|
||||
}
|
||||
data += 3 * oR;
|
||||
}
|
||||
if (pixIndex) {
|
||||
jpeg->tft->writePixels(pixBuf, pixIndex);
|
||||
// SPI.writePixels((uint8_t *)pixBuf, pixIndex * 2);
|
||||
}
|
||||
jpeg->tft->endWrite();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool jpgDecode(jpg_file_decoder_t *jpeg,
|
||||
uint32_t (*reader)(JDEC *, uint8_t *, uint32_t)) {
|
||||
static uint8_t work[3100];
|
||||
JDEC decoder;
|
||||
|
||||
JRESULT jres = jd_prepare(&decoder, reader, work, 3100, jpeg);
|
||||
if (jres != JDR_OK) {
|
||||
log_e("jd_prepare failed! %s", jd_errors[jres]);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t jpgWidth = decoder.width / (1 << (uint8_t)(jpeg->scale));
|
||||
uint16_t jpgHeight = decoder.height / (1 << (uint8_t)(jpeg->scale));
|
||||
|
||||
if (jpeg->offX >= jpgWidth || jpeg->offY >= jpgHeight) {
|
||||
log_e("Offset Outside of JPEG size");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t jpgMaxWidth = jpgWidth - jpeg->offX;
|
||||
size_t jpgMaxHeight = jpgHeight - jpeg->offY;
|
||||
|
||||
jpeg->outWidth =
|
||||
(jpgMaxWidth > jpeg->maxWidth) ? jpeg->maxWidth : jpgMaxWidth;
|
||||
jpeg->outHeight =
|
||||
(jpgMaxHeight > jpeg->maxHeight) ? jpeg->maxHeight : jpgMaxHeight;
|
||||
|
||||
jres = jd_decomp(&decoder, jpgWrite, (uint8_t)jpeg->scale);
|
||||
if (jres != JDR_OK) {
|
||||
log_e("jd_decomp failed! %s", jd_errors[jres]);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void M5Display::drawJpg(const uint8_t *jpg_data, size_t jpg_len, uint16_t x,
|
||||
uint16_t y, uint16_t maxWidth, uint16_t maxHeight,
|
||||
uint16_t offX, uint16_t offY, jpeg_div_t scale) {
|
||||
if ((x + maxWidth) > width() || (y + maxHeight) > height()) {
|
||||
log_e("Bad dimensions given");
|
||||
return;
|
||||
}
|
||||
|
||||
jpg_file_decoder_t jpeg;
|
||||
|
||||
if (!maxWidth) {
|
||||
maxWidth = width() - x;
|
||||
}
|
||||
if (!maxHeight) {
|
||||
maxHeight = height() - y;
|
||||
}
|
||||
|
||||
jpeg.src = jpg_data;
|
||||
jpeg.len = jpg_len;
|
||||
jpeg.index = 0;
|
||||
jpeg.x = x;
|
||||
jpeg.y = y;
|
||||
jpeg.maxWidth = maxWidth;
|
||||
jpeg.maxHeight = maxHeight;
|
||||
jpeg.offX = offX;
|
||||
jpeg.offY = offY;
|
||||
jpeg.scale = scale;
|
||||
jpeg.tft = this;
|
||||
|
||||
jpgDecode(&jpeg, jpgRead);
|
||||
}
|
||||
|
||||
void M5Display::drawJpgFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y,
|
||||
uint16_t maxWidth, uint16_t maxHeight, uint16_t offX,
|
||||
uint16_t offY, jpeg_div_t scale) {
|
||||
if ((x + maxWidth) > width() || (y + maxHeight) > height()) {
|
||||
log_e("Bad dimensions given");
|
||||
return;
|
||||
}
|
||||
|
||||
File file = fs.open(path);
|
||||
if (!file) {
|
||||
log_e("Failed to open file for reading");
|
||||
return;
|
||||
}
|
||||
|
||||
jpg_file_decoder_t jpeg;
|
||||
|
||||
if (!maxWidth) {
|
||||
maxWidth = width() - x;
|
||||
}
|
||||
if (!maxHeight) {
|
||||
maxHeight = height() - y;
|
||||
}
|
||||
|
||||
jpeg.src = &file;
|
||||
jpeg.len = file.size();
|
||||
jpeg.index = 0;
|
||||
jpeg.x = x;
|
||||
jpeg.y = y;
|
||||
jpeg.maxWidth = maxWidth;
|
||||
jpeg.maxHeight = maxHeight;
|
||||
jpeg.offX = offX;
|
||||
jpeg.offY = offY;
|
||||
jpeg.scale = scale;
|
||||
jpeg.tft = this;
|
||||
|
||||
jpgDecode(&jpeg, jpgReadFile);
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PNG
|
||||
*/
|
||||
|
||||
#include "utility/pngle.h"
|
||||
#include <HTTPClient.h>
|
||||
|
||||
typedef struct _png_draw_params {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t maxWidth;
|
||||
uint16_t maxHeight;
|
||||
uint16_t offX;
|
||||
uint16_t offY;
|
||||
double scale;
|
||||
uint8_t alphaThreshold;
|
||||
|
||||
M5Display *tft;
|
||||
} png_file_decoder_t;
|
||||
|
||||
static void pngle_draw_callback(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])
|
||||
{
|
||||
png_file_decoder_t *p = (png_file_decoder_t *)pngle_get_user_data(pngle);
|
||||
uint16_t color = jpgColor(rgba); // XXX: It's PNG ;)
|
||||
|
||||
if (x < p->offX || y < p->offY) return ;
|
||||
x -= p->offX;
|
||||
y -= p->offY;
|
||||
|
||||
// An interlaced file with alpha channel causes disaster, so use 1 here for simplicity
|
||||
w = 1;
|
||||
h = 1;
|
||||
|
||||
if (p->scale != 1.0) {
|
||||
x = (uint32_t)ceil(x * p->scale);
|
||||
y = (uint32_t)ceil(y * p->scale);
|
||||
w = (uint32_t)ceil(w * p->scale);
|
||||
h = (uint32_t)ceil(h * p->scale);
|
||||
}
|
||||
|
||||
if (x >= p->maxWidth || y >= p->maxHeight) return ;
|
||||
if (x + w >= p->maxWidth) w = p->maxWidth - x;
|
||||
if (y + h >= p->maxHeight) h = p->maxHeight - y;
|
||||
|
||||
x += p->x;
|
||||
y += p->y;
|
||||
|
||||
if (rgba[3] >= p->alphaThreshold) {
|
||||
p->tft->fillRect(x, y, w, h, color);
|
||||
}
|
||||
}
|
||||
|
||||
void M5Display::drawPngFile(fs::FS &fs, const char *path, uint16_t x, uint16_t y,
|
||||
uint16_t maxWidth, uint16_t maxHeight, uint16_t offX,
|
||||
uint16_t offY, double scale, uint8_t alphaThreshold)
|
||||
{
|
||||
File file = fs.open(path);
|
||||
if (!file) {
|
||||
log_e("Failed to open file for reading");
|
||||
return ;
|
||||
}
|
||||
|
||||
pngle_t *pngle = pngle_new();
|
||||
|
||||
png_file_decoder_t png;
|
||||
|
||||
if (!maxWidth) {
|
||||
maxWidth = width() - x;
|
||||
}
|
||||
if (!maxHeight) {
|
||||
maxHeight = height() - y;
|
||||
}
|
||||
|
||||
png.x = x;
|
||||
png.y = y;
|
||||
png.maxWidth = maxWidth;
|
||||
png.maxHeight = maxHeight;
|
||||
png.offX = offX;
|
||||
png.offY = offY;
|
||||
png.scale = scale;
|
||||
png.alphaThreshold = alphaThreshold;
|
||||
png.tft = this;
|
||||
|
||||
pngle_set_user_data(pngle, &png);
|
||||
pngle_set_draw_callback(pngle, pngle_draw_callback);
|
||||
|
||||
// Feed data to pngle
|
||||
uint8_t buf[1024];
|
||||
int remain = 0;
|
||||
int len;
|
||||
while ((len = file.read(buf + remain, sizeof(buf) - remain)) > 0) {
|
||||
int fed = pngle_feed(pngle, buf, remain + len);
|
||||
if (fed < 0) {
|
||||
log_e("[pngle error] %s", pngle_error(pngle));
|
||||
break;
|
||||
}
|
||||
|
||||
remain = remain + len - fed;
|
||||
if (remain > 0) memmove(buf, buf + fed, remain);
|
||||
}
|
||||
|
||||
pngle_destroy(pngle);
|
||||
file.close();
|
||||
}
|
||||
|
||||
void M5Display::drawPngUrl(const char *url, uint16_t x, uint16_t y,
|
||||
uint16_t maxWidth, uint16_t maxHeight, uint16_t offX,
|
||||
uint16_t offY, double scale, uint8_t alphaThreshold)
|
||||
{
|
||||
HTTPClient http;
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
log_e("Not connected");
|
||||
return ;
|
||||
}
|
||||
|
||||
http.begin(url);
|
||||
|
||||
int httpCode = http.GET();
|
||||
if (httpCode != HTTP_CODE_OK) {
|
||||
log_e("HTTP ERROR: %d\n", httpCode);
|
||||
http.end();
|
||||
return ;
|
||||
}
|
||||
|
||||
WiFiClient *stream = http.getStreamPtr();
|
||||
|
||||
pngle_t *pngle = pngle_new();
|
||||
|
||||
png_file_decoder_t png;
|
||||
|
||||
if (!maxWidth) {
|
||||
maxWidth = width() - x;
|
||||
}
|
||||
if (!maxHeight) {
|
||||
maxHeight = height() - y;
|
||||
}
|
||||
|
||||
|
||||
png.x = x;
|
||||
png.y = y;
|
||||
png.maxWidth = maxWidth;
|
||||
png.maxHeight = maxHeight;
|
||||
png.offX = offX;
|
||||
png.offY = offY;
|
||||
png.scale = scale;
|
||||
png.alphaThreshold = alphaThreshold;
|
||||
png.tft = this;
|
||||
|
||||
pngle_set_user_data(pngle, &png);
|
||||
pngle_set_draw_callback(pngle, pngle_draw_callback);
|
||||
|
||||
// Feed data to pngle
|
||||
uint8_t buf[1024];
|
||||
int remain = 0;
|
||||
int len;
|
||||
while (http.connected()) {
|
||||
size_t size = stream->available();
|
||||
if (!size) { delay(1); continue; }
|
||||
|
||||
if (size > sizeof(buf) - remain) size = sizeof(buf) - remain;
|
||||
if ((len = stream->readBytes(buf + remain, size)) > 0) {
|
||||
int fed = pngle_feed(pngle, buf, remain + len);
|
||||
if (fed < 0) {
|
||||
log_e("[pngle error] %s", pngle_error(pngle));
|
||||
break;
|
||||
}
|
||||
|
||||
remain = remain + len - fed;
|
||||
if (remain > 0) memmove(buf, buf + fed, remain);
|
||||
}
|
||||
}
|
||||
|
||||
pngle_destroy(pngle);
|
||||
http.end();
|
||||
}
|
||||
|
||||
|
||||
// Saves and restores font properties, datum, cursor, colors
|
||||
|
||||
void M5Display::pushState() {
|
||||
DisplayState s;
|
||||
s.textfont = textfont;
|
||||
s.textsize = textsize;
|
||||
s.textcolor = textcolor;
|
||||
s.textbgcolor = textbgcolor;
|
||||
s.cursor_x = cursor_x;
|
||||
s.cursor_y = cursor_y;
|
||||
s.padX = padX;
|
||||
s.gfxFont = gfxFont;
|
||||
_displayStateStack.push_back(s);
|
||||
}
|
||||
|
||||
void M5Display::popState() {
|
||||
if (_displayStateStack.empty()) return;
|
||||
DisplayState s = _displayStateStack.back();
|
||||
_displayStateStack.pop_back();
|
||||
textfont = s.textfont;
|
||||
textsize = s.textsize;
|
||||
textcolor = s.textcolor;
|
||||
textbgcolor = s.textbgcolor;
|
||||
cursor_x = s.cursor_x;
|
||||
cursor_y = s.cursor_y;
|
||||
padX = s.padX;
|
||||
if (s.gfxFont && s.gfxFont != gfxFont) setFreeFont(s.gfxFont);
|
||||
}
|
||||
|
||||
#ifdef M5Stack_M5Core2
|
||||
|
||||
#ifdef TFT_eSPI_TOUCH_EMULATION
|
||||
|
||||
// Emulates the native (resistive) TFT_eSPI touch interface using M5.Touch
|
||||
|
||||
uint8_t M5Display::getTouchRaw(uint16_t *x, uint16_t *y) {
|
||||
return getTouch(x, y);
|
||||
}
|
||||
|
||||
uint16_t M5Display::getTouchRawZ(void) {
|
||||
return (TOUCH->ispressed()) ? 1000 : 0;
|
||||
}
|
||||
|
||||
void M5Display::convertRawXY(uint16_t *x, uint16_t *y) { return; }
|
||||
|
||||
uint8_t M5Display::getTouch(uint16_t *x, uint16_t *y,
|
||||
uint16_t threshold /* = 600 */) {
|
||||
TOUCH->read();
|
||||
if (TOUCH->points) {
|
||||
*x = TOUCH->point[0].x;
|
||||
*y = TOUCH->point[0].y;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void M5Display::calibrateTouch(uint16_t *data, uint32_t color_fg,
|
||||
uint32_t color_bg, uint8_t size) {
|
||||
return;
|
||||
}
|
||||
|
||||
void M5Display::setTouch(uint16_t *data) { return; }
|
||||
|
||||
#endif /* TFT_eSPI_TOUCH_EMULATION */
|
||||
|
||||
#endif /* M5Stack_M5Core2 */
|
||||
Reference in New Issue
Block a user