diff --git a/src/lgfx/v1/LGFXBase.cpp b/src/lgfx/v1/LGFXBase.cpp index 6e70d7c2..a672cd9a 100644 --- a/src/lgfx/v1/LGFXBase.cpp +++ b/src/lgfx/v1/LGFXBase.cpp @@ -2144,7 +2144,6 @@ namespace lgfx //_decoderState = utf8_decode_state_t::utf8_state0; font->getDefaultMetric(&_font_metrics); - } /// load VLW font @@ -2154,6 +2153,39 @@ namespace lgfx return load_font(&_font_data); } + bool LGFXBase::load_font_with_path(const char *path) + { + this->unloadFont(); + + if (this->_font_file.get() == nullptr) return false; + + this->prepareTmpTransaction(this->_font_file.get()); + this->_font_file->preRead(); + + bool result = this->_font_file->open(path); + if (!result) + { + size_t alloclen = strlen(path) + 8; + auto filename = (char*)alloca(alloclen); + memset(filename, 0, alloclen); + filename[0] = '/'; + + strcpy(&filename[1], &path[(path[0] == '/') ? 1 : 0]); + int len = strlen(filename); + if (memcmp(&filename[len - 4], ".vlw", 4)) + { + strcpy(&filename[len], ".vlw"); + } + result = this->_font_file->open(filename); + } + + if (result) { + result = this->load_font(this->_font_file.get()); + } + this->_font_file->postRead(); + return result; + } + bool LGFXBase::load_font(lgfx::DataWrapper* data) { this->unloadFont(); diff --git a/src/lgfx/v1/LGFXBase.hpp b/src/lgfx/v1/LGFXBase.hpp index 91a75ead..d9fbdec7 100644 --- a/src/lgfx/v1/LGFXBase.hpp +++ b/src/lgfx/v1/LGFXBase.hpp @@ -742,6 +742,23 @@ namespace lgfx /// load VLW font bool loadFont(const uint8_t* array); + /// load vlw font from filesystem. + bool loadFont(const char *path) + { + this->unloadFont(); + this->_font_file.reset(_create_data_wrapper()); + return load_font_with_path(path); + } + + + template + bool loadFont(T &fs, const char *path) + { + unloadFont(); + _font_file.reset(new DataWrapperT(&fs)); + return load_font_with_path(path); + } + /// unload VLW font void unloadFont(void); @@ -754,6 +771,16 @@ namespace lgfx uint8_t getAttribute(attribute_t attr_id); uint8_t getAttribute(uint8_t attr_id) { return getAttribute((attribute_t)attr_id); } + template + void setFileStorage(T& fs) { + _data_wrapper_factory.reset(new DataWrapperTFactoryT(&fs)); + } + + template + void setFileStorage(T* fs) { _data_wrapper_factory.reset(new DataWrapperTFactoryT(fs)); } + + void clearFileStorage(void) { _data_wrapper_factory.reset(new DataWrapperTFactoryT(nullptr)); } + //---------------------------------------------------------------------------- // print & text support //---------------------------------------------------------------------------- @@ -822,9 +849,9 @@ namespace lgfx void qrcode(const char *string, int32_t x = -1, int32_t y = -1, int32_t width = -1, uint8_t version = 1); #define LGFX_FUNCTION_GENERATOR(drawImg, draw_img) \ - protected: \ + protected: \ bool draw_img(DataWrapper* data, int32_t x, int32_t y, int32_t maxWidth, int32_t maxHeight, int32_t offX, int32_t offY, float scale_x, float scale_y, datum_t datum); \ - public: \ + public: \ bool drawImg(const uint8_t *data, uint32_t len, int32_t x=0, int32_t y=0, int32_t maxWidth=0, int32_t maxHeight=0, int32_t offX=0, int32_t offY=0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ { \ PointerWrapper data_wrapper; \ @@ -835,6 +862,34 @@ namespace lgfx { \ return this->draw_img(data, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ } \ + bool drawImg##File(DataWrapper* file, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + { \ + bool res = false; \ + this->prepareTmpTransaction(file); \ + file->preRead(); \ + if (file->open(path)) \ + { \ + res = this->draw_img(file, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ + file->close(); \ + } \ + file->postRead(); \ + return res; \ + } \ + inline bool drawImg##File(const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + { \ + auto data = _create_data_wrapper(); \ + bool res = drawImg##File(data, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ + delete data; \ + return res; \ + } \ + template \ + inline bool drawImg##File(T &fs, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + { \ + DataWrapperT file ( &fs ); \ + bool res = this->drawImg##File(&file, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ + file.close(); \ + return res; \ + } LGFX_FUNCTION_GENERATOR(drawBmp, draw_bmp) LGFX_FUNCTION_GENERATOR(drawJpg, draw_jpg) @@ -851,6 +906,11 @@ namespace lgfx { return drawJpg(data, x, y, maxWidth, maxHeight, offX, offY, 1.0f / (1 << scale)); } + [[deprecated("use float scale")]] + inline bool drawJpgFile(const char *path, int32_t x, int32_t y, int32_t maxWidth, int32_t maxHeight, int32_t offX, int32_t offY, jpeg_div::jpeg_div_t scale) + { + return drawJpgFile(path, x, y, maxWidth, maxHeight, offX, offY, 1.0f / (1 << scale)); + } void* createPng( size_t* datalen, int32_t x = 0, int32_t y = 0, int32_t width = 0, int32_t height = 0); @@ -917,6 +977,9 @@ namespace lgfx std::shared_ptr _font_file; // run-time font file PointerWrapper _font_data; + std::shared_ptr _data_wrapper_factory; + DataWrapper* _create_data_wrapper(void) { if (nullptr == _data_wrapper_factory.get()) { clearFileStorage(); } return _data_wrapper_factory->create(); } + bool _textwrap_x = true; bool _textwrap_y = false; bool _textscroll = false; @@ -1220,6 +1283,7 @@ namespace lgfx size_t draw_string(const char *string, int32_t x, int32_t y, textdatum_t datum, const IFont* font = nullptr); int32_t text_width(const char *string, const IFont* font, FontMetrics* metrics); bool load_font(lgfx::DataWrapper* data); + bool load_font_with_path(const char *path); static void tmpBeginTransaction(LGFXBase* lgfx) { diff --git a/src/lgfx/v1/LGFX_Sprite.cpp b/src/lgfx/v1/LGFX_Sprite.cpp index 496f2832..97f3152b 100644 --- a/src/lgfx/v1/LGFX_Sprite.cpp +++ b/src/lgfx/v1/LGFX_Sprite.cpp @@ -473,16 +473,16 @@ namespace lgfx uint32_t sx32 = param->src_x32; uint32_t sy32 = param->src_y32; - y *= _bitwidth; + uint32_t yb = y * _bitwidth; do { - int32_t pos = x + y; + int32_t pos = x + yb; int32_t end = pos + w; while (end != (pos = param->fp_copy(_img, pos, end, param)) && end != (pos = param->fp_skip( pos, end, param))); param->src_x32 = (sx32 += nextx); param->src_y32 = (sy32 += nexty); - y += _bitwidth; + yb += _bitwidth; } while (--h); } @@ -680,6 +680,107 @@ namespace lgfx } } +//---------------------------------------------------------------------------- + + bool LGFX_Sprite::create_from_bmp_file(DataWrapper* data, const char *path) { + data->need_transaction = false; + bool res = false; + if (data->open(path)) { + res = createFromBmp(data); + data->close(); + } + return res; + } + + bool LGFX_Sprite::createFromBmp(DataWrapper* data) + { + bitmap_header_t bmpdata; + + if (!bmpdata.load_bmp_header(data) + || ( bmpdata.biCompression > 3)) { + return false; + } + uint32_t seekOffset = bmpdata.bfOffBits; + uint_fast16_t bpp = bmpdata.biBitCount; // 24 bcBitCount 24=RGB24bit + setColorDepth(bpp < 32 ? bpp : 24); + uint32_t w = bmpdata.biWidth; + int32_t h = bmpdata.biHeight; // bcHeight Image height (pixels) + if (!createSprite(w, h)) return false; + + //If the value of Height is positive, the image data is from bottom to top + //If the value of Height is negative, the image data is from top to bottom. + int32_t flow = (h < 0) ? 1 : -1; + int32_t y = 0; + if (h < 0) h = -h; + else y = h - 1; + + if (bpp <= 8) { + if (!_palette) createPalette(); + uint_fast16_t palettecount = 1 << bpp; + argb8888_t *palette = (argb8888_t*)alloca(sizeof(argb8888_t*) * palettecount); + data->seek(bmpdata.biSize + 14); + data->read((uint8_t*)palette, (palettecount * sizeof(argb8888_t))); // load palette + for (uint_fast16_t i = 0; i < _palette_count; ++i) + { + _palette.img24()[i].set(color_convert(palette[i].get())); + } + } + + data->seek(seekOffset); + + auto bitwidth = _panel_sprite._bitwidth; + + size_t buffersize = ((w * bpp + 31) >> 5) << 2; // readline 4Byte align. + auto lineBuffer = (uint8_t*)alloca(buffersize); + if (bpp <= 8) { + do { + if (bmpdata.biCompression == 1) { + bmpdata.load_bmp_rle8(data, lineBuffer, w); + } else + if (bmpdata.biCompression == 2) { + bmpdata.load_bmp_rle4(data, lineBuffer, w); + } else { + data->read(lineBuffer, buffersize); + } + memcpy(&_img8[y * bitwidth * bpp >> 3], lineBuffer, (w * bpp + 7) >> 3); + y += flow; + } while (--h); + } else if (bpp == 16) { + do { + data->read(lineBuffer, buffersize); + auto img = (uint16_t*)(&_img8[y * bitwidth * bpp >> 3]); + y += flow; + for (size_t i = 0; i < w; ++i) + { + img[i] = (lineBuffer[i << 1] << 8) + lineBuffer[(i << 1) + 1]; + } + } while (--h); + } else if (bpp == 24) { + do { + data->read(lineBuffer, buffersize); + auto img = &_img8[y * bitwidth * bpp >> 3]; + y += flow; + for (size_t i = 0; i < w; ++i) { + img[i * 3 ] = lineBuffer[i * 3 + 2]; + img[i * 3 + 1] = lineBuffer[i * 3 + 1]; + img[i * 3 + 2] = lineBuffer[i * 3 ]; + } + } while (--h); + } else if (bpp == 32) { + do { + data->read(lineBuffer, buffersize); + auto img = &_img8[y * bitwidth * 3]; + y += flow; + for (size_t i = 0; i < w; ++i) { + img[i * 3 ] = lineBuffer[(i << 2) + 2]; + img[i * 3 + 1] = lineBuffer[(i << 2) + 1]; + img[i * 3 + 2] = lineBuffer[(i << 2) + 0]; + } + } while (--h); + } + return true; + } + //---------------------------------------------------------------------------- } } diff --git a/src/lgfx/v1/LGFX_Sprite.hpp b/src/lgfx/v1/LGFX_Sprite.hpp index dfc7ecfd..58210b58 100644 --- a/src/lgfx/v1/LGFX_Sprite.hpp +++ b/src/lgfx/v1/LGFX_Sprite.hpp @@ -194,49 +194,22 @@ namespace lgfx return _img; } -#if defined (SdFat_h) - #if SD_FAT_VERSION >= 20102 - #define LGFX_SDFAT_TYPE SdBase - #else - #define LGFX_SDFAT_TYPE SdBase - #endif - - inline void createFromBmp(LGFX_SDFAT_TYPE &fs, const char *path) { createFromBmpFile(fs, path); } - void createFromBmpFile(LGFX_SDFAT_TYPE &fs, const char *path) { - SdFatWrapper file; - file.setFS(fs); - createFromBmpFile(&file, path); - } - - #undef LGFX_SDFAT_TYPE -#endif + bool createFromBmp(DataWrapper* data); -#if defined (ARDUINO) - #if defined (FS_H) || defined (__SEEED_FS__) - - inline void createFromBmp(fs::FS &fs, const char *path) { createFromBmpFile(fs, path); } - void createFromBmpFile(fs::FS &fs, const char *path) { - FileWrapper file; - file.setFS(fs); - createFromBmpFile(&file, path); + bool createFromBmp(const uint8_t *bmp_data, uint32_t bmp_len = ~0u) { + PointerWrapper data (bmp_data, bmp_len); + return createFromBmp(&data); } - #endif - -#elif defined (ESP_PLATFORM) || defined(__SAMD51_HARMONY__) || defined(stdin) // ESP-IDF, Harmony, stdio - - void createFromBmpFile(const char *path) { - FileWrapper file; - createFromBmpFile(&file, path); + template + bool createFromBmpFile(T &fs, const char *path) + { + DataWrapperT data { &fs }; + return create_from_bmp_file(&data, path); } -#endif - - void createFromBmp(const uint8_t *bmp_data, uint32_t bmp_len = ~0u) { - PointerWrapper data; - data.set(bmp_data, bmp_len); - create_from_bmp(&data); - } + template + bool createFromBmp(T &fs, const char *path) { return createFromBmpFile(fs, path); } bool createPalette(void) { @@ -437,102 +410,7 @@ namespace lgfx return true; } - void createFromBmpFile(DataWrapper* file, const char *path) { - file->need_transaction = false; - if (file->open(path)) { - create_from_bmp(file); - file->close(); - } - } - - bool create_from_bmp(DataWrapper* data) - { - bitmap_header_t bmpdata; - - if (!bmpdata.load_bmp_header(data) - || ( bmpdata.biCompression > 3)) { - return false; - } - uint32_t seekOffset = bmpdata.bfOffBits; - uint_fast16_t bpp = bmpdata.biBitCount; // 24 bcBitCount 24=RGB24bit - setColorDepth(bpp < 32 ? bpp : 24); - uint32_t w = bmpdata.biWidth; - int32_t h = bmpdata.biHeight; // bcHeight Image height (pixels) - if (!createSprite(w, h)) return false; - - //If the value of Height is positive, the image data is from bottom to top - //If the value of Height is negative, the image data is from top to bottom. - int32_t flow = (h < 0) ? 1 : -1; - int32_t y = 0; - if (h < 0) h = -h; - else y = h - 1; - - if (bpp <= 8) { - if (!_palette) createPalette(); - uint_fast16_t palettecount = 1 << bpp; - argb8888_t *palette = (argb8888_t*)alloca(sizeof(argb8888_t*) * palettecount); - data->seek(bmpdata.biSize + 14); - data->read((uint8_t*)palette, (palettecount * sizeof(argb8888_t))); // load palette - for (uint_fast16_t i = 0; i < _palette_count; ++i) - { - _palette.img24()[i].set(color_convert(palette[i].get())); - } - } - - data->seek(seekOffset); - - auto bitwidth = _panel_sprite._bitwidth; - - size_t buffersize = ((w * bpp + 31) >> 5) << 2; // readline 4Byte align. - auto lineBuffer = (uint8_t*)alloca(buffersize); - if (bpp <= 8) { - do { - if (bmpdata.biCompression == 1) { - bmpdata.load_bmp_rle8(data, lineBuffer, w); - } else - if (bmpdata.biCompression == 2) { - bmpdata.load_bmp_rle4(data, lineBuffer, w); - } else { - data->read(lineBuffer, buffersize); - } - memcpy(&_img8[y * bitwidth * bpp >> 3], lineBuffer, (w * bpp + 7) >> 3); - y += flow; - } while (--h); - } else if (bpp == 16) { - do { - data->read(lineBuffer, buffersize); - auto img = (uint16_t*)(&_img8[y * bitwidth * bpp >> 3]); - y += flow; - for (size_t i = 0; i < w; ++i) - { - img[i] = (lineBuffer[i << 1] << 8) + lineBuffer[(i << 1) + 1]; - } - } while (--h); - } else if (bpp == 24) { - do { - data->read(lineBuffer, buffersize); - auto img = &_img8[y * bitwidth * bpp >> 3]; - y += flow; - for (size_t i = 0; i < w; ++i) { - img[i * 3 ] = lineBuffer[i * 3 + 2]; - img[i * 3 + 1] = lineBuffer[i * 3 + 1]; - img[i * 3 + 2] = lineBuffer[i * 3 ]; - } - } while (--h); - } else if (bpp == 32) { - do { - data->read(lineBuffer, buffersize); - auto img = &_img8[y * bitwidth * 3]; - y += flow; - for (size_t i = 0; i < w; ++i) { - img[i * 3 ] = lineBuffer[(i << 2) + 2]; - img[i * 3 + 1] = lineBuffer[(i << 2) + 1]; - img[i * 3 + 2] = lineBuffer[(i << 2) + 0]; - } - } while (--h); - } - return true; - } + bool create_from_bmp_file(DataWrapper* data, const char *path); void push_sprite(LovyanGFX* dst, int32_t x, int32_t y, uint32_t transp = pixelcopy_t::NON_TRANSP) { @@ -561,7 +439,6 @@ namespace lgfx } RGBColor* getPalette_impl(void) const override { return _palette.img24(); } - }; //---------------------------------------------------------------------------- diff --git a/src/lgfx/v1/gitTagVersion.h b/src/lgfx/v1/gitTagVersion.h index 39764c8d..0ec4d296 100644 --- a/src/lgfx/v1/gitTagVersion.h +++ b/src/lgfx/v1/gitTagVersion.h @@ -1,4 +1,4 @@ #define LGFX_VERSION_MAJOR 1 #define LGFX_VERSION_MINOR 1 -#define LGFX_VERSION_PATCH 10 +#define LGFX_VERSION_PATCH 12 #define LOVYANGFX_VERSION F( LGFX_VERSION_MAJOR "." LGFX_VERSION_MINOR "." LGFX_VERSION_PATCH ) diff --git a/src/lgfx/v1/lgfx_filesystem_support.hpp b/src/lgfx/v1/lgfx_filesystem_support.hpp index 4cecb417..a1007371 100644 --- a/src/lgfx/v1/lgfx_filesystem_support.hpp +++ b/src/lgfx/v1/lgfx_filesystem_support.hpp @@ -57,59 +57,35 @@ namespace lgfx using Base::drawJpg; using Base::drawPng; using Base::drawQoi; + using Base::drawBmpFile; + using Base::drawJpgFile; + using Base::drawPngFile; + using Base::drawQoiFile; using Base::loadFont; #if defined (ARDUINO) - #if defined (FS_H) || defined (__SEEED_FS__) || defined (__LITTLEFS_H) || defined (_LiffleFS_H_) || defined (SDFS_H) - /// load vlw fontdata from filesystem. - bool loadFont(const char *path, fs::FS &fs -#if defined (_SD_H_) - = SD -#elif defined (_SPIFFS_H_) - = SPIFFS -#elif defined (__LITTLEFS_H) || defined (_LiffleFS_H_) - = LittleFS -#elif defined SDFS_H - = SDFS -#endif - ) - { - init_font_file(fs); - return load_font_with_path(path); - } - - bool loadFont(fs::FS &fs, const char *path) - { - init_font_file(fs); - return load_font_with_path(path); - } + #if defined (FS_H) #define LGFX_FUNCTION_GENERATOR(drawImg, draw_img) \ - inline bool drawImg##File(fs::FS &fs, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { FileWrapper file(fs); \ - bool res = this->drawImg##File(&file, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - file.close(); \ - return res; \ - } \ - inline bool drawImg##File(fs::FS &fs, fs::File *file, int32_t x=0, int32_t y=0, int32_t maxWidth=0, int32_t maxHeight=0, int32_t offX=0, int32_t offY=0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + template \ + inline bool drawImg##File(T &fs, fs::File *file, int32_t x=0, int32_t y=0, int32_t maxWidth=0, int32_t maxHeight=0, int32_t offX=0, int32_t offY=0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ { \ - FileWrapper data(fs, file); \ + DataWrapperT data { fs, file }; \ bool res = this->draw_img(&data, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ data.close(); \ return res; \ } \ - inline bool drawImg##File(fs::FS &fs, const String& path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { \ - return drawImg##File(fs, path.c_str(), x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - } \ - inline bool drawImg(fs::File *dataSource, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + inline bool drawImg(fs::File *file, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ { \ - StreamWrapper data; \ - data.set(dataSource); \ - data.need_transaction = true; \ + DataWrapperT data { file }; \ return this->draw_img(&data, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ } \ + template \ + inline bool drawImg##File(T &fs, const String& path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ + { \ + return drawImg##File(fs, path.c_str(), x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ + } LGFX_FUNCTION_GENERATOR(drawBmp, draw_bmp) LGFX_FUNCTION_GENERATOR(drawJpg, draw_jpg) @@ -122,7 +98,6 @@ namespace lgfx { return drawBmpFile(fs, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); } - [[deprecated("use float scale")]] inline bool drawJpgFile(fs::FS &fs, const char *path, int32_t x, int32_t y, int32_t maxWidth, int32_t maxHeight, int32_t offX, int32_t offY, jpeg_div::jpeg_div_t scale) { @@ -140,7 +115,7 @@ namespace lgfx } #endif - +/* #if defined (__STORAGE_H__) // for SPRESENSE /// load vlw fontdata from filesystem. @@ -211,71 +186,7 @@ namespace lgfx } #endif - - #if defined (SdFat_h) - #if SD_FAT_VERSION >= 20102 - #define LGFX_SDFAT_TYPE SdBase - #else - #define LGFX_SDFAT_TYPE SdBase - #endif - - bool loadFont(const char *path, LGFX_SDFAT_TYPE &fs) - { - init_font_file(fs); - return load_font_with_path(path); - } - - bool loadFont(LGFX_SDFAT_TYPE &fs, const char *path) - { - init_font_file(fs); - return load_font_with_path(path); - } - - #define LGFX_FUNCTION_GENERATOR(drawImg, draw_img) \ - inline bool drawImg##File(LGFX_SDFAT_TYPE &fs, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { \ - SdFatWrapper file(fs); \ - bool res = this->drawImg##File(&file, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - file.close(); \ - return res; \ - } \ - inline bool drawImg##File(LGFX_SDFAT_TYPE &fs, FsFile *file, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { \ - SdFatWrapper data(fs, file); \ - bool res = this->draw_img(&data, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - data.close(); \ - return res; \ - } \ - inline bool drawImg##File(LGFX_SDFAT_TYPE &fs, const String& path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { \ - return drawImg##File(fs, path.c_str(), x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - } \ - - LGFX_FUNCTION_GENERATOR(drawBmp, draw_bmp) - LGFX_FUNCTION_GENERATOR(drawJpg, draw_jpg) - LGFX_FUNCTION_GENERATOR(drawPng, draw_png) - LGFX_FUNCTION_GENERATOR(drawQoi, draw_qoi) - - #undef LGFX_FUNCTION_GENERATOR - - inline bool drawBmp(LGFX_SDFAT_TYPE &fs, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) - { - return drawBmpFile(fs, path, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); - } - [[deprecated("use float scale")]] - inline bool drawJpgFile(LGFX_SDFAT_TYPE &fs, const char *path, int32_t x, int32_t y, int32_t maxWidth, int32_t maxHeight, int32_t offX, int32_t offY, jpeg_div::jpeg_div_t scale) - { - return drawJpgFile(fs, path, x, y, maxWidth, maxHeight, offX, offY, 1.0f / (1 << scale)); - } - [[deprecated("use float scale")]] - inline bool drawJpgFile(LGFX_SDFAT_TYPE &fs, FsFile *file, int32_t x, int32_t y, int32_t maxWidth, int32_t maxHeight, int32_t offX, int32_t offY, jpeg_div::jpeg_div_t scale) - { - return drawJpgFile(fs, file, x, y, maxWidth, maxHeight, offX, offY, 1.0f / (1 << scale)); - } - - #undef LGFX_SDFAT_TYPE - #endif - +//*/ #if defined (Stream_h) || defined ARDUINO_ARCH_RP2040 // RP2040 has no defines for builtin Stream API #define LGFX_FUNCTION_GENERATOR(drawImg, draw_img) \ @@ -351,7 +262,7 @@ namespace lgfx #endif #endif - +/* #elif defined (ESP_PLATFORM) || defined(__SAMD51_HARMONY__) || defined(stdin) // ESP-IDF, Harmony, stdio #define LGFX_FUNCTION_GENERATOR(drawImg) \ @@ -379,7 +290,7 @@ namespace lgfx init_font_file(); return load_font_with_path(path); } - +//*/ #endif #define LGFX_URL_MAXLENGTH 2083 @@ -771,28 +682,6 @@ namespace lgfx #undef LGFX_URL_MAXLENGTH - #define LGFX_FUNCTION_GENERATOR(drawImg, draw_img) \ - bool drawImg##File(DataWrapper* file, const char *path, int32_t x = 0, int32_t y = 0, int32_t maxWidth = 0, int32_t maxHeight = 0, int32_t offX = 0, int32_t offY = 0, float scale_x = 1.0f, float scale_y = 0.0f, datum_t datum = datum_t::top_left) \ - { \ - bool res = false; \ - this->prepareTmpTransaction(file); \ - file->preRead(); \ - if (file->open(path)) \ - { \ - res = this->draw_img(file, x, y, maxWidth, maxHeight, offX, offY, scale_x, scale_y, datum); \ - file->close(); \ - } \ - file->postRead(); \ - return res; \ - } \ - - LGFX_FUNCTION_GENERATOR(drawBmp, draw_bmp) - LGFX_FUNCTION_GENERATOR(drawJpg, draw_jpg) - LGFX_FUNCTION_GENERATOR(drawPng, draw_png) - LGFX_FUNCTION_GENERATOR(drawQoi, draw_qoi) - - #undef LGFX_FUNCTION_GENERATOR - private: template @@ -808,40 +697,6 @@ namespace lgfx this->unloadFont(); this->_font_file.reset(new T()); } - - bool load_font_with_path(const char *path) - { - this->unloadFont(); - - if (this->_font_file.get() == nullptr) return false; - //if (this->_font_file == nullptr) { init_font_file(SD); } - - this->prepareTmpTransaction(this->_font_file.get()); - this->_font_file->preRead(); - - bool result = this->_font_file->open(path); - if (!result) - { - size_t alloclen = strlen(path) + 8; - auto filename = (char*)alloca(alloclen); - memset(filename, 0, alloclen); - filename[0] = '/'; - - strcpy(&filename[1], &path[(path[0] == '/') ? 1 : 0]); - int len = strlen(filename); - if (memcmp(&filename[len - 4], ".vlw", 4)) - { - strcpy(&filename[len], ".vlw"); - } - result = this->_font_file->open(filename); - } - - if (result) { - result = this->load_font(this->_font_file.get()); - } - this->_font_file->postRead(); - return result; - } }; //---------------------------------------------------------------------------- diff --git a/src/lgfx/v1/misc/DataWrapper.hpp b/src/lgfx/v1/misc/DataWrapper.hpp index 376f6c79..bb387f47 100644 --- a/src/lgfx/v1/misc/DataWrapper.hpp +++ b/src/lgfx/v1/misc/DataWrapper.hpp @@ -22,6 +22,7 @@ Original Source: #endif #include +#include #include #include "../../utility/pgmspace.h" @@ -44,8 +45,6 @@ namespace lgfx constexpr DataWrapper(void) = default; virtual ~DataWrapper(void) = default; - bool need_transaction = false; - uint8_t read8(void) { uint8_t result; @@ -83,12 +82,80 @@ namespace lgfx LGFXBase* parent = nullptr; void (*fp_pre_read )(LGFXBase*) = nullptr; void (*fp_post_read)(LGFXBase*) = nullptr; + bool need_transaction = false; + }; + +//---------------------------------------------------------------------------- + + template + struct DataWrapperT : public DataWrapper { + DataWrapperT(void) : DataWrapper() {} + DataWrapperT(void*) : DataWrapper() {} + }; + + struct DataWrapperFactory { + virtual DataWrapper* create(void) = 0; + virtual ~DataWrapperFactory() {}; + }; + +//---------------------------------------------------------------------------- + +#if defined (__FILE_defined) || defined (_FILE_DEFINED) || defined (_FSTDIO) + template <> + struct DataWrapperT : public DataWrapper + { + DataWrapperT(FILE* fp = nullptr) : DataWrapper() , _fp { fp } + { + need_transaction = true; + } +#if defined (__STDC_WANT_SECURE_LIB__) + bool open(const char* path) override { + while (0 != fopen_s(&_fp, path, "rb") && path[0] == '/') + { ++path; } + return _fp; + } +#else + bool open(const char* path) override { + while (nullptr == (_fp = fopen(path, "rb")) && path[0] == '/') + { ++path; } + return _fp; + } +#endif + int read(uint8_t *buf, uint32_t len) override { return fread((char*)buf, 1, len, _fp); } + void skip(int32_t offset) override { seek(offset, SEEK_CUR); } + bool seek(uint32_t offset) override { return seek(offset, SEEK_SET); } + bool seek(uint32_t offset, int origin) { return fseek(_fp, offset, origin); } + void close(void) override { if (_fp) { fclose(_fp); _fp = nullptr; } } + int32_t tell(void) override { return ftell(_fp); } + protected: + FILE* _fp; }; + template <> + struct DataWrapperT : public DataWrapperT + { + DataWrapperT(void) : DataWrapperT() {} + }; +#else + template <> + struct DataWrapperT : public DataWrapper + { + DataWrapperT(void) : DataWrapper() { } + int read(uint8_t *buf, uint32_t len) override { return false; } + void skip(int32_t offset) override { } + bool seek(uint32_t offset) override { return false; } + bool seek(uint32_t offset, int origin) { return false; } + void close(void) override { } + int32_t tell(void) override { return 0; } + }; +#endif + //---------------------------------------------------------------------------- struct PointerWrapper : public DataWrapper { + PointerWrapper() : DataWrapper{} , _ptr { nullptr }, _index { 0 }, _length { 0 } {}; + PointerWrapper(const uint8_t* src, uint32_t length = ~0) : DataWrapper{}, _ptr { src }, _index { 0 }, _length { length } {} void set(const uint8_t* src, uint32_t length = ~0) { _ptr = src; _length = length; _index = 0; } int read(uint8_t *buf, uint32_t len) override { if (len > _length - _index) { len = _length - _index; } @@ -102,65 +169,91 @@ namespace lgfx int32_t tell(void) override { return _index; } protected: - const uint8_t* _ptr = nullptr; - uint32_t _index = 0; - uint32_t _length = 0; + const uint8_t* _ptr; + uint32_t _index; + uint32_t _length; }; //---------------------------------------------------------------------------- #if defined (SdFat_h) - #if SD_FAT_VERSION >= 20102 - #define LGFX_SDFAT_TYPE SdBase - #else - #define LGFX_SDFAT_TYPE SdBase - #endif - - struct SdFatWrapper : public DataWrapper + // #if SD_FAT_VERSION >= 20102 + // #define LGFX_SDFAT_TYPE SdBase + // #else + // #define LGFX_SDFAT_TYPE SdBase + // #endif + + template + struct DataWrapperT_SdFatFile : public DataWrapper { - SdFatWrapper() : DataWrapper() - { - need_transaction = true; - _fs = nullptr; - _fp = nullptr; - } + DataWrapperT_SdFatFile(TFile* fp = nullptr) : DataWrapper{}, _fp { fp } { need_transaction = true; } + int read(uint8_t *buf, uint32_t len) override { uint32_t a = _fp->available(); return _fp->read(buf, a < len ? a : len); } + void skip(int32_t offset) override { _fp->seekCur(offset); } + bool seek(uint32_t offset) override { return _fp->seekSet(offset); } + void close(void) override { if (_fp) { _fp->close(); _fp = nullptr; } } + int32_t tell(void) override { return _fp->position(); } + protected: + TFile *_fp; + }; - LGFX_SDFAT_TYPE *_fs; - FsFile *_fp; - FsFile _file; + template <> + struct DataWrapperT : public DataWrapperT_SdFatFile { + DataWrapperT(FsFile* fp = nullptr) : DataWrapperT_SdFatFile(fp) {} + }; - SdFatWrapper(LGFX_SDFAT_TYPE &fs, FsFile* fp = nullptr) : DataWrapper(), _fs(&fs), _fp(fp) { need_transaction = true; } - void setFS(LGFX_SDFAT_TYPE &fs) { - _fs = &fs; - need_transaction = true; - } + template <> + struct DataWrapperT : public DataWrapperT_SdFatFile { + DataWrapperT(ExFile* fp = nullptr) : DataWrapperT_SdFatFile(fp) {} + }; - bool open(LGFX_SDFAT_TYPE &fs, const char* path) - { - setFS(fs); - _file = fs.open(path, O_RDONLY); - _fp = &_file; - return _file; - } + template <> + struct DataWrapperT : public DataWrapperT_SdFatFile { + DataWrapperT(File32* fp = nullptr) : DataWrapperT_SdFatFile(fp) {} + }; + + template + struct DataWrapperT_SdFatFS : public DataWrapperT_SdFatFile + { + DataWrapperT_SdFatFS(TFS *fs, TFile* fp = nullptr) : DataWrapperT_SdFatFile{ fp }, _fs { fs } {} bool open(const char* path) override { _file = _fs->open(path, O_RDONLY); - _fp = &_file; + DataWrapperT_SdFatFile::_fp = &_file; return _file; } - int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, std::min(_fp->available(), len)); } - void skip(int32_t offset) override { _fp->seekCur(offset); } - bool seek(uint32_t offset) override { return _fp->seekSet(offset); } - void close(void) override { if (_fp) _fp->close(); } - int32_t tell(void) override { return _fp->position(); } + protected: + TFS *_fs; + TFile _file; + }; + + template <> + struct DataWrapperT : public DataWrapperT_SdFatFS { + DataWrapperT(SdFs* fs, FsFile* fp = nullptr) : DataWrapperT_SdFatFS(fs, fp) {} }; - #undef LGFX_SDFAT_TYPE + template <> + struct DataWrapperT : public DataWrapperT_SdFatFS { + DataWrapperT(SdExFat* fs, ExFile* fp = nullptr) : DataWrapperT_SdFatFS(fs, fp) {} + }; + + template <> + struct DataWrapperT : public DataWrapperT_SdFatFS { + DataWrapperT(SdFat32* fs, File32* fp = nullptr) : DataWrapperT_SdFatFS(fs, fp) {} + }; + + struct SdFatWrapper : public DataWrapperT + { + SdFatWrapper(SdFs &fs, FsFile* fp = nullptr) : DataWrapperT ( &fs, fp ) {} + SdFatWrapper(SdFs *fs, FsFile* fp = nullptr) : DataWrapperT ( fs, fp ) {} + }; + +// #undef LGFX_SDFAT_TYPE + #endif //---------------------------------------------------------------------------- -#if ( defined (ARDUINO) && defined (Stream_h) ) || defined ARDUINO_ARCH_RP2040 // RP2040 has no defines for builtin Stream API +#if ( defined (ARDUINO) && defined (Stream_h) ) || defined (ARDUINO_ARCH_RP2040) // RP2040 has no defines for builtin Stream API struct StreamWrapper : public DataWrapper { @@ -210,14 +303,33 @@ namespace lgfx Stream* _stream; uint32_t _index; uint32_t _length = 0; - }; #endif +//---------------------------------------------------------------------------- + + template + struct DataWrapperTFactoryT : public DataWrapperFactory { + DataWrapperTFactoryT(T* fs) : _fs { fs } {} + DataWrapperTFactoryT(T& fs) : _fs { &fs } {} + DataWrapper* create(void) override { return new DataWrapperT(_fs); } + protected: + T* _fs; + }; + + template <> + struct DataWrapperTFactoryT : public DataWrapperFactory { + DataWrapperTFactoryT(void) {} + DataWrapperTFactoryT(void*) {} + DataWrapper* create(void) override { return new DataWrapperT(); } + }; + //---------------------------------------------------------------------------- #undef LGFX_INLINE +//---------------------------------------------------------------------------- + } } diff --git a/src/lgfx/v1/misc/range.hpp b/src/lgfx/v1/misc/range.hpp index cc4d66e5..749a4c76 100644 --- a/src/lgfx/v1/misc/range.hpp +++ b/src/lgfx/v1/misc/range.hpp @@ -73,6 +73,7 @@ namespace lgfx LGFX_INLINE int_fast16_t height(void) const { return bottom - top + 1; } LGFX_INLINE bool empty(void) const { return left > right || top > bottom; } LGFX_INLINE bool contain(int_fast16_t x, int_fast16_t y) const { return left <= x && x <= right && top <= y && y <= bottom; } + LGFX_INLINE bool intersectsWith(const range_rect_t& rect) const { return horizon.intersectsWith(rect.horizon) && vertical.intersectsWith(rect.vertical); } #undef LGFX_INLINE }; diff --git a/src/lgfx/v1/platforms/esp32/common.hpp b/src/lgfx/v1/platforms/esp32/common.hpp index 23d5c1bc..6a42bdc2 100644 --- a/src/lgfx/v1/platforms/esp32/common.hpp +++ b/src/lgfx/v1/platforms/esp32/common.hpp @@ -138,100 +138,84 @@ namespace lgfx //---------------------------------------------------------------------------- #if defined (ARDUINO) - #if defined (FS_H) + #if defined (_SD_H_) + #define LGFX_FILESYSTEM_SD SD + #endif + #if defined (_LITTLEFS_H_) || defined (__LITTLEFS_H) || defined (_LiffleFS_H_) + #define LGFX_FILESYSTEM_LITTLEFS LittleFS + #endif + #if defined (_SPIFFS_H_) + #define LGFX_FILESYSTEM_SPIFFS SPIFFS + #endif + #if defined (_FFAT_H_) + #define LGFX_FILESYSTEM_FFAT FFat + #endif - struct FileWrapper : public DataWrapper - { -private: -#if defined (_SPIFFS_H_) - bool _check_need_transaction(void) const { return _fs != &SPIFFS; } -#else - bool _check_need_transaction(void) const { return true; } -#endif + #if defined (FS_H) \ + || defined (LGFX_FILESYSTEM_SD) \ + || defined (LGFX_FILESYSTEM_LITTLEFS) \ + || defined (LGFX_FILESYSTEM_SPIFFS) \ + || defined (LGFX_FILESYSTEM_FFAT) -public: - FileWrapper() : DataWrapper() - { -#if defined (_SD_H_) - _fs = &SD; -#elif defined (_SPIFFS_H_) - _fs = &SPIFFS; -#else - _fs = nullptr; -#endif - need_transaction = _check_need_transaction(); - _fp = nullptr; + template <> + struct DataWrapperT : public DataWrapper { + DataWrapperT(fs::File* fp = nullptr) : DataWrapper{}, _fp { fp } { + need_transaction = true; } - - fs::FS* _fs; + int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } + void skip(int32_t offset) override { _fp->seek(offset, SeekCur); } + bool seek(uint32_t offset) override { return _fp->seek(offset, SeekSet); } + bool seek(uint32_t offset, SeekMode mode) { return _fp->seek(offset, mode); } + void close(void) override { if (_fp) _fp->close(); } + int32_t tell(void) override { return _fp->position(); } +protected: fs::File *_fp; - fs::File _file; - - FileWrapper(fs::FS& fs, fs::File* fp = nullptr) : DataWrapper(), _fs(&fs), _fp(fp) { need_transaction = _check_need_transaction(); } - void setFS(fs::FS& fs) { - _fs = &fs; - need_transaction = _check_need_transaction(); - } + }; - bool open(fs::FS& fs, const char* path) - { - setFS(fs); - return open(path); + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT { fp }, _fs { fs } { +#if defined (LGFX_FILESYSTEM_SD) + need_transaction = (fs == &LGFX_FILESYSTEM_SD); +#endif } bool open(const char* path) override { _file = _fs->open(path, "r"); - _fp = &_file; + DataWrapperT::_fp = &_file; return _file; } - int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } - void skip(int32_t offset) override { seek(offset, SeekCur); } - bool seek(uint32_t offset) override { return seek(offset, SeekSet); } - bool seek(uint32_t offset, SeekMode mode) { return _fp->seek(offset, mode); } - void close(void) override { if (_fp) _fp->close(); } - int32_t tell(void) override { return _fp->position(); } - }; - #else - // dummy - struct FileWrapper : public DataWrapper - { - FileWrapper() : DataWrapper() - { - need_transaction = true; - } - void* _fp; - - template - void setFS(T& fs) {} - - bool open(const char* path, const char* mode) { return false; } - int read(uint8_t *buf, uint32_t len) override { return false; } - void skip(int32_t offset) override { } - bool seek(uint32_t offset) override { return false; } - bool seek(uint32_t offset, int origin) { return false; } - void close() override { } - int32_t tell(void) override { return 0; } - }; - - #endif -#else // ESP-IDF - struct FileWrapper : public DataWrapper - { - FileWrapper() : DataWrapper() - { - need_transaction = true; - } - FILE* _fp; - bool open(const char* path) override { return (_fp = fopen(path, "r")); } - int read(uint8_t *buf, uint32_t len) override { return fread((char*)buf, 1, len, _fp); } - void skip(int32_t offset) override { seek(offset, SEEK_CUR); } - bool seek(uint32_t offset) override { return seek(offset, SEEK_SET); } - bool seek(uint32_t offset, int origin) { return fseek(_fp, offset, origin); } - void close() override { if (_fp) fclose(_fp); } - int32_t tell(void) override { return ftell(_fp); } +protected: + fs::FS* _fs; + fs::File _file; }; + #if defined (LGFX_FILESYSTEM_SD) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; + #endif + #if defined (LGFX_FILESYSTEM_SPIFFS) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; + #endif + #if defined (LGFX_FILESYSTEM_LITTLEFS) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; + #endif + #if defined (LGFX_FILESYSTEM_FFAT) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; + #endif + #endif #endif //---------------------------------------------------------------------------- diff --git a/src/lgfx/v1/platforms/esp8266/common.hpp b/src/lgfx/v1/platforms/esp8266/common.hpp index 118bf6a5..6af77a85 100644 --- a/src/lgfx/v1/platforms/esp8266/common.hpp +++ b/src/lgfx/v1/platforms/esp8266/common.hpp @@ -94,6 +94,82 @@ namespace lgfx //---------------------------------------------------------------------------- +#if defined (ARDUINO) + #if defined (SDFS_H) + sdfs:: + #endif + #if defined (_SD_H_) + #define LGFX_FILESYSTEM_SD_INSTANCE SD + #define LGFX_FILESYSTEM_SD_TYPENAME fs::SDFS + #elif defined (SDFS_H) \ + || defined (__SD_H__) // Seeed_SD.h + #define LGFX_FILESYSTEM_SD_INSTANCE SDFS + #define LGFX_FILESYSTEM_SD_TYPENAME fs::SDFS + #endif + #if defined (_LITTLEFS_H_) || defined (__LITTLEFS_H) || defined (_LiffleFS_H_) + #define LGFX_FILESYSTEM_LITTLEFS_INSTANCE LittleFS + #define LGFX_FILESYSTEM_LITTLEFS_TYPENAME fs::LittleFSFS + #endif + #if defined (_SPIFFS_H_) + #define LGFX_FILESYSTEM_SPIFFS_INSTANCE SPIFFS + #define LGFX_FILESYSTEM_SPIFFS_TYPENAME fs::SPIFFSFS + #endif + #if defined (LGFX_FILESYSTEM_SD_INSTANCE) + #define LGFX_DEFAULT_FILESYSTEM LGFX_FILESYSTEM_SD_INSTANCE + #elif defined (LGFX_FILESYSTEM_LITTLEFS_INSTANCE) + #define LGFX_DEFAULT_FILESYSTEM LGFX_FILESYSTEM_LITTLEFS_INSTANCE + #elif defined (LGFX_FILESYSTEM_SPIFFS_INSTANCE) + #define LGFX_DEFAULT_FILESYSTEM LGFX_FILESYSTEM_SPIFFS_INSTANCE + #endif + + #if defined (FS_H) || defined (__SD_H__) \ + || defined (LGFX_FILESYSTEM_SD_INSTANCE) \ + || defined (LGFX_FILESYSTEM_LITTLEFS_INSTANCE) \ + || defined (LGFX_FILESYSTEM_SPIFFS_INSTANCE) + + template <> + struct DataWrapperT : public DataWrapper { + DataWrapperT(fs::File* fp = nullptr) : DataWrapper{}, _fp { fp } { + need_transaction = true; + } + int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } + void skip(int32_t offset) override { _fp->seek(offset, SeekCur); } + bool seek(uint32_t offset) override { return _fp->seek(offset, SeekSet); } + bool seek(uint32_t offset, SeekMode mode) { return _fp->seek(offset, mode); } + void close(void) override { if (_fp) _fp->close(); } + int32_t tell(void) override { return _fp->position(); } +protected: + fs::File *_fp; + }; + + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT { fp }, _fs { fs } { +#if defined (LGFX_FILESYSTEM_SD_INSTANCE) + need_transaction = (fs == &LGFX_FILESYSTEM_SD_INSTANCE); +#endif + } + bool open(const char* path) override + { + _file = _fs->open(path, "r"); + DataWrapperT::_fp = &_file; + return _file; + } + +protected: + fs::FS* _fs; + fs::File _file; + }; + + #if defined (LGFX_FILESYSTEM_SD_INSTANCE) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; + #endif + #endif +#endif +/* #if defined (ARDUINO) #if defined (FS_H) @@ -192,6 +268,7 @@ namespace lgfx }; #endif +*/ //---------------------------------------------------------------------------- } diff --git a/src/lgfx/v1/platforms/rp2040/common.hpp b/src/lgfx/v1/platforms/rp2040/common.hpp index 2e94b4f9..87fa4d14 100644 --- a/src/lgfx/v1/platforms/rp2040/common.hpp +++ b/src/lgfx/v1/platforms/rp2040/common.hpp @@ -90,11 +90,11 @@ namespace lgfx }; //---------------------------------------------------------------------------- + +/* struct FileWrapper : public DataWrapper { - - #if defined ARDUINO && ( defined SDFS_H || defined __LITTLEFS_H ) private: @@ -201,7 +201,7 @@ namespace lgfx #endif }; - +//*/ //---------------------------------------------------------------------------- } } diff --git a/src/lgfx/v1/platforms/samd21/common.hpp b/src/lgfx/v1/platforms/samd21/common.hpp index 36257d8f..560c25e7 100644 --- a/src/lgfx/v1/platforms/samd21/common.hpp +++ b/src/lgfx/v1/platforms/samd21/common.hpp @@ -128,60 +128,98 @@ namespace lgfx void pinAssignPeriph(int pin_and_port, int type = PIO_SERCOM); //---------------------------------------------------------------------------- - struct FileWrapper : public DataWrapper - { - FileWrapper() : DataWrapper() { need_transaction = true; } - -#if defined (ARDUINO) && defined (__SEEED_FS__) - - fs::File _file; - fs::File *_fp; - fs::FS *_fs = nullptr; - void setFS(fs::FS& fs) { - _fs = &fs; - need_transaction = false; - } - FileWrapper(fs::FS& fs) : DataWrapper(), _fp(nullptr) { setFS(fs); } - FileWrapper(fs::FS& fs, fs::File* fp) : DataWrapper(), _fp(fp) { setFS(fs); } +#if defined (__SEEED_FS__) - bool open(fs::FS& fs, const char* path) { - setFS(fs); - return open(path); + template <> + struct DataWrapperT : public DataWrapper { + DataWrapperT(fs::File* fp = nullptr) : DataWrapper{}, _fp { fp } { + need_transaction = true; } - - bool open(const char* path) override { - fs::File file = _fs->open(path, "r"); - // この邪悪なmemcpyは、Seeed_FSのFile実装が所有権moveを提供してくれないのにデストラクタでcloseを呼ぶ実装になっているため、; - // 正攻法ではFileをクラスメンバに保持できない状況を打開すべく応急処置的に実装したものです。; - memcpy(&_file, &file, sizeof(fs::File)); - // memsetにより一時変数の中身を吹っ飛ばし、デストラクタによるcloseを予防します。; - memset(&file, 0, sizeof(fs::File)); - _fp = &_file; - return _file; - } - int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } - void skip(int32_t offset) override { seek(offset, SeekCur); } - bool seek(uint32_t offset) override { return seek(offset, SeekSet); } + void skip(int32_t offset) override { _fp->seek(offset, SeekCur); } + bool seek(uint32_t offset) override { return _fp->seek(offset, SeekSet); } bool seek(uint32_t offset, SeekMode mode) { return _fp->seek(offset, mode); } void close(void) override { if (_fp) _fp->close(); } int32_t tell(void) override { return _fp->position(); } +protected: + fs::File *_fp; + }; -#else // dummy. + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT { fp }, _fs { fs } {} + bool open(const char* path) override + { + _file = _fs->open(path, "r"); + DataWrapperT::_fp = &_file; + return _file; + } - bool open(const char*) override { return false; } - int read(uint8_t*, uint32_t) override { return 0; } - void skip(int32_t) override { } - bool seek(uint32_t) override { return false; } - bool seek(uint32_t, int) { return false; } - void close() override { } - int32_t tell(void) override { return 0; } +protected: + fs::FS* _fs; + fs::File _file; + }; +#if defined (__SD_H__) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; #endif +#endif + +#if defined (__SAMD51_HARMONY__) && ( defined (__FILE_defined) || defined (_FILE_DEFINED) || defined (_FSTDIO) ) + template <> + struct DataWrapperT : public DataWrapper + { + DataWrapperT(FILE* fp = nullptr) : DataWrapper() , _fp { fp } + { + need_transaction = true; + } + bool open(const char* path) override { + this->handle = SYS_FS_FileOpen(path, SYS_FS_FILE_OPEN_ATTRIBUTES::SYS_FS_FILE_OPEN_READ); + return this->handle != SYS_FS_HANDLE_INVALID; + } + int read(uint8_t* buffer, uint32_t length) override + { + return SYS_FS_FileRead(this->handle, buffer, length); + } + void skip(int32_t offset) override + { + SYS_FS_FileSeek(this->handle, offset, SYS_FS_FILE_SEEK_CONTROL::SYS_FS_SEEK_CUR); + } + bool seek(uint32_t offset) override + { + return SYS_FS_FileSeek(this->handle, offset, SYS_FS_FILE_SEEK_CONTROL::SYS_FS_SEEK_SET) >= 0; + } + bool seek(uint32_t offset, SYS_FS_FILE_SEEK_CONTROL mode) + { + return SYS_FS_FileSeek(this->handle, offset, mode) >= 0; + } + void close(void) override + { + if( this->handle != SYS_FS_HANDLE_INVALID ) { + SYS_FS_FileClose(this->handle); + this->handle = SYS_FS_HANDLE_INVALID; + } + } + int32_t tell(void) override + { + return SYS_FS_FileTell(this->handle); + } + protected: + SYS_FS_HANDLE handle = SYS_FS_HANDLE_INVALID; }; + template <> + struct DataWrapperT : public DataWrapperT + { + DataWrapperT(void) : DataWrapperT() {} + }; +#endif + //---------------------------------------------------------------------------- } } diff --git a/src/lgfx/v1/platforms/samd51/common.hpp b/src/lgfx/v1/platforms/samd51/common.hpp index 8e39e82c..b31a255f 100644 --- a/src/lgfx/v1/platforms/samd51/common.hpp +++ b/src/lgfx/v1/platforms/samd51/common.hpp @@ -158,52 +158,57 @@ namespace lgfx void pinAssignPeriph(int pin_and_port, int type = PIO_SERCOM); //---------------------------------------------------------------------------- - struct FileWrapper : public DataWrapper - { - FileWrapper() : DataWrapper() { need_transaction = true; } - -#if defined (ARDUINO) && defined (__SEEED_FS__) - - fs::File _file; - fs::File *_fp; - fs::FS *_fs = nullptr; - void setFS(fs::FS& fs) { - _fs = &fs; - need_transaction = false; - } - FileWrapper(fs::FS& fs) : DataWrapper(), _fp(nullptr) { setFS(fs); } - FileWrapper(fs::FS& fs, fs::File* fp) : DataWrapper(), _fp(fp) { setFS(fs); } - - bool open(fs::FS& fs, const char* path) { - setFS(fs); - return open(path); - } +#if defined (__SEEED_FS__) - bool open(const char* path) override { - fs::File file = _fs->open(path, "r"); - // この邪悪なmemcpyは、Seeed_FSのFile実装が所有権moveを提供してくれないのにデストラクタでcloseを呼ぶ実装になっているため、; - // 正攻法ではFileをクラスメンバに保持できない状況を打開すべく応急処置的に実装したものです。; - memcpy(&_file, &file, sizeof(fs::File)); - // memsetにより一時変数の中身を吹っ飛ばし、デストラクタによるcloseを予防します。; - memset(&file, 0, sizeof(fs::File)); - _fp = &_file; - return _file; + template <> + struct DataWrapperT : public DataWrapper { + DataWrapperT(fs::File* fp = nullptr) : DataWrapper{}, _fp { fp } { + need_transaction = true; } - int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } - void skip(int32_t offset) override { seek(offset, SeekCur); } - bool seek(uint32_t offset) override { return seek(offset, SeekSet); } + void skip(int32_t offset) override { _fp->seek(offset, SeekCur); } + bool seek(uint32_t offset) override { return _fp->seek(offset, SeekSet); } bool seek(uint32_t offset, SeekMode mode) { return _fp->seek(offset, mode); } void close(void) override { if (_fp) _fp->close(); } int32_t tell(void) override { return _fp->position(); } +protected: + fs::File *_fp; + }; -#elif __SAMD51_HARMONY__ + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT { fp }, _fs { fs } {} + bool open(const char* path) override + { + _file = _fs->open(path, "r"); + DataWrapperT::_fp = &_file; + return _file; + } - SYS_FS_HANDLE handle = SYS_FS_HANDLE_INVALID; +protected: + fs::FS* _fs; + fs::File _file; + }; - bool open(const char* path) override +#if defined (__SD_H__) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(fs::FS* fs, fs::File* fp = nullptr) : DataWrapperT(fs, fp) {} + }; +#endif +#endif + +#if defined (__SAMD51_HARMONY__) && ( defined (__FILE_defined) || defined (_FILE_DEFINED) || defined (_FSTDIO) ) + + template <> + struct DataWrapperT : public DataWrapper + { + DataWrapperT(FILE* fp = nullptr) : DataWrapper() , _fp { fp } { + need_transaction = true; + } + bool open(const char* path) override { this->handle = SYS_FS_FileOpen(path, SYS_FS_FILE_OPEN_ATTRIBUTES::SYS_FS_FILE_OPEN_READ); return this->handle != SYS_FS_HANDLE_INVALID; } @@ -234,20 +239,16 @@ namespace lgfx { return SYS_FS_FileTell(this->handle); } + protected: + SYS_FS_HANDLE handle = SYS_FS_HANDLE_INVALID; + }; -#else // dummy. - - bool open(const char*) override { return false; } - int read(uint8_t*, uint32_t) override { return 0; } - void skip(int32_t) override { } - bool seek(uint32_t) override { return false; } - bool seek(uint32_t, int) { return false; } - void close() override { } - int32_t tell(void) override { return 0; } - -#endif - + template <> + struct DataWrapperT : public DataWrapperT + { + DataWrapperT(void) : DataWrapperT() {} }; +#endif //---------------------------------------------------------------------------- } diff --git a/src/lgfx/v1/platforms/spresense/common.hpp b/src/lgfx/v1/platforms/spresense/common.hpp index 42a50f78..165b43eb 100644 --- a/src/lgfx/v1/platforms/spresense/common.hpp +++ b/src/lgfx/v1/platforms/spresense/common.hpp @@ -81,65 +81,49 @@ namespace lgfx //---------------------------------------------------------------------------- #if defined (ARDUINO) - #if defined (__STORAGE_H__) - - struct FileWrapper : public DataWrapper - { + #if defined (__FILE_H__) -public: - FileWrapper() : DataWrapper() - { - _fs = nullptr; - _fp = nullptr; + template <> + struct DataWrapperT : public DataWrapper { + DataWrapperT(File* fp = nullptr) : DataWrapper{}, _fp { fp } { + need_transaction = true; } - - StorageClass* _fs; + int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } + void skip(int32_t offset) override { _fp->seek(_fp->position() + offset); } + bool seek(uint32_t offset) override { return _fp->seek(offset); } + void close(void) override { if (_fp) _fp->close(); } + int32_t tell(void) override { return _fp->position(); } +protected: File *_fp; - File _file; + }; - FileWrapper(StorageClass& fs, File* fp = nullptr) : DataWrapper(), _fs(&fs), _fp(fp) {} - void setFS(StorageClass& fs) { - _fs = &fs; - } + #if defined (__STORAGE_H__) - bool open(StorageClass& fs, const char* path) - { - setFS(fs); - return open(path); + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(StorageClass* fs, File* fp = nullptr) : DataWrapperT { fp }, _fs { fs } { + need_transaction = true; } bool open(const char* path) override { _file = _fs->open(path); - _fp = &_file; + DataWrapperT::_fp = &_file; return _file; } - int read(uint8_t *buf, uint32_t len) override { return _fp->read(buf, len); } - void skip(int32_t offset) override { _fp->seek(_fp->position() + offset); } - bool seek(uint32_t offset) override { return _fp->seek(offset); } - void close(void) override { if (_fp) _fp->close(); } - int32_t tell(void) override { return _fp->position(); } + +protected: + StorageClass* _fs; + File _file; }; - #else - struct FileWrapper : public DataWrapper - { - FileWrapper() : DataWrapper() - { - need_transaction = false; - } - void* _fp; - - template - void setFS(T& fs) {} - - bool open(const char* , const char* ) { return false; } - int read(uint8_t *, uint32_t ) override { return false; } - void skip(int32_t ) override { } - bool seek(uint32_t ) override { return false; } - bool seek(uint32_t , int ) { return false; } - void close() override { } - int32_t tell(void) override { return 0; } + #if defined (__SD_H__) + template <> + struct DataWrapperT : public DataWrapperT { + DataWrapperT(SDClass* fs, File* fp = nullptr) : DataWrapperT(fs, fp) {} }; + #endif + + #endif #endif