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
*/
const uint32_t* data() const noexcept;
const uint32_t* data(uint32_t* w, uint32_t* h) const noexcept;
/**
* Must remove it!

View file

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

View file

@ -266,7 +266,7 @@ struct SwMpool
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)
@ -289,7 +289,7 @@ static inline uint32_t ALPHA_MULTIPLY(uint32_t c, uint32_t a)
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);
@ -329,7 +329,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
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 imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);

View file

@ -26,12 +26,8 @@
/* 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);
auto outline = image->outline;
@ -42,6 +38,9 @@ static bool _genOutline(SwImage* image, const Picture* pdata, const Matrix* tran
outline->reservedCntrsCnt = 1;
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}};
for (int i = 0; i < 4; i++) {
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;
image->outline = outline;
image->w = w;
image->h = h;
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);
}

View file

@ -181,7 +181,11 @@ struct SwImageTask : SwTask
if (prepareImage) {
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?
if (clips.count > 0) {
@ -194,8 +198,7 @@ struct SwImageTask : SwTask
}
}
}
}
image.data = const_cast<uint32_t*>(pdata->data());
}
end:
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.
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;
}

View file

@ -76,7 +76,6 @@ struct Picture::Impl
return ret;
}
uint32_t reload()
{
if (loader) {
@ -100,17 +99,33 @@ struct Picture::Impl
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();
if (pixels) rdata = renderer.prepare(*picture, rdata, transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
else if (paint) {
if (pixels) {
auto transform = resizeTransform(pTransform);
rdata = renderer.prepare(*picture, rdata, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
} else if (paint) {
if (resizing) {
loader->resize(paint, w, h);
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;
}

View file

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