In the cae when Result::InsufficientCondition was retured by the save()
api, the user had to remember to delete the passed paint - fixed.
Also path was not released.
If paint has no path information or stroke information,
it is not referenced inside bounds.
This will access the uninitialized variable at line 759, 760.
Introducing the gradient transform() apis and changing the grad
algorithms made it possible to apply the shape's transformation
before saving the tvg file, in case the shape (or its stroke)
has a fill.
Current paint::bounds() returns the coordinates under the raw status,
the values are not quite useful if the paint object has the transformed children.
Thus, we extends the feature and give an additional parameter "transformed"
to return the coordinates values after transformation by user demands.
This is also necessary for tvg format, since we need the exact view size of the scene information.
The previous api is deprecated and we introduce a new api to replace it.
@APIs:
+ Result Paint::bounds(float* x, float* y, float* w, float* h, bool transformed) const noexcept;
- Result Paint::bounds(float* x, float* y, float* w, float* h) const noexcept;
@Issues: https://github.com/Samsung/thorvg/issues/746
Saver tries to pre-transfom to skip the matrix data,
but it missed the case - transformed stroking,
we skip it also only when xy scaling factors are same excluding the dash properties,
because scaled of the stroking is depent on the engines,
we have no idea of the proper input data in advance.
@Issues: https://github.com/Samsung/thorvg/issues/773
This reserved count was just missed,
Aside from it, tvg_loader logic is not well organized (hard to expect)
We can refine it by recovering the data tree structure in the reverse order.
@Issues: https://github.com/Samsung/thorvg/issues/768
there some multiple wrong calculation about size during tvg optimiation.
this patch fixes them.
1. picture needs to return the current desired size because
it will save the transformed the geometry. the final size should be
recorvered as the base size from the loader.
2. clippath missed to multiply parents transform, it's fixed.
@Issue: https://github.com/Samsung/thorvg/issues/752
By choosing compress option, tvg tries to compress the data to reduce the binary size.
Since the compression has the double-edges sword, we provides an option to users
to select it by their demand. Basically, compression is better than non-compression.
After profiling, we decided to use the encoder/decoder of Guilherme R. Lampert's.
Here is the profiling result:
test.tvg: 296037 -> 243411 (-17%)
tiger.tvg: 54568 -> 50622 (-7%)
image-embedded.tvg: 2282 -> 1231 (-46%)
@Issue: https://github.com/Samsung/thorvg/issues/639
About compression method:
Lempel–Ziv–Welch (LZW) encoder/decoder by Guilherme R. Lampert
This is the compression scheme used by the GIF image format and the Unix 'compress' tool.
Main differences from this implementation is that End Of Input (EOI) and Clear Codes (CC)
are not stored in the output and the max code length in bits is 12, vs 16 in compress.
EOI is simply detected by the end of the data stream, while CC happens if the
dictionary gets filled. Data is written/read from bit streams, which handle
byte-alignment for us in a transparent way.
The decoder relies on the hardcoded data layout produced by the encoder, since
no additional reconstruction data is added to the output, so they must match.
The nice thing about LZW is that we can reconstruct the dictionary directly from
the stream of codes generated by the encoder, so this avoids storing additional
headers in the bit stream.
The output code length is variable. It starts with the minimum number of bits
required to store the base byte-sized dictionary and automatically increases
as the dictionary gets larger (it starts at 9-bits and grows to 10-bits when
code 512 is added, then 11-bits when 1024 is added, and so on). If the dictionary
is filled (4096 items for a 12-bits dictionary), the whole thing is cleared and
the process starts over. This is the main reason why the encoder and the decoder
must match perfectly, since the lengths of the codes will not be specified with
the data itself.
So this optimization stragtegy is to merging shapes.
If two shapes have the same layer, having save properties except the paths,
we can integrate two shapes to one, this helps to build up a simpler
scene-tree, reduce the runtime memory, helps for faster processing for rendering.
As far as I checked tiger.svg, it removes 142 shape nodes,
decreased the binary size: 60537 -> 54568.
Overall, avg 4% binary size can be reduced among our example svgs by this patch.
This optimizes binary size by skipping the scene if it has the only child.
though the reduced size is too trivial size (avg 0.4% as far as I checked our example svgs),
we can reduce the loading job & runtime memory as well.
Skip to save transform data by accumulating them through the scene tree,
and then applying the final transform to the path points.
Assume that each transform have 36 bytes, it could be increased linear to paints node count
if every paints has transform in the worst case.
Fudamentally, this save their memory and only remains to Bitmap Pictures,
also helps to reduce the loading/rendering workloads since
it doesn't need to perform any transform jobs after converting.
tvg file stores the version info of thorvg when it's generated,
in order to compare it with the runtime thorvg version when it's loaded.
For this, thorvg builds up the current version of symbol on the initilaization step,
that can be referred by the tvg loader.
This reduces tvg binary format size by converting PathCommand to more compact size.
This optimization increase +12% compress rate with our example:
195,668 => 174,071 (sum of all converted tvgs from svgs)
@Issues: https://github.com/Samsung/thorvg/issues/639