mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-20 15:03:25 +00:00
common Picture : Introduce Picture's size setter, getter APIs
* common Picture : Introduce Picture's size setter, getter APIs If picture or file loaded by picture has an explicit Size(width, height), it is transformed to fit the size.
This commit is contained in:
parent
ceb14e73a8
commit
6889f0ad1f
8 changed files with 81 additions and 37 deletions
|
@ -282,6 +282,9 @@ public:
|
||||||
Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept;
|
Result load(uint32_t* data, uint32_t w, uint32_t h, bool copy) noexcept;
|
||||||
Result viewbox(float* x, float* y, float* w, float* h) const noexcept;
|
Result viewbox(float* x, float* y, float* w, float* h) const noexcept;
|
||||||
|
|
||||||
|
Result size(uint32_t w, uint32_t h) noexcept;
|
||||||
|
Result size(uint32_t* w, uint32_t* h) const noexcept;
|
||||||
|
|
||||||
static std::unique_ptr<Picture> gen() noexcept;
|
static std::unique_ptr<Picture> gen() noexcept;
|
||||||
|
|
||||||
_TVG_DECLARE_PRIVATE(Picture);
|
_TVG_DECLARE_PRIVATE(Picture);
|
||||||
|
|
|
@ -25,25 +25,8 @@ void svgDirCallback(const char* name, const char* path, void* data)
|
||||||
|
|
||||||
if (picture->load(buf) != tvg::Result::Success) return;
|
if (picture->load(buf) != tvg::Result::Success) return;
|
||||||
|
|
||||||
float x, y, w, h;
|
picture->size(SIZE, SIZE);
|
||||||
picture->viewbox(&x, &y, &w, &h);
|
picture->translate((count % NUM_PER_LINE) * SIZE, SIZE * (count / NUM_PER_LINE));
|
||||||
|
|
||||||
float rate = (SIZE/(w > h ? w : h));
|
|
||||||
picture->scale(rate);
|
|
||||||
|
|
||||||
x *= rate;
|
|
||||||
y *= rate;
|
|
||||||
w *= rate;
|
|
||||||
h *= rate;
|
|
||||||
|
|
||||||
//Center Align ?
|
|
||||||
if (w > h) {
|
|
||||||
y -= (SIZE - h) * 0.5f;
|
|
||||||
} else {
|
|
||||||
x -= (SIZE - w) * 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
picture->translate((count % NUM_PER_LINE) * SIZE - x, SIZE * (count / NUM_PER_LINE) - y);
|
|
||||||
|
|
||||||
pictures.push_back(move(picture));
|
pictures.push_back(move(picture));
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,10 @@ public:
|
||||||
float vw = 0;
|
float vw = 0;
|
||||||
float vh = 0;
|
float vh = 0;
|
||||||
|
|
||||||
|
uint32_t w = 0; //default size
|
||||||
|
uint32_t h = 0; //default size
|
||||||
|
bool preserveAspect = true; //keep aspect ratio by default.
|
||||||
|
|
||||||
virtual ~Loader() {}
|
virtual ~Loader() {}
|
||||||
|
|
||||||
virtual bool open(const string& path) { /* Not supported */ return false; };
|
virtual bool open(const string& path) { /* Not supported */ return false; };
|
||||||
|
|
|
@ -73,3 +73,19 @@ Result Picture::viewbox(float* x, float* y, float* w, float* h) const noexcept
|
||||||
if (pImpl->viewbox(x, y, w, h)) return Result::Success;
|
if (pImpl->viewbox(x, y, w, h)) return Result::Success;
|
||||||
return Result::InsufficientCondition;
|
return Result::InsufficientCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result Picture::size(uint32_t w, uint32_t h) noexcept
|
||||||
|
{
|
||||||
|
if (pImpl->size(w, h)) return Result::Success;
|
||||||
|
return Result::InsufficientCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result Picture::size(uint32_t* w, uint32_t* h) const noexcept
|
||||||
|
{
|
||||||
|
if (w) *w = pImpl->w;
|
||||||
|
if (h) *h = pImpl->h;
|
||||||
|
return Result::Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct Picture::Impl
|
||||||
Picture *picture = nullptr;
|
Picture *picture = nullptr;
|
||||||
void *edata = nullptr; //engine data
|
void *edata = nullptr; //engine data
|
||||||
|
|
||||||
|
uint32_t w = 0, h = 0;
|
||||||
|
bool resizing = false;
|
||||||
|
|
||||||
Impl(Picture* p) : picture(p)
|
Impl(Picture* p) : picture(p)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -56,6 +59,36 @@ struct Picture::Impl
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resize()
|
||||||
|
{
|
||||||
|
uint32_t w = 0, h = 0;
|
||||||
|
if (this->w != 0 && this->h != 0) {
|
||||||
|
w = this->w;
|
||||||
|
h = this->h;
|
||||||
|
}
|
||||||
|
else if (loader->w != 0 && loader->h != 0) {
|
||||||
|
w = loader->w;
|
||||||
|
h = loader->h;
|
||||||
|
}
|
||||||
|
if (w != 0 && h != 0) {
|
||||||
|
auto sx = w / (loader->vw + (loader->vx > 0 ? loader->vx : -1 * loader->vx));
|
||||||
|
auto sy = h / (loader->vh + (loader->vy > 0 ? loader->vy : -1 * loader->vy));
|
||||||
|
if (!loader->preserveAspect) {
|
||||||
|
Matrix m = {sx, 0, -loader->vx,
|
||||||
|
0, sy, -loader->vy,
|
||||||
|
0, 0, 1};
|
||||||
|
paint->transform(m);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
auto scale = sx < sy ? sx : sy;
|
||||||
|
paint->translate(((w - loader->vw) * scale) / 2.0, ((h - loader->vh) * scale) / 2.0);
|
||||||
|
paint->scale(scale);
|
||||||
|
paint->translate(-loader->vx, -loader->vy);
|
||||||
|
}
|
||||||
|
resizing = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t reload()
|
uint32_t reload()
|
||||||
{
|
{
|
||||||
if (loader) {
|
if (loader) {
|
||||||
|
@ -63,6 +96,7 @@ struct Picture::Impl
|
||||||
auto scene = loader->scene();
|
auto scene = loader->scene();
|
||||||
if (scene) {
|
if (scene) {
|
||||||
paint = scene.release();
|
paint = scene.release();
|
||||||
|
resizing = true;
|
||||||
loader->close();
|
loader->close();
|
||||||
if (paint) return RenderUpdateFlag::None;
|
if (paint) return RenderUpdateFlag::None;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +114,10 @@ struct Picture::Impl
|
||||||
uint32_t flag = reload();
|
uint32_t flag = reload();
|
||||||
|
|
||||||
if (pixels) edata = renderer.prepare(*picture, edata, pixels, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
if (pixels) edata = renderer.prepare(*picture, edata, pixels, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||||
else if (paint) edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
else if (paint) {
|
||||||
|
if (resizing) resize();
|
||||||
|
edata = paint->pImpl->update(renderer, transform, opacity, compList, static_cast<RenderUpdateFlag>(pFlag | flag));
|
||||||
|
}
|
||||||
return edata;
|
return edata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +138,14 @@ struct Picture::Impl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool size(uint32_t w, uint32_t h)
|
||||||
|
{
|
||||||
|
this->w = w;
|
||||||
|
this->h = h;
|
||||||
|
resizing = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool bounds(float* x, float* y, float* w, float* h)
|
bool bounds(float* x, float* y, float* w, float* h)
|
||||||
{
|
{
|
||||||
if (!paint) return false;
|
if (!paint) return false;
|
||||||
|
|
|
@ -2466,10 +2466,15 @@ bool SvgLoader::header()
|
||||||
|
|
||||||
if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) {
|
if (loaderData.doc && loaderData.doc->type == SvgNodeType::Doc) {
|
||||||
//Return the brief resource info such as viewbox:
|
//Return the brief resource info such as viewbox:
|
||||||
this->vx = loaderData.doc->node.doc.vx;
|
vx = loaderData.doc->node.doc.vx;
|
||||||
this->vy = loaderData.doc->node.doc.vy;
|
vy = loaderData.doc->node.doc.vy;
|
||||||
this->vw = loaderData.doc->node.doc.vw;
|
vw = loaderData.doc->node.doc.vw;
|
||||||
this->vh = loaderData.doc->node.doc.vh;
|
vh = loaderData.doc->node.doc.vh;
|
||||||
|
|
||||||
|
w = loaderData.doc->node.doc.w;
|
||||||
|
h = loaderData.doc->node.doc.h;
|
||||||
|
|
||||||
|
preserveAspect = loaderData.doc->node.doc.preserveAspect;
|
||||||
} else {
|
} else {
|
||||||
//LOG: No SVG File. There is no <svg/>
|
//LOG: No SVG File. There is no <svg/>
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -384,10 +384,5 @@ unique_ptr<Scene> SvgSceneBuilder::build(SvgNode* node)
|
||||||
{
|
{
|
||||||
if (!node || (node->type != SvgNodeType::Doc)) return nullptr;
|
if (!node || (node->type != SvgNodeType::Doc)) return nullptr;
|
||||||
|
|
||||||
viewBox.x = node->node.doc.vx;
|
return _sceneBuildHelper(node, node->node.doc.vx, node->node.doc.vy, node->node.doc.vw, node->node.doc.vh, 255);
|
||||||
viewBox.y = node->node.doc.vy;
|
|
||||||
viewBox.w = node->node.doc.vw;
|
|
||||||
viewBox.h = node->node.doc.vh;
|
|
||||||
preserveAspect = node->node.doc.preserveAspect;
|
|
||||||
return _sceneBuildHelper(node, viewBox.x, viewBox.y, viewBox.w, viewBox.h, 255);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,13 +27,6 @@
|
||||||
|
|
||||||
class SvgSceneBuilder
|
class SvgSceneBuilder
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
struct {
|
|
||||||
int x, y;
|
|
||||||
uint32_t w, h;
|
|
||||||
} viewBox = {0, 0, 0, 0};
|
|
||||||
bool preserveAspect = false;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SvgSceneBuilder();
|
SvgSceneBuilder();
|
||||||
~SvgSceneBuilder();
|
~SvgSceneBuilder();
|
||||||
|
|
Loading…
Add table
Reference in a new issue