summaryrefslogtreecommitdiff
path: root/thirdparty/thorvg/src
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/thorvg/src')
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h3
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp6
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp92
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h6
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h8
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp5
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgAccessor.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgArray.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgBezier.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgBezier.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgBinaryDesc.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgCanvas.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgCanvasImpl.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgCommon.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgFill.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgFill.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgGlCanvas.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgInitializer.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgIteratorAccessor.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLinearGradient.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLoadModule.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLoader.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLoader.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLzw.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgLzw.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgMath.h4
-rw-r--r--thirdparty/thorvg/src/lib/tvgPaint.cpp8
-rw-r--r--thirdparty/thorvg/src/lib/tvgPaint.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgPicture.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgPictureImpl.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgRadialGradient.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgRender.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgRender.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgSaveModule.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgSaver.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgScene.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgSceneImpl.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgShape.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgShapeImpl.h2
-rw-r--r--thirdparty/thorvg/src/lib/tvgSwCanvas.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp2
-rw-r--r--thirdparty/thorvg/src/lib/tvgTaskScheduler.h2
-rw-r--r--thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp7
-rw-r--r--thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp7
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp21
-rw-r--r--thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h2
-rw-r--r--thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/png/tvgLodePng.h2
-rw-r--r--thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp11
-rw-r--r--thirdparty/thorvg/src/loaders/png/tvgPngLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp186
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h34
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp571
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h49
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp134
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h2
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp67
-rw-r--r--thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h15
-rw-r--r--thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h2
-rw-r--r--thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp2
-rw-r--r--thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h2
-rw-r--r--thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp2
-rw-r--r--thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h2
85 files changed, 1047 insertions, 319 deletions
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h
index e0ffc1fb97..be7042d6de 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -235,6 +235,7 @@ struct SwImage
struct SwBlender
{
uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
+ uint32_t (*lumaValue)(uint32_t c);
};
struct SwCompositor;
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp
index 0bf051c17f..04014a9ec3 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwFill.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
index fe22fce017..f24d2d6f27 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwImage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -84,8 +84,8 @@ bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipReg
//Fast track: Non-transformed image but just shifted.
if (image->direct) {
- image->ox = -static_cast<uint32_t>(round(transform->e13));
- image->oy = -static_cast<uint32_t>(round(transform->e23));
+ image->ox = -static_cast<int32_t>(round(transform->e13));
+ image->oy = -static_cast<int32_t>(round(transform->e23));
//Figure out the scale factor by transform matrix
} else {
auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21));
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp
index 7a3529bd69..7f13609525 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMath.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp
index a44be85bbb..3ab0b6069e 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwMemPool.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
index deebed16ee..e3deebe24f 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRaster.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,6 +47,18 @@ static inline uint32_t _ialpha(uint32_t c)
}
+static inline uint32_t _abgrLumaValue(uint32_t c)
+{
+ return ((((c&0xff)*54) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*19))) >> 8; //0.2125*R + 0.7154*G + 0.0721*B
+}
+
+
+static inline uint32_t _argbLumaValue(uint32_t c)
+{
+ return ((((c&0xff)*19) + (((c>>8)&0xff)*183) + (((c>>16)&0xff)*54))) >> 8; //0.0721*B + 0.7154*G + 0.2125*R
+}
+
+
static inline uint32_t _abgrJoin(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
return (a << 24 | b << 16 | g << 8 | r);
@@ -139,7 +151,7 @@ static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint32_t
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
- auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
@@ -173,6 +185,8 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint32_t color
return _rasterMaskedRect(surface, region, color, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterMaskedRect(surface, region, color, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterMaskedRect(surface, region, color, surface->blender.lumaValue);
}
} else {
if (opacity == 255) {
@@ -246,6 +260,8 @@ static bool _rasterRle(SwSurface* surface, SwRleData* rle, uint32_t color, uint8
return _rasterMaskedRle(surface, rle, color, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterMaskedRle(surface, rle, color, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterMaskedRle(surface, rle, color, surface->blender.lumaValue);
}
} else {
if (opacity == 255) {
@@ -275,6 +291,8 @@ static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, c
return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, surface->blender.lumaValue);
}
} else {
return _rasterTexmapPolygon(surface, image, transform, nullptr, opacity, nullptr);
@@ -481,7 +499,10 @@ static bool _rasterScaledRleRGBAImage(SwSurface* surface, const SwImage* image,
static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
{
Matrix itransform;
- if (transform && !mathInverse(transform, &itransform)) return false;
+
+ if (transform) {
+ if (!mathInverse(transform, &itransform)) return false;
+ } else mathIdentity(&itransform);
auto halfScale = _halfScale(image->scale);
@@ -491,12 +512,16 @@ static bool _scaledRleRGBAImage(SwSurface* surface, const SwImage* image, const
return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterScaledMaskedRleRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue);
}
} else {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue);
}
}
} else {
@@ -613,12 +638,16 @@ static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32
return _rasterDirectMaskedRleRGBAImage(surface, image, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedRleRGBAImage(surface, image, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.lumaValue);
}
} else {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.lumaValue);
}
}
} else {
@@ -640,6 +669,8 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons
return _rasterTexmapPolygon(surface, image, transform, &region, opacity, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTexmapPolygon(surface, image, transform, &region, opacity, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterTexmapPolygon(surface, image, transform, &region, opacity, surface->blender.lumaValue);
}
} else {
return _rasterTexmapPolygon(surface, image, transform, &region, opacity, nullptr);
@@ -816,7 +847,10 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
{
Matrix itransform;
- if (transform && !mathInverse(transform, &itransform)) return false;
+
+ if (transform) {
+ if (!mathInverse(transform, &itransform)) return false;
+ } else mathIdentity(&itransform);
auto halfScale = _halfScale(image->scale);
@@ -826,12 +860,16 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat
return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.lumaValue);
}
} else {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.lumaValue);
}
}
} else {
@@ -855,7 +893,7 @@ static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* imag
auto w2 = static_cast<uint32_t>(region.max.x - region.min.x);
auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
- auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h2; ++y) {
auto dst = buffer;
@@ -882,7 +920,7 @@ static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const Sw
auto w2 = static_cast<uint32_t>(region.max.x - region.min.x);
auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
- auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h2; ++y) {
auto dst = buffer;
@@ -946,12 +984,16 @@ static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwB
return _rasterDirectMaskedRGBAImage(surface, image, region, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedRGBAImage(surface, image, region, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.lumaValue);
}
} else {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.lumaValue);
}
}
} else {
@@ -1056,6 +1098,8 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region,
return _rasterLinearGradientMaskedRect(surface, region, fill, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterLinearGradientMaskedRect(surface, region, fill, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterLinearGradientMaskedRect(surface, region, fill, surface->blender.lumaValue);
}
} else {
if (fill->translucent) return _rasterTranslucentLinearGradientRect(surface, region, fill);
@@ -1113,12 +1157,12 @@ static bool _rasterTranslucentLinearGradientRle(SwSurface* surface, const SwRleD
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
}
} else {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
}
}
@@ -1142,8 +1186,8 @@ static bool _rasterSolidLinearGradientRle(SwSurface* surface, const SwRleData* r
} else {
fillFetchLinear(fill, buf, span->y, span->x, span->len);
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- for (uint32_t i = 0; i < span->len; ++i) {
- dst[i] = INTERPOLATE(span->coverage, buf[i], dst[i]);
+ for (uint32_t x = 0; x < span->len; ++x) {
+ dst[x] = INTERPOLATE(span->coverage, buf[x], dst[x]);
}
}
}
@@ -1160,6 +1204,8 @@ static bool _rasterLinearGradientRle(SwSurface* surface, const SwRleData* rle, c
return _rasterLinearGradientMaskedRle(surface, rle, fill, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterLinearGradientMaskedRle(surface, rle, fill, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterLinearGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue);
}
} else {
if (fill->translucent) return _rasterTranslucentLinearGradientRle(surface, rle, fill);
@@ -1247,6 +1293,8 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region,
return _rasterRadialGradientMaskedRect(surface, region, fill, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterRadialGradientMaskedRect(surface, region, fill, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterRadialGradientMaskedRect(surface, region, fill, surface->blender.lumaValue);
}
} else {
if (fill->translucent) return _rasterTranslucentRadialGradientRect(surface, region, fill);
@@ -1302,12 +1350,12 @@ static bool _rasterTranslucentRadialGradientRle(SwSurface* surface, const SwRleD
auto dst = &surface->buffer[span->y * surface->stride + span->x];
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
if (span->coverage == 255) {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = buffer[i] + ALPHA_BLEND(*dst, _ialpha(buffer[i]));
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = buffer[x] + ALPHA_BLEND(*dst, _ialpha(buffer[x]));
}
} else {
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- auto tmp = ALPHA_BLEND(buffer[i], span->coverage);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ auto tmp = ALPHA_BLEND(buffer[x], span->coverage);
*dst = tmp + ALPHA_BLEND(*dst, _ialpha(tmp));
}
}
@@ -1332,8 +1380,8 @@ static bool _rasterSolidRadialGradientRle(SwSurface* surface, const SwRleData* r
} else {
fillFetchRadial(fill, buf, span->y, span->x, span->len);
auto ialpha = 255 - span->coverage;
- for (uint32_t i = 0; i < span->len; ++i, ++dst) {
- *dst = ALPHA_BLEND(buf[i], span->coverage) + ALPHA_BLEND(*dst, ialpha);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst) {
+ *dst = ALPHA_BLEND(buf[x], span->coverage) + ALPHA_BLEND(*dst, ialpha);
}
}
}
@@ -1350,6 +1398,8 @@ static bool _rasterRadialGradientRle(SwSurface* surface, const SwRleData* rle, c
return _rasterRadialGradientMaskedRle(surface, rle, fill, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterRadialGradientMaskedRle(surface, rle, fill, _ialpha);
+ } else if (surface->compositor->method == CompositeMethod::LumaMask) {
+ return _rasterRadialGradientMaskedRle(surface, rle, fill, surface->blender.lumaValue);
}
} else {
if (fill->translucent) _rasterTranslucentRadialGradientRle(surface, rle, fill);
@@ -1379,8 +1429,10 @@ bool rasterCompositor(SwSurface* surface)
{
if (surface->cs == SwCanvas::ABGR8888 || surface->cs == SwCanvas::ABGR8888_STRAIGHT) {
surface->blender.join = _abgrJoin;
+ surface->blender.lumaValue = _abgrLumaValue;
} else if (surface->cs == SwCanvas::ARGB8888 || surface->cs == SwCanvas::ARGB8888_STRAIGHT) {
surface->blender.join = _argbJoin;
+ surface->blender.lumaValue = _argbLumaValue;
} else {
//What Color Space ???
return false;
@@ -1487,11 +1539,11 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
{
//Verify Boundary
- if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= surface->w || bbox.min.y >= surface->h) return false;
+ if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return false;
//TOOD: switch (image->format)
//TODO: case: _rasterRGBImage()
//TODO: case: _rasterGrayscaleImage()
//TODO: case: _rasterAlphaImage()
return _rasterRGBAImage(surface, image, transform, bbox, opacity);
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h
index 1d6552f3e9..7a129a3a80 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterAvx.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h
index 6d60957eb9..d479ede15f 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterC.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h
index c74a6b309c..a4b3cdaeb2 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterNeon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -26,8 +26,8 @@
static inline uint8x8_t ALPHA_BLEND(uint8x8_t c, uint8x8_t a)
{
- uint16x8_t t = vmull_u8(c, a);
- return vshrn_n_u16(t, 8);
+ uint16x8_t t = vmull_u8(c, a);
+ return vshrn_n_u16(t, 8);
}
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h
index 2cf9fb4e93..1faedd60aa 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
index 4e8d342137..f31ea1eb97 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRasterTexmapInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -58,8 +58,8 @@
y = yStart;
while (y < yEnd) {
- x1 = _xa;
- x2 = _xb;
+ x1 = (int32_t)_xa;
+ x2 = (int32_t)_xb;
if (!region) {
minx = INT32_MAX;
@@ -160,4 +160,4 @@ next:
xb = _xb;
ua = _ua;
va = _va;
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
index c75e73760e..c3872f3207 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -19,11 +19,10 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#include <math.h>
+#include "tvgMath.h"
#include "tvgSwCommon.h"
#include "tvgTaskScheduler.h"
#include "tvgSwRenderer.h"
-#include "tvgMath.h"
/************************************************************************/
/* Internal Class Implementation */
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h
index 3f883ac409..574d9d488f 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRenderer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp
index b41e48b7ca..aa975869e0 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwRle.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp
index 7b49c232b1..2a2c6a1da3 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwShape.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp
index c0cfc1be26..04aa9a36ec 100644
--- a/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp
+++ b/thirdparty/thorvg/src/lib/sw_engine/tvgSwStroke.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgAccessor.cpp b/thirdparty/thorvg/src/lib/tvgAccessor.cpp
index 085c8a3cbc..9fd564dd23 100644
--- a/thirdparty/thorvg/src/lib/tvgAccessor.cpp
+++ b/thirdparty/thorvg/src/lib/tvgAccessor.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
diff --git a/thirdparty/thorvg/src/lib/tvgArray.h b/thirdparty/thorvg/src/lib/tvgArray.h
index d04e68e73c..04ddbaee2b 100644
--- a/thirdparty/thorvg/src/lib/tvgArray.h
+++ b/thirdparty/thorvg/src/lib/tvgArray.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgBezier.cpp b/thirdparty/thorvg/src/lib/tvgBezier.cpp
index 2290afa728..95e2055943 100644
--- a/thirdparty/thorvg/src/lib/tvgBezier.cpp
+++ b/thirdparty/thorvg/src/lib/tvgBezier.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgBezier.h b/thirdparty/thorvg/src/lib/tvgBezier.h
index 866e39148e..7d7c84e34e 100644
--- a/thirdparty/thorvg/src/lib/tvgBezier.h
+++ b/thirdparty/thorvg/src/lib/tvgBezier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgBinaryDesc.h b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h
index 30ba2d5a29..f139def470 100644
--- a/thirdparty/thorvg/src/lib/tvgBinaryDesc.h
+++ b/thirdparty/thorvg/src/lib/tvgBinaryDesc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgCanvas.cpp b/thirdparty/thorvg/src/lib/tvgCanvas.cpp
index bb42441c62..e8529e47c2 100644
--- a/thirdparty/thorvg/src/lib/tvgCanvas.cpp
+++ b/thirdparty/thorvg/src/lib/tvgCanvas.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgCanvasImpl.h b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h
index 848c03aaed..0adec8fa52 100644
--- a/thirdparty/thorvg/src/lib/tvgCanvasImpl.h
+++ b/thirdparty/thorvg/src/lib/tvgCanvasImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgCommon.h b/thirdparty/thorvg/src/lib/tvgCommon.h
index b1c586188c..1d66f2e1a2 100644
--- a/thirdparty/thorvg/src/lib/tvgCommon.h
+++ b/thirdparty/thorvg/src/lib/tvgCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgFill.cpp b/thirdparty/thorvg/src/lib/tvgFill.cpp
index 4bfb93c102..0c0581a180 100644
--- a/thirdparty/thorvg/src/lib/tvgFill.cpp
+++ b/thirdparty/thorvg/src/lib/tvgFill.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgFill.h b/thirdparty/thorvg/src/lib/tvgFill.h
index 912091f8cb..fff2475c4f 100644
--- a/thirdparty/thorvg/src/lib/tvgFill.h
+++ b/thirdparty/thorvg/src/lib/tvgFill.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp
index 3a88b6d799..56feb69541 100644
--- a/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp
+++ b/thirdparty/thorvg/src/lib/tvgGlCanvas.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgInitializer.cpp b/thirdparty/thorvg/src/lib/tvgInitializer.cpp
index 83ec50be95..42997c3493 100644
--- a/thirdparty/thorvg/src/lib/tvgInitializer.cpp
+++ b/thirdparty/thorvg/src/lib/tvgInitializer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h
index 10b55a536d..8e566acb72 100644
--- a/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h
+++ b/thirdparty/thorvg/src/lib/tvgIteratorAccessor.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp
index 6ec7ddab20..df34af3aa1 100644
--- a/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp
+++ b/thirdparty/thorvg/src/lib/tvgLinearGradient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLoadModule.h b/thirdparty/thorvg/src/lib/tvgLoadModule.h
index 0c34ecbf6a..bfcc165f31 100644
--- a/thirdparty/thorvg/src/lib/tvgLoadModule.h
+++ b/thirdparty/thorvg/src/lib/tvgLoadModule.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLoader.cpp b/thirdparty/thorvg/src/lib/tvgLoader.cpp
index fb93e0faec..991c260159 100644
--- a/thirdparty/thorvg/src/lib/tvgLoader.cpp
+++ b/thirdparty/thorvg/src/lib/tvgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLoader.h b/thirdparty/thorvg/src/lib/tvgLoader.h
index 8ba3c139fa..ab32f89a2f 100644
--- a/thirdparty/thorvg/src/lib/tvgLoader.h
+++ b/thirdparty/thorvg/src/lib/tvgLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLzw.cpp b/thirdparty/thorvg/src/lib/tvgLzw.cpp
index 0049c89962..1aaf37831a 100644
--- a/thirdparty/thorvg/src/lib/tvgLzw.cpp
+++ b/thirdparty/thorvg/src/lib/tvgLzw.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgLzw.h b/thirdparty/thorvg/src/lib/tvgLzw.h
index 3fdb439a02..1bd5c61fac 100644
--- a/thirdparty/thorvg/src/lib/tvgLzw.h
+++ b/thirdparty/thorvg/src/lib/tvgLzw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgMath.h b/thirdparty/thorvg/src/lib/tvgMath.h
index 94b4fe1cf1..6120216d74 100644
--- a/thirdparty/thorvg/src/lib/tvgMath.h
+++ b/thirdparty/thorvg/src/lib/tvgMath.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,7 +47,7 @@ static inline bool mathEqual(float a, float b)
static inline bool mathRightAngle(const Matrix* m)
{
- auto radian = fabsf(atan2(m->e21, m->e11));
+ auto radian = fabsf(atan2f(m->e21, m->e11));
if (radian < FLT_EPSILON || mathEqual(radian, float(M_PI_2)) || mathEqual(radian, float(M_PI))) return true;
return false;
}
diff --git a/thirdparty/thorvg/src/lib/tvgPaint.cpp b/thirdparty/thorvg/src/lib/tvgPaint.cpp
index 30e82fbc60..d0e908ddf2 100644
--- a/thirdparty/thorvg/src/lib/tvgPaint.cpp
+++ b/thirdparty/thorvg/src/lib/tvgPaint.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -79,8 +79,8 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform,
viewport.x = static_cast<int32_t>(v1.x);
viewport.y = static_cast<int32_t>(v1.y);
- viewport.w = static_cast<int32_t>(v2.x - v1.x + 0.5f);
- viewport.h = static_cast<int32_t>(v2.y - v1.y + 0.5f);
+ viewport.w = static_cast<int32_t>(ceil(v2.x - viewport.x));
+ viewport.h = static_cast<int32_t>(ceil(v2.y - viewport.y));
if (viewport.w < 0) viewport.w = 0;
if (viewport.h < 0) viewport.h = 0;
@@ -404,4 +404,4 @@ uint8_t Paint::opacity() const noexcept
uint32_t Paint::identifier() const noexcept
{
return pImpl->id;
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/lib/tvgPaint.h b/thirdparty/thorvg/src/lib/tvgPaint.h
index 4003bdbeac..c170559a37 100644
--- a/thirdparty/thorvg/src/lib/tvgPaint.h
+++ b/thirdparty/thorvg/src/lib/tvgPaint.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgPicture.cpp b/thirdparty/thorvg/src/lib/tvgPicture.cpp
index 1d9776363c..1125b1eb58 100644
--- a/thirdparty/thorvg/src/lib/tvgPicture.cpp
+++ b/thirdparty/thorvg/src/lib/tvgPicture.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgPictureImpl.h b/thirdparty/thorvg/src/lib/tvgPictureImpl.h
index 00e8aa6dd9..b2e097d400 100644
--- a/thirdparty/thorvg/src/lib/tvgPictureImpl.h
+++ b/thirdparty/thorvg/src/lib/tvgPictureImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp
index 42a83461e3..7aba550e48 100644
--- a/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp
+++ b/thirdparty/thorvg/src/lib/tvgRadialGradient.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgRender.cpp b/thirdparty/thorvg/src/lib/tvgRender.cpp
index a48075dd04..145f974cee 100644
--- a/thirdparty/thorvg/src/lib/tvgRender.cpp
+++ b/thirdparty/thorvg/src/lib/tvgRender.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgRender.h b/thirdparty/thorvg/src/lib/tvgRender.h
index f927947aa6..ed66f393da 100644
--- a/thirdparty/thorvg/src/lib/tvgRender.h
+++ b/thirdparty/thorvg/src/lib/tvgRender.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgSaveModule.h b/thirdparty/thorvg/src/lib/tvgSaveModule.h
index 2a0f427f11..3531662fdd 100644
--- a/thirdparty/thorvg/src/lib/tvgSaveModule.h
+++ b/thirdparty/thorvg/src/lib/tvgSaveModule.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgSaver.cpp b/thirdparty/thorvg/src/lib/tvgSaver.cpp
index 1a3e8614a6..e71953700c 100644
--- a/thirdparty/thorvg/src/lib/tvgSaver.cpp
+++ b/thirdparty/thorvg/src/lib/tvgSaver.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgScene.cpp b/thirdparty/thorvg/src/lib/tvgScene.cpp
index 4b2f77dde9..ff43d3c881 100644
--- a/thirdparty/thorvg/src/lib/tvgScene.cpp
+++ b/thirdparty/thorvg/src/lib/tvgScene.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgSceneImpl.h b/thirdparty/thorvg/src/lib/tvgSceneImpl.h
index de94a66e2f..6a7614c667 100644
--- a/thirdparty/thorvg/src/lib/tvgSceneImpl.h
+++ b/thirdparty/thorvg/src/lib/tvgSceneImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgShape.cpp b/thirdparty/thorvg/src/lib/tvgShape.cpp
index 8db5635932..3a3af5f76e 100644
--- a/thirdparty/thorvg/src/lib/tvgShape.cpp
+++ b/thirdparty/thorvg/src/lib/tvgShape.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgShapeImpl.h b/thirdparty/thorvg/src/lib/tvgShapeImpl.h
index dcf4e6e954..738b21ed70 100644
--- a/thirdparty/thorvg/src/lib/tvgShapeImpl.h
+++ b/thirdparty/thorvg/src/lib/tvgShapeImpl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp
index f7a03b819c..8c9de8cb51 100644
--- a/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp
+++ b/thirdparty/thorvg/src/lib/tvgSwCanvas.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp
index 780127b87b..8c07dc3859 100644
--- a/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp
+++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/lib/tvgTaskScheduler.h b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h
index f30bdf9a8f..163e387f29 100644
--- a/thirdparty/thorvg/src/lib/tvgTaskScheduler.h
+++ b/thirdparty/thorvg/src/lib/tvgTaskScheduler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp
index 6f9416b69c..522c3c71a6 100644
--- a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h
index 7d35e57d72..3f82af8003 100644
--- a/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h
+++ b/thirdparty/thorvg/src/loaders/external_jpg/tvgJpgLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp
index c3d281482a..05db65cb23 100644
--- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -93,7 +93,10 @@ bool PngLoader::read()
png_image_free(image);
return false;
}
- if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) return false;
+ if (!png_image_finish_read(image, NULL, buffer, 0, NULL)) {
+ free(buffer);
+ return false;
+ }
content = reinterpret_cast<uint32_t*>(buffer);
_premultiply(reinterpret_cast<uint32_t*>(buffer), image->width, image->height);
diff --git a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h
index b42537c73f..8beff0a3b3 100644
--- a/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h
+++ b/thirdparty/thorvg/src/loaders/external_png/tvgPngLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
index 8846613c6b..7b90b4aef9 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,6 +47,7 @@ JpgLoader::~JpgLoader()
{
jpgdDelete(decoder);
if (freeData) free(data);
+ free(image);
}
@@ -128,5 +129,9 @@ unique_ptr<Surface> JpgLoader::bitmap()
void JpgLoader::run(unsigned tid)
{
+ if (image) {
+ free(image);
+ image = nullptr;
+ }
image = jpgdDecompress(decoder);
} \ No newline at end of file
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h
index 39732dbc3a..d6b886cb29 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
index fa72734ec4..dacd45ed03 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -382,8 +382,8 @@ struct Row
const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
- const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS;
+ const int tmp0 = static_cast<unsigned int>(ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS;
+ const int tmp1 = static_cast<unsigned int>(ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS;
const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
@@ -461,8 +461,8 @@ struct Col
const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
- const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS;
+ const int tmp0 = static_cast<unsigned int>(ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS;
+ const int tmp1 = static_cast<unsigned int>(ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS;
const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
@@ -1080,7 +1080,9 @@ namespace DCT_Upsample
// Unconditionally frees all allocated m_blocks.
void jpeg_decoder::free_all_blocks()
{
+ delete(m_pStream);
m_pStream = nullptr;
+
for (mem_block *b = m_pMem_blocks; b; ) {
mem_block *n = b->m_pNext;
free(b);
@@ -2555,7 +2557,7 @@ void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int
s = JPGD_HUFF_EXTEND(r, s);
}
pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
- p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
+ p[0] = static_cast<jpgd_block_t>(static_cast<unsigned int>(s) << pD->m_successive_low);
}
@@ -2586,7 +2588,7 @@ void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int
if ((k += r) > 63) pD->stop_decoding(JPGD_DECODE_ERROR);
r = pD->get_bits_no_markers(s);
s = JPGD_HUFF_EXTEND(r, s);
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
+ p[g_ZAG[k]] = static_cast<jpgd_block_t>(static_cast<unsigned int>(s) << pD->m_successive_low);
} else {
if (r == 15) {
if ((k += 15) > 63) pD->stop_decoding(JPGD_DECODE_ERROR);
@@ -2605,7 +2607,7 @@ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, in
{
int s, k, r;
int p1 = 1 << pD->m_successive_low;
- int m1 = (-1) << pD->m_successive_low;
+ int m1 = static_cast<unsigned int>(-1) << pD->m_successive_low;
jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
JPGD_ASSERT(pD->m_spectral_end <= 63);
@@ -2815,7 +2817,6 @@ int jpeg_decoder::begin_decoding()
jpeg_decoder::~jpeg_decoder()
{
free_all_blocks();
- delete(m_pStream);
}
@@ -3025,4 +3026,4 @@ unsigned char* jpgdDecompress(jpeg_decoder* decoder)
}
}
return pImage_data;
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
index d32ffd99d4..ca9cb35c32 100644
--- a/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
+++ b/thirdparty/thorvg/src/loaders/jpg/tvgJpgd.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp
index f2dfa02875..5c01c5a1e2 100644
--- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp
+++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h
index 02e1feeec5..c9f0e56ab6 100644
--- a/thirdparty/thorvg/src/loaders/png/tvgLodePng.h
+++ b/thirdparty/thorvg/src/loaders/png/tvgLodePng.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
index c6d95be5ba..3e293176b7 100644
--- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -72,6 +72,7 @@ PngLoader::PngLoader()
PngLoader::~PngLoader()
{
if (freeData) free(data);
+ free(image);
}
@@ -121,7 +122,7 @@ bool PngLoader::open(const char* data, uint32_t size, bool copy)
clear();
lodepng_state_init(&state);
-
+
unsigned int width, height;
if (lodepng_inspect(&width, &height, &state, (unsigned char*)(data), size) > 0) return false;
@@ -180,10 +181,14 @@ unique_ptr<Surface> PngLoader::bitmap()
void PngLoader::run(unsigned tid)
{
+ if (image) {
+ free(image);
+ image = nullptr;
+ }
auto width = static_cast<unsigned>(w);
auto height = static_cast<unsigned>(h);
lodepng_decode(&image, &width, &height, &state, data, size);
_premultiply((uint32_t*)(image), width, height);
-} \ No newline at end of file
+}
diff --git a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h
index 34dbeed012..8f07f6418f 100644
--- a/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h
+++ b/thirdparty/thorvg/src/loaders/png/tvgPngLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp
index d7d425b119..2da399d8c3 100644
--- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h
index 20fa332981..e4f3423b41 100644
--- a/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h
+++ b/thirdparty/thorvg/src/loaders/raw/tvgRawLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp
new file mode 100644
index 0000000000..e537cfa27f
--- /dev/null
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "tvgSvgCssStyle.h"
+
+/************************************************************************/
+/* Internal Class Implementation */
+/************************************************************************/
+
+static void _copyStyle(SvgStyleProperty* to, const SvgStyleProperty* from)
+{
+ if (from == nullptr) return;
+ //Copy the properties of 'from' only if they were explicitly set (not the default ones).
+ if (from->curColorSet && !((int)to->flags & (int)SvgStyleFlags::Color)) {
+ to->color = from->color;
+ to->curColorSet = true;
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Color);
+ }
+ //Fill
+ if (((int)from->fill.flags & (int)SvgFillFlags::Paint) && !((int)to->flags & (int)SvgStyleFlags::Fill)) {
+ to->fill.paint.color = from->fill.paint.color;
+ to->fill.paint.none = from->fill.paint.none;
+ to->fill.paint.curColor = from->fill.paint.curColor;
+ if (from->fill.paint.url) to->fill.paint.url = strdup(from->fill.paint.url);
+ to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Paint);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Fill);
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::Opacity) && !((int)to->flags & (int)SvgStyleFlags::FillOpacity)) {
+ to->fill.opacity = from->fill.opacity;
+ to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::Opacity);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::FillOpacity);
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::FillRule) && !((int)to->flags & (int)SvgStyleFlags::FillRule)) {
+ to->fill.fillRule = from->fill.fillRule;
+ to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)SvgFillFlags::FillRule);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::FillRule);
+ }
+ //Stroke
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Paint) && !((int)to->flags & (int)SvgStyleFlags::Stroke)) {
+ to->stroke.paint.color = from->stroke.paint.color;
+ to->stroke.paint.none = from->stroke.paint.none;
+ to->stroke.paint.curColor = from->stroke.paint.curColor;
+ if (from->stroke.paint.url) to->stroke.paint.url = strdup(from->stroke.paint.url);
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Paint);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Stroke);
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity) && !((int)to->flags & (int)SvgStyleFlags::StrokeOpacity)) {
+ to->stroke.opacity = from->stroke.opacity;
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Opacity);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeOpacity);
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Width) && !((int)to->flags & (int)SvgStyleFlags::StrokeWidth)) {
+ to->stroke.width = from->stroke.width;
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Width);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeWidth);
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Dash) && !((int)to->flags & (int)SvgStyleFlags::StrokeDashArray)) {
+ if (from->stroke.dash.array.count > 0) {
+ to->stroke.dash.array.clear();
+ to->stroke.dash.array.reserve(from->stroke.dash.array.count);
+ for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
+ to->stroke.dash.array.push(from->stroke.dash.array.data[i]);
+ }
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Dash);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeDashArray);
+ }
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Cap) && !((int)to->flags & (int)SvgStyleFlags::StrokeLineCap)) {
+ to->stroke.cap = from->stroke.cap;
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Cap);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeLineCap);
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Join) && !((int)to->flags & (int)SvgStyleFlags::StrokeLineJoin)) {
+ to->stroke.join = from->stroke.join;
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)SvgStrokeFlags::Join);
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::StrokeLineJoin);
+ }
+ //Opacity
+ //TODO: it can be set to be 255 and shouldn't be changed by attribute 'opacity'
+ if (from->opacity < 255 && !((int)to->flags & (int)SvgStyleFlags::Opacity)) {
+ to->opacity = from->opacity;
+ to->flags = (SvgStyleFlags)((int)to->flags | (int)SvgStyleFlags::Opacity);
+ }
+}
+
+
+/************************************************************************/
+/* External Class Implementation */
+/************************************************************************/
+
+void cssCopyStyleAttr(SvgNode* to, const SvgNode* from)
+{
+ //Copy matrix attribute
+ if (from->transform && !((int)to->style->flags & (int)SvgStyleFlags::Transform)) {
+ to->transform = (Matrix*)malloc(sizeof(Matrix));
+ if (to->transform) {
+ *to->transform = *from->transform;
+ to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)SvgStyleFlags::Transform);
+ }
+ }
+ //Copy style attribute
+ _copyStyle(to->style, from->style);
+
+ if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
+ if (from->style->mask.url) to->style->mask.url = strdup(from->style->mask.url);
+}
+
+
+SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type)
+{
+ if (!style) return nullptr;
+
+ auto child = style->child.data;
+ for (uint32_t i = 0; i < style->child.count; ++i, ++child) {
+ if ((*child)->type == type) {
+ if ((!title && !(*child)->id) || (title && (*child)->id && !strcmp((*child)->id, title))) return (*child);
+ }
+ }
+ return nullptr;
+}
+
+
+SvgNode* cssFindStyleNode(const SvgNode* style, const char* title)
+{
+ if (!style) return nullptr;
+
+ auto child = style->child.data;
+ for (uint32_t i = 0; i < style->child.count; ++i, ++child) {
+ if ((*child)->type == SvgNodeType::CssStyle) {
+ if ((title && (*child)->id && !strcmp((*child)->id, title))) return (*child);
+ }
+ }
+ return nullptr;
+}
+
+
+void cssUpdateStyle(SvgNode* doc, SvgNode* style)
+{
+ if (doc->child.count > 0) {
+ auto child = doc->child.data;
+ for (uint32_t i = 0; i < doc->child.count; ++i, ++child) {
+ if (auto cssNode = cssFindStyleNode(style, nullptr, (*child)->type)) {
+ cssCopyStyleAttr(*child, cssNode);
+ }
+ if (auto cssNode = cssFindStyleNode(style, nullptr)) {
+ cssCopyStyleAttr(*child, cssNode);
+ }
+ cssUpdateStyle(*child, style);
+ }
+ }
+}
+
+
+void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style)
+{
+ for (uint32_t i = 0; i < postponeds.count; ++i) {
+ auto nodeIdPair = postponeds.data[i];
+
+ //css styling: tag.name has higher priority than .name
+ if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id, nodeIdPair.node->type)) {
+ cssCopyStyleAttr(nodeIdPair.node, cssNode);
+ }
+ if (auto cssNode = cssFindStyleNode(style, nodeIdPair.id)) {
+ cssCopyStyleAttr(nodeIdPair.node, cssNode);
+ }
+ }
+} \ No newline at end of file
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h
new file mode 100644
index 0000000000..66477c1a32
--- /dev/null
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgCssStyle.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved.
+
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _TVG_SVG_CSS_STYLE_H_
+#define _TVG_SVG_CSS_STYLE_H_
+
+#include "tvgSvgLoaderCommon.h"
+
+void cssCopyStyleAttr(SvgNode* to, const SvgNode* from);
+SvgNode* cssFindStyleNode(const SvgNode* style, const char* title, SvgNodeType type);
+SvgNode* cssFindStyleNode(const SvgNode* style, const char* title);
+void cssUpdateStyle(SvgNode* doc, SvgNode* style);
+void cssApplyStyleToPostponeds(Array<SvgNodeIdPair>& postponeds, SvgNode* style);
+
+#endif //_TVG_SVG_CSS_STYLE_H_
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
index cf103774c5..a842b7fa8b 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -60,6 +60,8 @@
#include "tvgSvgLoader.h"
#include "tvgSvgSceneBuilder.h"
#include "tvgSvgUtil.h"
+#include "tvgSvgCssStyle.h"
+#include "tvgMath.h"
/************************************************************************/
/* Internal Class Implementation */
@@ -75,11 +77,10 @@
#define PX_PER_MM 3.779528f //1 in = 25.4 mm -> PX_PER_IN/25.4
#define PX_PER_CM 37.79528f //1 in = 2.54 cm -> PX_PER_IN/2.54
-
-typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength);
+typedef bool (*parseAttributes)(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data);
+typedef SvgNode* (*FactoryMethod)(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func);
typedef SvgStyleGradient* (*GradientFactoryMethod)(SvgLoaderData* loader, const char* buf, unsigned bufLength);
-
static char* _skipSpace(const char* str, const char* end)
{
while (((end && str < end) || (!end && *str != '\0')) && isspace(*str)) {
@@ -200,6 +201,14 @@ static int _toOpacity(const char* str)
}
+static SvgMaskType _toMaskType(const char* str)
+{
+ if (!strcmp(str, "Alpha")) return SvgMaskType::Alpha;
+
+ return SvgMaskType::Luminance;
+}
+
+
#define _PARSE_TAG(Type, Name, Name1, Tags_Array, Default) \
static Type _to##Name1(const char* str) \
{ \
@@ -541,7 +550,7 @@ static void _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char**
}
}
}
- } else if (len >= 3 && !strncmp(str, "url", 3)) {
+ } else if (ref && len >= 3 && !strncmp(str, "url", 3)) {
*ref = _idFromUrl((const char*)(str + 3));
} else {
//Handle named color
@@ -726,6 +735,12 @@ error:
}
+static void _postpone(Array<SvgNodeIdPair>& nodes, SvgNode *node, char* id)
+{
+ nodes.push({node, id});
+}
+
+
/*
// TODO - remove?
static constexpr struct
@@ -786,14 +801,12 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value)
} else if (!strcmp(key, "preserveAspectRatio")) {
if (!strcmp(value, "none")) doc->preserveAspect = false;
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
- }
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
#ifdef THORVG_LOG_ENABLED
- else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON ) {
+ } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(svgUtilStrtof(value, nullptr)) > FLT_EPSILON) {
TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value);
- }
#endif
- else {
+ } else {
return _parseStyleAttr(loader, key, value, false);
}
return true;
@@ -922,6 +935,12 @@ static void _handleMaskAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, con
}
+static void _handleMaskTypeAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
+{
+ node->node.mask.type = _toMaskType(value);
+}
+
+
static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node, const char* value)
{
//TODO : The display attribute can have various values as well as "none".
@@ -933,6 +952,29 @@ static void _handleDisplayAttr(TVG_UNUSED SvgLoaderData* loader, SvgNode* node,
}
+static void _handleCssClassAttr(SvgLoaderData* loader, SvgNode* node, const char* value)
+{
+ auto cssClass = &node->style->cssClass;
+
+ if (*cssClass && value) free(*cssClass);
+ *cssClass = _copyId(value);
+
+ bool cssClassFound = false;
+
+ //css styling: tag.name has higher priority than .name
+ if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass, node->type)) {
+ cssClassFound = true;
+ cssCopyStyleAttr(node, cssNode);
+ }
+ if (auto cssNode = cssFindStyleNode(loader->cssStyle, *cssClass)) {
+ cssClassFound = true;
+ cssCopyStyleAttr(node, cssNode);
+ }
+
+ if (!cssClassFound) _postpone(loader->nodesToStyle, node, *cssClass);
+}
+
+
typedef void (*styleMethod)(SvgLoaderData* loader, SvgNode* node, const char* value);
#define STYLE_DEF(Name, Name1, Flag) { #Name, sizeof(#Name), _handle##Name1##Attr, Flag }
@@ -959,6 +1001,7 @@ static constexpr struct
STYLE_DEF(transform, Transform, SvgStyleFlags::Transform),
STYLE_DEF(clip-path, ClipPath, SvgStyleFlags::ClipPath),
STYLE_DEF(mask, Mask, SvgStyleFlags::Mask),
+ STYLE_DEF(mask-type, MaskType, SvgStyleFlags::MaskType),
STYLE_DEF(display, Display, SvgStyleFlags::Display)
};
@@ -1006,12 +1049,14 @@ static bool _attrParseGNode(void* data, const char* key, const char* value)
SvgNode* node = loader->svgParse->node;
if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "transform")) {
node->transform = _parseTransformationMatrix(value);
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1030,17 +1075,19 @@ static bool _attrParseClipPathNode(void* data, const char* key, const char* valu
{
SvgLoaderData* loader = (SvgLoaderData*)data;
SvgNode* node = loader->svgParse->node;
- SvgCompositeNode* comp = &(node->node.comp);
+ SvgClipNode* clip = &(node->node.clip);
if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "transform")) {
node->transform = _parseTransformationMatrix(value);
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "clipPathUnits")) {
- if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false;
+ if (!strcmp(value, "objectBoundingBox")) clip->userSpace = false;
} else {
return _parseStyleAttr(loader, key, value, false);
}
@@ -1052,17 +1099,36 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value)
{
SvgLoaderData* loader = (SvgLoaderData*)data;
SvgNode* node = loader->svgParse->node;
- SvgCompositeNode* comp = &(node->node.comp);
+ SvgMaskNode* mask = &(node->node.mask);
if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "transform")) {
node->transform = _parseTransformationMatrix(value);
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "maskContentUnits")) {
- if (!strcmp(value, "objectBoundingBox")) comp->userSpace = false;
+ if (!strcmp(value, "objectBoundingBox")) mask->userSpace = false;
+ } else if (!strcmp(key, "mask-type")) {
+ mask->type = _toMaskType(value);
+ } else {
+ return _parseStyleAttr(loader, key, value, false);
+ }
+ return true;
+}
+
+
+static bool _attrParseCssStyleNode(void* data, const char* key, const char* value)
+{
+ SvgLoaderData* loader = (SvgLoaderData*)data;
+ SvgNode* node = loader->svgParse->node;
+
+ if (!strcmp(key, "id")) {
+ if (node->id && value) free(node->id);
+ node->id = _copyId(value);
} else {
return _parseStyleAttr(loader, key, value, false);
}
@@ -1070,6 +1136,31 @@ static bool _attrParseMaskNode(void* data, const char* key, const char* value)
}
+static bool _attrParseSymbolNode(void* data, const char* key, const char* value)
+{
+ SvgLoaderData* loader = (SvgLoaderData*)data;
+ SvgNode* node = loader->svgParse->node;
+ SvgSymbolNode* symbol = &(node->node.symbol);
+
+ if (!strcmp(key, "viewBox")) {
+ if (!_parseNumber(&value, &symbol->vx) || !_parseNumber(&value, &symbol->vy)) return false;
+ if (!_parseNumber(&value, &symbol->vw) || !_parseNumber(&value, &symbol->vh)) return false;
+ } else if (!strcmp(key, "width")) {
+ symbol->w = _toFloat(loader->svgParse, value, SvgParserLengthType::Horizontal);
+ } else if (!strcmp(key, "height")) {
+ symbol->h = _toFloat(loader->svgParse, value, SvgParserLengthType::Vertical);
+ } else if (!strcmp(key, "preserveAspectRatio")) {
+ if (!strcmp(value, "none")) symbol->preserveAspect = false;
+ } else if (!strcmp(key, "overflow")) {
+ if (!strcmp(value, "visible")) symbol->overflowVisible = true;
+ } else {
+ return _attrParseGNode(data, key, value);
+ }
+
+ return true;
+}
+
+
static SvgNode* _createNode(SvgNode* parent, SvgNodeType type)
{
SvgNode* node = (SvgNode*)calloc(1, sizeof(SvgNode));
@@ -1121,7 +1212,7 @@ static SvgNode* _createNode(SvgNode* parent, SvgNodeType type)
}
-static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED SvgNode* parent, const char* buf, unsigned bufLength, TVG_UNUSED parseAttributes func)
{
if (loader->def && loader->doc->node.doc.defs) return loader->def;
SvgNode* node = _createNode(nullptr, SvgNodeType::Defs);
@@ -1132,17 +1223,17 @@ static SvgNode* _createDefsNode(TVG_UNUSED SvgLoaderData* loader, TVG_UNUSED Svg
}
-static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createGNode(TVG_UNUSED SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::G);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseGNode, loader);
+ func(buf, bufLength, _attrParseGNode, loader);
return loader->svgParse->node;
}
-static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Doc);
if (!loader->svgParse->node) return nullptr;
@@ -1152,7 +1243,7 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha
loader->svgParse->global.h = 0;
doc->preserveAspect = true;
- simpleXmlParseAttributes(buf, bufLength, _attrParseSvgNode, loader);
+ func(buf, bufLength, _attrParseSvgNode, loader);
if (loader->svgParse->global.w == 0) {
if (doc->w < FLT_EPSILON) loader->svgParse->global.w = 1;
@@ -1167,32 +1258,60 @@ static SvgNode* _createSvgNode(SvgLoaderData* loader, SvgNode* parent, const cha
}
-static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength)
+static SvgNode* _createMaskNode(SvgLoaderData* loader, SvgNode* parent, TVG_UNUSED const char* buf, TVG_UNUSED unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Mask);
if (!loader->svgParse->node) return nullptr;
- loader->svgParse->node->node.comp.userSpace = true;
+ loader->svgParse->node->node.mask.userSpace = true;
+ loader->svgParse->node->node.mask.type = SvgMaskType::Luminance;
- simpleXmlParseAttributes(buf, bufLength, _attrParseMaskNode, loader);
+ func(buf, bufLength, _attrParseMaskNode, loader);
return loader->svgParse->node;
}
-static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createClipPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::ClipPath);
if (!loader->svgParse->node) return nullptr;
loader->svgParse->node->display = false;
- loader->svgParse->node->node.comp.userSpace = true;
+ loader->svgParse->node->node.clip.userSpace = true;
+
+ func(buf, bufLength, _attrParseClipPathNode, loader);
+
+ return loader->svgParse->node;
+}
+
+
+static SvgNode* _createCssStyleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
+{
+ loader->svgParse->node = _createNode(parent, SvgNodeType::CssStyle);
+ if (!loader->svgParse->node) return nullptr;
+
+ func(buf, bufLength, _attrParseCssStyleNode, loader);
+
+ return loader->svgParse->node;
+}
+
+
+static SvgNode* _createSymbolNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
+{
+ loader->svgParse->node = _createNode(parent, SvgNodeType::Symbol);
+ if (!loader->svgParse->node) return nullptr;
+
+ loader->svgParse->node->display = false;
+ loader->svgParse->node->node.symbol.preserveAspect = true;
+ loader->svgParse->node->node.symbol.overflowVisible = false;
- simpleXmlParseAttributes(buf, bufLength, _attrParseClipPathNode, loader);
+ func(buf, bufLength, _attrParseSymbolNode, loader);
return loader->svgParse->node;
}
+
static bool _attrParsePathNode(void* data, const char* key, const char* value)
{
SvgLoaderData* loader = (SvgLoaderData*)data;
@@ -1203,7 +1322,7 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value)
//Temporary: need to copy
path->path = _copyId(value);
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1211,6 +1330,8 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value)
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else {
return _parseStyleAttr(loader, key, value, false);
}
@@ -1218,13 +1339,13 @@ static bool _attrParsePathNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createPathNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Path);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParsePathNode, loader);
+ func(buf, bufLength, _attrParsePathNode, loader);
return loader->svgParse->node;
}
@@ -1263,7 +1384,7 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value)
}
if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1271,6 +1392,8 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value)
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else {
return _parseStyleAttr(loader, key, value, false);
}
@@ -1278,13 +1401,13 @@ static bool _attrParseCircleNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createCircleNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Circle);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseCircleNode, loader);
+ func(buf, bufLength, _attrParseCircleNode, loader);
return loader->svgParse->node;
}
@@ -1325,8 +1448,10 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value
if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1338,13 +1463,13 @@ static bool _attrParseEllipseNode(void* data, const char* key, const char* value
}
-static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createEllipseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Ellipse);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseEllipseNode, loader);
+ func(buf, bufLength, _attrParseEllipseNode, loader);
return loader->svgParse->node;
}
@@ -1400,7 +1525,7 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value
if (!strcmp(key, "points")) {
return _attrParsePolygonPoints(value, &polygon->points, &polygon->pointsCount);
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1408,6 +1533,8 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else {
return _parseStyleAttr(loader, key, value, false);
}
@@ -1415,24 +1542,24 @@ static bool _attrParsePolygonNode(void* data, const char* key, const char* value
}
-static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createPolygonNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Polygon);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader);
+ func(buf, bufLength, _attrParsePolygonNode, loader);
return loader->svgParse->node;
}
-static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createPolylineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Polyline);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParsePolygonNode, loader);
+ func(buf, bufLength, _attrParsePolygonNode, loader);
return loader->svgParse->node;
}
@@ -1482,8 +1609,10 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value)
if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "style")) {
- ret = simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ ret = simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1496,7 +1625,7 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Rect);
@@ -1504,7 +1633,7 @@ static SvgNode* _createRectNode(SvgLoaderData* loader, SvgNode* parent, const ch
loader->svgParse->node->node.rect.hasRx = loader->svgParse->node->node.rect.hasRy = false;
- simpleXmlParseAttributes(buf, bufLength, _attrParseRectNode, loader);
+ func(buf, bufLength, _attrParseRectNode, loader);
return loader->svgParse->node;
}
@@ -1545,8 +1674,10 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value)
if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
@@ -1558,13 +1689,13 @@ static bool _attrParseLineNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createLineNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Line);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseLineNode, loader);
+ func(buf, bufLength, _attrParseLineNode, loader);
return loader->svgParse->node;
}
@@ -1611,16 +1742,21 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value)
}
if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (image->href && value) free(image->href);
image->href = _idFromHref(value);
} else if (!strcmp(key, "id")) {
if (node->id && value) free(node->id);
node->id = _copyId(value);
+ } else if (!strcmp(key, "class")) {
+ _handleCssClassAttr(loader, node, value);
} else if (!strcmp(key, "style")) {
- return simpleXmlParseW3CAttribute(value, _parseStyleAttr, loader);
+ return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader);
} else if (!strcmp(key, "clip-path")) {
_handleClipPathAttr(loader, node, value);
} else if (!strcmp(key, "mask")) {
_handleMaskAttr(loader, node, value);
+ } else if (!strcmp(key, "transform")) {
+ node->transform = _parseTransformationMatrix(value);
} else {
return _parseStyleAttr(loader, key, value);
}
@@ -1628,13 +1764,13 @@ static bool _attrParseImageNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createImageNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Image);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseImageNode, loader);
+ func(buf, bufLength, _attrParseImageNode, loader);
return loader->svgParse->node;
}
@@ -1728,6 +1864,112 @@ error_grad_alloc:
}
+static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
+{
+ if (parent == nullptr) return;
+ //Inherit the property of parent if not present in child.
+ if (!child->curColorSet) {
+ child->color = parent->color;
+ child->curColorSet = parent->curColorSet;
+ }
+ //Fill
+ if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
+ child->fill.paint.color = parent->fill.paint.color;
+ child->fill.paint.none = parent->fill.paint.none;
+ child->fill.paint.curColor = parent->fill.paint.curColor;
+ if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
+ }
+ if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
+ child->fill.opacity = parent->fill.opacity;
+ }
+ if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
+ child->fill.fillRule = parent->fill.fillRule;
+ }
+ //Stroke
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
+ child->stroke.paint.color = parent->stroke.paint.color;
+ child->stroke.paint.none = parent->stroke.paint.none;
+ child->stroke.paint.curColor = parent->stroke.paint.curColor;
+ child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
+ child->stroke.opacity = parent->stroke.opacity;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
+ child->stroke.width = parent->stroke.width;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
+ if (parent->stroke.dash.array.count > 0) {
+ child->stroke.dash.array.clear();
+ child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
+ for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
+ child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
+ }
+ }
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
+ child->stroke.cap = parent->stroke.cap;
+ }
+ if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
+ child->stroke.join = parent->stroke.join;
+ }
+}
+
+
+static void _styleCopy(SvgStyleProperty* to, const SvgStyleProperty* from)
+{
+ if (from == nullptr) return;
+ //Copy the properties of 'from' only if they were explicitly set (not the default ones).
+ if (from->curColorSet) {
+ to->color = from->color;
+ to->curColorSet = true;
+ }
+ //Fill
+ to->fill.flags = (SvgFillFlags)((int)to->fill.flags | (int)from->fill.flags);
+ if (((int)from->fill.flags & (int)SvgFillFlags::Paint)) {
+ to->fill.paint.color = from->fill.paint.color;
+ to->fill.paint.none = from->fill.paint.none;
+ to->fill.paint.curColor = from->fill.paint.curColor;
+ if (from->fill.paint.url) to->fill.paint.url = _copyId(from->fill.paint.url);
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::Opacity)) {
+ to->fill.opacity = from->fill.opacity;
+ }
+ if (((int)from->fill.flags & (int)SvgFillFlags::FillRule)) {
+ to->fill.fillRule = from->fill.fillRule;
+ }
+ //Stroke
+ to->stroke.flags = (SvgStrokeFlags)((int)to->stroke.flags | (int)from->stroke.flags);
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Paint)) {
+ to->stroke.paint.color = from->stroke.paint.color;
+ to->stroke.paint.none = from->stroke.paint.none;
+ to->stroke.paint.curColor = from->stroke.paint.curColor;
+ to->stroke.paint.url = from->stroke.paint.url ? _copyId(from->stroke.paint.url) : nullptr;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
+ to->stroke.opacity = from->stroke.opacity;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Width)) {
+ to->stroke.width = from->stroke.width;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Dash)) {
+ if (from->stroke.dash.array.count > 0) {
+ to->stroke.dash.array.clear();
+ to->stroke.dash.array.reserve(from->stroke.dash.array.count);
+ for (uint32_t i = 0; i < from->stroke.dash.array.count; ++i) {
+ to->stroke.dash.array.push(from->stroke.dash.array.data[i]);
+ }
+ }
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Cap)) {
+ to->stroke.cap = from->stroke.cap;
+ }
+ if (((int)from->stroke.flags & (int)SvgStrokeFlags::Join)) {
+ to->stroke.join = from->stroke.join;
+ }
+}
+
+
static void _copyAttr(SvgNode* to, const SvgNode* from)
{
//Copy matrix attribute
@@ -1736,7 +1978,8 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
if (to->transform) *to->transform = *from->transform;
}
//Copy style attribute
- *to->style = *from->style;
+ _styleCopy(to->style, from->style);
+ to->style->flags = (SvgStyleFlags)((int)to->style->flags | (int)from->style->flags);
if (from->style->fill.paint.url) to->style->fill.paint.url = strdup(from->style->fill.paint.url);
if (from->style->stroke.paint.url) to->style->stroke.paint.url = strdup(from->style->stroke.paint.url);
if (from->style->clipPath.url) to->style->clipPath.url = strdup(from->style->clipPath.url);
@@ -1780,15 +2023,17 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
break;
}
case SvgNodeType::Polygon: {
- to->node.polygon.pointsCount = from->node.polygon.pointsCount;
- to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
- memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
+ if ((to->node.polygon.pointsCount = from->node.polygon.pointsCount)) {
+ to->node.polygon.points = (float*)malloc(to->node.polygon.pointsCount * sizeof(float));
+ memcpy(to->node.polygon.points, from->node.polygon.points, to->node.polygon.pointsCount * sizeof(float));
+ }
break;
}
case SvgNodeType::Polyline: {
- to->node.polyline.pointsCount = from->node.polyline.pointsCount;
- to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
- memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
+ if ((to->node.polyline.pointsCount = from->node.polyline.pointsCount)) {
+ to->node.polyline.points = (float*)malloc(to->node.polyline.pointsCount * sizeof(float));
+ memcpy(to->node.polyline.points, from->node.polyline.points, to->node.polyline.pointsCount * sizeof(float));
+ }
break;
}
case SvgNodeType::Image: {
@@ -1806,35 +2051,42 @@ static void _copyAttr(SvgNode* to, const SvgNode* from)
}
-static void _cloneNode(SvgNode* from, SvgNode* parent)
+static void _cloneNode(SvgNode* from, SvgNode* parent, int depth)
{
+ /* Exception handling: Prevent invalid SVG data input.
+ The size is the arbitrary value, we need an experimental size. */
+ if (depth == 8192) {
+ TVGERR("SVG", "Infinite recursive call - stopped after %d calls! Svg file may be incorrectly formatted.", depth);
+ return;
+ }
+
SvgNode* newNode;
- if (!from || !parent) return;
+ if (!from || !parent || from == parent) return;
newNode = _createNode(parent, from->type);
-
if (!newNode) return;
+ _styleInherit(newNode->style, parent->style);
_copyAttr(newNode, from);
auto child = from->child.data;
for (uint32_t i = 0; i < from->child.count; ++i, ++child) {
- _cloneNode(*child, newNode);
+ _cloneNode(*child, newNode, depth + 1);
}
}
-static void _postponeCloneNode(SvgLoaderData* loader, SvgNode *node, char* id) {
- loader->cloneNodes.push({node, id});
-}
-
-
-static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes) {
+static void _clonePostponedNodes(Array<SvgNodeIdPair>* cloneNodes, SvgNode* doc)
+{
for (uint32_t i = 0; i < cloneNodes->count; ++i) {
auto nodeIdPair = cloneNodes->data[i];
auto defs = _getDefsNode(nodeIdPair.node);
auto nodeFrom = _findChildById(defs, nodeIdPair.id);
- _cloneNode(nodeFrom, nodeIdPair.node);
+ if (!nodeFrom) nodeFrom = _findChildById(doc, nodeIdPair.id);
+ _cloneNode(nodeFrom, nodeIdPair.node, 0);
+ if (nodeFrom && nodeFrom->type == SvgNodeType::Symbol && nodeIdPair.node->type == SvgNodeType::Use) {
+ nodeIdPair.node->node.use.symbol = nodeFrom;
+ }
free(nodeIdPair.id);
}
}
@@ -1847,10 +2099,10 @@ static constexpr struct
int sz;
size_t offset;
} useTags[] = {
- {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgRectNode, x)},
- {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgRectNode, y)},
- {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgRectNode, w)},
- {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgRectNode, h)}
+ {"x", SvgParserLengthType::Horizontal, sizeof("x"), offsetof(SvgUseNode, x)},
+ {"y", SvgParserLengthType::Vertical, sizeof("y"), offsetof(SvgUseNode, y)},
+ {"width", SvgParserLengthType::Horizontal, sizeof("width"), offsetof(SvgUseNode, w)},
+ {"height", SvgParserLengthType::Vertical, sizeof("height"), offsetof(SvgUseNode, h)}
};
@@ -1866,6 +2118,10 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
for (unsigned int i = 0; i < sizeof(useTags) / sizeof(useTags[0]); i++) {
if (useTags[i].sz - 1 == sz && !strncmp(useTags[i].tag, key, sz)) {
*((float*)(array + useTags[i].offset)) = _toFloat(loader->svgParse, value, useTags[i].type);
+
+ if (useTags[i].offset == offsetof(SvgUseNode, w)) use->isWidthSet = true;
+ else if (useTags[i].offset == offsetof(SvgUseNode, h)) use->isHeightSet = true;
+
return true;
}
}
@@ -1875,18 +2131,15 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
defs = _getDefsNode(node);
nodeFrom = _findChildById(defs, id);
if (nodeFrom) {
- _cloneNode(nodeFrom, node);
+ _cloneNode(nodeFrom, node, 0);
+ if (nodeFrom->type == SvgNodeType::Symbol) use->symbol = nodeFrom;
free(id);
} else {
//some svg export software include <defs> element at the end of the file
//if so the 'from' element won't be found now and we have to repeat finding
//after the whole file is parsed
- _postponeCloneNode(loader, node, id);
+ _postpone(loader->cloneNodes, node, id);
}
- } else if (!strcmp(key, "clip-path")) {
- _handleClipPathAttr(loader, node, value);
- } else if (!strcmp(key, "mask")) {
- _handleMaskAttr(loader, node, value);
} else {
return _attrParseGNode(data, key, value);
}
@@ -1894,16 +2147,20 @@ static bool _attrParseUseNode(void* data, const char* key, const char* value)
}
-static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength)
+static SvgNode* _createUseNode(SvgLoaderData* loader, SvgNode* parent, const char* buf, unsigned bufLength, parseAttributes func)
{
loader->svgParse->node = _createNode(parent, SvgNodeType::Use);
if (!loader->svgParse->node) return nullptr;
- simpleXmlParseAttributes(buf, bufLength, _attrParseUseNode, loader);
+ loader->svgParse->node->node.use.isWidthSet = false;
+ loader->svgParse->node->node.use.isHeightSet = false;
+
+ func(buf, bufLength, _attrParseUseNode, loader);
return loader->svgParse->node;
}
+
//TODO: Implement 'text' primitive
static constexpr struct
{
@@ -1933,7 +2190,9 @@ static constexpr struct
{"g", sizeof("g"), _createGNode},
{"svg", sizeof("svg"), _createSvgNode},
{"mask", sizeof("mask"), _createMaskNode},
- {"clipPath", sizeof("clipPath"), _createClipPathNode}
+ {"clipPath", sizeof("clipPath"), _createClipPathNode},
+ {"style", sizeof("style"), _createCssStyleNode},
+ {"symbol", sizeof("symbol"), _createSymbolNode}
};
@@ -2081,13 +2340,15 @@ static bool _attrParseRadialGradientNode(void* data, const char* key, const char
}
if (!strcmp(key, "id")) {
+ if (grad->id && value) free(grad->id);
grad->id = _copyId(value);
} else if (!strcmp(key, "spreadMethod")) {
grad->spread = _parseSpreadValue(value);
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (grad->ref && value) free(grad->ref);
grad->ref = _idFromHref(value);
- } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
- grad->userSpace = true;
+ } else if (!strcmp(key, "gradientUnits")) {
+ if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true;
} else if (!strcmp(key, "gradientTransform")) {
grad->transform = _parseTransformationMatrix(value);
} else {
@@ -2173,7 +2434,7 @@ static bool _attrParseStops(void* data, const char* key, const char* value)
_toColor(value, &stop->r, &stop->g, &stop->b, nullptr);
}
} else if (!strcmp(key, "style")) {
- simpleXmlParseW3CAttribute(value, _attrParseStopsStyle, data);
+ simpleXmlParseW3CAttribute(value, strlen(value), _attrParseStopsStyle, data);
} else {
return false;
}
@@ -2269,13 +2530,15 @@ static bool _attrParseLinearGradientNode(void* data, const char* key, const char
}
if (!strcmp(key, "id")) {
+ if (grad->id && value) free(grad->id);
grad->id = _copyId(value);
} else if (!strcmp(key, "spreadMethod")) {
grad->spread = _parseSpreadValue(value);
} else if (!strcmp(key, "href") || !strcmp(key, "xlink:href")) {
+ if (grad->ref && value) free(grad->ref);
grad->ref = _idFromHref(value);
- } else if (!strcmp(key, "gradientUnits") && !strcmp(value, "userSpaceOnUse")) {
- grad->userSpace = true;
+ } else if (!strcmp(key, "gradientUnits")) {
+ if (!strcmp(value, "userSpaceOnUse")) grad->userSpace = true;
} else if (!strcmp(key, "gradientTransform")) {
grad->transform = _parseTransformationMatrix(value);
} else {
@@ -2359,11 +2622,13 @@ static constexpr struct
{"svg", sizeof("svg")},
{"defs", sizeof("defs")},
{"mask", sizeof("mask")},
- {"clipPath", sizeof("clipPath")}
+ {"clipPath", sizeof("clipPath")},
+ {"style", sizeof("style")},
+ {"symbol", sizeof("symbol")}
};
-static void _svgLoaderParerXmlClose(SvgLoaderData* loader, const char* content)
+static void _svgLoaderParserXmlClose(SvgLoaderData* loader, const char* content)
{
content = _skipSpace(content, nullptr);
@@ -2408,15 +2673,23 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
if ((method = _findGroupFactory(tagName))) {
//Group
+ if (empty) return;
if (!loader->doc) {
if (strcmp(tagName, "svg")) return; //Not a valid svg document
- node = method(loader, nullptr, attrs, attrsLength);
+ node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes);
loader->doc = node;
} else {
if (!strcmp(tagName, "svg")) return; //Already loaded <svg>(SvgNodeType::Doc) tag
if (loader->stack.count > 0) parent = loader->stack.data[loader->stack.count - 1];
else parent = loader->doc;
- node = method(loader, parent, attrs, attrsLength);
+ if (!strcmp(tagName, "style")) {
+ node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes);
+ loader->cssStyle = node;
+ loader->doc->node.doc.style = node;
+ loader->style = true;
+ } else {
+ node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes);
+ }
}
if (!node) return;
@@ -2426,7 +2699,7 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
} else if ((method = _findGraphicsFactory(tagName))) {
if (loader->stack.count > 0) parent = loader->stack.data[loader->stack.count - 1];
else parent = loader->doc;
- node = method(loader, parent, attrs, attrsLength);
+ node = method(loader, parent, attrs, attrsLength, simpleXmlParseAttributes);
} else if ((gradientMethod = _findGradientFactory(tagName))) {
SvgStyleGradient* gradient;
gradient = gradientMethod(loader, attrs, attrsLength);
@@ -2457,6 +2730,42 @@ static void _svgLoaderParserXmlOpen(SvgLoaderData* loader, const char* content,
}
+static void _svgLoaderParserXmlCssStyle(SvgLoaderData* loader, const char* content, unsigned int length)
+{
+ char* tag;
+ char* name;
+ const char* attrs = nullptr;
+ unsigned int attrsLength = 0;
+
+ FactoryMethod method;
+ GradientFactoryMethod gradientMethod;
+ SvgNode *node = nullptr;
+
+ while (auto next = simpleXmlParseCSSAttribute(content, length, &tag, &name, &attrs, &attrsLength)) {
+ if ((method = _findGroupFactory(tag))) {
+ if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name);
+ } else if ((method = _findGraphicsFactory(tag))) {
+ if ((node = method(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name);
+ } else if ((gradientMethod = _findGradientFactory(tag))) {
+ TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag);
+ } else if (!strcmp(tag, "stop")) {
+ TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag);
+ } else if (!strcmp(tag, "all")) {
+ if ((node = _createCssStyleNode(loader, loader->cssStyle, attrs, attrsLength, simpleXmlParseW3CAttribute))) node->id = _copyId(name);
+ } else if (!isIgnoreUnsupportedLogElements(tag)) {
+ TVGLOG("SVG", "Unsupported elements used in the internal CSS style sheets [Elements: %s]", tag);
+ }
+
+ length -= next - content;
+ content = next;
+
+ free(tag);
+ free(name);
+ }
+ loader->style = false;
+}
+
+
static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content, unsigned int length)
{
SvgLoaderData* loader = (SvgLoaderData*)data;
@@ -2471,11 +2780,14 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content
break;
}
case SimpleXMLType::Close: {
- _svgLoaderParerXmlClose(loader, content);
+ _svgLoaderParserXmlClose(loader, content);
break;
}
case SimpleXMLType::Data:
- case SimpleXMLType::CData:
+ case SimpleXMLType::CData: {
+ if (loader->style) _svgLoaderParserXmlCssStyle(loader, content, length);
+ break;
+ }
case SimpleXMLType::DoctypeChild: {
break;
}
@@ -2493,63 +2805,12 @@ static bool _svgLoaderParser(void* data, SimpleXMLType type, const char* content
}
-static void _styleInherit(SvgStyleProperty* child, const SvgStyleProperty* parent)
+static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node)
{
- if (parent == nullptr) return;
- //Inherit the property of parent if not present in child.
- //Fill
- if (!((int)child->fill.flags & (int)SvgFillFlags::Paint)) {
- child->fill.paint.color = parent->fill.paint.color;
- child->fill.paint.none = parent->fill.paint.none;
- child->fill.paint.curColor = parent->fill.paint.curColor;
- if (parent->fill.paint.url) child->fill.paint.url = _copyId(parent->fill.paint.url);
- } else if (child->fill.paint.curColor && !child->curColorSet) {
- child->color = parent->color;
- }
- if (!((int)child->fill.flags & (int)SvgFillFlags::Opacity)) {
- child->fill.opacity = parent->fill.opacity;
- }
- if (!((int)child->fill.flags & (int)SvgFillFlags::FillRule)) {
- child->fill.fillRule = parent->fill.fillRule;
- }
- //Stroke
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Paint)) {
- child->stroke.paint.color = parent->stroke.paint.color;
- child->stroke.paint.none = parent->stroke.paint.none;
- child->stroke.paint.curColor = parent->stroke.paint.curColor;
- child->stroke.paint.url = parent->stroke.paint.url ? _copyId(parent->stroke.paint.url) : nullptr;
- } else if (child->stroke.paint.curColor && !child->curColorSet) {
- child->color = parent->color;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Opacity)) {
- child->stroke.opacity = parent->stroke.opacity;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Width)) {
- child->stroke.width = parent->stroke.width;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Dash)) {
- if (parent->stroke.dash.array.count > 0) {
- child->stroke.dash.array.clear();
- child->stroke.dash.array.reserve(parent->stroke.dash.array.count);
- for (uint32_t i = 0; i < parent->stroke.dash.array.count; ++i) {
- child->stroke.dash.array.push(parent->stroke.dash.array.data[i]);
- }
- }
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Cap)) {
- child->stroke.cap = parent->stroke.cap;
- }
- if (!((int)child->stroke.flags & (int)SvgStrokeFlags::Join)) {
- child->stroke.join = parent->stroke.join;
- }
-}
-
-
-static void _inefficientNodeCheck(TVG_UNUSED SvgNode* node){
#ifdef THORVG_LOG_ENABLED
auto type = simpleXmlNodeTypeToString(node->type);
- if (!node->display && node->type != SvgNodeType::ClipPath) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type);
+ if (!node->display && node->type != SvgNodeType::ClipPath && node->type != SvgNodeType::Symbol) TVGLOG("SVG", "Inefficient elements used [Display is none][Node Type : %s]", type);
if (node->style->opacity == 0) TVGLOG("SVG", "Inefficient elements used [Opacity is zero][Node Type : %s]", type);
if (node->style->fill.opacity == 0 && node->style->stroke.opacity == 0) TVGLOG("SVG", "Inefficient elements used [Fill opacity and stroke opacity are zero][Node Type : %s]", type);
@@ -2679,6 +2940,7 @@ static void _freeNodeStyle(SvgStyleProperty* style)
//style->clipPath.node and style->mask.node has only the addresses of node. Therefore, node is released from _freeNode.
free(style->clipPath.url);
free(style->mask.url);
+ free(style->cssClass);
if (style->fill.paint.gradient) {
style->fill.paint.gradient->clear();
@@ -2723,6 +2985,7 @@ static void _freeNode(SvgNode* node)
}
case SvgNodeType::Doc: {
_freeNode(node->node.doc.defs);
+ _freeNode(node->node.doc.style);
break;
}
case SvgNodeType::Defs: {
@@ -2776,7 +3039,7 @@ static bool _svgLoaderParserForValidCheckXmlOpen(SvgLoaderData* loader, const ch
if ((method = _findGroupFactory(tagName))) {
if (!loader->doc) {
if (strcmp(tagName, "svg")) return true; //Not a valid svg document
- node = method(loader, nullptr, attrs, attrsLength);
+ node = method(loader, nullptr, attrs, attrsLength, simpleXmlParseAttributes);
loader->doc = node;
loader->stack.push(node);
return false;
@@ -2836,16 +3099,20 @@ void SvgLoader::run(unsigned tid)
if (!simpleXmlParse(content, size, true, _svgLoaderParser, &(loaderData))) return;
if (loaderData.doc) {
- _updateStyle(loaderData.doc, nullptr);
auto defs = loaderData.doc->node.doc.defs;
- if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
- if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
+ if (loaderData.nodesToStyle.count > 0) cssApplyStyleToPostponeds(loaderData.nodesToStyle, loaderData.cssStyle);
+ if (loaderData.cssStyle) cssUpdateStyle(loaderData.doc, loaderData.cssStyle);
+
+ if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes, loaderData.doc);
_updateComposite(loaderData.doc, loaderData.doc);
if (defs) _updateComposite(loaderData.doc, defs);
- if (loaderData.cloneNodes.count > 0) _clonePostponedNodes(&loaderData.cloneNodes);
+ if (loaderData.gradients.count > 0) _updateGradient(loaderData.doc, &loaderData.gradients);
+ if (defs) _updateGradient(loaderData.doc, &defs->node.defs.gradients);
+
+ _updateStyle(loaderData.doc, nullptr);
}
root = svgSceneBuild(loaderData.doc, vx, vy, vw, vh, w, h, preserveAspect, svgPath);
}
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h
index 468f05801d..093fb671b3 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h
index cceef915f0..1f25e82adc 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoaderCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -51,6 +51,8 @@ enum class SvgNodeType
Video,
ClipPath,
Mask,
+ CssStyle,
+ Symbol,
Unknown
};
@@ -111,7 +113,8 @@ enum class SvgStyleFlags
Transform = 0x800,
ClipPath = 0x1000,
Mask = 0x2000,
- Display = 0x4000
+ MaskType = 0x4000,
+ Display = 0x8000
};
enum class SvgStopStyleFlags
@@ -127,6 +130,12 @@ enum class SvgFillRule
OddEven = 1
};
+enum class SvgMaskType
+{
+ Luminance = 0,
+ Alpha
+};
+
//Length type to recalculate %, pt, pc, mm, cm etc
enum class SvgParserLengthType
{
@@ -145,6 +154,7 @@ struct SvgDocNode
float vw;
float vh;
SvgNode* defs;
+ SvgNode* style;
bool preserveAspect;
};
@@ -157,12 +167,22 @@ struct SvgDefsNode
Array<SvgStyleGradient*> gradients;
};
+struct SvgSymbolNode
+{
+ float w, h;
+ float vx, vy, vw, vh;
+ bool preserveAspect;
+ bool overflowVisible;
+};
+
struct SvgUseNode
{
float x, y, w, h;
+ bool isWidthSet;
+ bool isHeightSet;
+ SvgNode* symbol;
};
-
struct SvgEllipseNode
{
float cx;
@@ -215,11 +235,21 @@ struct SvgPolygonNode
float* points;
};
-struct SvgCompositeNode
+struct SvgClipNode
{
bool userSpace;
};
+struct SvgMaskNode
+{
+ SvgMaskType type;
+ bool userSpace;
+};
+
+struct SvgCssStyleNode
+{
+};
+
struct SvgLinearGradient
{
float x1;
@@ -328,6 +358,7 @@ struct SvgStyleProperty
int opacity;
SvgColor color;
bool curColorSet;
+ char* cssClass;
SvgStyleFlags flags;
};
@@ -352,7 +383,10 @@ struct SvgNode
SvgPathNode path;
SvgLineNode line;
SvgImageNode image;
- SvgCompositeNode comp;
+ SvgMaskNode mask;
+ SvgClipNode clip;
+ SvgCssStyleNode cssStyle;
+ SvgSymbolNode symbol;
} node;
bool display;
~SvgNode();
@@ -384,15 +418,18 @@ struct SvgNodeIdPair
struct SvgLoaderData
{
- Array<SvgNode *> stack = {nullptr, 0, 0};
+ Array<SvgNode*> stack = {nullptr, 0, 0};
SvgNode* doc = nullptr;
SvgNode* def = nullptr;
+ SvgNode* cssStyle = nullptr;
Array<SvgStyleGradient*> gradients;
SvgStyleGradient* latestGradient = nullptr; //For stops
SvgParser* svgParse = nullptr;
Array<SvgNodeIdPair> cloneNodes;
+ Array<SvgNodeIdPair> nodesToStyle;
int level = 0;
bool result = false;
+ bool style = false;
};
/*
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
index 32685ee620..a09a2797d0 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h
index 7f26c4a213..8f5f9035dc 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgPath.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
index ae17634f31..90705f2523 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -68,12 +68,12 @@ struct Box
static bool _appendShape(SvgNode* node, Shape* shape, const Box& vBox, const string& svgPath);
-static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask);
+static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite = nullptr);
static inline bool _isGroupType(SvgNodeType type)
{
- if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath) return true;
+ if (type == SvgNodeType::Doc || type == SvgNodeType::G || type == SvgNodeType::Use || type == SvgNodeType::ClipPath || type == SvgNodeType::Symbol) return true;
return false;
}
@@ -276,15 +276,21 @@ static void _applyComposition(Paint* paint, const SvgNode* node, const Box& vBox
Composition can be applied recursively if its children nodes have composition target to this one. */
if (node->style->mask.applying) {
TVGLOG("SVG", "Multiple Composition Tried! Check out Circular dependency?");
- } else {
+ } else {
auto compNode = node->style->mask.node;
if (compNode && compNode->child.count > 0) {
node->style->mask.applying = true;
- auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true);
+ bool isMaskWhite = true;
+ auto comp = _sceneBuildHelper(compNode, vBox, svgPath, true, &isMaskWhite);
if (comp) {
if (node->transform) comp->transform(*node->transform);
- paint->composite(move(comp), CompositeMethod::AlphaMask);
+
+ if (compNode->node.mask.type == SvgMaskType::Luminance && !isMaskWhite) {
+ paint->composite(move(comp), CompositeMethod::LumaMask);
+ } else {
+ paint->composite(move(comp), CompositeMethod::AlphaMask);
+ }
}
node->style->mask.applying = false;
@@ -534,57 +540,137 @@ static unique_ptr<Picture> _imageBuildHelper(SvgNode* node, const Box& vBox, con
string imagePath = href;
if (strncmp(href, "/", 1)) {
auto last = svgPath.find_last_of("/");
- imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1 )) + imagePath;
+ imagePath = svgPath.substr(0, (last == string::npos ? 0 : last + 1)) + imagePath;
}
if (picture->load(imagePath) != Result::Success) return nullptr;
}
float w, h;
+ Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1};
if (picture->size(&w, &h) == Result::Success && w > 0 && h > 0) {
auto sx = node->node.image.w / w;
auto sy = node->node.image.h / h;
- Matrix m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1};
- picture->transform(m);
+ m = {sx, 0, node->node.image.x, 0, sy, node->node.image.y, 0, 0, 1};
}
+ if (node->transform) m = mathMultiply(node->transform, &m);
+ picture->transform(m);
_applyComposition(picture.get(), node, vBox, svgPath);
return picture;
}
-static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath)
+static unique_ptr<Scene> _useBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool* isMaskWhite)
{
- auto scene = _sceneBuildHelper(node, vBox, svgPath, false);
+ unique_ptr<Scene> finalScene;
+ auto scene = _sceneBuildHelper(node, vBox, svgPath, false, isMaskWhite);
+
+ // mUseTransform = mUseTransform * mTranslate
+ Matrix mUseTransform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+ if (node->transform) mUseTransform = *node->transform;
if (node->node.use.x != 0.0f || node->node.use.y != 0.0f) {
- scene->translate(node->node.use.x, node->node.use.y);
+ Matrix mTranslate = {1, 0, node->node.use.x, 0, 1, node->node.use.y, 0, 0, 1};
+ mUseTransform = mathMultiply(&mUseTransform, &mTranslate);
}
- if (node->node.use.w > 0.0f && node->node.use.h > 0.0f) {
- //TODO: handle width/height properties
+
+ if (node->node.use.symbol) {
+ auto symbol = node->node.use.symbol->node.symbol;
+
+ auto width = symbol.w;
+ if (node->node.use.isWidthSet) width = node->node.use.w;
+ auto height = symbol.h;
+ if (node->node.use.isHeightSet) height = node->node.use.h;
+
+ Matrix mViewBox = {1, 0, 0, 0, 1, 0, 0, 0, 1};
+ if ((!mathEqual(width, symbol.vw) || !mathEqual(height, symbol.vh)) && symbol.vw > 0 && symbol.vh > 0) {
+ auto sx = width / symbol.vw;
+ auto sy = height / symbol.vh;
+ if (symbol.preserveAspect) {
+ if (sx < sy) sy = sx;
+ else sx = sy;
+ }
+
+ auto tvx = symbol.vx * sx;
+ auto tvy = symbol.vy * sy;
+ auto tvw = symbol.vw * sx;
+ auto tvh = symbol.vh * sy;
+ tvy -= (symbol.h - tvh) * 0.5f;
+ tvx -= (symbol.w - tvw) * 0.5f;
+ mViewBox = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1};
+ } else if (!mathZero(symbol.vx) || !mathZero(symbol.vy)) {
+ mViewBox = {1, 0, -symbol.vx, 0, 1, -symbol.vy, 0, 0, 1};
+ }
+
+ // mSceneTransform = mUseTransform * mSymbolTransform * mViewBox
+ Matrix mSceneTransform = mViewBox;
+ if (node->node.use.symbol->transform) {
+ mSceneTransform = mathMultiply(node->node.use.symbol->transform, &mViewBox);
+ }
+ mSceneTransform = mathMultiply(&mUseTransform, &mSceneTransform);
+ scene->transform(mSceneTransform);
+
+ if (node->node.use.symbol->node.symbol.overflowVisible) {
+ finalScene = move(scene);
+ } else {
+ auto viewBoxClip = Shape::gen();
+ viewBoxClip->appendRect(0, 0, width, height, 0, 0);
+
+ // mClipTransform = mUseTransform * mSymbolTransform
+ Matrix mClipTransform = mUseTransform;
+ if (node->node.use.symbol->transform) {
+ mClipTransform = mathMultiply(&mUseTransform, node->node.use.symbol->transform);
+ }
+ viewBoxClip->transform(mClipTransform);
+
+ auto compositeLayer = Scene::gen();
+ compositeLayer->composite(move(viewBoxClip), CompositeMethod::ClipPath);
+ compositeLayer->push(move(scene));
+
+ auto root = Scene::gen();
+ root->push(move(compositeLayer));
+
+ finalScene = move(root);
+ }
+ } else {
+ if (!mathIdentity((const Matrix*)(&mUseTransform))) scene->transform(mUseTransform);
+ finalScene = move(scene);
}
- return scene;
+
+ return finalScene;
}
-static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask)
+static unique_ptr<Scene> _sceneBuildHelper(const SvgNode* node, const Box& vBox, const string& svgPath, bool mask, bool* isMaskWhite)
{
if (_isGroupType(node->type) || mask) {
auto scene = Scene::gen();
- if (!mask && node->transform) scene->transform(*node->transform);
+ // For a Symbol node, the viewBox transformation has to be applied first - see _useBuildHelper()
+ if (!mask && node->transform && node->type != SvgNodeType::Symbol) scene->transform(*node->transform);
if (node->display && node->style->opacity != 0) {
auto child = node->child.data;
for (uint32_t i = 0; i < node->child.count; ++i, ++child) {
if (_isGroupType((*child)->type)) {
if ((*child)->type == SvgNodeType::Use)
- scene->push(_useBuildHelper(*child, vBox, svgPath));
+ scene->push(_useBuildHelper(*child, vBox, svgPath, isMaskWhite));
else
- scene->push(_sceneBuildHelper(*child, vBox, svgPath, false));
+ scene->push(_sceneBuildHelper(*child, vBox, svgPath, false, isMaskWhite));
} else if ((*child)->type == SvgNodeType::Image) {
auto image = _imageBuildHelper(*child, vBox, svgPath);
if (image) scene->push(move(image));
} else if ((*child)->type != SvgNodeType::Mask) {
auto shape = _shapeBuildHelper(*child, vBox, svgPath);
- if (shape) scene->push(move(shape));
+ if (shape) {
+ if (isMaskWhite) {
+ uint8_t r, g, b;
+ shape->fillColor(&r, &g, &b, nullptr);
+ if (shape->fill() || r < 255 || g < 255 || b < 255 || shape->strokeFill() ||
+ (shape->strokeColor(&r, &g, &b, nullptr) == Result::Success && (r < 255 || g < 255 || b < 255))) {
+ *isMaskWhite = false;
+ }
+ }
+ scene->push(move(shape));
+ }
}
}
_applyComposition(scene.get(), node, vBox, svgPath);
@@ -620,17 +706,13 @@ unique_ptr<Scene> svgSceneBuild(SvgNode* node, float vx, float vy, float vw, flo
auto tvy = vy * scale;
auto tvw = vw * scale;
auto tvh = vh * scale;
- if (vw > vh) tvy -= (h - tvh) * 0.5f;
- else tvx -= (w - tvw) * 0.5f;
+ tvx -= (w - tvw) * 0.5f;
+ tvy -= (h - tvh) * 0.5f;
docNode->translate(-tvx, -tvy);
} else {
//Align
auto tvx = vx * sx;
auto tvy = vy * sy;
- auto tvw = vw * sx;
- auto tvh = vh * sy;
- if (tvw > tvh) tvy -= (h - tvh) * 0.5f;
- else tvx -= (w - tvw) * 0.5f;
Matrix m = {sx, 0, -tvx, 0, sy, -tvy, 0, 0, 1};
docNode->transform(m);
}
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h
index 4232aca612..cecbbf02a8 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgSceneBuilder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
index 9f269b29a2..1f1fe2a718 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h
index 4320cfed4e..b5e6e1bdb2 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgUtil.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
index 1571aa4e25..a12689c7dd 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
+++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -220,15 +220,15 @@ static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &to
if ((itr + sizeof("<!DOCTYPE>") - 1 < itrEnd) && (!memcmp(itr + 2, "DOCTYPE", sizeof("DOCTYPE") - 1)) && ((itr[2 + sizeof("DOCTYPE") - 1] == '>') || (isspace((unsigned char)itr[2 + sizeof("DOCTYPE") - 1])))) {
toff = sizeof("!DOCTYPE") - 1;
return SimpleXMLType::Doctype;
- } else if (itr + sizeof("<!>") - 1 < itrEnd) {
- toff = sizeof("!") - 1;
- return SimpleXMLType::DoctypeChild;
} else if ((itr + sizeof("<![CDATA[]]>") - 1 < itrEnd) && (!memcmp(itr + 2, "[CDATA[", sizeof("[CDATA[") - 1))) {
toff = sizeof("![CDATA[") - 1;
return SimpleXMLType::CData;
} else if ((itr + sizeof("<!---->") - 1 < itrEnd) && (!memcmp(itr + 2, "--", sizeof("--") - 1))) {
toff = sizeof("!--") - 1;
return SimpleXMLType::Comment;
+ } else if (itr + sizeof("<!>") - 1 < itrEnd) {
+ toff = sizeof("!") - 1;
+ return SimpleXMLType::DoctypeChild;
}
return SimpleXMLType::Open;
}
@@ -236,6 +236,14 @@ static SimpleXMLType _getXMLType(const char* itr, const char* itrEnd, size_t &to
}
+static char* _strndup(const char* src, unsigned len)
+{
+ auto ret = (char*)malloc(len + 1);
+ if (!ret) return nullptr;
+ ret[len] = '\0';
+ return (char*)memcpy(ret, src, len);
+}
+
/************************************************************************/
/* External Class Implementation */
/************************************************************************/
@@ -264,6 +272,7 @@ const char* simpleXmlNodeTypeToString(TVG_UNUSED SvgNodeType type)
"Video",
"ClipPath",
"Mask",
+ "Symbol",
"Unknown",
};
return TYPE_NAMES[(int) type];
@@ -450,7 +459,7 @@ bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb
}
-bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data)
+bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data)
{
const char* end;
char* key;
@@ -459,7 +468,7 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons
if (!buf) return false;
- end = buf + strlen(buf);
+ end = buf + bufLength;
key = (char*)alloca(end - buf + 1);
val = (char*)alloca(end - buf + 1);
@@ -468,6 +477,11 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons
do {
char* sep = (char*)strchr(buf, ':');
next = (char*)strchr(buf, ';');
+ if (sep >= end) {
+ next = nullptr;
+ sep = nullptr;
+ }
+ if (next >= end) next = nullptr;
key[0] = '\0';
val[0] = '\0';
@@ -509,6 +523,47 @@ bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, cons
}
+/*
+ * Supported formats:
+ * tag {}, .name {}, tag.name{}
+ */
+const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char** tag, char** name, const char** attrs, unsigned* attrsLength)
+{
+ if (!buf) return nullptr;
+
+ *tag = *name = nullptr;
+ *attrsLength = 0;
+
+ auto itr = _simpleXmlSkipWhiteSpace(buf, buf + bufLength);
+ auto itrEnd = (const char*)memchr(buf, '{', bufLength);
+
+ if (!itrEnd || itr == itrEnd) return nullptr;
+
+ auto nextElement = (const char*)memchr(itrEnd, '}', bufLength - (itrEnd - buf));
+ if (!nextElement) return nullptr;
+
+ *attrs = itrEnd + 1;
+ *attrsLength = nextElement - *attrs;
+
+ const char *p;
+
+ itrEnd = _simpleXmlUnskipWhiteSpace(itrEnd, itr);
+ if (*(itrEnd - 1) == '.') return nullptr;
+
+ for (p = itr; p < itrEnd; p++) {
+ if (*p == '.') break;
+ }
+
+ if (p == itr) *tag = strdup("all");
+ else *tag = _strndup(itr, p - itr);
+
+ if (p == itrEnd) *name = nullptr;
+ else *name = _strndup(p + 1, itrEnd - p - 1);
+
+ return (nextElement ? nextElement + 1 : nullptr);
+}
+
+
const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength)
{
const char *itr = buf, *itrEnd = buf + bufLength;
diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h
index d96a631528..e2761ca8da 100644
--- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h
+++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2020 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,7 +32,7 @@ const int xmlEntityLength[] = {6, 6, 6, 5, 4, 4, 6, 6};
enum class SimpleXMLType
{
Open = 0, //!< \<tag attribute="value"\>
- OpenEmpty, //!< \<tag attribute="value" /\>
+ OpenEmpty, //!< \<tag attribute="value" /\>
Close, //!< \</tag\>
Data, //!< tag text data
CData, //!< \<![cdata[something]]\>
@@ -41,16 +41,17 @@ enum class SimpleXMLType
Doctype, //!< \<!doctype html
Comment, //!< \<!-- something --\>
Ignored, //!< whatever is ignored by parser, like whitespace
- DoctypeChild //!< \<!doctype_child
+ DoctypeChild //!< \<!doctype_child
};
typedef bool (*simpleXMLCb)(void* data, SimpleXMLType type, const char* content, unsigned int length);
typedef bool (*simpleXMLAttributeCb)(void* data, const char* key, const char* value);
-bool simpleXmlParseAttributes(const char* buf, unsigned buflen, simpleXMLAttributeCb func, const void* data);
-bool simpleXmlParse(const char* buf, unsigned buflen, bool strip, simpleXMLCb func, const void* data);
-bool simpleXmlParseW3CAttribute(const char* buf, simpleXMLAttributeCb func, const void* data);
-const char *simpleXmlFindAttributesTag(const char* buf, unsigned buflen);
+bool simpleXmlParseAttributes(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data);
+bool simpleXmlParse(const char* buf, unsigned bufLength, bool strip, simpleXMLCb func, const void* data);
+bool simpleXmlParseW3CAttribute(const char* buf, unsigned bufLength, simpleXMLAttributeCb func, const void* data);
+const char* simpleXmlParseCSSAttribute(const char* buf, unsigned bufLength, char** tag, char** name, const char** attrs, unsigned* attrsLength);
+const char* simpleXmlFindAttributesTag(const char* buf, unsigned bufLength);
bool isIgnoreUnsupportedLogElements(const char* tagName);
const char* simpleXmlNodeTypeToString(SvgNodeType type);
diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp
index b0364b1055..2b85342b2c 100644
--- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp
+++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgBinInterpreter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h
index e7c3eba488..62181605a2 100644
--- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h
+++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgCommon.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp
index d7f3184435..95d629d1f6 100644
--- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp
+++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h
index d276ded33a..3ae841aa85 100644
--- a/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h
+++ b/thirdparty/thorvg/src/loaders/tvg/tvgTvgLoader.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
index 9dd57e5a89..aa54d21342 100644
--- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
+++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h
index 27186b5d4a..4acb35e76a 100644
--- a/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h
+++ b/thirdparty/thorvg/src/savers/tvg/tvgTvgSaver.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2021 - 2022 Samsung Electronics Co., Ltd. All rights reserved.
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal