mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
common loader: code refactoring
Bitmap based pictures doesn't need the viewbox, LoaderModule should delegate the viewbox to the derived classes which having vector-based image loaders such as svg, tvg. In that case, paint resizing can be performed by the loaders by own policy.
This commit is contained in:
parent
3cb0caf2c4
commit
d213a67180
9 changed files with 99 additions and 59 deletions
|
@ -30,19 +30,17 @@ namespace tvg
|
|||
class LoadModule
|
||||
{
|
||||
public:
|
||||
//default view box, if any.
|
||||
float vx = 0;
|
||||
float vy = 0;
|
||||
float vw = 0;
|
||||
float vh = 0;
|
||||
float w = 0, h = 0; //default image size
|
||||
bool preserveAspect = true; //keep aspect ratio by default.
|
||||
|
||||
virtual ~LoadModule() {}
|
||||
|
||||
virtual bool open(const string& path) { return false; };
|
||||
virtual bool open(const char* data, uint32_t size, bool copy) { return false; };
|
||||
virtual bool open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) { return false; };
|
||||
|
||||
//Override this if the vector-format has own resizing policy.
|
||||
virtual bool resize(Paint* paint, float w, float h) { return false; };
|
||||
|
||||
virtual bool read() = 0;
|
||||
virtual bool close() = 0;
|
||||
virtual const uint32_t* pixels() { return nullptr; };
|
||||
|
|
|
@ -76,37 +76,6 @@ struct Picture::Impl
|
|||
return ret;
|
||||
}
|
||||
|
||||
void resize()
|
||||
{
|
||||
auto sx = w / loader->vw;
|
||||
auto sy = h / loader->vh;
|
||||
|
||||
if (loader->preserveAspect) {
|
||||
//Scale
|
||||
auto scale = sx < sy ? sx : sy;
|
||||
paint->scale(scale);
|
||||
//Align
|
||||
auto vx = loader->vx * scale;
|
||||
auto vy = loader->vy * scale;
|
||||
auto vw = loader->vw * scale;
|
||||
auto vh = loader->vh * scale;
|
||||
if (vw > vh) vy -= (h - vh) * 0.5f;
|
||||
else vx -= (w - vw) * 0.5f;
|
||||
paint->translate(-vx, -vy);
|
||||
} else {
|
||||
//Align
|
||||
auto vx = loader->vx * sx;
|
||||
auto vy = loader->vy * sy;
|
||||
auto vw = loader->vw * sx;
|
||||
auto vh = loader->vh * sy;
|
||||
if (vw > vh) vy -= (h - vh) * 0.5f;
|
||||
else vx -= (w - vw) * 0.5f;
|
||||
|
||||
Matrix m = {sx, 0, -vx, 0, sy, -vy, 0, 0, 1};
|
||||
paint->transform(m);
|
||||
}
|
||||
resizing = false;
|
||||
}
|
||||
|
||||
uint32_t reload()
|
||||
{
|
||||
|
@ -115,7 +84,10 @@ struct Picture::Impl
|
|||
if (auto p = loader->paint()) {
|
||||
paint = p.release();
|
||||
loader->close();
|
||||
if (w != loader->w && h != loader->h) resize();
|
||||
if (w != loader->w && h != loader->h) {
|
||||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
if (paint) return RenderUpdateFlag::None;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +106,10 @@ struct Picture::Impl
|
|||
|
||||
if (pixels) rdata = renderer.prepare(*picture, rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||
else if (paint) {
|
||||
if (resizing) resize();
|
||||
if (resizing) {
|
||||
loader->resize(paint, w, h);
|
||||
resizing = false;
|
||||
}
|
||||
rdata = paint->pImpl->update(renderer, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||
}
|
||||
return rdata;
|
||||
|
|
|
@ -79,8 +79,8 @@ bool JpgLoader::open(const string& path)
|
|||
int width, height, subSample, colorSpace;
|
||||
if (tjDecompressHeader3(jpegDecompressor, data, size, &width, &height, &subSample, &colorSpace) < 0) goto failure;
|
||||
|
||||
vw = w = static_cast<float>(width);
|
||||
vh = h = static_cast<float>(height);
|
||||
w = static_cast<float>(width);
|
||||
h = static_cast<float>(height);
|
||||
ret = true;
|
||||
freeData = true;
|
||||
|
||||
|
@ -111,8 +111,8 @@ bool JpgLoader::open(const char* data, uint32_t size, bool copy)
|
|||
this->data = (unsigned char *) data;
|
||||
}
|
||||
|
||||
vw = w = static_cast<float>(width);
|
||||
vh = h = static_cast<float>(height);
|
||||
w = static_cast<float>(width);
|
||||
h = static_cast<float>(height);
|
||||
this->size = size;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -45,8 +45,8 @@ bool PngLoader::open(const string& path)
|
|||
|
||||
if (!png_image_begin_read_from_file(image, path.c_str())) return false;
|
||||
|
||||
vw = w = image->width;
|
||||
vh = h = image->height;
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
|
|||
|
||||
if (!png_image_begin_read_from_memory(image, data, size)) return false;
|
||||
|
||||
vw = w = image->width;
|
||||
vh = h = image->height;
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -45,14 +45,14 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy)
|
|||
{
|
||||
if (!data || w == 0 || h == 0) return false;
|
||||
|
||||
this->w = vw = w;
|
||||
this->h = vh = h;
|
||||
this->w = w;
|
||||
this->h = h;
|
||||
this->copy = copy;
|
||||
|
||||
if (copy) {
|
||||
content = (uint32_t*)malloc(sizeof(uint32_t) * vw * vh);
|
||||
content = (uint32_t*)malloc(sizeof(uint32_t) * w * h);
|
||||
if (!content) return false;
|
||||
memcpy((void*)content, data, sizeof(uint32_t) * vw * vh);
|
||||
memcpy((void*)content, data, sizeof(uint32_t) * w * h);
|
||||
}
|
||||
else content = data;
|
||||
|
||||
|
|
|
@ -2850,6 +2850,41 @@ bool SvgLoader::open(const string& path)
|
|||
}
|
||||
|
||||
|
||||
bool SvgLoader::resize(Paint* paint, float w, float h)
|
||||
{
|
||||
if (!paint) return false;
|
||||
|
||||
auto sx = w / vw;
|
||||
auto sy = h / vh;
|
||||
|
||||
if (preserveAspect) {
|
||||
//Scale
|
||||
auto scale = sx < sy ? sx : sy;
|
||||
paint->scale(scale);
|
||||
//Align
|
||||
auto vx = this->vx * scale;
|
||||
auto vy = this->vy * scale;
|
||||
auto vw = this->vw * scale;
|
||||
auto vh = this->vh * scale;
|
||||
if (vw > vh) vy -= (h - vh) * 0.5f;
|
||||
else vx -= (w - vw) * 0.5f;
|
||||
paint->translate(-vx, -vy);
|
||||
} else {
|
||||
//Align
|
||||
auto vx = this->vx * sx;
|
||||
auto vy = this->vy * sy;
|
||||
auto vw = this->vw * sx;
|
||||
auto vh = this->vh * sy;
|
||||
if (vw > vh) vy -= (h - vh) * 0.5f;
|
||||
else vx -= (w - vw) * 0.5f;
|
||||
|
||||
Matrix m = {sx, 0, -vx, 0, sy, -vy, 0, 0, 1};
|
||||
paint->transform(m);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SvgLoader::read()
|
||||
{
|
||||
if (!content || size == 0) return false;
|
||||
|
|
|
@ -35,7 +35,14 @@ public:
|
|||
SvgLoaderData loaderData;
|
||||
unique_ptr<Scene> root;
|
||||
|
||||
//default view box, if any.
|
||||
float vx = 0;
|
||||
float vy = 0;
|
||||
float vw = 0;
|
||||
float vh = 0;
|
||||
|
||||
bool copy = false;
|
||||
bool preserveAspect = true; //aspect ratio option
|
||||
|
||||
SvgLoader();
|
||||
~SvgLoader();
|
||||
|
@ -43,16 +50,15 @@ public:
|
|||
using LoadModule::open;
|
||||
bool open(const string& path) override;
|
||||
bool open(const char* data, uint32_t size, bool copy) override;
|
||||
|
||||
bool header();
|
||||
bool resize(Paint* paint, float w, float h) override;
|
||||
bool read() override;
|
||||
bool close() override;
|
||||
void run(unsigned tid) override;
|
||||
|
||||
unique_ptr<Paint> paint() override;
|
||||
|
||||
private:
|
||||
bool header();
|
||||
void clear();
|
||||
void run(unsigned tid) override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ bool TvgLoader::open(const string &path)
|
|||
return tvgValidateData(pointer, size);
|
||||
}
|
||||
|
||||
|
||||
bool TvgLoader::open(const char *data, uint32_t size, bool copy)
|
||||
{
|
||||
clear();
|
||||
|
@ -102,6 +103,30 @@ bool TvgLoader::open(const char *data, uint32_t size, bool copy)
|
|||
return tvgValidateData(pointer, size);
|
||||
}
|
||||
|
||||
|
||||
bool TvgLoader::resize(Paint* paint, float w, float h)
|
||||
{
|
||||
if (!paint) return false;
|
||||
|
||||
auto sx = w / this->w;
|
||||
auto sy = h / this->h;
|
||||
|
||||
//Scale
|
||||
auto scale = sx < sy ? sx : sy;
|
||||
paint->scale(scale);
|
||||
|
||||
//Align
|
||||
float tx = 0, ty = 0;
|
||||
auto sw = this->w * scale;
|
||||
auto sh = this->h * scale;
|
||||
if (sw > sh) ty -= (h - sh) * 0.5f;
|
||||
else tx -= (w - sw) * 0.5f;
|
||||
paint->translate(-tx, -ty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TvgLoader::read()
|
||||
{
|
||||
if (!pointer || size == 0) return false;
|
||||
|
@ -111,6 +136,7 @@ bool TvgLoader::read()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TvgLoader::close()
|
||||
{
|
||||
this->done();
|
||||
|
@ -118,6 +144,7 @@ bool TvgLoader::close()
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TvgLoader::run(unsigned tid)
|
||||
{
|
||||
if (root) root.reset();
|
||||
|
@ -125,6 +152,7 @@ void TvgLoader::run(unsigned tid)
|
|||
if (!root) clear();
|
||||
}
|
||||
|
||||
|
||||
unique_ptr<Paint> TvgLoader::paint()
|
||||
{
|
||||
this->done();
|
||||
|
|
|
@ -31,9 +31,7 @@ public:
|
|||
const char* data = nullptr;
|
||||
const char* pointer = nullptr;
|
||||
uint32_t size = 0;
|
||||
|
||||
unique_ptr<Scene> root = nullptr;
|
||||
|
||||
bool copy = false;
|
||||
|
||||
~TvgLoader();
|
||||
|
@ -43,11 +41,11 @@ public:
|
|||
bool open(const char *data, uint32_t size, bool copy) override;
|
||||
bool read() override;
|
||||
bool close() override;
|
||||
|
||||
void run(unsigned tid) override;
|
||||
bool resize(Paint* paint, float w, float h) override;
|
||||
unique_ptr<Paint> paint() override;
|
||||
|
||||
private:
|
||||
void run(unsigned tid) override;
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue