thorvg: Update to 0.14.1
This commit is contained in:
parent
16f98cd707
commit
79a24fa7e0
|
@ -882,7 +882,7 @@ instead of `miniz.h` as an external dependency.
|
||||||
## thorvg
|
## thorvg
|
||||||
|
|
||||||
- Upstream: https://github.com/thorvg/thorvg
|
- Upstream: https://github.com/thorvg/thorvg
|
||||||
- Version: 0.14.0 (ae4e9d003c93325f1eba64319fa9852a0d764b4c, 2024)
|
- Version: 0.14.1 (70b2f2dad158316dd08166d613b425248b36fd27, 2024)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
// For internal debugging:
|
// For internal debugging:
|
||||||
//#define THORVG_LOG_ENABLED
|
//#define THORVG_LOG_ENABLED
|
||||||
|
|
||||||
#define THORVG_VERSION_STRING "0.14.0"
|
#define THORVG_VERSION_STRING "0.14.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -631,6 +631,8 @@ public:
|
||||||
* The Canvas rendering can be performed asynchronously. To make sure that rendering is finished,
|
* The Canvas rendering can be performed asynchronously. To make sure that rendering is finished,
|
||||||
* the sync() must be called after the draw() regardless of threading.
|
* the sync() must be called after the draw() regardless of threading.
|
||||||
*
|
*
|
||||||
|
* @retval Result::InsufficientCondition: The canvas is either already in sync condition or in a damaged condition (a draw is required before syncing).
|
||||||
|
*
|
||||||
* @see Canvas::draw()
|
* @see Canvas::draw()
|
||||||
*/
|
*/
|
||||||
virtual Result sync() noexcept;
|
virtual Result sync() noexcept;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef _TVG_SW_COMMON_H_
|
#ifndef _TVG_SW_COMMON_H_
|
||||||
#define _TVG_SW_COMMON_H_
|
#define _TVG_SW_COMMON_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include "tvgCommon.h"
|
#include "tvgCommon.h"
|
||||||
#include "tvgRender.h"
|
#include "tvgRender.h"
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,66 @@ static void _calculateCoefficients(const SwFill* fill, uint32_t x, uint32_t y, f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t _estimateAAMargin(const Fill* fdata)
|
||||||
|
{
|
||||||
|
constexpr float marginScalingFactor = 800.0f;
|
||||||
|
if (fdata->identifier() == TVG_CLASS_ID_RADIAL) {
|
||||||
|
auto radius = P(static_cast<const RadialGradient*>(fdata))->r;
|
||||||
|
return mathZero(radius) ? 0 : static_cast<uint32_t>(marginScalingFactor / radius);
|
||||||
|
}
|
||||||
|
auto grad = P(static_cast<const LinearGradient*>(fdata));
|
||||||
|
Point p1 {grad->x1, grad->y1};
|
||||||
|
Point p2 {grad->x2, grad->y2};
|
||||||
|
auto length = mathLength(&p1, &p2);
|
||||||
|
return mathZero(length) ? 0 : static_cast<uint32_t>(marginScalingFactor / length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _adjustAAMargin(uint32_t& iMargin, uint32_t index)
|
||||||
|
{
|
||||||
|
constexpr float threshold = 0.1f;
|
||||||
|
constexpr uint32_t iMarginMax = 40;
|
||||||
|
|
||||||
|
auto iThreshold = static_cast<uint32_t>(index * threshold);
|
||||||
|
if (iMargin > iThreshold) iMargin = iThreshold;
|
||||||
|
if (iMargin > iMarginMax) iMargin = iMarginMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32_t _alphaUnblend(uint32_t c)
|
||||||
|
{
|
||||||
|
auto a = (c >> 24);
|
||||||
|
if (a == 255 || a == 0) return c;
|
||||||
|
auto invA = 255.0f / static_cast<float>(a);
|
||||||
|
auto c0 = static_cast<uint8_t>(static_cast<float>((c >> 16) & 0xFF) * invA);
|
||||||
|
auto c1 = static_cast<uint8_t>(static_cast<float>((c >> 8) & 0xFF) * invA);
|
||||||
|
auto c2 = static_cast<uint8_t>(static_cast<float>(c & 0xFF) * invA);
|
||||||
|
|
||||||
|
return (a << 24) | (c0 << 16) | (c1 << 8) | c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void _applyAA(const SwFill* fill, uint32_t begin, uint32_t end)
|
||||||
|
{
|
||||||
|
if (begin == 0 || end == 0) return;
|
||||||
|
|
||||||
|
auto i = GRADIENT_STOP_SIZE - end;
|
||||||
|
auto rgbaEnd = _alphaUnblend(fill->ctable[i]);
|
||||||
|
auto rgbaBegin = _alphaUnblend(fill->ctable[begin]);
|
||||||
|
|
||||||
|
auto dt = 1.0f / (begin + end + 1.0f);
|
||||||
|
float t = dt;
|
||||||
|
while (i != begin) {
|
||||||
|
auto dist = 255 - static_cast<int32_t>(255 * t);
|
||||||
|
auto color = INTERPOLATE(rgbaEnd, rgbaBegin, dist);
|
||||||
|
fill->ctable[i++] = ALPHA_BLEND((color | 0xff000000), (color >> 24));
|
||||||
|
|
||||||
|
if (i == GRADIENT_STOP_SIZE) i = 0;
|
||||||
|
t += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* surface, uint8_t opacity)
|
static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* surface, uint8_t opacity)
|
||||||
{
|
{
|
||||||
if (!fill->ctable) {
|
if (!fill->ctable) {
|
||||||
|
@ -88,6 +148,11 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface*
|
||||||
auto pos = 1.5f * inc;
|
auto pos = 1.5f * inc;
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
//If repeat is true, anti-aliasing must be applied between the last and the first colors.
|
||||||
|
auto repeat = fill->spread == FillSpread::Repeat;
|
||||||
|
uint32_t iAABegin = repeat ? _estimateAAMargin(fdata) : 0;
|
||||||
|
uint32_t iAAEnd = 0;
|
||||||
|
|
||||||
fill->ctable[i++] = ALPHA_BLEND(rgba | 0xff000000, a);
|
fill->ctable[i++] = ALPHA_BLEND(rgba | 0xff000000, a);
|
||||||
|
|
||||||
while (pos <= pColors->offset) {
|
while (pos <= pColors->offset) {
|
||||||
|
@ -97,6 +162,11 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface*
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t j = 0; j < cnt - 1; ++j) {
|
for (uint32_t j = 0; j < cnt - 1; ++j) {
|
||||||
|
if (repeat && j == cnt - 2 && iAAEnd == 0) {
|
||||||
|
iAAEnd = iAABegin;
|
||||||
|
_adjustAAMargin(iAAEnd, GRADIENT_STOP_SIZE - i);
|
||||||
|
}
|
||||||
|
|
||||||
auto curr = colors + j;
|
auto curr = colors + j;
|
||||||
auto next = curr + 1;
|
auto next = curr + 1;
|
||||||
auto delta = 1.0f / (next->offset - curr->offset);
|
auto delta = 1.0f / (next->offset - curr->offset);
|
||||||
|
@ -118,14 +188,18 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface*
|
||||||
}
|
}
|
||||||
rgba = rgba2;
|
rgba = rgba2;
|
||||||
a = a2;
|
a = a2;
|
||||||
|
|
||||||
|
if (repeat && j == 0) _adjustAAMargin(iAABegin, i - 1);
|
||||||
}
|
}
|
||||||
rgba = ALPHA_BLEND((rgba | 0xff000000), a);
|
rgba = ALPHA_BLEND((rgba | 0xff000000), a);
|
||||||
|
|
||||||
for (; i < GRADIENT_STOP_SIZE; ++i)
|
for (; i < GRADIENT_STOP_SIZE; ++i)
|
||||||
fill->ctable[i] = rgba;
|
fill->ctable[i] = rgba;
|
||||||
|
|
||||||
//Make sure the last color stop is represented at the end of the table
|
//For repeat fill spread apply anti-aliasing between the last and first colors,
|
||||||
fill->ctable[GRADIENT_STOP_SIZE - 1] = rgba;
|
//othewise make sure the last color stop is represented at the end of the table.
|
||||||
|
if (repeat) _applyAA(fill, iAABegin, iAAEnd);
|
||||||
|
else fill->ctable[GRADIENT_STOP_SIZE - 1] = rgba;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1087,6 +1087,7 @@ static bool _rasterDirectScaledMaskedImage(SwSurface* surface, const SwImage* im
|
||||||
|
|
||||||
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
TVGERR("SW_ENGINE", "Not supported ScaledMaskedImage!");
|
||||||
#if 0 //Enable it when GRAYSCALE image is supported
|
#if 0 //Enable it when GRAYSCALE image is supported
|
||||||
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
TVGLOG("SW_ENGINE", "Scaled Masked(%d) Image [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y);
|
||||||
|
|
||||||
|
@ -1100,6 +1101,11 @@ static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, c
|
||||||
|
|
||||||
static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
if (surface->channelSize == sizeof(uint8_t)) {
|
||||||
|
TVGERR("SW_ENGINE", "Not supported grayscale scaled matted image!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
||||||
|
@ -1130,6 +1136,11 @@ static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, c
|
||||||
|
|
||||||
static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
|
if (surface->channelSize == sizeof(uint8_t)) {
|
||||||
|
TVGERR("SW_ENGINE", "Not supported grayscale scaled blending image!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
|
@ -1152,14 +1163,16 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
|
||||||
|
|
||||||
static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
auto sampleSize = _sampleSize(image->scale);
|
auto sampleSize = _sampleSize(image->scale);
|
||||||
int32_t miny = 0, maxy = 0;
|
int32_t miny = 0, maxy = 0;
|
||||||
|
|
||||||
for (auto y = region.min.y; y < region.max.y; ++y, dbuffer += surface->stride) {
|
//32bits channels
|
||||||
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
|
auto buffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
||||||
|
for (auto y = region.min.y; y < region.max.y; ++y, buffer += surface->stride) {
|
||||||
SCALED_IMAGE_RANGE_Y(y)
|
SCALED_IMAGE_RANGE_Y(y)
|
||||||
auto dst = dbuffer;
|
auto dst = buffer;
|
||||||
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
|
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
|
||||||
SCALED_IMAGE_RANGE_X
|
SCALED_IMAGE_RANGE_X
|
||||||
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
|
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
|
||||||
|
@ -1167,17 +1180,24 @@ static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const M
|
||||||
*dst = src + ALPHA_BLEND(*dst, IA(src));
|
*dst = src + ALPHA_BLEND(*dst, IA(src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (surface->channelSize == sizeof(uint8_t)) {
|
||||||
|
auto buffer = surface->buf8 + (region.min.y * surface->stride + region.min.x);
|
||||||
|
for (auto y = region.min.y; y < region.max.y; ++y, buffer += surface->stride) {
|
||||||
|
SCALED_IMAGE_RANGE_Y(y)
|
||||||
|
auto dst = buffer;
|
||||||
|
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
|
||||||
|
SCALED_IMAGE_RANGE_X
|
||||||
|
auto src = scaleMethod(image->buf32, image->stride, image->w, image->h, sx, sy, miny, maxy, sampleSize);
|
||||||
|
*dst = MULTIPLY(A(src), opacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity)
|
static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint8_t opacity)
|
||||||
{
|
{
|
||||||
if (surface->channelSize == sizeof(uint8_t)) {
|
|
||||||
TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix itransform;
|
Matrix itransform;
|
||||||
|
|
||||||
if (transform) {
|
if (transform) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include "tvgMath.h"
|
#include "tvgMath.h"
|
||||||
#include "tvgSwCommon.h"
|
#include "tvgSwCommon.h"
|
||||||
#include "tvgTaskScheduler.h"
|
#include "tvgTaskScheduler.h"
|
||||||
|
@ -86,7 +87,7 @@ struct SwShapeTask : SwTask
|
||||||
Additionally, the stroke style should not be dashed. */
|
Additionally, the stroke style should not be dashed. */
|
||||||
bool antialiasing(float strokeWidth)
|
bool antialiasing(float strokeWidth)
|
||||||
{
|
{
|
||||||
return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim();
|
return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color[3] < 255;;
|
||||||
}
|
}
|
||||||
|
|
||||||
float validStrokeWidth()
|
float validStrokeWidth()
|
||||||
|
|
|
@ -129,7 +129,7 @@ struct Canvas::Impl
|
||||||
return Result::Success;
|
return Result::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result::InsufficientCondition;
|
return Result::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result viewport(int32_t x, int32_t y, int32_t w, int32_t h)
|
Result viewport(int32_t x, int32_t y, int32_t w, int32_t h)
|
||||||
|
|
|
@ -103,7 +103,7 @@ struct RenderRegion
|
||||||
void intersect(const RenderRegion& rhs);
|
void intersect(const RenderRegion& rhs);
|
||||||
void add(const RenderRegion& rhs);
|
void add(const RenderRegion& rhs);
|
||||||
|
|
||||||
bool operator==(const RenderRegion& rhs)
|
bool operator==(const RenderRegion& rhs) const
|
||||||
{
|
{
|
||||||
if (x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h) return true;
|
if (x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h) return true;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -296,6 +296,7 @@ struct Shape::Impl
|
||||||
if (!rs.stroke) rs.stroke = new RenderStroke();
|
if (!rs.stroke) rs.stroke = new RenderStroke();
|
||||||
if (rs.stroke->fill && rs.stroke->fill != p) delete(rs.stroke->fill);
|
if (rs.stroke->fill && rs.stroke->fill != p) delete(rs.stroke->fill);
|
||||||
rs.stroke->fill = p;
|
rs.stroke->fill = p;
|
||||||
|
rs.stroke->color[3] = 0;
|
||||||
|
|
||||||
flag |= RenderUpdateFlag::Stroke;
|
flag |= RenderUpdateFlag::Stroke;
|
||||||
flag |= RenderUpdateFlag::GradientStroke;
|
flag |= RenderUpdateFlag::GradientStroke;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
|
||||||
VERSION=0.14.0
|
VERSION=0.14.1
|
||||||
|
|
||||||
cd thirdparty/thorvg/ || true
|
cd thirdparty/thorvg/ || true
|
||||||
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/
|
||||||
|
|
Loading…
Reference in New Issue