common picture: fix crash at picture duplication.

A duplicated picture needs to access internal picture loader data
to get its properties while rasterizing.

But it missed the loader since it's not copied from origin.

Thus, we fix this by sharing the internal loader among the duplications and origin.

@Examples: Duplicate
This commit is contained in:
Hermet Park 2021-03-19 19:41:18 +09:00 committed by GitHub
parent 95c022da1f
commit 53d23e9862
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 14 deletions

View file

@ -113,6 +113,8 @@ void tvgDrawCmds(tvg::Canvas* canvas)
canvas->push(move(picture1));
canvas->push(move(picture2));
free(data);
}
}

View file

@ -46,6 +46,8 @@ void tvgDrawCmds(tvg::Canvas* canvas)
picture2->composite(move(circle), tvg::CompositeMethod::ClipPath);
canvas->push(move(picture2));
free(data);
}
@ -148,8 +150,6 @@ int main(int argc, char **argv)
//Terminate ThorVG Engine
tvg::Initializer::term(tvg::CanvasEngine::Sw);
if (data) free(data);
} else {
cout << "engine is not supported" << endl;
}

View file

@ -89,22 +89,22 @@ bool LoaderMgr::term()
}
unique_ptr<Loader> LoaderMgr::loader(const string& path)
shared_ptr<Loader> LoaderMgr::loader(const string& path)
{
if (auto loader = _find(path)) {
if (loader->open(path)) return unique_ptr<Loader>(loader);
if (loader->open(path)) return shared_ptr<Loader>(loader);
else delete(loader);
}
return nullptr;
}
unique_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
shared_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
{
for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) {
auto loader = _find(static_cast<FileType>(i));
if (loader) {
if (loader->open(data, size)) return unique_ptr<Loader>(loader);
if (loader->open(data, size)) return shared_ptr<Loader>(loader);
else delete(loader);
}
}
@ -112,12 +112,12 @@ unique_ptr<Loader> LoaderMgr::loader(const char* data, uint32_t size)
}
unique_ptr<Loader> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
shared_ptr<Loader> LoaderMgr::loader(const uint32_t *data, uint32_t w, uint32_t h, bool copy)
{
for (int i = 0; i < static_cast<int>(FileType::Unknown); i++) {
auto loader = _find(static_cast<FileType>(i));
if (loader) {
if (loader->open(data, w, h, copy)) return unique_ptr<Loader>(loader);
if (loader->open(data, w, h, copy)) return shared_ptr<Loader>(loader);
else delete(loader);
}
}

View file

@ -30,9 +30,9 @@ struct LoaderMgr
{
static bool init();
static bool term();
static unique_ptr<Loader> loader(const string& path);
static unique_ptr<Loader> loader(const char* data, uint32_t size);
static unique_ptr<Loader> loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy);
static shared_ptr<Loader> loader(const string& path);
static shared_ptr<Loader> loader(const char* data, uint32_t size);
static shared_ptr<Loader> loader(const uint32_t* data, uint32_t w, uint32_t h, bool copy);
};
#endif //_TVG_LOADER_MGR_H_

View file

@ -32,7 +32,7 @@
struct Picture::Impl
{
unique_ptr<Loader> loader = nullptr;
shared_ptr<Loader> loader = nullptr;
Paint* paint = nullptr;
uint32_t *pixels = nullptr;
Picture *picture = nullptr;
@ -105,6 +105,7 @@ struct Picture::Impl
}
if (!pixels) {
pixels = const_cast<uint32_t*>(loader->pixels());
loader->close();
if (pixels) return RenderUpdateFlag::Image;
}
}
@ -195,11 +196,17 @@ struct Picture::Impl
{
reload();
if (!paint) return nullptr;
auto ret = Picture::gen();
if (!ret) return nullptr;
auto dup = ret.get()->pImpl;
dup->paint = paint->duplicate();
if (paint) dup->paint = paint->duplicate();
dup->loader = loader;
dup->pixels = pixels;
dup->w = w;
dup->h = h;
dup->resizing = resizing;
return ret.release();
}