RedworkDE пре 2 година
родитељ
комит
cfed867da1
28 измењених фајлова са 206 додато и 62 уклоњено
  1. 1 1
      thirdparty/README.md
  2. 1 1
      thirdparty/thorvg/AUTHORS
  3. 1 1
      thirdparty/thorvg/inc/config.h
  4. 14 0
      thirdparty/thorvg/inc/thorvg.h
  5. 14 5
      thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
  6. 3 1
      thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h
  7. 1 1
      thirdparty/thorvg/src/lib/tvgAccessor.cpp
  8. 2 1
      thirdparty/thorvg/src/lib/tvgLoadModule.h
  9. 6 0
      thirdparty/thorvg/src/lib/tvgMath.h
  10. 16 3
      thirdparty/thorvg/src/lib/tvgPaint.cpp
  11. 2 0
      thirdparty/thorvg/src/lib/tvgPaint.h
  12. 3 1
      thirdparty/thorvg/src/lib/tvgPictureImpl.h
  13. 2 0
      thirdparty/thorvg/src/lib/tvgRender.h
  14. 1 1
      thirdparty/thorvg/src/lib/tvgScene.cpp
  15. 12 1
      thirdparty/thorvg/src/lib/tvgSceneImpl.h
  16. 26 3
      thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp
  17. 2 2
      thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h
  18. 25 3
      thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
  19. 1 1
      thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h
  20. 28 7
      thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp
  21. 2 2
      thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h
  22. 20 14
      thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
  23. 1 0
      thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h
  24. 1 2
      thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h
  25. 1 2
      thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
  26. 4 0
      thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
  27. 14 7
      thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
  28. 2 2
      thirdparty/thorvg/update-thorvg.sh

+ 1 - 1
thirdparty/README.md

@@ -686,7 +686,7 @@ instead of `miniz.h` as an external dependency.
 ## thorvg
 ## thorvg
 
 
 - Upstream: https://github.com/Samsung/thorvg
 - Upstream: https://github.com/Samsung/thorvg
-- Version: 0.8.3 (a0fcf51f80a75f63a066df085f60cdaf715188b6, 2022)
+- Version: 0.8.4 (b0b7f207c6235691d694fc3f76e0b96e4858e606, 2023)
 - License: MIT
 - License: MIT
 
 
 Files extracted from upstream source:
 Files extracted from upstream source:

+ 1 - 1
thirdparty/thorvg/AUTHORS

@@ -4,7 +4,7 @@ Junsu Choi <[email protected]>
 Pranay Samanta <[email protected]>
 Pranay Samanta <[email protected]>
 Mateusz Palkowski <[email protected]>
 Mateusz Palkowski <[email protected]>
 Subhransu Mohanty <[email protected]>
 Subhransu Mohanty <[email protected]>
-Mira Grudzinska <m.grudzinska@samsung.com>
+Mira Grudzinska <veleveta@gmail.com>
 Michal Szczecinski <[email protected]>
 Michal Szczecinski <[email protected]>
 Shinwoo Kim <[email protected]>
 Shinwoo Kim <[email protected]>
 Piotr Kalota <[email protected]>
 Piotr Kalota <[email protected]>

+ 1 - 1
thirdparty/thorvg/inc/config.h

@@ -13,5 +13,5 @@
 
 
 #define THORVG_JPG_LOADER_SUPPORT 1
 #define THORVG_JPG_LOADER_SUPPORT 1
 
 
-#define THORVG_VERSION_STRING "0.8.3"
+#define THORVG_VERSION_STRING "0.8.4"
 #endif
 #endif

+ 14 - 0
thirdparty/thorvg/inc/thorvg.h

@@ -335,6 +335,20 @@ public:
      */
      */
     CompositeMethod composite(const Paint** target) const noexcept;
     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.
      * @brief Return the unique id value of the paint instance.
      *
      *

+ 14 - 5
thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp

@@ -76,7 +76,9 @@ struct SwShapeTask : SwTask
 
 
     void run(unsigned tid) override
     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;
         uint8_t strokeAlpha = 0;
         auto visibleStroke = false;
         auto visibleStroke = false;
@@ -98,7 +100,7 @@ struct SwShapeTask : SwTask
             sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
             sdata->fillColor(nullptr, nullptr, nullptr, &alpha);
             alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
             alpha = static_cast<uint8_t>(static_cast<uint32_t>(alpha) * opacity / 255);
             visibleFill = (alpha > 0 || sdata->fill());
             visibleFill = (alpha > 0 || sdata->fill());
-            if (visibleFill || visibleStroke) {
+            if (visibleFill || visibleStroke || usedAsClip) {
                 shapeReset(&shape);
                 shapeReset(&shape);
                 if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err;
                 if (!shapePrepare(&shape, sdata, transform, clipRegion, bbox, mpool, tid, clips.count > 0 ? true : false)) goto err;
             }
             }
@@ -110,7 +112,7 @@ struct SwShapeTask : SwTask
 
 
         //Fill
         //Fill
         if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
         if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) {
-            if (visibleFill) {
+            if (visibleFill || usedAsClip) {
                 /* We assume that if stroke width is bigger than 2,
                 /* We assume that if stroke width is bigger than 2,
                    shape outline below stroke could be full covered by stroke drawing.
                    shape outline below stroke could be full covered by stroke drawing.
                    Thus it turns off antialising in that condition.
                    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;
     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->stride = stride;
     surface->w = w;
     surface->w = w;
     surface->h = h;
     surface->h = h;
-    surface->cs = cs;
+    surface->cs = colorSpace;
 
 
     vport.x = vport.y = 0;
     vport.x = vport.y = 0;
     vport.w = surface->w;
     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)
 bool SwRenderer::init(uint32_t threads)
 {
 {
     if ((initEngineCnt++) > 0) return true;
     if ((initEngineCnt++) > 0) return true;

+ 3 - 1
thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h

@@ -48,7 +48,7 @@ public:
 
 
     bool clear() override;
     bool clear() override;
     bool sync() 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);
     bool mempool(bool shared);
 
 
     Compositor* target(const RenderRegion& region) override;
     Compositor* target(const RenderRegion& region) override;
@@ -56,6 +56,8 @@ public:
     bool endComposite(Compositor* cmp) override;
     bool endComposite(Compositor* cmp) override;
     void clearCompositors();
     void clearCompositors();
 
 
+    uint32_t colorSpace() override;
+
     static SwRenderer* gen();
     static SwRenderer* gen();
     static bool init(uint32_t threads);
     static bool init(uint32_t threads);
     static int32_t init();
     static int32_t init();

+ 1 - 1
thirdparty/thorvg/src/lib/tvgAccessor.cpp

@@ -72,7 +72,7 @@ Accessor::~Accessor()
 }
 }
 
 
 
 
-Accessor::Accessor()
+Accessor::Accessor() : pImpl(nullptr)
 {
 {
 
 
 }
 }

+ 2 - 1
thirdparty/thorvg/src/lib/tvgLoadModule.h

@@ -36,6 +36,7 @@ public:
     float vw = 0;
     float vw = 0;
     float vh = 0;
     float vh = 0;
     float w = 0, h = 0;         //default image size
     float w = 0, h = 0;         //default image size
+    uint32_t colorSpace = SwCanvas::ARGB8888;
 
 
     virtual ~LoadModule() {}
     virtual ~LoadModule() {}
 
 
@@ -48,7 +49,7 @@ public:
 
 
     virtual bool read() = 0;
     virtual bool read() = 0;
     virtual bool close() = 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; }
     virtual unique_ptr<Paint> paint() { return nullptr; }
 };
 };
 
 

+ 6 - 0
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)
 static inline bool mathIdentity(const Matrix* m)
 {
 {
     if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) ||
     if (!mathEqual(m->e11, 1.0f) || !mathZero(m->e12) || !mathZero(m->e13) ||

+ 16 - 3
thirdparty/thorvg/src/lib/tvgPaint.cpp

@@ -38,9 +38,9 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
 
 
     if (rTransform) rTransform->update();
     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?
     //Perpendicular Rectangle?
     auto pt1 = pts + 0;
     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
 Result Paint::opacity(uint8_t o) noexcept
 {
 {
     if (pImpl->opacity == o) return Result::Success;
     if (pImpl->opacity == o) return Result::Success;

+ 2 - 0
thirdparty/thorvg/src/lib/tvgPaint.h

@@ -62,6 +62,7 @@ namespace tvg
         StrategyMethod* smethod = nullptr;
         StrategyMethod* smethod = nullptr;
         RenderTransform* rTransform = nullptr;
         RenderTransform* rTransform = nullptr;
         Composite* compData = nullptr;
         Composite* compData = nullptr;
+        Paint* compSource = nullptr;
         uint32_t renderFlag = RenderUpdateFlag::None;
         uint32_t renderFlag = RenderUpdateFlag::None;
         uint32_t ctxFlag = ContextFlag::Invalid;
         uint32_t ctxFlag = ContextFlag::Invalid;
         uint32_t id;
         uint32_t id;
@@ -136,6 +137,7 @@ namespace tvg
                 if (!target && method == CompositeMethod::None) return true;
                 if (!target && method == CompositeMethod::None) return true;
                 compData = static_cast<Composite*>(calloc(1, sizeof(Composite)));
                 compData = static_cast<Composite*>(calloc(1, sizeof(Composite)));
             }
             }
+            target->pImpl->compSource = source;
             compData->target = target;
             compData->target = target;
             compData->source = source;
             compData->source = source;
             compData->method = method;
             compData->method = method;

+ 3 - 1
thirdparty/thorvg/src/lib/tvgPictureImpl.h

@@ -66,6 +66,7 @@ struct Picture::Impl
     void* rdata = nullptr;            //engine data
     void* rdata = nullptr;            //engine data
     float w = 0, h = 0;
     float w = 0, h = 0;
     bool resizing = false;
     bool resizing = false;
+    uint32_t rendererColorSpace = 0;
 
 
     ~Impl()
     ~Impl()
     {
     {
@@ -100,7 +101,7 @@ struct Picture::Impl
                 }
                 }
             }
             }
             free(surface);
             free(surface);
-            if ((surface = loader->bitmap().release())) {
+            if ((surface = loader->bitmap(rendererColorSpace).release())) {
                 loader->close();
                 loader->close();
                 return RenderUpdateFlag::Image;
                 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)
     void* update(RenderMethod &renderer, const RenderTransform* pTransform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag pFlag)
     {
     {
+        rendererColorSpace = renderer.colorSpace();
         auto flag = reload();
         auto flag = reload();
 
 
         if (surface) {
         if (surface) {

+ 2 - 0
thirdparty/thorvg/src/lib/tvgRender.h

@@ -106,6 +106,8 @@ public:
     virtual Compositor* target(const RenderRegion& region) = 0;
     virtual Compositor* target(const RenderRegion& region) = 0;
     virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
     virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
     virtual bool endComposite(Compositor* cmp) = 0;
     virtual bool endComposite(Compositor* cmp) = 0;
+
+    virtual uint32_t colorSpace() = 0;
 };
 };
 
 
 }
 }

+ 1 - 1
thirdparty/thorvg/src/lib/tvgScene.cpp

@@ -25,7 +25,7 @@
 /* External Class Implementation                                        */
 /* External Class Implementation                                        */
 /************************************************************************/
 /************************************************************************/
 
 
-Scene::Scene() : pImpl(new Impl())
+Scene::Scene() : pImpl(new Impl(this))
 {
 {
     Paint::pImpl->id = TVG_CLASS_ID_SCENE;
     Paint::pImpl->id = TVG_CLASS_ID_SCENE;
     Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl));
     Paint::pImpl->method(new PaintMethod<Scene::Impl>(pImpl));

+ 12 - 1
thirdparty/thorvg/src/lib/tvgSceneImpl.h

@@ -60,6 +60,11 @@ struct Scene::Impl
     Array<Paint*> paints;
     Array<Paint*> paints;
     uint8_t opacity;                     //for composition
     uint8_t opacity;                     //for composition
     RenderMethod* renderer = nullptr;    //keep it for explicit clear
     RenderMethod* renderer = nullptr;    //keep it for explicit clear
+    Scene* scene = nullptr;
+
+    Impl(Scene* s) : scene(s)
+    {
+    }
 
 
     ~Impl()
     ~Impl()
     {
     {
@@ -81,8 +86,14 @@ struct Scene::Impl
 
 
     bool needComposition(uint32_t opacity)
     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.
         //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 scene has several children or only scene, it may require composition.
         if (paints.count > 1) return true;
         if (paints.count > 1) return true;

+ 26 - 3
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()
 PngLoader::PngLoader()
 {
 {
     image = static_cast<png_imagep>(calloc(1, sizeof(png_image)));
     image = static_cast<png_imagep>(calloc(1, sizeof(png_image)));
@@ -110,16 +128,21 @@ bool PngLoader::close()
     return true;
     return true;
 }
 }
 
 
-unique_ptr<Surface> PngLoader::bitmap()
+unique_ptr<Surface> PngLoader::bitmap(uint32_t colorSpace)
 {
 {
     if (!content) return nullptr;
     if (!content) return nullptr;
+    if (this->colorSpace != colorSpace) {
+        this->colorSpace = colorSpace;
+        _changeColorSpace(content, w, h);
+    }
 
 
     auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
     auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
-    surface->buffer = (uint32_t*)(content);
+    surface->buffer = content;
     surface->stride = w;
     surface->stride = w;
     surface->w = w;
     surface->w = w;
     surface->h = h;
     surface->h = h;
-    surface->cs = SwCanvas::ARGB8888;
+    surface->cs = colorSpace;
 
 
     return unique_ptr<Surface>(surface);
     return unique_ptr<Surface>(surface);
 }
 }
+

+ 2 - 2
thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h

@@ -36,11 +36,11 @@ public:
     bool read() override;
     bool read() override;
     bool close() override;
     bool close() override;
 
 
-    unique_ptr<Surface> bitmap() override;
+    unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
 
 
 private:
 private:
     png_imagep image = nullptr;
     png_imagep image = nullptr;
-    const uint32_t* content = nullptr;
+    uint32_t* content = nullptr;
 };
 };
 
 
 #endif //_TVG_PNG_LOADER_H_
 #endif //_TVG_PNG_LOADER_H_

+ 25 - 3
thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp

@@ -28,6 +28,24 @@
 /* Internal Class Implementation                                        */
 /* 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()
 void JpgLoader::clear()
 {
 {
     jpgdDelete(decoder);
     jpgdDelete(decoder);
@@ -110,18 +128,22 @@ bool JpgLoader::close()
 }
 }
 
 
 
 
-unique_ptr<Surface> JpgLoader::bitmap()
+unique_ptr<Surface> JpgLoader::bitmap(uint32_t colorSpace)
 {
 {
     this->done();
     this->done();
 
 
     if (!image) return nullptr;
     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)));
     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->stride = static_cast<uint32_t>(w);
     surface->w = static_cast<uint32_t>(w);
     surface->w = static_cast<uint32_t>(w);
     surface->h = static_cast<uint32_t>(h);
     surface->h = static_cast<uint32_t>(h);
-    surface->cs = SwCanvas::ARGB8888;
+    surface->cs = colorSpace;
 
 
     return unique_ptr<Surface>(surface);
     return unique_ptr<Surface>(surface);
 }
 }

+ 1 - 1
thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h

@@ -44,7 +44,7 @@ public:
     bool read() override;
     bool read() override;
     bool close() override;
     bool close() override;
 
 
-    unique_ptr<Surface> bitmap() override;
+    unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
     void run(unsigned tid) override;
     void run(unsigned tid) override;
 };
 };
 
 

+ 28 - 7
thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp

@@ -28,6 +28,23 @@
 /* Internal Class Implementation                                        */
 /* 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                                        */
 /* 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;
         if (!content) return false;
         memcpy((void*)content, data, sizeof(uint32_t) * w * h);
         memcpy((void*)content, data, sizeof(uint32_t) * w * h);
     }
     }
-    else content = data;
+    else content = const_cast<uint32_t*>(data);
 
 
     return true;
     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 (!content) return nullptr;
+    if (this->colorSpace != colorSpace) {
+        this->colorSpace = colorSpace;
+        _changeColorSpace(content, w, h);
+    }
 
 
     auto surface = static_cast<Surface*>(malloc(sizeof(Surface)));
     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);
     return unique_ptr<Surface>(surface);
 }
 }

+ 2 - 2
thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h

@@ -25,7 +25,7 @@
 class RawLoader : public LoadModule
 class RawLoader : public LoadModule
 {
 {
 public:
 public:
-    const uint32_t* content = nullptr;
+    uint32_t* content = nullptr;
     bool copy = false;
     bool copy = false;
 
 
     ~RawLoader();
     ~RawLoader();
@@ -35,7 +35,7 @@ public:
     bool read() override;
     bool read() override;
     bool close() override;
     bool close() override;
 
 
-    unique_ptr<Surface> bitmap() override;
+    unique_ptr<Surface> bitmap(uint32_t colorSpace) override;
 };
 };
 
 
 
 

+ 20 - 14
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 (type == SvgParserLengthType::Horizontal) parsedValue = (parsedValue / 100.0) * svgParse->global.w;
         else //if other then it's radius
         else //if other then it's radius
         {
         {
-            float max = (float)svgParse->global.w;
+            float max = svgParse->global.w;
             if (max < svgParse->global.h)
             if (max < svgParse->global.h)
-                max = (float)svgParse->global.h;
+                max = svgParse->global.h;
             parsedValue = (parsedValue / 100.0) * max;
             parsedValue = (parsedValue / 100.0) * max;
         }
         }
     }
     }
@@ -341,7 +341,7 @@ static void _parseDashArray(SvgLoaderData* loader, const char *str, SvgDash* das
             ++end;
             ++end;
             //Refers to the diagonal length of the viewport.
             //Refers to the diagonal length of the viewport.
             //https://www.w3.org/TR/SVG2/coords.html#Units
             //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);
         (*dash).array.push(parsedValue);
         str = end;
         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;
     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);
             *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] == ')') {
     } 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 == ',') {
         if (red && *red == ',') {
-            tg = _parserColor(red + 1, &green);
+            tg = _parseColor(red + 1, &green);
             if (green && *green == ',') {
             if (green && *green == ',') {
-                tb = _parserColor(green + 1, &blue);
+                tb = _parseColor(green + 1, &blue);
                 if (blue && blue[0] == ')' && blue[1] == '\0') {
                 if (blue && blue[0] == ')' && blue[1] == '\0') {
                     *r = tr;
                     *r = tr;
                     *g = tg;
                     *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->vy)) {
                 if (_parseNumber(&value, &doc->vw)) {
                 if (_parseNumber(&value, &doc->vw)) {
                     _parseNumber(&value, &doc->vh);
                     _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")) {
     } else if (!strcmp(key, "preserveAspectRatio")) {
         _parseAspectRatio(&value, &doc->align, &doc->meetOrSlice);
         _parseAspectRatio(&value, &doc->align, &doc->meetOrSlice);
     } else if (!strcmp(key, "style")) {
     } 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 (loader->svgParse->global.w == 0) {
         if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1;
         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 (loader->svgParse->global.h == 0) {
         if (doc->h < FLT_EPSILON) loader->svgParse->global.h = 1;
         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;
     return loader->svgParse->node;
@@ -2375,7 +2375,7 @@ static void _recalcRadialFyAttr(SvgLoaderData* loader, SvgRadialGradient* radial
 static void _recalcRadialRAttr(SvgLoaderData* loader, SvgRadialGradient* radial, bool userSpace)
 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
     // 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)
 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 (!simpleXmlParse(content, size, true, _svgLoaderParser, &(loaderData))) return;
 
 
     if (loaderData.doc) {
     if (loaderData.doc) {

+ 1 - 0
thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h

@@ -52,6 +52,7 @@ public:
 private:
 private:
     AspectRatioAlign align = AspectRatioAlign::XMidYMid;
     AspectRatioAlign align = AspectRatioAlign::XMidYMid;
     AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet;
     AspectRatioMeetOrSlice meetOrSlice = AspectRatioMeetOrSlice::Meet;
+    bool renderingDisabled = false;
 
 
     bool header();
     bool header();
     void clear();
     void clear();

+ 1 - 2
thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h

@@ -425,8 +425,7 @@ struct SvgParser
     SvgStopStyleFlags flags;
     SvgStopStyleFlags flags;
     struct
     struct
     {
     {
-        int x, y;
-        uint32_t w, h;
+        float x, y, w, h;
     } global;
     } global;
     struct
     struct
     {
     {

+ 1 - 2
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;
             node->style->clipPath.applying = true;
 
 
             auto comp = Shape::gen();
             auto comp = Shape::gen();
-            comp->fill(255, 255, 255, 255);
             if (node->transform) comp->transform(*node->transform);
             if (node->transform) comp->transform(*node->transform);
 
 
             auto child = compNode->child.data;
             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 stroke property is nullptr then do nothing
     if (style->stroke.paint.none) {
     if (style->stroke.paint.none) {
-        //Do nothing
+        vg->stroke(0.0f);
     } else if (style->stroke.paint.gradient) {
     } else if (style->stroke.paint.gradient) {
         Box bBox = vBox;
         Box bBox = vBox;
         if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg);
         if (!style->stroke.paint.gradient->userSpace) bBox = _boundingBox(vg);

+ 4 - 0
thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp

@@ -137,7 +137,11 @@ float svgUtilStrtof(const char *nPtr, char **endPtr)
                     pow10 *= 10ULL;
                     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);
         val += static_cast<float>(decimalPart) / static_cast<float>(pow10);
         a = iter;
         a = iter;
     }
     }

+ 14 - 7
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)
 bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data)
 {
 {
     const char *itr = buf, *itrEnd = buf + bufLength;
     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) {
     while (itr < itrEnd) {
         const char* p = _skipWhiteSpacesAndXmlEntities(itr, itrEnd);
         const char* p = _skipWhiteSpacesAndXmlEntities(itr, itrEnd);
         const char *key, *keyEnd, *value, *valueEnd;
         const char *key, *keyEnd, *value, *valueEnd;
         char* tval;
         char* tval;
 
 
-        if (p == itrEnd) return true;
+        if (p == itrEnd) goto success;
 
 
         key = p;
         key = p;
         for (keyEnd = key; keyEnd < itrEnd; keyEnd++) {
         for (keyEnd = key; keyEnd < itrEnd; keyEnd++) {
             if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break;
             if ((*keyEnd == '=') || (isspace((unsigned char)*keyEnd))) break;
         }
         }
-        if (keyEnd == itrEnd) return false;
+        if (keyEnd == itrEnd) goto error;
         if (keyEnd == key) continue;
         if (keyEnd == key) continue;
 
 
         if (*keyEnd == '=') value = keyEnd + 1;
         if (*keyEnd == '=') value = keyEnd + 1;
         else {
         else {
             value = (const char*)memchr(keyEnd, '=', itrEnd - keyEnd);
             value = (const char*)memchr(keyEnd, '=', itrEnd - keyEnd);
-            if (!value) return false;
+            if (!value) goto error;
             value++;
             value++;
         }
         }
         keyEnd = _simpleXmlUnskipXmlEntities(keyEnd, key);
         keyEnd = _simpleXmlUnskipXmlEntities(keyEnd, key);
 
 
         value = _skipWhiteSpacesAndXmlEntities(value, itrEnd);
         value = _skipWhiteSpacesAndXmlEntities(value, itrEnd);
-        if (value == itrEnd) return false;
+        if (value == itrEnd) goto error;
 
 
         if ((*value == '"') || (*value == '\'')) {
         if ((*value == '"') || (*value == '\'')) {
             valueEnd = (const char*)memchr(value + 1, *value, itrEnd - value);
             valueEnd = (const char*)memchr(value + 1, *value, itrEnd - value);
-            if (!valueEnd) return false;
+            if (!valueEnd) goto error;
             value++;
             value++;
         } else {
         } else {
             valueEnd = _simpleXmlFindWhiteSpace(value, itrEnd);
             valueEnd = _simpleXmlFindWhiteSpace(value, itrEnd);
@@ -364,7 +364,14 @@ bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttr
             }
             }
         }
         }
     }
     }
+
+success:
+    free(tmpBuf);
     return true;
     return true;
+
+error:
+    free(tmpBuf);
+    return false;
 }
 }
 
 
 
 

+ 2 - 2
thirdparty/thorvg/update-thorvg.sh

@@ -1,6 +1,6 @@
-VERSION=0.8.3
+VERSION=0.8.4
 rm -rf AUTHORS inc LICENSE src *.zip
 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
 bsdtar --strip-components=1 -xvf *.zip
 rm *.zip
 rm *.zip
 rm -rf .github docs pc res test tools tvgcompat .git* *.md *.txt wasm_build.sh
 rm -rf .github docs pc res test tools tvgcompat .git* *.md *.txt wasm_build.sh