diff --git a/thirdparty/README.md b/thirdparty/README.md index 78df38f513fe..2245fd225080 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -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 diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 05b0275e6640..c5745dab1bdf 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -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 diff --git a/thirdparty/thorvg/patches/Fix_compiler_shadowing_warning.patch b/thirdparty/thorvg/patches/Fix_compiler_shadowing_warning.patch new file mode 100644 index 000000000000..e0647628d360 --- /dev/null +++ b/thirdparty/thorvg/patches/Fix_compiler_shadowing_warning.patch @@ -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_ ++ diff --git a/thirdparty/thorvg/src/common/tvgLock.h b/thirdparty/thorvg/src/common/tvgLock.h index 3b27e415a131..8bf1534605a0 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& p_key) + ScopedLock(Key& k) { - p_key.mtx.lock(); - key = &p_key; + k.mtx.lock(); + key = &k; } ~ScopedLock() diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp index 10277f846d7f..6c4c8410e82f 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp @@ -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(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(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(); diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp index 111180b6571f..9c57c665ca4c 100644 --- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp @@ -35,6 +35,8 @@ void PngLoader::run(unsigned tid) auto width = static_cast(w); auto height = static_cast(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(width); h = static_cast(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(height); this->size = size; - surface.cs = ColorSpace::ABGR8888; - return true; } diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp index 049318c72826..98374d3f23ca 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp @@ -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((sx - rx) * 255.0f); - auto dy = static_cast((sy - ry) * 255.0f); + auto dx = (sx > 0.0f) ? static_cast((sx - rx) * 255.0f) : 0; + auto dy = (sy > 0.0f) ? static_cast((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(surface->w) || bbox.min.y >= static_cast(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(surface->w) || bbox.min.y >= static_cast(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); diff --git a/thirdparty/thorvg/src/renderer/tvgCommon.h b/thirdparty/thorvg/src/renderer/tvgCommon.h index deb419bc65e2..d080ea19cf6e 100644 --- a/thirdparty/thorvg/src/renderer/tvgCommon.h +++ b/thirdparty/thorvg/src/renderer/tvgCommon.h @@ -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; diff --git a/thirdparty/thorvg/src/renderer/tvgLoadModule.h b/thirdparty/thorvg/src/renderer/tvgLoadModule.h index 0ea766395e12..0dc57253ed9f 100644 --- a/thirdparty/thorvg/src/renderer/tvgLoadModule.h +++ b/thirdparty/thorvg/src/renderer/tvgLoadModule.h @@ -68,6 +68,8 @@ struct LoadModule struct ImageLoader : LoadModule { + static ColorSpace cs; //desired value + float w = 0, h = 0; //default image size Surface surface; diff --git a/thirdparty/thorvg/src/renderer/tvgLoader.cpp b/thirdparty/thorvg/src/renderer/tvgLoader.cpp index b0c631eb824c..fc93a0cbdcc4 100644 --- a/thirdparty/thorvg/src/renderer/tvgLoader.cpp +++ b/thirdparty/thorvg/src/renderer/tvgLoader.cpp @@ -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 _activeLoaders; @@ -73,6 +75,24 @@ static Inlist _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(FileType::Raw); i++) { + if (auto loader = _find(static_cast(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(FileType::Unknown); i++) { - auto loader = _find(static_cast(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(FileType::Raw); i++) { + auto loader = _find(static_cast(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; diff --git a/thirdparty/thorvg/src/renderer/tvgScene.h b/thirdparty/thorvg/src/renderer/tvgScene.h index 2267a2f71b98..5fb6e45cab4d 100644 --- a/thirdparty/thorvg/src/renderer/tvgScene.h +++ b/thirdparty/thorvg/src/renderer/tvgScene.h @@ -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 diff --git a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp index 44040570496b..d154a600d599 100644 --- a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp @@ -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(cs); + return Result::Success; #endif return Result::NonSupport; diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index e2c84e58b5a8..2811a43339fd 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -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/