Skip to content

Commit

Permalink
Change FileWrapper to DataWrapperT
Browse files Browse the repository at this point in the history
  • Loading branch information
lovyan03 committed Dec 31, 2023
1 parent 50f5a96 commit 52baec6
Show file tree
Hide file tree
Showing 14 changed files with 689 additions and 563 deletions.
34 changes: 33 additions & 1 deletion src/lgfx/v1/LGFXBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2144,7 +2144,6 @@ namespace lgfx
//_decoderState = utf8_decode_state_t::utf8_state0;

font->getDefaultMetric(&_font_metrics);

}

/// load VLW font
Expand All @@ -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();
Expand Down
68 changes: 66 additions & 2 deletions src/lgfx/v1/LGFXBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
bool loadFont(T &fs, const char *path)
{
unloadFont();
_font_file.reset(new DataWrapperT<T>(&fs));
return load_font_with_path(path);
}

/// unload VLW font
void unloadFont(void);

Expand All @@ -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 <typename T>
void setFileStorage(T& fs) {
_data_wrapper_factory.reset(new DataWrapperTFactoryT<T>(&fs));
}

template <typename T>
void setFileStorage(T* fs) { _data_wrapper_factory.reset(new DataWrapperTFactoryT<T>(fs)); }

void clearFileStorage(void) { _data_wrapper_factory.reset(new DataWrapperTFactoryT<void>(nullptr)); }

//----------------------------------------------------------------------------
// print & text support
//----------------------------------------------------------------------------
Expand Down Expand Up @@ -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; \
Expand All @@ -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 <typename T> \
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<T> 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)
Expand All @@ -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);

Expand Down Expand Up @@ -917,6 +977,9 @@ namespace lgfx
std::shared_ptr<DataWrapper> _font_file; // run-time font file
PointerWrapper _font_data;

std::shared_ptr<DataWrapperFactory> _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;
Expand Down Expand Up @@ -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)
{
Expand Down
107 changes: 104 additions & 3 deletions src/lgfx/v1/LGFX_Sprite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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<bgr888_t, argb8888_t>(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;
}

//----------------------------------------------------------------------------
}
}
Expand Down
Loading

0 comments on commit 52baec6

Please sign in to comment.