common picture: correct non-working size() behavior.

Pixel-based image picture doesn't work at size() method.
Obvisouly, we missed to implement it properly.

This patch corrects it.

@Issue: https://github.com/Samsung/thorvg/issues/656
This commit is contained in:
Hermet Park 2021-07-28 20:55:10 +09:00 committed by Hermet Park
parent 750d170978
commit 02081d8cdc
9 changed files with 49 additions and 31 deletions

View file

@ -1048,7 +1048,7 @@ public:
* *
* @BETA_API * @BETA_API
*/ */
const uint32_t* data() const noexcept; const uint32_t* data(uint32_t* w, uint32_t* h) const noexcept;
/** /**
* Must remove it! * Must remove it!

View file

@ -40,7 +40,7 @@ void tvgDrawCmds(tvg::Canvas* canvas)
} }
picture->translate(i* 150, i * 150); picture->translate(i* 150, i * 150);
picture->rotate(30 * i); picture->rotate(30 * i);
picture->scale(0.25); picture->size(200, 200);
if (canvas->push(move(picture)) != tvg::Result::Success) return; if (canvas->push(move(picture)) != tvg::Result::Success) return;
} }

View file

@ -38,7 +38,7 @@ void tvgDrawCmds(tvg::Canvas* canvas)
} }
picture->translate(i* 150, i * 150); picture->translate(i* 150, i * 150);
picture->rotate(30 * i); picture->rotate(30 * i);
picture->scale(0.25); picture->size(200, 200);
if (canvas->push(move(picture)) != tvg::Result::Success) return; if (canvas->push(move(picture)) != tvg::Result::Success) return;
} }
} }

View file

@ -266,7 +266,7 @@ struct SwMpool
static inline SwCoord TO_SWCOORD(float val) static inline SwCoord TO_SWCOORD(float val)
{ {
return SwCoord(val * 64); return SwCoord(val * 64.0f);
} }
static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a) static inline uint32_t ALPHA_BLEND(uint32_t c, uint32_t a)
@ -289,7 +289,7 @@ static inline uint32_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
static inline SwCoord HALF_STROKE(float width) static inline SwCoord HALF_STROKE(float width)
{ {
return TO_SWCOORD(width * 0.5); return TO_SWCOORD(width * 0.5f);
} }
int64_t mathMultiply(int64_t a, int64_t b); int64_t mathMultiply(int64_t a, int64_t b);
@ -329,7 +329,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
void strokeFree(SwStroke* stroke); void strokeFree(SwStroke* stroke);
bool imagePrepare(SwImage* image, const Picture* pdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
bool imagePrepared(const SwImage* image); bool imagePrepared(const SwImage* image);
bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias); bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);

View file

@ -26,12 +26,8 @@
/* Internal Class Implementation */ /* Internal Class Implementation */
/************************************************************************/ /************************************************************************/
static bool _genOutline(SwImage* image, const Picture* pdata, const Matrix* transform, SwMpool* mpool, unsigned tid) static bool _genOutline(SwImage* image, const Matrix* transform, SwMpool* mpool, unsigned tid)
{ {
float w, h;
pdata->size(&w, &h);
if (w == 0 || h == 0) return false;
image->outline = mpoolReqOutline(mpool, tid); image->outline = mpoolReqOutline(mpool, tid);
auto outline = image->outline; auto outline = image->outline;
@ -42,6 +38,9 @@ static bool _genOutline(SwImage* image, const Picture* pdata, const Matrix* tran
outline->reservedCntrsCnt = 1; outline->reservedCntrsCnt = 1;
outline->cntrs = static_cast<uint32_t*>(realloc(outline->cntrs, outline->reservedCntrsCnt * sizeof(uint32_t))); outline->cntrs = static_cast<uint32_t*>(realloc(outline->cntrs, outline->reservedCntrsCnt * sizeof(uint32_t)));
auto w = static_cast<float>(image->w);
auto h = static_cast<float>(image->h);
Point to[4] = {{0 ,0}, {w, 0}, {w, h}, {0, h}}; Point to[4] = {{0 ,0}, {w, 0}, {w, h}, {0, h}};
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform); outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform);
@ -59,8 +58,6 @@ static bool _genOutline(SwImage* image, const Picture* pdata, const Matrix* tran
outline->opened = false; outline->opened = false;
image->outline = outline; image->outline = outline;
image->w = w;
image->h = h;
return true; return true;
} }
@ -71,9 +68,9 @@ static bool _genOutline(SwImage* image, const Picture* pdata, const Matrix* tran
/************************************************************************/ /************************************************************************/
bool imagePrepare(SwImage* image, const Picture* pdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
{ {
if (!_genOutline(image, pdata, transform, mpool, tid)) return false; if (!_genOutline(image, transform, mpool, tid)) return false;
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion); return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion);
} }

View file

@ -181,7 +181,11 @@ struct SwImageTask : SwTask
if (prepareImage) { if (prepareImage) {
imageReset(&image); imageReset(&image);
if (!imagePrepare(&image, pdata, transform, clipRegion, bbox, mpool, tid)) goto end;
image.data = const_cast<uint32_t*>(pdata->data(&image.w, &image.h));
if (!image.data || image.w == 0 || image.h == 0) goto end;
if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end;
//Clip Path? //Clip Path?
if (clips.count > 0) { if (clips.count > 0) {
@ -195,7 +199,6 @@ struct SwImageTask : SwTask
} }
} }
} }
image.data = const_cast<uint32_t*>(pdata->data());
end: end:
imageDelOutline(&image, mpool, tid); imageDelOutline(&image, mpool, tid);
} }

View file

@ -85,11 +85,18 @@ Result Picture::size(float* w, float* h) const noexcept
} }
const uint32_t* Picture::data() const noexcept const uint32_t* Picture::data(uint32_t* w, uint32_t* h) const noexcept
{ {
//Try it, If not loaded yet. //Try it, If not loaded yet.
if (pImpl->loader) return pImpl->loader->pixels(); pImpl->reload();
if (pImpl->loader) {
if (w) *w = static_cast<uint32_t>(pImpl->loader->w);
if (h) *h = static_cast<uint32_t>(pImpl->loader->h);
} else {
if (w) *w = 0;
if (h) *h = 0;
}
return pImpl->pixels; return pImpl->pixels;
} }

View file

@ -76,7 +76,6 @@ struct Picture::Impl
return ret; return ret;
} }
uint32_t reload() uint32_t reload()
{ {
if (loader) { if (loader) {
@ -100,17 +99,33 @@ struct Picture::Impl
return RenderUpdateFlag::None; return RenderUpdateFlag::None;
} }
void* update(RenderMethod &renderer, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) RenderTransform resizeTransform(const RenderTransform* pTransform)
{
//Overriding Transformation by the desired image size
auto sx = w / loader->w;
auto sy = h / loader->h;
auto scale = sx < sy ? sx : sy;
RenderTransform tmp;
tmp.m = {scale, 0, 0, 0, scale, 0, 0, 0, 1};
if (!pTransform) return tmp;
else return RenderTransform(pTransform, &tmp);
}
void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
{ {
auto flag = reload(); auto flag = reload();
if (pixels) rdata = renderer.prepare(*picture, rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); if (pixels) {
else if (paint) { auto transform = resizeTransform(pTransform);
rdata = renderer.prepare(*picture, rdata, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
} else if (paint) {
if (resizing) { if (resizing) {
loader->resize(paint, w, h); loader->resize(paint, w, h);
resizing = false; resizing = false;
} }
rdata = paint->pImpl->update(renderer, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); rdata = paint->pImpl->update(renderer, pTransform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
} }
return rdata; return rdata;
} }

View file

@ -319,13 +319,9 @@ TvgBinCounter TvgSaver::serializePicture(const Picture* picture)
TvgBinCounter cnt = 0; TvgBinCounter cnt = 0;
//Bitmap Image //Bitmap Image
if (auto pixels = picture->data()) { uint32_t w, h;
//TODO: Loader expects uints
float fw, fh;
picture->size(&fw, &fh);
auto w = static_cast<uint32_t>(fw); if (auto pixels = picture->data(&w, &h)) {
auto h = static_cast<uint32_t>(fh);
TvgBinCounter sizeCnt = sizeof(w); TvgBinCounter sizeCnt = sizeof(w);
TvgBinCounter imgSize = w * h * sizeof(pixels[0]); TvgBinCounter imgSize = w * h * sizeof(pixels[0]);