diff --git a/thirdparty/thorvg/inc/config.h b/thirdparty/thorvg/inc/config.h index 3ae166cf22c..9c83f25c79b 100644 --- a/thirdparty/thorvg/inc/config.h +++ b/thirdparty/thorvg/inc/config.h @@ -13,5 +13,5 @@ // For internal debugging: //#define THORVG_LOG_ENABLED -#define THORVG_VERSION_STRING "0.13.3" +#define THORVG_VERSION_STRING "0.13.5" #endif diff --git a/thirdparty/thorvg/inc/thorvg.h b/thirdparty/thorvg/inc/thorvg.h index 93ce18197ef..f7396050d76 100644 --- a/thirdparty/thorvg/inc/thorvg.h +++ b/thirdparty/thorvg/inc/thorvg.h @@ -649,6 +649,30 @@ public: */ virtual Result draw() noexcept; + /** + * @brief Sets the drawing region in the canvas. + * + * This function defines the rectangular area of the canvas that will be used for drawing operations. + * The specified viewport is used to clip the rendering output to the boundaries of the rectangle. + * + * @param[in] x The x-coordinate of the upper-left corner of the rectangle. + * @param[in] y The y-coordinate of the upper-left corner of the rectangle. + * @param[in] w The width of the rectangle. + * @param[in] h The height of the rectangle. + * + * @retval Result::Success when succeed, Result::InsufficientCondition otherwise. + * + * @see SwCanvas::target() + * @see GlCanvas::target() + * @see WgCanvas::target() + * + * @warning It's not allowed to change the viewport during Canvas::push() - Canvas::sync() or Canvas::update() - Canvas::sync(). + * + * @note When resetting the target, the viewport will also be reset to the target size. + * @note Experimental API + */ + virtual Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept; + /** * @brief Guarantees that drawing task is finished. * @@ -1660,7 +1684,9 @@ public: * @retval Result::InvalidArguments In case no valid pointer is provided or the width, or the height or the stride is zero. * @retval Result::NonSupport In case the software engine is not supported. * - * @warning Do not access @p buffer during Canvas::draw() - Canvas::sync(). It should not be accessed while TVG is writing on it. + * @warning Do not access @p buffer during Canvas::push() - Canvas::sync(). It should not be accessed while the engine is writing on it. + * + * @see Canvas::viewport() */ Result target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, Colorspace cs) noexcept; @@ -1726,6 +1752,8 @@ public: * @warning This API is experimental and not officially supported. It may be modified or removed in future versions. * @warning Drawing on the main surface is currently not permitted. If the identifier (@p id) is set to @c 0, the operation will be aborted. * + * @see Canvas::viewport() + * * @note Currently, this only allows the GL_RGBA8 color space format. * @note Experimental API */ @@ -1764,6 +1792,7 @@ public: * @warning Please do not use it, this API is not official one. It could be modified in the next version. * * @note Experimental API + * @see Canvas::viewport() */ Result target(void* window, uint32_t w, uint32_t h) noexcept; @@ -1856,6 +1885,7 @@ public: * * @note For efficiency, ThorVG ignores updates to the new frame value if the difference from the current frame value * is less than 0.001. In such cases, it returns @c Result::InsufficientCondition. + * Values less than 0.001 may be disregarded and may not be accurately retained by the Animation. * * @see totalFrame() * diff --git a/thirdparty/thorvg/src/common/tvgMath.h b/thirdparty/thorvg/src/common/tvgMath.h index 60ea1d21b04..5c2966956af 100644 --- a/thirdparty/thorvg/src/common/tvgMath.h +++ b/thirdparty/thorvg/src/common/tvgMath.h @@ -31,6 +31,7 @@ #define MATH_PI 3.14159265358979323846f #define MATH_PI2 1.57079632679489661923f +#define FLOAT_EPSILON 1.0e-06f //1.192092896e-07f #define PATH_KAPPA 0.552284f #define mathMin(x, y) (((x) < (y)) ? (x) : (y)) @@ -58,13 +59,19 @@ static inline float mathRad2Deg(float radian) static inline bool mathZero(float a) { - return (fabsf(a) < FLT_EPSILON) ? true : false; + return (fabsf(a) <= FLOAT_EPSILON) ? true : false; +} + + +static inline bool mathZero(const Point& p) +{ + return mathZero(p.x) && mathZero(p.y); } static inline bool mathEqual(float a, float b) { - return (fabsf(a - b) < FLT_EPSILON); + return mathZero(a - b); } @@ -82,14 +89,14 @@ static inline bool mathEqual(const Matrix& a, const Matrix& b) static inline bool mathRightAngle(const Matrix* m) { auto radian = fabsf(atan2f(m->e21, m->e11)); - if (radian < FLT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true; + if (radian < FLOAT_EPSILON || mathEqual(radian, MATH_PI2) || mathEqual(radian, MATH_PI)) return true; return false; } static inline bool mathSkewed(const Matrix* m) { - return (fabsf(m->e21 + m->e12) > FLT_EPSILON); + return !mathZero(m->e21 + m->e12); } @@ -169,6 +176,12 @@ static inline float mathLength(const Point* a, const Point* b) } +static inline float mathLength(const Point& a) +{ + return sqrtf(a.x * a.x + a.y * a.y); +} + + static inline Point operator-(const Point& lhs, const Point& rhs) { return {lhs.x - rhs.x, lhs.y - rhs.y}; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp index 7706051e3b0..0a47112084b 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp +++ b/thirdparty/thorvg/src/loaders/svg/tvgSvgLoader.cpp @@ -709,7 +709,7 @@ static bool _toColor(const char* str, uint8_t* r, uint8_t* g, uint8_t* b, char** *ref = _idFromUrl((const char*)(str + 3)); return true; } else if (len >= 10 && (str[0] == 'h' || str[0] == 'H') && (str[1] == 's' || str[1] == 'S') && (str[2] == 'l' || str[2] == 'L') && str[3] == '(' && str[len - 1] == ')') { - float_t th, ts, tb; + float th, ts, tb; const char *content, *hue, *satuation, *brightness; content = str + 4; content = _skipSpace(content, nullptr); @@ -988,7 +988,7 @@ static bool _attrParseSvgNode(void* data, const char* key, const char* value) } else if (!strcmp(key, "style")) { return simpleXmlParseW3CAttribute(value, strlen(value), _parseStyleAttr, loader); #ifdef THORVG_LOG_ENABLED - } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLT_EPSILON) { + } else if ((!strcmp(key, "x") || !strcmp(key, "y")) && fabsf(strToFloat(value, nullptr)) > FLOAT_EPSILON) { TVGLOG("SVG", "Unsupported attributes used [Elements type: Svg][Attribute: %s][Value: %s]", key, value); #endif } else { @@ -1824,8 +1824,8 @@ static bool _attrParseRectNode(void* data, const char* key, const char* value) if (!strncmp(rectTags[i].tag, "rx", sz)) rect->hasRx = true; if (!strncmp(rectTags[i].tag, "ry", sz)) rect->hasRy = true; - if ((rect->rx >= FLT_EPSILON) && (rect->ry < FLT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; - if ((rect->ry >= FLT_EPSILON) && (rect->rx < FLT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; + if ((rect->rx >= FLOAT_EPSILON) && (rect->ry < FLOAT_EPSILON) && rect->hasRx && !rect->hasRy) rect->ry = rect->rx; + if ((rect->ry >= FLOAT_EPSILON) && (rect->rx < FLOAT_EPSILON) && !rect->hasRx && rect->hasRy) rect->rx = rect->ry; return ret; } } @@ -3708,7 +3708,7 @@ SvgLoader::~SvgLoader() void SvgLoader::run(unsigned tid) { //According to the SVG standard the value of the width/height of the viewbox set to 0 disables rendering - if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLT_EPSILON || fabsf(vh) <= FLT_EPSILON)) { + if ((viewFlag & SvgViewFlag::Viewbox) && (fabsf(vw) <= FLOAT_EPSILON || fabsf(vh) <= FLOAT_EPSILON)) { TVGLOG("SVG", "The width and/or height set to 0 - rendering disabled."); root = Scene::gen().release(); return; diff --git a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h index 30ca23b565f..4151fbcdb33 100644 --- a/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h +++ b/thirdparty/thorvg/src/loaders/svg/tvgXmlParser.h @@ -25,9 +25,9 @@ #include "tvgSvgLoaderCommon.h" -#define NUMBER_OF_XML_ENTITIES 8 -const char* const xmlEntity[] = {""", " ", "'", "&", "<", ">", "#", "'"}; -const int xmlEntityLength[] = {6, 6, 6, 5, 4, 4, 6, 6}; +#define NUMBER_OF_XML_ENTITIES 9 +const char* const xmlEntity[] = {" ", """, " ", "'", "&", "<", ">", "#", "'"}; +const int xmlEntityLength[] = {5, 6, 6, 6, 5, 4, 4, 6, 6}; enum class SimpleXMLType { diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp index 60763068d49..3d582d291c8 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwFill.cpp @@ -140,7 +140,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr fill->linear.dy = y2 - y1; fill->linear.len = fill->linear.dx * fill->linear.dx + fill->linear.dy * fill->linear.dy; - if (fill->linear.len < FLT_EPSILON) return true; + if (fill->linear.len < FLOAT_EPSILON) return true; fill->linear.dx /= fill->linear.len; fill->linear.dy /= fill->linear.len; @@ -182,7 +182,7 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr auto fy = P(radial)->fy; auto fr = P(radial)->fr; - if (r < FLT_EPSILON) return true; + if (r < FLOAT_EPSILON) return true; fill->radial.dr = r - fr; fill->radial.dx = cx - fx; diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp index 4e0020ee524..04f36c727f9 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRaster.cpp @@ -1553,7 +1553,7 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill) { - if (fill->linear.len < FLT_EPSILON) return false; + if (fill->linear.len < FLOAT_EPSILON) return false; if (_compositing(surface)) { if (_matting(surface)) return _rasterGradientMattedRect(surface, region, fill); diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp index 3387905761e..0b2940c32d3 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -434,10 +434,6 @@ bool SwRenderer::target(pixel_t* data, uint32_t stride, uint32_t w, uint32_t h, surface->channelSize = CHANNEL_SIZE(cs); surface->premultiplied = true; - vport.x = vport.y = 0; - vport.w = surface->w; - vport.h = surface->h; - return rasterCompositor(surface); } @@ -607,6 +603,12 @@ bool SwRenderer::mempool(bool shared) } +const Surface* SwRenderer::mainSurface() +{ + return surface; +} + + Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs) { auto x = region.x; diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h index 02359e4a391..57be558988c 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwRenderer.h @@ -49,6 +49,7 @@ public: bool viewport(const RenderRegion& vp) override; bool blend(BlendMethod method) override; ColorSpace colorSpace() override; + const Surface* mainSurface() override; bool clear() override; bool sync() override; diff --git a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp index e38f13db256..b9327374b60 100644 --- a/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp +++ b/thirdparty/thorvg/src/renderer/sw_engine/tvgSwShape.cpp @@ -124,7 +124,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans len -= dash.curLen; lineSplitAt(cur, dash.curLen, left, right); if (!dash.curOpGap) { - if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.pt1, transform); dash.move = false; } @@ -185,7 +185,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct len -= dash.curLen; bezSplitAt(cur, dash.curLen, left, right); if (!dash.curOpGap) { - if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLT_EPSILON) { + if (dash.move || dash.pattern[dash.curIdx] - dash.curLen < FLOAT_EPSILON) { _outlineMoveTo(*dash.outline, &left.start, transform); dash.move = false; } diff --git a/thirdparty/thorvg/src/renderer/tvgCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgCanvas.cpp index 11d6b778f74..1a36e41e784 100644 --- a/thirdparty/thorvg/src/renderer/tvgCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgCanvas.cpp @@ -81,6 +81,12 @@ Result Canvas::update(Paint* paint) noexcept } +Result Canvas::viewport(int32_t x, int32_t y, int32_t w, int32_t h) noexcept +{ + return pImpl->viewport(x, y, w, h); +} + + Result Canvas::sync() noexcept { return pImpl->sync(); diff --git a/thirdparty/thorvg/src/renderer/tvgCanvas.h b/thirdparty/thorvg/src/renderer/tvgCanvas.h index a1556702b1d..a4b866eacbe 100644 --- a/thirdparty/thorvg/src/renderer/tvgCanvas.h +++ b/thirdparty/thorvg/src/renderer/tvgCanvas.h @@ -28,10 +28,14 @@ struct Canvas::Impl { + enum Status : uint8_t {Synced = 0, Updating, Drawing}; + list paints; RenderMethod* renderer; + RenderRegion vport = {0, 0, INT32_MAX, INT32_MAX}; + Status status = Status::Synced; + bool refresh = false; //if all paints should be updated by force. - bool drawing = false; //on drawing condition? Impl(RenderMethod* pRenderer) : renderer(pRenderer) { @@ -41,14 +45,12 @@ struct Canvas::Impl ~Impl() { //make it sure any deffered jobs - if (renderer) { - renderer->sync(); - renderer->clear(); - } + renderer->sync(); + renderer->clear(); clearPaints(); - if (renderer && (renderer->unref() == 0)) delete(renderer); + if (renderer->unref() == 0) delete(renderer); } void clearPaints() @@ -62,7 +64,7 @@ struct Canvas::Impl Result push(unique_ptr paint) { //You can not push paints during rendering. - if (drawing) return Result::InsufficientCondition; + if (status == Status::Drawing) return Result::InsufficientCondition; auto p = paint.release(); if (!p) return Result::MemoryCorruption; @@ -75,12 +77,12 @@ struct Canvas::Impl Result clear(bool free) { //Clear render target before drawing - if (!renderer || !renderer->clear()) return Result::InsufficientCondition; + if (!renderer->clear()) return Result::InsufficientCondition; //Free paints if (free) clearPaints(); - drawing = false; + status = Status::Synced; return Result::Success; } @@ -92,7 +94,7 @@ struct Canvas::Impl Result update(Paint* paint, bool force) { - if (paints.empty() || drawing || !renderer) return Result::InsufficientCondition; + if (paints.empty() || status == Status::Drawing) return Result::InsufficientCondition; Array clips; auto flag = RenderUpdateFlag::None; @@ -106,12 +108,13 @@ struct Canvas::Impl } refresh = false; } + status = Status::Updating; return Result::Success; } Result draw() { - if (drawing || paints.empty() || !renderer || !renderer->preRender()) return Result::InsufficientCondition; + if (status == Status::Drawing || paints.empty() || !renderer->preRender()) return Result::InsufficientCondition; bool rendered = false; for (auto paint : paints) { @@ -120,22 +123,37 @@ struct Canvas::Impl if (!rendered || !renderer->postRender()) return Result::InsufficientCondition; - drawing = true; - + status = Status::Drawing; return Result::Success; } Result sync() { - if (!drawing) return Result::InsufficientCondition; + if (status == Status::Synced) return Result::InsufficientCondition; if (renderer->sync()) { - drawing = false; + status = Status::Synced; return Result::Success; } return Result::InsufficientCondition; } + + Result viewport(int32_t x, int32_t y, int32_t w, int32_t h) + { + if (status != Status::Synced) return Result::InsufficientCondition; + RenderRegion val = {x, y, w, h}; + //intersect if the target buffer is already set. + auto surface = renderer->mainSurface(); + if (surface && surface->w > 0 && surface->h > 0) { + val.intersect({0, 0, (int32_t)surface->w, (int32_t)surface->h}); + } + if (vport == val) return Result::Success; + renderer->viewport(val); + vport = val; + needRefresh(); + return Result::Success; + } }; #endif /* _TVG_CANVAS_H_ */ diff --git a/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp index 940e6682f8c..211dbb589c6 100644 --- a/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgGlCanvas.cpp @@ -68,6 +68,8 @@ Result GlCanvas::target(int32_t id, uint32_t w, uint32_t h) noexcept if (!renderer) return Result::MemoryCorruption; if (!renderer->target(id, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. Canvas::pImpl->needRefresh(); diff --git a/thirdparty/thorvg/src/renderer/tvgPicture.cpp b/thirdparty/thorvg/src/renderer/tvgPicture.cpp index cfa1bccd086..5bd55a3f7b4 100644 --- a/thirdparty/thorvg/src/renderer/tvgPicture.cpp +++ b/thirdparty/thorvg/src/renderer/tvgPicture.cpp @@ -29,7 +29,9 @@ RenderUpdateFlag Picture::Impl::load() { if (loader) { - if (!paint) { + if (paint) { + loader->sync(); + } else { paint = loader->paint(); if (paint) { if (w != loader->w || h != loader->h) { @@ -42,8 +44,7 @@ RenderUpdateFlag Picture::Impl::load() } return RenderUpdateFlag::None; } - } else loader->sync(); - + } if (!surface) { if ((surface = loader->bitmap())) { return RenderUpdateFlag::Image; diff --git a/thirdparty/thorvg/src/renderer/tvgRender.cpp b/thirdparty/thorvg/src/renderer/tvgRender.cpp index bdfb9f322eb..14f77571fb1 100644 --- a/thirdparty/thorvg/src/renderer/tvgRender.cpp +++ b/thirdparty/thorvg/src/renderer/tvgRender.cpp @@ -60,3 +60,35 @@ RenderTransform::RenderTransform(const RenderTransform* lhs, const RenderTransfo else if (rhs) m = rhs->m; else mathIdentity(&m); } + + +void RenderRegion::intersect(const RenderRegion& rhs) +{ + auto x1 = x + w; + auto y1 = y + h; + auto x2 = rhs.x + rhs.w; + auto y2 = rhs.y + rhs.h; + + x = (x > rhs.x) ? x : rhs.x; + y = (y > rhs.y) ? y : rhs.y; + w = ((x1 < x2) ? x1 : x2) - x; + h = ((y1 < y2) ? y1 : y2) - y; + + if (w < 0) w = 0; + if (h < 0) h = 0; +} + + +void RenderRegion::add(const RenderRegion& rhs) +{ + if (rhs.x < x) { + w += (x - rhs.x); + x = rhs.x; + } + if (rhs.y < y) { + h += (y - rhs.y); + y = rhs.y; + } + if (rhs.x + rhs.w > x + w) w = (rhs.x + rhs.w) - x; + if (rhs.y + rhs.h > y + h) h = (rhs.y + rhs.h) - y; +} diff --git a/thirdparty/thorvg/src/renderer/tvgRender.h b/thirdparty/thorvg/src/renderer/tvgRender.h index 4f54f2fe6b4..6ea516c2f9d 100644 --- a/thirdparty/thorvg/src/renderer/tvgRender.h +++ b/thirdparty/thorvg/src/renderer/tvgRender.h @@ -100,34 +100,13 @@ struct RenderRegion { int32_t x, y, w, h; - void intersect(const RenderRegion& rhs) + void intersect(const RenderRegion& rhs); + void add(const RenderRegion& rhs); + + bool operator==(const RenderRegion& rhs) { - auto x1 = x + w; - auto y1 = y + h; - auto x2 = rhs.x + rhs.w; - auto y2 = rhs.y + rhs.h; - - x = (x > rhs.x) ? x : rhs.x; - y = (y > rhs.y) ? y : rhs.y; - w = ((x1 < x2) ? x1 : x2) - x; - h = ((y1 < y2) ? y1 : y2) - y; - - if (w < 0) w = 0; - if (h < 0) h = 0; - } - - void add(const RenderRegion& rhs) - { - if (rhs.x < x) { - w += (x - rhs.x); - x = rhs.x; - } - if (rhs.y < y) { - h += (y - rhs.y); - y = rhs.y; - } - if (rhs.x + rhs.w > x + w) w = (rhs.x + rhs.w) - x; - if (rhs.y + rhs.h > y + h) h = (rhs.y + rhs.h) - y; + if (x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h) return true; + return false; } }; @@ -293,6 +272,7 @@ public: virtual bool viewport(const RenderRegion& vp) = 0; virtual bool blend(BlendMethod method) = 0; virtual ColorSpace colorSpace() = 0; + virtual const Surface* mainSurface() = 0; virtual bool clear() = 0; virtual bool sync() = 0; diff --git a/thirdparty/thorvg/src/renderer/tvgShape.h b/thirdparty/thorvg/src/renderer/tvgShape.h index 813cf9e2e38..55335214bed 100644 --- a/thirdparty/thorvg/src/renderer/tvgShape.h +++ b/thirdparty/thorvg/src/renderer/tvgShape.h @@ -67,7 +67,7 @@ struct Shape::Impl if (opacity == 0) return false; //Shape composition is only necessary when stroking & fill are valid. - if (!rs.stroke || rs.stroke->width < FLT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; + if (!rs.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; if (!rs.fill && rs.color[3] == 0) return false; //translucent fill & stroke @@ -301,7 +301,7 @@ struct Shape::Impl } for (uint32_t i = 0; i < cnt; i++) { - if (pattern[i] < FLT_EPSILON) return Result::InvalidArguments; + if (pattern[i] < FLOAT_EPSILON) return Result::InvalidArguments; } //Reset dash diff --git a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp index d154a600d59..52d85d83201 100644 --- a/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgSwCanvas.cpp @@ -87,6 +87,8 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t if (!renderer) return Result::MemoryCorruption; if (!renderer->target(buffer, stride, w, h, static_cast(cs))) return Result::InvalidArguments; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. Canvas::pImpl->needRefresh(); diff --git a/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp b/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp index 5205df17372..7db77f6d0c6 100644 --- a/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp +++ b/thirdparty/thorvg/src/renderer/tvgWgCanvas.cpp @@ -63,6 +63,8 @@ Result WgCanvas::target(void* window, uint32_t w, uint32_t h) noexcept if (!renderer) return Result::MemoryCorruption; if (!renderer->target(window, w, h)) return Result::Unknown; + Canvas::pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; + renderer->viewport(Canvas::pImpl->vport); //Paints must be updated again with this new target. Canvas::pImpl->needRefresh(); diff --git a/thirdparty/thorvg/update-thorvg.sh b/thirdparty/thorvg/update-thorvg.sh index 796060d3fb1..cd1aeadec06 100755 --- a/thirdparty/thorvg/update-thorvg.sh +++ b/thirdparty/thorvg/update-thorvg.sh @@ -1,6 +1,6 @@ #!/bin/bash -e -VERSION=0.13.3 +VERSION=0.13.5 cd thirdparty/thorvg/ || true rm -rf AUTHORS LICENSE inc/ src/ *.zip *.tar.gz tmp/