Implement gsk_contour_default_add_stroke, which takes a contour
and stroke parameters, and adds contours to a path builder for
the outline that woul be produced by stroking the path with these
parameters.
The current implementation does not try to handle short segments
in the vicinity of sharp joins in any special way, so there can
be some artifacts in that situation.
Nothing prevents control points from being identical,
and if that happens, some of our constructions involving
tangents and normals break down. Handle these cases in
get_{start,end}_tangent and offset, for the case of
cubics.
graphene_rect_intersect returns FALSE when you
intersect the bounding boxes of axis-aligned
lines, so we never find intersections with those.
Make things better by making the bounding boxes worse.
The test takes a lottie file and a timestamp in seconds and produces a
rendernode at that timestamp.
It then serializes that node and compares it via diff(1) with a file
containing the expected output.
This is a lot stricter than it needs to be (because different node files
can generate the same output and updates to the rendering pipeline can
break everything) but I chose this method on purpose because it does a
good job at guarding against accidental changes in other parts of the
code.
It's also better than comparing image output because it avoids
antialiasing artifacts when using curves and things like that.
These are just nice apis to have and avoid having to carry
these around as extra arguments in many places.
This was showing up as inconvenience in writing tests
for the measure apis.
The progress is non-uniform, so simple translation of progress doesn't work.
So check if larger and smaller values inch closer towards minimal distance.
Conics are evil in that their parameter skews towards the center, and if
it's a very flat conic (weight almost equal to 0), then we'd approximate
it with a single segment and not subdivide, which would cause the
parameter to be wildly off around 0.25 or 0.75.
And that would cause offset calculations to fail.
GskCurve is an abstraction for path operations. It's essentially a
collection of vfuncs per GskPathOperation.
GskStandardContour has been ported to use it where appropriate.
A gskpathop is a pointer to a graphene_point_t* with the low bits used
to encode the GskPathOperation. It's an easy way to introduce API for
operations.
So far it's just used to replace GskStandardOperation.