ThorVG: update from v0.12.4 to v0.12.5

https://github.com/thorvg/thorvg/releases/tag/v0.12.5

    + Full Changelog:
      https://github.com/thorvg/thorvg/compare/v0.12.4...v0.12.5

Godot-related SVG bug fixes:

    + sw_engine: Improve image up-scaler quality.
      thorvg/thorvg#1960

    + renderer: Ensure canvas rendering continues
      despite invalid scene parts.
      thorvg/thorvg#1957

    + Portability: Fix compiler shadowing warning (patch)
      thorvg/thorvg#1975
This commit is contained in:
Martin Capitanio 2024-02-08 09:44:54 +01:00
parent a0106607e8
commit b5ec79906c
13 changed files with 113 additions and 67 deletions

View file

@ -856,13 +856,13 @@ instead of `miniz.h` as an external dependency.
## thorvg
- Upstream: https://github.com/thorvg/thorvg
- Version: 0.12.4 (331839d49368e19ca15f35abee5ac541dbf23637, 2024)
- Version: 0.12.5 (9c8eeaab9629b5d241b1092a3398fe6351c259cd, 2024)
- License: MIT
Files extracted from upstream source:
See `thorvg/update-thorvg.sh` for extraction instructions. Set the version
number and run the script.
number and run the script and apply patches from the `patches` folder.
## vhacd

View file

@ -10,5 +10,5 @@
// For internal debugging:
//#define THORVG_LOG_ENABLED
#define THORVG_VERSION_STRING "0.12.4"
#define THORVG_VERSION_STRING "0.12.5"
#endif

View file

@ -0,0 +1,23 @@
diff --git a/thirdparty/thorvg/src/common/tvgLock.h b/thirdparty/thorvg/src/common/tvgLock.h
index e6d993a41e..5dd3d5a624 100644
--- a/thirdparty/thorvg/src/common/tvgLock.h
+++ b/thirdparty/thorvg/src/common/tvgLock.h
@@ -38,10 +38,10 @@ namespace tvg {
{
Key* key = nullptr;
- ScopedLock(Key& key)
+ ScopedLock(Key& k)
{
- key.mtx.lock();
- this->key = &key;
+ k.mtx.lock();
+ key = &k;
}
~ScopedLock()
@@ -68,3 +68,4 @@ namespace tvg {
#endif //THORVG_THREAD_SUPPORT
#endif //_TVG_LOCK_H_
+

View file

@ -38,10 +38,10 @@ namespace tvg {
{
Key* key = nullptr;
ScopedLock(Key& p_key)
ScopedLock(Key& k)
{
p_key.mtx.lock();
key = &p_key;
k.mtx.lock();
key = &k;
}
~ScopedLock()

View file

@ -84,14 +84,15 @@ bool PngLoader::read()
if (w == 0 || h == 0) return false;
png_bytep buffer;
image->format = PNG_FORMAT_BGRA;
buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image))));
if (!buffer) {
//out of memory, only time when libpng doesnt free its data
png_image_free(image);
return false;
if (cs == ColorSpace::ARGB8888 || cs == ColorSpace::ARGB8888S) {
image->format = PNG_FORMAT_BGRA;
surface.cs = ColorSpace::ARGB8888;
} else {
image->format = PNG_FORMAT_RGBA;
surface.cs = ColorSpace::ABGR8888;
}
auto buffer = static_cast<png_bytep>(malloc(PNG_IMAGE_SIZE((*image))));
if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) {
free(buffer);
return false;
@ -103,7 +104,7 @@ bool PngLoader::read()
surface.w = (uint32_t)w;
surface.h = (uint32_t)h;
surface.channelSize = sizeof(uint32_t);
surface.cs = ColorSpace::ARGB8888;
//TODO: we can acquire a pre-multiplied image. See "png_structrp"
surface.premultiplied = false;
clear();

View file

@ -35,6 +35,8 @@ void PngLoader::run(unsigned tid)
auto width = static_cast<unsigned>(w);
auto height = static_cast<unsigned>(h);
state.info_raw.colortype = LCT_RGBA; //request this image format
if (lodepng_decode(&surface.buf8, &width, &height, &state, data, size)) {
TVGERR("PNG", "Failed to decode image");
}
@ -43,8 +45,11 @@ void PngLoader::run(unsigned tid)
surface.stride = width;
surface.w = width;
surface.h = height;
surface.cs = ColorSpace::ABGR8888;
surface.channelSize = sizeof(uint32_t);
surface.premultiplied = false;
if (state.info_png.color.colortype == LCT_RGBA) surface.premultiplied = false;
else surface.premultiplied = true;
}
@ -93,9 +98,6 @@ bool PngLoader::open(const string& path)
w = static_cast<float>(width);
h = static_cast<float>(height);
if (state.info_png.color.colortype == LCT_RGBA) surface.cs = ColorSpace::ABGR8888;
else surface.cs = ColorSpace::ARGB8888;
ret = true;
goto finalize;
@ -125,8 +127,6 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
h = static_cast<float>(height);
this->size = size;
surface.cs = ColorSpace::ABGR8888;
return true;
}

View file

@ -257,15 +257,15 @@ static uint32_t _interpUpScaler(const uint32_t *img, TVG_UNUSED uint32_t stride,
auto ry2 = ry + 1;
if (ry2 >= h) ry2 = h - 1;
auto dx = static_cast<uint8_t>((sx - rx) * 255.0f);
auto dy = static_cast<uint8_t>((sy - ry) * 255.0f);
auto dx = (sx > 0.0f) ? static_cast<uint8_t>((sx - rx) * 255.0f) : 0;
auto dy = (sy > 0.0f) ? static_cast<uint8_t>((sy - ry) * 255.0f) : 0;
auto c1 = img[rx + ry * w];
auto c2 = img[rx2 + ry * w];
auto c3 = img[rx2 + ry2 * w];
auto c4 = img[rx + ry2 * w];
auto c3 = img[rx + ry2 * w];
auto c4 = img[rx2 + ry2 * w];
return INTERPOLATE(INTERPOLATE(c3, c4, dx), INTERPOLATE(c2, c1, dx), dy);
return INTERPOLATE(INTERPOLATE(c4, c3, dx), INTERPOLATE(c2, c1, dx), dy);
}
@ -671,10 +671,10 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
/************************************************************************/
#define SCALED_IMAGE_RANGE_Y(y) \
auto sy = (y) * itransform->e22 + itransform->e23; \
auto my = (int32_t)round(sy); \
if (my < 0 || (uint32_t)sy >= image->h) continue; \
auto sy = (y) * itransform->e22 + itransform->e23 - 0.49f; \
if (sy <= -0.5f || (uint32_t)(sy + 0.5f) >= image->h) continue; \
if (scaleMethod == _interpDownScaler) { \
auto my = (int32_t)round(sy); \
miny = my - (int32_t)sampleSize; \
if (miny < 0) miny = 0; \
maxy = my + (int32_t)sampleSize; \
@ -682,8 +682,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint8_t g,
}
#define SCALED_IMAGE_RANGE_X \
auto sx = x * itransform->e11 + itransform->e13; \
if ((int32_t)round(sx) < 0 || (uint32_t) sx >= image->w) continue;
auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \
if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \
#if 0 //Enable it when GRAYSCALE image is supported
@ -1928,8 +1928,8 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity)
{
//Verify Boundary
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return false;
//Outside of the viewport, skip the rendering
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return true;
if (mesh && mesh->triangleCnt > 0) return _rasterTexmapPolygonMesh(surface, image, mesh, transform, &bbox, opacity);
else return _rasterImage(surface, image, transform, bbox, opacity);

View file

@ -63,7 +63,7 @@ using namespace tvg;
#define TVG_CLASS_ID_RADIAL 5
#define TVG_CLASS_ID_TEXT 6
enum class FileType { Tvg = 0, Svg, Ttf, Lottie, Raw, Png, Jpg, Webp, Gif, Unknown };
enum class FileType { Png = 0, Jpg, Webp, Tvg, Svg, Lottie, Ttf, Raw, Gif, Unknown };
using Size = Point;

View file

@ -68,6 +68,8 @@ struct LoadModule
struct ImageLoader : LoadModule
{
static ColorSpace cs; //desired value
float w = 0, h = 0; //default image size
Surface surface;

View file

@ -66,6 +66,8 @@ uint64_t HASH_KEY(const char* data, uint64_t size)
/* Internal Class Implementation */
/************************************************************************/
ColorSpace ImageLoader::cs = ColorSpace::ARGB8888;
static Key key;
static Inlist<LoadModule> _activeLoaders;
@ -73,6 +75,24 @@ static Inlist<LoadModule> _activeLoaders;
static LoadModule* _find(FileType type)
{
switch(type) {
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
case FileType::Tvg: {
#ifdef THORVG_TVG_LOADER_SUPPORT
return new TvgLoader;
@ -101,24 +121,6 @@ static LoadModule* _find(FileType type)
return new RawLoader;
break;
}
case FileType::Png: {
#ifdef THORVG_PNG_LOADER_SUPPORT
return new PngLoader;
#endif
break;
}
case FileType::Jpg: {
#ifdef THORVG_JPG_LOADER_SUPPORT
return new JpgLoader;
#endif
break;
}
case FileType::Webp: {
#ifdef THORVG_WEBP_LOADER_SUPPORT
return new WebpLoader;
#endif
break;
}
default: {
break;
}
@ -305,8 +307,22 @@ LoadModule* LoaderMgr::loader(const string& path, bool* invalid)
return loader;
}
delete(loader);
*invalid = true;
}
//Unkown MimeType. Try with the candidates in the order
for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
if (auto loader = _find(static_cast<FileType>(i))) {
if (loader->open(path)) {
loader->hashpath = strdup(path.c_str());
{
ScopedLock lock(key);
_activeLoaders.back(loader);
}
return loader;
}
delete(loader);
}
}
*invalid = true;
return nullptr;
}
@ -349,21 +365,20 @@ LoadModule* LoaderMgr::loader(const char* data, uint32_t size, const string& mim
delete(loader);
}
}
}
//Unkown MimeType. Try with the candidates in the order
} else {
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, copy)) {
loader->hashkey = HASH_KEY(data, size);
{
ScopedLock lock(key);
_activeLoaders.back(loader);
}
return loader;
for (int i = 0; i < static_cast<int>(FileType::Raw); i++) {
auto loader = _find(static_cast<FileType>(i));
if (loader) {
if (loader->open(data, size, copy)) {
loader->hashkey = HASH_KEY(data, size);
{
ScopedLock lock(key);
_activeLoaders.back(loader);
}
delete(loader);
return loader;
}
delete(loader);
}
}
return nullptr;

View file

@ -128,6 +128,7 @@ struct Scene::Impl
bool render(RenderMethod* renderer)
{
Compositor* cmp = nullptr;
auto ret = true;
if (needComp) {
cmp = renderer->target(bounds(renderer), renderer->colorSpace());
@ -136,12 +137,12 @@ struct Scene::Impl
}
for (auto paint : paints) {
if (!paint->pImpl->render(renderer)) return false;
ret &= paint->pImpl->render(renderer);
}
if (cmp) renderer->endComposite(cmp);
return true;
return ret;
}
RenderRegion bounds(RenderMethod* renderer) const

View file

@ -21,6 +21,7 @@
*/
#include "tvgCanvas.h"
#include "tvgLoadModule.h"
#ifdef THORVG_SW_RASTER_SUPPORT
#include "tvgSwRenderer.h"
@ -90,6 +91,9 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
//Paints must be updated again with this new target.
Canvas::pImpl->needRefresh();
//FIXME: The value must be associated with an individual canvas instance.
ImageLoader::cs = static_cast<ColorSpace>(cs);
return Result::Success;
#endif
return Result::NonSupport;

View file

@ -1,6 +1,6 @@
#!/bin/bash -e
VERSION=0.12.4
VERSION=0.12.5
cd thirdparty/thorvg/ || true
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/