Commit Graph

77310 Commits

Author SHA1 Message Date
Benjamin Otte
e88d753f64 path: Handle segments of degenerate curves via lines
When curves have long straight parts that decompose into a single line,
don't try to split them. Instead, split at a well-known position and a
the part of that long straight line as a line.

This gives way more accurate numbers and is more accurate than 1% for
everything but contours with very small weight and
start_point == end_point, where the error is closer to 1.5%.
2023-07-31 16:51:04 +02:00
Benjamin Otte
34c52b4683 curve: Add a reason to decomposition
When decomposing curves that are too straight, we may emit lines for
long parts of the curve. These lines do not properly map
  t => distance
and it is better to treat them as a regular line than a curve.

This reason argument gives that information.

No users so far, that will happen in followup commits.
2023-07-31 16:51:04 +02:00
Benjamin Otte
ed737beda1 path: Move gsk_path_new_from_cairo() away
This is a regular path creation API, so treat it that way.

On top, it is rather awkward if the only constructor for a path that is
immediately visible to people reading the docs is the one that takes a
Cairo path - when we want to deprecate Cairo.
2023-07-31 16:51:04 +02:00
Matthias Clasen
5c7c452ea3 gtk-demo: Rewrite the text mask demo
Use GtkSnapshot and GskPath instead of cairo for this.
2023-07-31 16:51:04 +02:00
Benjamin Otte
25277d4d9e gtk-demo: Make path-text demo use gsk_builder_add_layout() 2023-07-31 16:51:04 +02:00
Matthias Clasen
a11d9cb942 path fill demo: Use gsk_path_builder_add_layout
We have an api now to hide the cairo use.
2023-07-31 16:51:04 +02:00
Matthias Clasen
49e3e8242a gsk: Add gsk_path_builder_add_layout
This api makes it easy to turn text into a path that
can be further manipulated. The implementation currently
goes via cairo.
2023-07-31 16:51:04 +02:00
Benjamin Otte
bae72fd737 path: Add gsk_path_builder_add_ellipse() 2023-07-31 16:51:04 +02:00
Benjamin Otte
4d4f4791e4 path: Change semantics of gtk_path_builder_add_segment()
Allow start >= end to mean that the path continues at the beginning
after reaching the end until it reaches the point at @end.
2023-07-31 16:51:04 +02:00
Benjamin Otte
ea3983b9ab path: Add gsk_path_measure_is_closed () 2023-07-31 16:51:04 +02:00
Benjamin Otte
c410e0510d path: Add gsk_path_measure_restrict_to_contour() 2023-07-31 16:51:04 +02:00
Matthias Clasen
67ee3ba0a3 Add gsk_path_measure_get_{path,tolerance}
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.
2023-07-31 16:51:04 +02:00
Benjamin Otte
2f7ef4832e xxx path)_fill 2023-07-31 16:51:04 +02:00
Matthias Clasen
f728418d22 Add gsk_path_get_stroke_bounds
A relatively cheap way to get bounds for the area
that would be affected by stroking a path.
2023-07-31 16:51:04 +02:00
Benjamin Otte
5328e6d1ca testsuite: Add tests for the dasher 2023-07-31 16:51:04 +02:00
Benjamin Otte
70319b0316 path: Add a foreach function that dashes a path 2023-07-31 16:51:04 +02:00
Benjamin Otte
eb543bc58b path: Deal with non-uniformness of progress parameter
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.
2023-07-31 16:51:04 +02:00
Benjamin Otte
e277bcdd12 path: Always decompose conics into at least 2 segments
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.
2023-07-31 16:51:04 +02:00
Matthias Clasen
e52d9d55a8 testsuite Add curve tangent tests 2023-07-31 16:51:04 +02:00
Benjamin Otte
b66935f168 testsuite: Add a test for the conic that got us segment() 2023-07-31 16:51:04 +02:00
Benjamin Otte
947e813d4b path: Add gsk_curve_segment()
Using split() twice with scaled t values does not work with conics.
2023-07-31 16:51:04 +02:00
Benjamin Otte
673d85ff16 testsuite: Add a test for gsk_curve_decompose() 2023-07-31 16:51:04 +02:00
Benjamin Otte
5a85046c09 testuite: Add tests for gsk_curve_get_tangent() 2023-07-31 16:51:04 +02:00
Matthias Clasen
887c1ff416 testuite: Add tests for gsk_curve_get_point()
Add a few tests for gsk_curve_get_point().

Since GskCurve is not public api, we add gskcurve.c
as source to the test binary.
2023-07-31 16:51:04 +02:00
Benjamin Otte
5877155c40 curve: Split eval() into get_point() and get_tangent()
That's more in line with the get_start/end_point/tangent() functions.

Plus, those calls are independent and we usually want one or the other.
2023-07-31 16:51:04 +02:00
Matthias Clasen
041b9170cc Add gsk_curve_get_{start,end}_tangent
Add a way to get the tangents at the start and end of the curve.
This will be used in stroking.
2023-07-31 16:51:04 +02:00
Benjamin Otte
968f5aea61 testsuite: Add conics to the random paths 2023-07-31 16:51:04 +02:00
Benjamin Otte
2badf27114 path: Add GskCurve
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.
2023-07-31 16:51:04 +02:00
Benjamin Otte
0a05d864d1 path: Introduce gskpathop
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.
2023-07-31 16:51:04 +02:00
Benjamin Otte
46fe43c5df WIP: css: Replace border rendering code with GskPath
The weight is wrong still, I need to compute the correct one to get real
45deg circle corners and not just roughly correct ones.
2023-07-31 16:51:04 +02:00
Benjamin Otte
74164440f6 WIP: pathbuilder: Add gsk_path_builder_add_rounded_rect()
It works, but does not use a custom contour yet.
2023-07-31 16:51:04 +02:00
Benjamin Otte
0cea93777a path: Add conic curves
So far this just adds the API, if you use it, you'll get lots of
g_warnings().

This will be fixed in future commits.
2023-07-31 16:51:04 +02:00
Benjamin Otte
70077d9a2a path: Rename to gtk_path_builder_add_segment()
It's about bulding paths, not about measuring them.
2023-07-31 16:51:04 +02:00
Benjamin Otte
df34aceee1 path: Split contours into their own file
I'm not sure I want to keep all contours in one file, but for now that's
how it is.
2023-07-31 16:51:04 +02:00
Benjamin Otte
70c6756639 path: Make all private contour APIs take a GskContour
... instead of a path, index tuple.
2023-07-31 16:51:04 +02:00
Benjamin Otte
63398ea869 stroke: Add support for dashes
... and hook it up in the node parser and for Cairo rendering.
2023-07-31 16:51:04 +02:00
Matthias Clasen
d315e0687e gsk: Implement parsing fill and stroke nodes
Make serialization and deserialization work for stroke and
fill nodes.
2023-07-31 16:51:04 +02:00
Benjamin Otte
89c63d1517 path: Add flags to gsk_path_foreach()
This way we can default to the siplest possible foreach() output - like
cairo_copy_path_flat() decomposing everything into lines - and add flags
to get more and more fancy.

This will be useful to have conics automatically decomposed for Cairo
drawing or if we want to add more line types in the future.
2023-07-31 16:51:04 +02:00
Benjamin Otte
3c5369a9ff testsuite: Add an in_fill() test 2023-07-31 16:51:04 +02:00
Matthias Clasen
e81e80e069 Implement gsk_path_measure_in_fill
Implement this in the obvious way, using the decomposed form
of standard contours. Since the decomposed form is part of the
measure object, this api moves from gsk_path_in_fill to
gsk_path_measure_in_fill.
2023-07-31 16:51:04 +02:00
Benjamin Otte
6dba706a9a testsuite: Add a parsing test
This test includes an implementation of a gsk_path_equal() func with
a tolerance that is necessary because parsing does not always work
100% exactly due to floating point rounding, so we can't just
compare the to_string() output.
2023-07-31 16:51:04 +02:00
Matthias Clasen
673e92645a path: Special-case rects and circles
Write out the commands for rects and circles in a special
way, and add code in the parser to recognize this, so we
can successfully round-trip these through the SVG path format.

The special way - for people who want to use it for debugging -
for now is that we use uppercase "Z" to close standard paths, but
lowercase "z" to close our special paths.

A test is included, but the random path serializations should take care
of it, too.
2023-07-31 16:51:04 +02:00
Matthias Clasen
8ef4b40e97 path: Fix serialization for circles
The svg A can not do a full circle, since it is a two point
parametrization - if the start and end point are the same,
it draws nothing. So, use two arcs.
2023-07-31 16:51:04 +02:00
Benjamin Otte
0ab25f0580 testsuite: Add librsvg path tests 2023-07-31 16:51:04 +02:00
Matthias Clasen
192bf4bbbe path: Implement gsk_path_parse
Implement the SVG path syntax to read back the strings
that we generate when serializing paths. The tests for
this code are taken from librsvg.

This includes an elliptical arc implementation according
to the SVG spec. The code is mostly taken from librsvg,
but pretty directly follows the SVG spec implementation
notes. We don't export this, since the parametrization
is inconvenient. We do want an arc_to API, but
these are not the arcs we are looking for.
2023-07-31 16:51:04 +02:00
Matthias Clasen
bddffb08cc path: Implement SVG arcs
This is elliptical arc implementation according to the SVG spec.
The code is mostly taken from librsvg, but pretty directly
follows the SVG spec implementation notes.

We don't export this, since the parametrization is inconvenient.
We do want an arc_to API, but these are not the arcs we are
looking for.

It will be used in parsing SVG path syntax.
2023-07-31 16:51:04 +02:00
Matthias Clasen
84dbd7c46f stroke: Add miter limit
Add a miter limit to GskStroke. This will be needed to
fully implement line joins.

Also introduce the GSK_LINE_JOIN_MITER_CLIP value,
following SVG 2.0. cairo does not have it, so translate
it to plain miter when using cairo.
2023-07-31 16:51:04 +02:00
Matthias Clasen
4487cafd40 Documentation typo fixes 2023-07-31 16:51:04 +02:00
Benjamin Otte
2f930f93cc testsuite: Add relative path functions
They're making the paths slightly weirder, but they test public API, so
woohoo!
2023-07-31 16:51:04 +02:00
Benjamin Otte
0a947d9a6a pathbuilder: Add relative path commands
And gsk_path_builder_get_current_point().

They will be needed by the string parser.
2023-07-31 16:51:04 +02:00