This change ensures at the api level that if the focal
point lies outside the end circle, it is projected onto
the edge of the end circle.
Additionally, if the start circle does not fully fit
inside the end circle (after possible repositioning), its
radius is reduced accordingly.
The modification aligns with the SVG 1.1 standard (for fr = 0).
Cases with fr > 0 are not covered by the SVG 1.1, and edge
cases have been handled here to avoid numerical issues.
Note:
This update replaces previous behavior where gl handled
the SVG 2.0 standard.
The API allows now values <= 0 for dashes and gaps. Negative values
are treated as zero. The exception is when all provided values
are <= 0, in which case the dash is ignored.
This fixes the issue when dash = 0 was provided for strokes with round
or butt caps - the dot was not drawn, even though it should have been.
docs: the strokeDash API behavior's clarification for odd numbers
of values in dashPattern and refinement of the accepted values.
Partial Rendering refers to a rendering technique where
only a portion of the scene or screen is updated, rather
than redrawing the entire output. It is commonly used as
a performance optimization strategy, focusing on redrawing
only the regions that have changed, often called dirty regions.
This introduces RenderDirtyRegion, which assists
in collecting a compact dirty region from render tasks.
To efficient data-processing, this divide the screen region
with a designated size of partition and handles the partitl rendering
computation with a divide-conquer metholodgy.
Each backend can utilize this class to support efficient partial rendering.
This is implemented using a Line Sweep and Subdivision Merging O(NlogN).
The basic per-frame workflow is as follows:
0. RenderDirtyRegion::init() //set the screen size to properly partition the regions
1. RenderDirtyRegion::prepare() //Call this in Renderer::preRender().
2. RenderDirtyRegion::add() //Add all dirty paints for the frame before rendering.
3. RenderDirtyRegion::commit() //Generate the partial rendering region list before rendering.
4. RenderDirtyRegion::partition() //Get a certian partition
5. RenderDirtyRegion::get() //Retrieve the current dirty region list of a partition and use it when drawing paints.
6. RenderDirtyRegion::clear() //Reset the state.
RenderMethod introduced for 2 utilities for paritial renderings
1. RenderMethod::damage() //add a force dirty region, especially useful for scene effects
2. RenderMethod::partial() //toggle the partial rendering feature
issue: https://github.com/thorvg/thorvg/issues/1747
Implemented support for clipping shapes and images using a render region
bounding box at render time. This allows partial drawing of content,
laying the groundwork for upcoming partial rendering functionality.
for fast access of the drawing region from the linear rle data,
we introduced the binary search for begin/end of rle instead of
additional y index buffer.
There is a reason for not using a y-index buffer:
the shapes in the RLE are not single, continuous shapes
but multiple shapes scattered across the space.
which means that we need a double-associated data structure
per shapes for y indexing, and this data preparation wouldn't be
cheaper enough than realtime binary search especially animated data.
issue: https://github.com/thorvg/thorvg/issues/1747
This approach should be introduced in d8ebd8b4f5.
Using FLOAT_EPSILON is not sufficient due to numerical precision,
since it's later inverted, and its very small value leads to
significant errors during inversion.
If the radial gradient's focal point lies outside
the end circle, it's projected onto the edge.
A slight inward offset is applied to avoid numerical
issues.
Note:
Focal point support in the sw and wg engines is
consistent with the SVG 1.1 standard, whereas the gl
engine aligns with the SVG 2.0 standard.
previous logic doesn't work if the clipping shape
has any inner corners. replace the logic
with a intermediate composition approach for
stability.
- performance can be drop at texture clipping by ~11%
- size is reduced by -0.5kb
issue: https://github.com/thorvg/thorvg/issues/3520
The old approach often produced incorrect results,
especially when the fixed pixel had a noticeably
different color from the texture due to the AA
target blending position was fixed.
Although the previous method worked well as an analytical AA
solution with good speed and fair quality, it couldn't
overcome the above limitation.
The new approach still applies AA only to polygon edges
for efficiency. While the quality may be slightly reduced,
it offers greater stability.
- binary size: -1.1kb
- performance diff: ignoreable
issue: https://github.com/thorvg/thorvg/issues/1729
- Replaced `modff()` with a custom method,
boosting texture mapping performance by ~15%.
- Unified opacity/non-opacity logic for improved
binary size efficiency(-0.5kb).
- Implemented minor changes for better cache effectiveness.
This commit has two purposes:
- refactoring to introduce y indexing method for the upcoming partial rendering.
- replaces the RLE-specific memory allocation with a shared array structure,
eliminating potential memory overflows during RLE clipping.
redefiend properties so that min/max are prioritized,
as they are accessed more frequently than pos/size
during rendering calculations.
also introduced miscellaneous functions to improve usability.
In some clipping cases, the memory allocated for storing spans
was too small. As a result, the entire clipped area might not
have been rendered.
This has been resolved by adding an experimental factor to increase
the size of allocated memory.
@issue: https://github.com/thorvg/thorvg/issues/3461
Added drawing exceptions when target is not properly ready.
Now, Canvas::update() Canvas::draw() will return InsufficientCondition
if the target has not been set beforehand.
revert the alpha skip condition introduced in
commit 2990e72b23.
color values with alpha = 0 must be transformed to 0
to ensure correct intermediate composition results.
Simplified parameters and ensured proper backend engine
initialization by using reference checking through canvas
instances.
C++ API Modification:
- Result Initializer::init(uint32_t threads, CanvasEngine engine)
-> Result Initializer::init(uint32_t threads)
- Result Initializer::term(CanvasEngine engine)
-> Result Initializer::term()
C API Modification:
- Tvg_Result tvg_engine_init(Tvg_Engine engine_method, unsigned threads)
-> Tvg_Result tvg_engine_init(unsigned threads);
- Tvg_Result tvg_engine_term(Tvg_Engine engine_method)
-> Tvg_Result tvg_engine_term()
issue: https://github.com/thorvg/thorvg/issues/3116
The following is a redesign that extends the class internally.
The main goal is to preserve the characteristics of the pImpl idiom
for data encapsulation, while simultaneously reducing the memory
allocation overhead typically associated with pImpl.
The stragegy is here:
Rather than alloc the impl memory inside of the thorvg engine,
impl extends the API classes in order to consolidate the memory.
size has been decreased by -4kb with optimization=s
issue: https://github.com/thorvg/thorvg/issues/3214
ThorVG did not consider updates to the clipping path
when a paint object was modified after being added to the scene.
This fix ensures that any updates to clipping are correctly
reflected during rendering.
issue: https://github.com/thorvg/thorvg/issues/3403
- modify the concept of AABB to apply only to transformed shapes.
- transform points before computing the bounding box min/max
to obtain a more compact shape region.
- trimmming memory by removing the cached matrix, about 36kb
of memory has been reduced per paint instance.
Generating the outline may return false, e.g., if the shape
is completely trimmed. If such a shape was used as a clip,
an attempt to generate 'rle' will still be made. In such a case,
a crash will occur because the outline is nullptr.
Until now, only stroke trimming was possible,
but the Lottie standard requires support for
trimming both (if present), stroke and fill.
This commit changes the API behavior.
@Issue: https://github.com/thorvg/thorvg/issues/3118
Before the C++ compiler couldn't decide the template of std::min (that happen if `int` type is not an `int32_t`), so explicitly changing all types to int32_t fixes this.
Support the bindings to be more integrable with a system's coherent memory management.
Pleaes note that thorvg now only allow the desinated memory allocators here:
malloc -> tvg::malloc
calloc -> tvg::calloc
realloc -> tvg::realloc
free -> tvg::free
issue: https://github.com/thorvg/thorvg/issues/2652