summaryrefslogtreecommitdiff
path: root/thirdparty/thorvg/src
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2023-04-11 21:01:58 +0200
committerGitHub <noreply@github.com>2023-04-11 21:01:58 +0200
commit16a6bdd423aa85272837d0bc6b9e709febdb4ec0 (patch)
treea7f70f8ed81aec219e990c0b3f174dbd200ae793 /thirdparty/thorvg/src
parent4762303f182e65c5293db8d22a4ce88521eba445 (diff)
parent177be9bd37e3dfa4d591eea3bb8ab14a17d06007 (diff)
Merge pull request #75786 from YuriSizov/4.0-cherrypicks
Cherry-picks for the 4.0 branch (future 4.0.3) - 1st batch
Diffstat (limited to 'thirdparty/thorvg/src')
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp19
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h4
-rw-r--r--thirdparty/thorvg/src/lib/tvgAccessor.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLoadModule.h3
-rw-r--r--thirdparty/thorvg/src/lib/tvgMath.h6
-rw-r--r--thirdparty/thorvg/src/lib/tvgPaint.cpp19
-rw-r--r--thirdparty/thorvg/src/lib/tvgPaint.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgPictureImpl.h4
-rw-r--r--thirdparty/thorvg/src/lib/tvgRender.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgScene.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgSceneImpl.h13
-rw-r--r--thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp29
-rw-r--r--thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h4
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp28
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp35
-rw-r--r--thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h4
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp34
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h1
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h3
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp3
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp4
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp21
23 files changed, 187 insertions, 57 deletions
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;
}