diff options
author | RedworkDE <10944644+RedworkDE@users.noreply.github.com> | 2023-04-07 17:44:36 +0200 |
---|---|---|
committer | Yuri Sizov <yuris@humnom.net> | 2023-04-07 17:44:36 +0200 |
commit | 4cc8a689bae5e3fe442a7ddbd962732ebf86a3e7 (patch) | |
tree | 1260e8961e05d5862b899a23d0b733846c0b1768 | |
parent | f8517e1c4b05a0a6e5fbf85884d814145a136244 (diff) |
Update thorvg to 0.8.4
(cherry picked from commit cfed867da1a696692442bd6991449b864707b1d3)
28 files changed, 206 insertions, 62 deletions
diff --git a/thirdparty/README.md b/thirdparty/README.md index 92e0a91596..b015c2bd47 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -686,7 +686,7 @@ instead of `miniz.h` as an external dependency. ## thorvg - Upstream: https://github.com/Samsung/thorvg -- Version: 0.8.3 (a0fcf51f80a75f63a066df085f60cdaf715188b6, 2022) +- Version: 0.8.4 (b0b7f207c6235691d694fc3f76e0b96e4858e606, 2023) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/thorvg/AUTHORS b/thirdparty/thorvg/AUTHORS index 0f8ba2dd7d..11f3f170a5 100644 --- a/thirdparty/thorvg/AUTHORS +++ b/thirdparty/thorvg/AUTHORS @@ -4,7 +4,7 @@ Junsu Choi <jsuya.choi@samsung.com> Pranay Samanta <pranay.ks@samsung.com> Mateusz Palkowski <m.palkowski@samsung.com> Subhransu Mohanty <sub.mohanty@samsung.com> -Mira Grudzinska <m.grudzinska@samsung.com> +Mira Grudzinska <veleveta@gmail.com> Michal Szczecinski <m.szczecinsk@partner.samsung.com> Shinwoo Kim <cinoo.kim@samsung.com> Piotr Kalota <p.kalota@samsung.com> diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index eda302aec0..78522d6d2d 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -13,5 +13,5 @@ #define THORVG_JPG_LOADER_SUPPORT 1 -#define THORVG_VERSION_STRING "0.8.3" +#define THORVG_VERSION_STRING "0.8.4" #endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h index 7e8988a65e..b1f2e9e286 100644 --- a/thirdparty/thorvg/inc/thorvg.h +++ b/thirdparty/thorvg/inc/thorvg.h @@ -336,6 +336,20 @@ public: CompositeMethod composite(const Paint** target) const noexcept; /** + * @brief Gets the composition source object and the composition method. + * + * @param[out] source The paint of the composition source object. + * @param[out] method The method used to composite the source object with the target. + * + * @return Result::Success when the paint object used as a composition target, Result::InsufficientCondition otherwise. + * + * @warning Please do not use it, this API is not official one. It could be modified in the next version. + * + * @BETA_API + */ + Result composite(const Paint** source, CompositeMethod* method) const noexcept; + + /** * @brief Return the unique id value of the paint instance. * * This method can be called for checking the current concrete instance type. diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp index c3872f3207..a1c0032a2e 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp @@ -76,7 +76,9 @@ struct SwShapeTask : SwTask void run(unsigned tid) override { - if (opacity == 0) return; //Invisible + auto compMethod = CompositeMethod::None; + auto usedAsClip = (sdata->composite(nullptr, &compMethod) == Result::Success) && (compMethod == CompositeMethod::ClipPath); + if (opacity == 0 && !usedAsClip) return; //Invisible uint8_t strokeAlpha = 0; auto visibleStroke = false; @@ -98,7 +100,7 @@ struct SwShapeTask : SwTask sdata->fillColor(nullptr, nullptr, nullptr, &alpha); alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255); visibleFill = (alpha > 0 || sdata->fill()); - if (visibleFill || visibleStroke) { + if (visibleFill || visibleStroke || usedAsClip) { shapeReset(&shape); if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err; } @@ -110,7 +112,7 @@ struct SwShapeTask : SwTask //Fill if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) { - if (visibleFill) { + if (visibleFill || usedAsClip) { /* We assume that if stroke width is bigger than 2, shape outline below stroke could be full covered by stroke drawing. Thus it turns off antialising in that condition. @@ -291,7 +293,7 @@ bool SwRenderer::viewport(const RenderRegion& vp) } -bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs) +bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace) { if (!buffer || stride == 0 || w == 0 || h == 0 || w > stride) return false; @@ -301,7 +303,7 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t surface->stride = stride; surface->w = w; surface->h = h; - surface->cs = cs; + surface->cs = colorSpace; vport.x = vport.y = 0; vport.w = surface->w; @@ -644,6 +646,13 @@ SwRenderer::SwRenderer():mpool(globalMpool) } +uint32_t SwRenderer::colorSpace() +{ + if (surface) return surface->cs; + return tvg::SwCanvas::ARGB8888; +} + + bool SwRenderer::init(uint32_t threads) { if ((initEngineCnt++) > 0) return true; diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h index 574d9d488f..cab93f9e1c 100644 --- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h +++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h @@ -48,7 +48,7 @@ public: bool clear() override; bool sync() override; - bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs); + bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t colorSpace); bool mempool(bool shared); Compositor* target(const RenderRegion& region) override; @@ -56,6 +56,8 @@ public: bool endComposite(Compositor* cmp) override; void clearCompositors(); + uint32_t colorSpace() override; + static SwRenderer* gen(); static bool init(uint32_t threads); static int32_t init(); diff --git a/thirdparty/thorvg/src/lib/tvgAccessor.cpp b/thirdparty/thorvg/src/lib/tvgAccessor.cpp index 092c8b0731..5ad24f4acf 100644 --- a/thirdparty/thorvg/src/lib/tvgAccessor.cpp +++ b/thirdparty/thorvg/src/lib/tvgAccessor.cpp @@ -72,7 +72,7 @@ Accessor::~Accessor() } -Accessor::Accessor() +Accessor::Accessor() : pImpl(nullptr) { } diff --git a/thirdparty/thorvg/src/lib/tvgLoadModule.h b/thirdparty/thorvg/src/lib/tvgLoadModule.h index 004983152b..0a154aa47d 100644 --- a/thirdparty/thorvg/src/lib/tvgLoadModule.h +++ b/thirdparty/thorvg/src/lib/tvgLoadModule.h @@ -36,6 +36,7 @@ public: float vw = 0; float vh = 0; float w = 0, h = 0; //default image size + uint32_t colorSpace = SwCanvas::ARGB8888; virtual ~LoadModule() {} @@ -48,7 +49,7 @@ public: virtual bool read() = 0; virtual bool close() = 0; - virtual unique_ptr<Surface> bitmap() { return nullptr; } + virtual unique_ptr<Surface> bitmap(uint32_t colorSpace) { return nullptr; } virtual unique_ptr<Paint> paint() { return nullptr; } }; diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h index 6120216d74..74f34fb744 100644 --- a/thirdparty/thorvg/src/lib/tvgMath.h +++ b/thirdparty/thorvg/src/lib/tvgMath.h @@ -53,6 +53,12 @@ static inline bool mathRightAngle(const Matrix* m) } +static inline bool mathSkewed(const Matrix* m) +{ + return (fabsf(m->e21 + m->e12) > FLT_EPSILON); +} + + static inline bool mathIdentity(const Matrix* m) { if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) || diff --git a/thirdparty/thorvg/src/lib/tvgPaint.cpp b/thirdparty/thorvg/src/lib/tvgPaint.cpp index d0e908ddf2..c90e95cd33 100644 --- a/thirdparty/thorvg/src/lib/tvgPaint.cpp +++ b/thirdparty/thorvg/src/lib/tvgPaint.cpp @@ -38,9 +38,9 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, if (rTransform) rTransform->update(); - //No rotational. - if (pTransform && !mathRightAngle(&pTransform->m)) return false; - if (rTransform && !mathRightAngle(&rTransform->m)) return false; + //No rotation and no skewing + if (pTransform && (!mathRightAngle(&pTransform->m) || mathSkewed(&pTransform->m))) return false; + if (rTransform && (!mathRightAngle(&rTransform->m) || mathSkewed(&rTransform->m))) return false; //Perpendicular Rectangle? auto pt1 = pts + 0; @@ -384,6 +384,19 @@ CompositeMethod Paint::composite(const Paint** target) const noexcept } +Result Paint::composite(const Paint** source, CompositeMethod* method) const noexcept +{ + if (source) *source = pImpl->compSource; + auto met = (pImpl->compSource && pImpl->compSource->pImpl->compData ? + pImpl->compSource->pImpl->compData->method : CompositeMethod::None); + if (method) *method = met; + + if (pImpl->compSource != nullptr && met != CompositeMethod::None) + return Result::Success; + return Result::InsufficientCondition; +} + + Result Paint::opacity(uint8_t o) noexcept { if (pImpl->opacity == o) return Result::Success; diff --git a/thirdparty/thorvg/src/lib/tvgPaint.h b/thirdparty/thorvg/src/lib/tvgPaint.h index c170559a37..94239c30a1 100644 --- a/thirdparty/thorvg/src/lib/tvgPaint.h +++ b/thirdparty/thorvg/src/lib/tvgPaint.h @@ -62,6 +62,7 @@ namespace tvg StrategyMethod* smethod = nullptr; RenderTransform* rTransform = nullptr; Composite* compData = nullptr; + Paint* compSource = nullptr; uint32_t renderFlag = RenderUpdateFlag::None; uint32_t ctxFlag = ContextFlag::Invalid; uint32_t id; @@ -136,6 +137,7 @@ namespace tvg if (!target && method == CompositeMethod::None) return true; compData = static_cast<Composite*>(calloc(1, sizeof(Composite))); } + target->pImpl->compSource = source; compData->target = target; compData->source = source; compData->method = method; diff --git a/thirdparty/thorvg/src/lib/tvgPictureImpl.h b/thirdparty/thorvg/src/lib/tvgPictureImpl.h index b2e097d400..b6bc19fa9c 100644 --- a/thirdparty/thorvg/src/lib/tvgPictureImpl.h +++ b/thirdparty/thorvg/src/lib/tvgPictureImpl.h @@ -66,6 +66,7 @@ struct Picture::Impl void* rdata = nullptr; //engine data float w = 0, h = 0; bool resizing = false; + uint32_t rendererColorSpace = 0; ~Impl() { @@ -100,7 +101,7 @@ struct Picture::Impl } } free(surface); - if ((surface = loader->bitmap().release())) { + if ((surface = loader->bitmap(rendererColorSpace).release())) { loader->close(); return RenderUpdateFlag::Image; } @@ -124,6 +125,7 @@ struct Picture::Impl void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag) { + rendererColorSpace = renderer.colorSpace(); auto flag = reload(); if (surface) { diff --git a/thirdparty/thorvg/src/lib/tvgRender.h b/thirdparty/thorvg/src/lib/tvgRender.h index ed66f393da..f474d87895 100644 --- a/thirdparty/thorvg/src/lib/tvgRender.h +++ b/thirdparty/thorvg/src/lib/tvgRender.h @@ -106,6 +106,8 @@ public: virtual Compositor* target(const RenderRegion& region) = 0; virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0; virtual bool endComposite(Compositor* cmp) = 0; + + virtual uint32_t colorSpace() = 0; }; } diff --git a/thirdparty/thorvg/src/lib/tvgScene.cpp b/thirdparty/thorvg/src/lib/tvgScene.cpp index 0beec47b38..9ed7d45d5c 100644 --- a/thirdparty/thorvg/src/lib/tvgScene.cpp +++ b/thirdparty/thorvg/src/lib/tvgScene.cpp @@ -25,7 +25,7 @@ /* External Class Implementation */ /************************************************************************/ -Scene::Scene() : pImpl(new Impl()) +Scene::Scene() : pImpl(new Impl(this)) { Paint::pImpl->id = TVG_CLASS_ID_SCENE; Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl)); diff --git a/thirdparty/thorvg/src/lib/tvgSceneImpl.h b/thirdparty/thorvg/src/lib/tvgSceneImpl.h index 6a7614c667..b6c68262c6 100644 --- a/thirdparty/thorvg/src/lib/tvgSceneImpl.h +++ b/thirdparty/thorvg/src/lib/tvgSceneImpl.h @@ -60,6 +60,11 @@ struct Scene::Impl Array<Paint*> paints; uint8_t opacity; //for composition RenderMethod* renderer = nullptr; //keep it for explicit clear + Scene* scene = nullptr; + + Impl(Scene* s) : scene(s) + { + } ~Impl() { @@ -81,8 +86,14 @@ struct Scene::Impl bool needComposition(uint32_t opacity) { + if (opacity == 0 || paints.count == 0) return false; + + //Masking may require composition (even if opacity == 255) + auto compMethod = scene->composite(nullptr); + if (compMethod != CompositeMethod::None && compMethod != CompositeMethod::ClipPath) return true; + //Half translucent requires intermediate composition. - if (opacity == 255 || opacity == 0) return false; + if (opacity == 255) return false; //If scene has several children or only scene, it may require composition. if (paints.count > 1) return true; diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp index 05db65cb23..1fb0681814 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp @@ -42,6 +42,24 @@ static void _premultiply(uint32_t* data, uint32_t w, uint32_t h) } +static inline uint32_t CHANGE_COLORSPACE(uint32_t c) +{ + return (c & 0xff000000) + ((c & 0x00ff0000)>>16) + (c & 0x0000ff00) + ((c & 0x000000ff)<<16); +} + + +static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h) +{ + auto buffer = data; + for (uint32_t y = 0; y < h; ++y, buffer += w) { + auto src = buffer; + for (uint32_t x = 0; x < w; ++x, ++src) { + *src = CHANGE_COLORSPACE(*src); + } + } +} + + PngLoader::PngLoader() { image = static_cast<png_imagep>(calloc(1, sizeof(png_image))); @@ -110,16 +128,21 @@ bool PngLoader::close() return true; } -unique_ptr<Surface> PngLoader::bitmap() +unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace) { if (!content) return nullptr; + if (this->colorSpace != colorSpace) { + this->colorSpace = colorSpace; + _changeColorSpace(content, w, h); + } auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); - surface->buffer = (uint32_t*)(content); + surface->buffer = content; surface->stride = w; surface->w = w; surface->h = h; - surface->cs = SwCanvas::ARGB8888; + surface->cs = colorSpace; return unique_ptr<Surface>(surface); } + diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h index 8beff0a3b3..f8c0daa61c 100644 --- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h +++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h @@ -36,11 +36,11 @@ public: bool read() override; bool close() override; - unique_ptr<Surface> bitmap() override; + unique_ptr<Surface> bitmap(uint32_t colorSpace) override; private: png_imagep image = nullptr; - const uint32_t* content = nullptr; + uint32_t* content = nullptr; }; #endif //_TVG_PNG_LOADER_H_ diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp index d11dfc1e7c..f64b7110fe 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp @@ -28,6 +28,24 @@ /* Internal Class Implementation */ /************************************************************************/ +static inline uint32_t CHANGE_COLORSPACE(uint32_t c) +{ + return (c & 0xff000000) + ((c & 0x00ff0000)>>16) + (c & 0x0000ff00) + ((c & 0x000000ff)<<16); +} + + +static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h) +{ + auto buffer = data; + for (uint32_t y = 0; y < h; ++y, buffer += w) { + auto src = buffer; + for (uint32_t x = 0; x < w; ++x, ++src) { + *src = CHANGE_COLORSPACE(*src); + } + } +} + + void JpgLoader::clear() { jpgdDelete(decoder); @@ -110,18 +128,22 @@ bool JpgLoader::close() } -unique_ptr<Surface> JpgLoader::bitmap() +unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace) { this->done(); if (!image) return nullptr; + if (this->colorSpace != colorSpace) { + this->colorSpace = colorSpace; + _changeColorSpace(reinterpret_cast<uint32_t*>(image), w, h); + } auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); - surface->buffer = (uint32_t*)(image); + surface->buffer = reinterpret_cast<uint32_t*>(image); surface->stride = static_cast<uint32_t>(w); surface->w = static_cast<uint32_t>(w); surface->h = static_cast<uint32_t>(h); - surface->cs = SwCanvas::ARGB8888; + surface->cs = colorSpace; return unique_ptr<Surface>(surface); } diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h index d6b886cb29..c47cb6704f 100644 --- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h +++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h @@ -44,7 +44,7 @@ public: bool read() override; bool close() override; - unique_ptr<Surface> bitmap() override; + unique_ptr<Surface> bitmap(uint32_t colorSpace) override; void run(unsigned tid) override; }; diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp index 889f130ce9..19c1dd6668 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp @@ -28,6 +28,23 @@ /* Internal Class Implementation */ /************************************************************************/ +static inline uint32_t CHANGE_COLORSPACE(uint32_t c) +{ + return (c & 0xff000000) + ((c & 0x00ff0000)>>16) + (c & 0x0000ff00) + ((c & 0x000000ff)<<16); +} + + +static void _changeColorSpace(uint32_t* data, uint32_t w, uint32_t h) +{ + auto buffer = data; + for (uint32_t y = 0; y < h; ++y, buffer += w) { + auto src = buffer; + for (uint32_t x = 0; x < w; ++x, ++src) { + *src = CHANGE_COLORSPACE(*src); + } + } +} + /************************************************************************/ /* External Class Implementation */ /************************************************************************/ @@ -54,7 +71,7 @@ bool RawLoader::open(const uint32_t* data, uint32_t w, uint32_t h, bool copy) if (!content) return false; memcpy((void*)content, data, sizeof(uint32_t) * w * h); } - else content = data; + else content = const_cast<uint32_t*>(data); return true; } @@ -72,16 +89,20 @@ bool RawLoader::close() } -unique_ptr<Surface> RawLoader::bitmap() +unique_ptr<Surface> RawLoader::bitmap(uint32_t colorSpace) { if (!content) return nullptr; + if (this->colorSpace != colorSpace) { + this->colorSpace = colorSpace; + _changeColorSpace(content, w, h); + } auto surface = static_cast<Surface*>(malloc(sizeof(Surface))); - surface->buffer = (uint32_t*)(content); - surface->stride = (uint32_t)w; - surface->w = (uint32_t)w; - surface->h = (uint32_t)h; - surface->cs = SwCanvas::ARGB8888; + surface->buffer = content; + surface->stride = static_cast<uint32_t>(w); + surface->w = static_cast<uint32_t>(w); + surface->h = static_cast<uint32_t>(h); + surface->cs = colorSpace; return unique_ptr<Surface>(surface); } diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h index e4f3423b41..8789b0cf51 100644 --- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h +++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h @@ -25,7 +25,7 @@ class RawLoader : public LoadModule { public: - const uint32_t* content = nullptr; + uint32_t* content = nullptr; bool copy = false; ~RawLoader(); @@ -35,7 +35,7 @@ public: bool read() override; bool close() override; - unique_ptr<Surface> bitmap() override; + unique_ptr<Surface> bitmap(uint32_t colorSpace) override; }; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp index 737fd96455..bc350a0eb8 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -180,9 +180,9 @@ static float _toFloat(const SvgParser* svgParse, const char* str, SvgParserLengt else if (type == SvgParserLengthType::Horizontal) parsedValue = (parsedValue / 100.0) * svgParse->global.w; else //if other then it's radius { - float max = (float)svgParse->global.w; + float max = svgParse->global.w; if (max < svgParse->global.h) - max = (float)svgParse->global.h; + max = svgParse->global.h; parsedValue = (parsedValue / 100.0) * max; } } @@ -341,7 +341,7 @@ static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* das ++end; //Refers to the diagonal length of the viewport. //https://www.w3.org/TR/SVG2/coords.html#Units - parsedValue = (sqrtf(pow(loader->svgParse->global.w, 2) + pow(loader->svgParse->global.h, 2)) / sqrtf(2.0f)) * (parsedValue / 100.0f); + parsedValue = (sqrtf(powf(loader->svgParse->global.w, 2) + powf(loader->svgParse->global.h, 2)) / sqrtf(2.0f)) * (parsedValue / 100.0f); } (*dash).array.push(parsedValue); str = end; @@ -376,7 +376,7 @@ static char* _idFromUrl(const char* url) } -static unsigned char _parserColor(const char* value, char** end) +static unsigned char _parseColor(const char* value, char** end) { float r; @@ -586,11 +586,11 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** *b = strtol(tmp, nullptr, 16); } } else if (len >= 10 && (str[0] == 'r' || str[0] == 'R') && (str[1] == 'g' || str[1] == 'G') && (str[2] == 'b' || str[2] == 'B') && str[3] == '(' && str[len - 1] == ')') { - tr = _parserColor(str + 4, &red); + tr = _parseColor(str + 4, &red); if (red && *red == ',') { - tg = _parserColor(red + 1, &green); + tg = _parseColor(red + 1, &green); if (green && *green == ',') { - tb = _parserColor(green + 1, &blue); + tb = _parseColor(green + 1, &blue); if (blue && blue[0] == ')' && blue[1] == '\0') { *r = tr; *g = tg; @@ -840,13 +840,13 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) if (_parseNumber(&value, &doc->vy)) { if (_parseNumber(&value, &doc->vw)) { _parseNumber(&value, &doc->vh); - loader->svgParse->global.h = (uint32_t)doc->vh; + loader->svgParse->global.h = doc->vh; } - loader->svgParse->global.w = (uint32_t)doc->vw; + loader->svgParse->global.w = doc->vw; } - loader->svgParse->global.y = (int)doc->vy; + loader->svgParse->global.y = doc->vy; } - loader->svgParse->global.x = (int)doc->vx; + loader->svgParse->global.x = doc->vx; } else if (!strcmp(key, "preserveAspectRatio")) { _parseAspectRatio(&value, &doc->align, &doc->meetOrSlice); } else if (!strcmp(key, "style")) { @@ -1300,11 +1300,11 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha if (loader->svgParse->global.w == 0) { if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1; - else loader->svgParse->global.w = (uint32_t)doc->w; + else loader->svgParse->global.w = doc->w; } if (loader->svgParse->global.h == 0) { if (doc->h < FLT_EPSILON) loader->svgParse->global.h = 1; - else loader->svgParse->global.h = (uint32_t)doc->h; + else loader->svgParse->global.h = doc->h; } return loader->svgParse->node; @@ -2375,7 +2375,7 @@ static void _recalcRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace) { // scaling factor based on the Units paragraph from : https://www.w3.org/TR/2015/WD-SVG2-20150915/coords.html - if (userSpace && !radial->isRPercentage) radial->r = radial->r / (sqrtf(pow(loader->svgParse->global.h, 2) + pow(loader->svgParse->global.w, 2)) / sqrtf(2.0)); + if (userSpace && !radial->isRPercentage) radial->r = radial->r / (sqrtf(powf(loader->svgParse->global.h, 2) + powf(loader->svgParse->global.w, 2)) / sqrtf(2.0)); } @@ -3180,6 +3180,12 @@ SvgLoader::~SvgLoader() void SvgLoader::run(unsigned tid) { + //According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering + if (renderingDisabled) { + root = Scene::gen(); + return; + } + if (!simpleXmlParse(content, size, true, _svgLoaderParser, &(loaderData))) return; if (loaderData.doc) { diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h index f224d1a4ac..c6fdde55af 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h @@ -52,6 +52,7 @@ public: private: AspectRatioAlign align = AspectRatioAlign::XMidYMid; AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet; + bool renderingDisabled = false; bool header(); void clear(); diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h index c657c0e21a..3588cabf0b 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h @@ -425,8 +425,7 @@ struct SvgParser SvgStopStyleFlags flags; struct { - int x, y; - uint32_t w, h; + float x, y, w, h; } global; struct { diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp index 4cb4ffdaeb..254ee2d008 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp @@ -255,7 +255,6 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox node->style->clipPath.applying = true; auto comp = Shape::gen(); - comp->fill(255, 255, 255, 255); if (node->transform) comp->transform(*node->transform); auto child = compNode->child.data; @@ -348,7 +347,7 @@ static void _applyProperty(SvgNode* node, Shape* vg, const Box& vBox, const stri //If stroke property is nullptr then do nothing if (style->stroke.paint.none) { - //Do nothing + vg->stroke(0.0f); } else if (style->stroke.paint.gradient) { Box bBox = vBox; if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg); diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp index 1f1fe2a718..7fb108bc21 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp @@ -137,7 +137,11 @@ float svgUtilStrtof(const char *nPtr, char **endPtr) pow10 *= 10ULL; } } + } else if (isspace(*iter)) { //skip if there is a space after the dot. + a = iter; + goto success; } + val += static_cast<float>(decimalPart) / static_cast<float>(pow10); a = iter; } diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp index 231badd27d..0e2c3fa141 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp @@ -304,38 +304,38 @@ bool isIgnoreUnsupportedLogElements(TVG_UNUSED const char* tagName) bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data) { const char *itr = buf, *itrEnd = buf + bufLength; - char* tmpBuf = (char*)alloca(bufLength + 1); + char* tmpBuf = (char*)malloc(bufLength + 1); - if (!buf || !func) return false; + if (!buf || !func || !tmpBuf) goto error; while (itr < itrEnd) { const char* p = _skipWhiteSpacesAndXmlEntities(itr, itrEnd); const char *key, *keyEnd, *value, *valueEnd; char* tval; - if (p == itrEnd) return true; + if (p == itrEnd) goto success; key = p; for (keyEnd = key; keyEnd < itrEnd; keyEnd++) { if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break; } - if (keyEnd == itrEnd) return false; + if (keyEnd == itrEnd) goto error; if (keyEnd == key) continue; if (*keyEnd == '=') value = keyEnd + 1; else { value = (const char*)memchr(keyEnd, '=', itrEnd - keyEnd); - if (!value) return false; + if (!value) goto error; value++; } keyEnd = _simpleXmlUnskipXmlEntities(keyEnd, key); value = _skipWhiteSpacesAndXmlEntities(value, itrEnd); - if (value == itrEnd) return false; + if (value == itrEnd) goto error; if ((*value == '"') || (*value == '\'')) { valueEnd = (const char*)memchr(value + 1, *value, itrEnd - value); - if (!valueEnd) return false; + if (!valueEnd) goto error; value++; } else { valueEnd = _simpleXmlFindWhiteSpace(value, itrEnd); @@ -364,7 +364,14 @@ bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttr } } } + +success: + free(tmpBuf); return true; + +error: + free(tmpBuf); + return false; } diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index 8cccc947ce..34bb3b8e59 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -1,6 +1,6 @@ -VERSION=0.8.3 +VERSION=0.8.4 rm -rf AUTHORS inc LICENSE src *.zip -curl -L -O https://github.com/Samsung/thorvg/archive/v$VERSION.zip +curl -L -O https://github.com/thorvg/thorvg/archive/v$VERSION.zip bsdtar --strip-components=1 -xvf *.zip rm *.zip rm -rf .github docs pc res test tools tvgcompat .git* *.md *.txt wasm_build.sh |