Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen
c543854e24 Revise gsk_path_foreach
Make this struct-based.
2023-08-25 21:25:27 -04:00
24 changed files with 250 additions and 323 deletions

77
NEWS
View File

@@ -1,81 +1,6 @@
Overview of Changes in 4.13.1, xx-xx-xxxx
Overview of Changes in 4.13.0, xx-xx-xxxx
=========================================
Overview of Changes in 4.13.0, 25-08-2023
=========================================
* GskPath, GskPathBuilder, GskPathMeasure:
Data types and APIs for path rendering. These APIs are still
considered experimental, and may change until 4.14. Please try
them out and give us feedback. Documentation can be found
here: https://docs.gtk.org/gsk4/paths.html
* GtkGridView:
- Fix a crash when scrolling
* GtkColumnView:
- Fix a refcounting issue in the new scroll_to api
* GtkTreeView
- Fix style classes for sort arrows
* GtkEntry:
- Improve tracking of user changes (for undo)
* GtkNotebook:
- Fix a critical when switching pages
* GtkColor/FontDialogButton:
- Make these widgets activatable
* GtkMenuButton:
- Fix problems with focus handling
- Fix problems with DND
- Make flags a settable property
* GtkShortcutsWindow:
- Add API to build shortcuts windows programmatically
* Printing
- Fix the cpdb backend build
* MacOS:
- Make file filters work again
* GSK:
- Fix issues with color matrix nodes
* Wayland:
- Fix a crash with compositors other than gnome-shell
* Deprecations:
- Remaining GtkTreeModel-related types
* Demos:
- Add a few path demos to gtk4-demo
* Tools:
- gtk4-path-tool provides a commandline interface for paths
* Translation updates:
Basque
Catalan
Finnish
Galician
Georgian
German
Greek
Indonesian
Kazakh
Persian
Polish
Romanian
Spanish
Swedish
Turkish
Ukrainian
Overview of Changes in 4.12.0, 05-08-2023
=========================================

View File

@@ -104,20 +104,19 @@ gtk_path_transform_point (GskPathMeasure *measure,
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gtk_path_transform_op (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
switch (control->op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], &transform->offset, transform->scale, &res);
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
@@ -125,7 +124,7 @@ gtk_path_transform_op (GskPathOperation op,
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res);
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
@@ -133,8 +132,8 @@ gtk_path_transform_op (GskPathOperation op,
case GSK_PATH_QUAD:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &control->quad.control, &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[1]);
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
}
break;
@@ -142,9 +141,9 @@ gtk_path_transform_op (GskPathOperation op,
case GSK_PATH_CUBIC:
{
graphene_point_t res[3];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[2], &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[2]);
gtk_path_transform_point (transform->measure, &control->cubic.control1, &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &control->cubic.control2, &transform->offset, transform->scale, &res[1]);
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[2]);
gsk_path_builder_cubic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, res[2].x, res[2].y);
}
break;
@@ -152,9 +151,9 @@ gtk_path_transform_op (GskPathOperation op,
case GSK_PATH_CONIC:
{
graphene_point_t res[2];
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, &pts[3], &transform->offset, transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, weight);
gtk_path_transform_point (transform->measure, &control->conic.control, &transform->offset, transform->scale, &res[0]);
gtk_path_transform_point (transform->measure, end, &transform->offset, transform->scale, &res[1]);
gsk_path_builder_conic_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y, control->conic.weight);
}
break;

View File

@@ -147,18 +147,6 @@ Creates a node like `gsk_cross_fade_node_new()` with the given properties.
Creates a node like `gsk_debug_node_new()` with the given properties.
### fill
| property | syntax | default | printed |
| -------- | ---------------- | ---------------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| fill-rule| `<fill-rule>` | winding | always |
Creates a node like `gsk_fill_node_new()` with the given properties.
The default child node is created with the bounds of the path.
### glshader
| property | syntax | default | printed |
@@ -301,23 +289,6 @@ Creates a node like `gsk_rounded_clip_node_new()` with the given properties.
Creates a node like `gsk_shadow_node_new()` with the given properties.
### stroke
| property | syntax | default | printed |
| ----------- | ------------------ | ----------------- | ----------- |
| child | `<node>` | *see below* | always |
| path | `<string>` | "" | always |
| line-width | `<number>` | 0 | non-default |
| line-cap | `<line-cap>` | butt | always |
| line-join | `<line-join>` | miter | always |
| miter-limit | `<number>` | 4 | non-default |
| dash | `<number>{+}|none` | none | non-default |
| dash-offset | `<number>` | 0 | non-default |
Creates a node like `gsk_stroke_node_new()` with the given properties.
The default child node is created with the stroke bounds of the path.
### text
| property | syntax | default | printed |

View File

@@ -95,11 +95,10 @@ static gboolean
gdk_gl_texture_invoke_callback (gpointer data)
{
InvokeData *invoke = data;
GdkGLContext *context, *previous;
GdkGLContext *context;
context = gdk_display_get_gl_context (gdk_gl_context_get_display (invoke->self->context));
previous = gdk_gl_context_get_current ();
gdk_gl_context_make_current (context);
if (invoke->self->sync && context != invoke->self->context)
@@ -111,11 +110,6 @@ gdk_gl_texture_invoke_callback (gpointer data)
g_atomic_int_set (&invoke->spinlock, 1);
if (previous)
gdk_gl_context_make_current (previous);
else
gdk_gl_context_clear_current ();
return FALSE;
}

View File

@@ -381,7 +381,10 @@ gsk_line_curve_decompose_curve (const GskCurve *curve,
{
const GskLineCurve *self = &curve->line;
return add_curve_func (GSK_PATH_LINE, self->points, 2, 0.f, user_data);
return add_curve_func (&self->points[0],
&self->points[1],
&(GskPathControl) { .op = GSK_PATH_LINE },
user_data);
}
static void
@@ -705,9 +708,10 @@ gsk_curve_add_line_cb (const graphene_point_t *from,
gpointer user_data)
{
AddLineData *data = user_data;
graphene_point_t p[2] = { *from, *to };
return data->add_curve (GSK_PATH_LINE, p, 2, 0.f, data->user_data);
return data->add_curve (from, to,
&(GskPathControl) { .op = GSK_PATH_LINE },
data->user_data);
}
static gboolean
@@ -720,13 +724,30 @@ gsk_quad_curve_decompose_curve (const GskCurve *curve,
const GskQuadCurve *self = &curve->quad;
if (flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return add_curve_func (GSK_PATH_QUAD, self->points, 3, 0.f, user_data);
return add_curve_func (&self->points[0],
&self->points[2],
&(GskPathControl) {
.op = GSK_PATH_QUAD,
.quad = (GskQuadControl) {
.control = self->points[1],
},
},
user_data);
else if (flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{
GskCurve c;
gsk_curve_elevate (curve, &c);
return add_curve_func (GSK_PATH_CUBIC, c.cubic.points, 4, 0.f, user_data);
return add_curve_func (&c.cubic.points[0],
&c.cubic.points[3],
&(GskPathControl) {
.op = GSK_PATH_CUBIC,
.cubic = (GskCubicControl) {
.control1 = c.cubic.points[1],
.control2 = c.cubic.points[2],
},
},
user_data);
}
else
{
@@ -1180,7 +1201,16 @@ gsk_cubic_curve_decompose_curve (const GskCurve *curve,
const GskCubicCurve *self = &curve->cubic;
if (flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
return add_curve_func (GSK_PATH_CUBIC, self->points, 4, 0.f, user_data);
return add_curve_func (&self->points[0],
&self->points[3],
&(GskPathControl) {
.op = GSK_PATH_CUBIC,
.cubic = (GskCubicControl) {
.control1 = self->points[1],
.control2 = self->points[2],
},
},
user_data);
/* FIXME: Quadratic or arc approximation */
return gsk_cubic_curve_decompose (curve,
@@ -1854,7 +1884,16 @@ gsk_conic_curve_decompose_or_add (const GskCurve *curve,
gpointer user_data)
{
if (gsk_conic_is_close_to_cubic (curve, cubic, tolerance))
return add_curve_func (GSK_PATH_CUBIC, cubic->cubic.points, 4, 0.f, user_data);
return add_curve_func (&cubic->cubic.points[0],
&cubic->cubic.points[3],
&(GskPathControl) {
.op = GSK_PATH_CUBIC,
.cubic = (GskCubicControl) {
.control1 = cubic->cubic.points[1],
.control2 = cubic->cubic.points[2],
},
},
user_data);
else
{
GskCurve c1, c2;
@@ -1881,13 +1920,16 @@ gsk_conic_curve_decompose_curve (const GskCurve *curve,
GskCurve c;
if (flags & GSK_PATH_FOREACH_ALLOW_CONIC)
return add_curve_func (GSK_PATH_CONIC,
(const graphene_point_t[3]) { self->points[0],
self->points[1],
self->points[3] },
3,
self->points[2].x,
user_data);
return add_curve_func (&self->points[0],
&self->points[3],
&(GskPathControl) {
.op = GSK_PATH_CONIC,
.conic = (GskConicControl) {
.control = self->points[1],
.weight = self->points[2].x
},
},
user_data);
if (flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{

View File

@@ -102,10 +102,9 @@ typedef gboolean (* GskCurveAddLineFunc) (const graphene_point_t *from,
GskCurveLineReason reason,
gpointer user_data);
typedef gboolean (* GskCurveAddCurveFunc) (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
typedef gboolean (* GskCurveAddCurveFunc) (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer user_data);
void gsk_curve_init (GskCurve *curve,

View File

@@ -177,7 +177,7 @@ gsk_path_get_flags (const GskPath *self)
* Converts @self into a human-readable string representation suitable
* for printing.
*
* The string is compatible with (a superset of)
* The string is compatible with
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* see [func@Gsk.Path.parse] for a summary of the syntax.
*
@@ -231,16 +231,15 @@ gsk_path_to_string (GskPath *self)
}
static gboolean
gsk_path_to_cairo_add_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gsk_path_to_cairo_add_op (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer cr)
{
switch (op)
switch (control->op)
{
case GSK_PATH_MOVE:
cairo_move_to (cr, pts[0].x, pts[0].y);
cairo_move_to (cr, end->x, end->y);
break;
case GSK_PATH_CLOSE:
@@ -248,11 +247,13 @@ gsk_path_to_cairo_add_op (GskPathOperation op,
break;
case GSK_PATH_LINE:
cairo_line_to (cr, pts[1].x, pts[1].y);
cairo_line_to (cr, end->x, end->y);
break;
case GSK_PATH_CUBIC:
cairo_curve_to (cr, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
cairo_curve_to (cr, control->cubic.control1.x, control->cubic.control1.y,
control->cubic.control2.x, control->cubic.control2.y,
end->x, end->y);
break;
case GSK_PATH_QUAD:
@@ -421,7 +422,6 @@ gsk_path_get_bounds (GskPath *self,
*
* Returns: `TRUE` if the path has bounds, `FALSE` if the path is known
* to be empty and have no bounds.
*
* Since: 4.14
*/
gboolean
@@ -669,64 +669,65 @@ gsk_path_foreach_trampoline_add_line (const graphene_point_t *from,
{
GskPathForeachTrampoline *trampoline = data;
return trampoline->func (GSK_PATH_LINE,
(graphene_point_t[2]) { *from, *to },
2,
0.f,
return trampoline->func (from, to,
&(GskPathControl) { GSK_PATH_LINE, },
trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline_add_curve (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gsk_path_foreach_trampoline_add_curve (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (start, end, control, trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gsk_path_foreach_trampoline (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
switch (op)
switch (control->op)
{
case GSK_PATH_MOVE:
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (start, end, control, trampoline->user_data);
case GSK_PATH_QUAD:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (start, end, control, trampoline->user_data);
else if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{
return trampoline->func (GSK_PATH_CUBIC,
(graphene_point_t[4]) {
pts[0],
GRAPHENE_POINT_INIT ((pts[0].x + 2 * pts[1].x) / 3,
(pts[0].y + 2 * pts[1].y) / 3),
GRAPHENE_POINT_INIT ((pts[2].x + 2 * pts[1].x) / 3,
(pts[2].y + 2 * pts[1].y) / 3),
pts[2],
return trampoline->func (start,
end,
&(GskPathControl) {
.op = GSK_PATH_CUBIC,
.cubic = (GskCubicControl) {
.control1 = GRAPHENE_POINT_INIT ((start->x + 2 * control->quad.control.x) / 3,
(start->y + 2 * control->quad.control.y) / 3),
.control2 = GRAPHENE_POINT_INIT ((end->x + 2 * control->quad.control.x) / 3,
(end->y + 2 * control->quad.control.y) / 3),
},
},
4,
weight,
trampoline->user_data);
}
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_QUAD, pts));
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_QUAD,
(graphene_point_t[3]) {
*start,
control->quad.control,
*end,
} ));
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
@@ -738,9 +739,15 @@ gsk_path_foreach_trampoline (GskPathOperation op,
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (start, end, control, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CUBIC, pts));
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CUBIC,
(const graphene_point_t[4]) {
*start,
control->cubic.control1,
control->cubic.control2,
*end,
}));
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CONIC))
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
@@ -759,9 +766,15 @@ gsk_path_foreach_trampoline (GskPathOperation op,
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CONIC)
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (start, end, control, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CONIC, (graphene_point_t[4]) { pts[0], pts[1], { weight, 0.f }, pts[2] } ));
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CONIC,
(graphene_point_t[4]) {
*start,
control->conic.control,
{ control->conic.weight, 0.f },
*end
} ));
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CUBIC))
return gsk_curve_decompose_curve (&curve,
trampoline->flags,

View File

@@ -53,21 +53,50 @@ typedef enum
GSK_PATH_FOREACH_ALLOW_CONIC = (1 << 2),
} GskPathForeachFlags;
typedef struct _GskQuadControl GskQuadControl;
struct _GskQuadControl
{
graphene_point_t control;
};
typedef struct _GskCubicControl GskCubicControl;
struct _GskCubicControl
{
graphene_point_t control1;
graphene_point_t control2;
};
typedef struct _GskConicControl GskConicControl;
struct _GskConicControl
{
graphene_point_t control;
float weight;
};
typedef struct _GskPathControl GskPathControl;
struct _GskPathControl
{
GskPathOperation op;
union {
GskQuadControl quad;
GskCubicControl cubic;
GskConicControl conic;
};
};
/**
* GskPathForeachFunc:
* @op: The operation
* @pts: The points of the operation
* @n_pts: The number of points
* @weight: The weight for conic curves, or unused if not a conic curve
* @start: The start point of the operation
* @end: The end point of the operation
* @control: The control data for the operation
* @user_data: The user data provided with the function
*
* Prototype of the callback to iterate through the operations of
* a path.
*
* For each operation, the callback is given the @op itself, the points
* that the operation is applied to in @pts, and a @weight for conic
* curves. The @n_pts argument is somewhat redundant, since the number
* of points can be inferred from the operation.
* For each operation, the callback is given the @op itself, the start-
* and endpoint, and the control data, depending on the kind of operation.
*
* Each contour of the path starts with a @GSK_PATH_MOVE operation.
* Closed contours end with a @GSK_PATH_CLOSE operation.
@@ -75,10 +104,9 @@ typedef enum
* Returns: %TRUE to continue iterating the path, %FALSE to
* immediately abort and not call the function again.
*/
typedef gboolean (* GskPathForeachFunc) (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
typedef gboolean (* GskPathForeachFunc) (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer user_data);
#define GSK_TYPE_PATH (gsk_path_get_type ())

View File

@@ -64,7 +64,7 @@
* [method@Gsk.PathBuilder.close] to close the path by connecting it
* back with a line to the starting point.
*
* This is similar to how paths are drawn in Cairo.
* This is similar for how paths are drawn in Cairo.
*
* Since: 4.14
*/
@@ -240,7 +240,7 @@ gsk_path_builder_unref (GskPathBuilder *self)
* @self: a `GskPathBuilder`
*
* Creates a new `GskPath` from the current state of the
* given builder, and unrefs the @builder instance.
* given builder, and frees the @builder instance.
*
* Returns: (transfer full): the newly created `GskPath`
* with all the contours added to the builder
@@ -310,14 +310,12 @@ gsk_path_builder_add_contour (GskPathBuilder *self,
* gsk_path_builder_get_current_point:
* @self: a `GskPathBuilder`
*
* Gets the current point.
* Gets the current point. The current point is used for relative
* drawing commands and updated after every operation.
*
* The current point is used for relative drawing commands and
* updated after every operation.
*
* When the builder is created, the default current point is set
* to `0, 0`. Note that this is different from cairo, which starts
* out without a current point.
* When the builder is created, the default current point is set to (0, 0).
* Note that this is different from cairo, which starts out without
* a current point.
*
* Returns: (transfer none): The current point
*
@@ -830,9 +828,7 @@ gsk_path_builder_cubic_to (GskPathBuilder *self,
*
* Adds a [cubic Bézier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve)
* from the current point to @x3, @y3 with @x1, @y1 and @x2, @y2 as the control
* points.
*
* All coordinates are given relative to the current point.
* points. All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.cubic_to].
*
@@ -869,7 +865,7 @@ gsk_path_builder_rel_cubic_to (GskPathBuilder *self,
*
* Adds a [conic curve](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
* from the current point to @x2, @y2 with the given @weight and @x1, @y1 as the
* control point.
* single control point.
*
* The weight determines how strongly the curve is pulled towards the control point.
* A conic with weight 1 is identical to a quadratic Bézier curve with the same points.
@@ -918,9 +914,7 @@ gsk_path_builder_conic_to (GskPathBuilder *self,
*
* Adds a [conic curve](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
* from the current point to @x2, @y2 with the given @weight and @x1, @y1 as the
* control point.
*
* All coordinates are given relative to the current point.
* single control point.
*
* This is the relative version of [method@Gsk.PathBuilder.conic_to].
*
@@ -991,9 +985,8 @@ gsk_path_builder_arc_to (GskPathBuilder *self,
* @y2: y coordinate of second control point
*
* Adds an elliptical arc from the current point to @x3, @y3
* with @x1, @y1 determining the tangent directions.
*
* All coordinates are given relative to the current point.
* with @x1, @y1 determining the tangent directions. All coordinates
* are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.arc_to].
*
@@ -1339,6 +1332,7 @@ angle_between_points (const graphene_point_t *c,
* the circle with the given radius touches the line from
* @x1, @y1 to @x2, @y2.
*
*
* Since: 4.14
*/
void
@@ -1423,7 +1417,8 @@ gsk_path_builder_rel_html_arc_to (GskPathBuilder *self,
* @self: a #GskPathBuilder
* @layout: the pango layout to add
*
* Adds the outlines for the glyphs in @layout to the builder.
* Adds the outlines for the glyphs in @layout to
* the builder.
*
* Since: 4.14
*/

View File

@@ -69,8 +69,7 @@ G_DEFINE_BOXED_TYPE (GskPathMeasure, gsk_path_measure,
* gsk_path_measure_new:
* @path: the path to measure
*
* Creates a measure object for the given @path with the
* default tolerance.
* Creates a measure object for the given @path.
*
* Returns: a new `GskPathMeasure` representing @path
*

View File

@@ -89,23 +89,50 @@ gsk_pathop_foreach (gskpathop pop,
switch (gsk_pathop_op (pop))
{
case GSK_PATH_MOVE:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 1, 0, user_data);
return func (&GRAPHENE_POINT_INIT (0, 0),
&gsk_pathop_points (pop)[0],
&(GskPathControl) { .op = gsk_pathop_op (pop), },
user_data);
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 2, 0, user_data);
return func (&gsk_pathop_points (pop)[0],
&gsk_pathop_points (pop)[1],
&(GskPathControl) { .op = gsk_pathop_op (pop), },
user_data);
case GSK_PATH_QUAD:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 3, 0, user_data);
return func (&gsk_pathop_points (pop)[0],
&gsk_pathop_points (pop)[2],
&(GskPathControl) {
.op = gsk_pathop_op (pop),
.quad = (GskQuadControl) { gsk_pathop_points (pop)[1] }
},
user_data);
case GSK_PATH_CUBIC:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 4, 0, user_data);
return func (&gsk_pathop_points (pop)[0],
&gsk_pathop_points (pop)[3],
&(GskPathControl) {
.op = gsk_pathop_op (pop),
.cubic = (GskCubicControl) {
.control1 = gsk_pathop_points (pop)[1],
.control2 = gsk_pathop_points (pop)[2]
},
},
user_data);
case GSK_PATH_CONIC:
{
const graphene_point_t *pts = gsk_pathop_points (pop);
return func (gsk_pathop_op (pop), (graphene_point_t[3]) { pts[0], pts[1], pts[3] }, 3, pts[2].x, user_data);
}
return func (&gsk_pathop_points (pop)[0],
&gsk_pathop_points (pop)[3],
&(GskPathControl) {
.op = gsk_pathop_op (pop),
.conic = (GskConicControl) {
.control = gsk_pathop_points (pop)[1],
.weight = gsk_pathop_points (pop)[2].x
},
},
user_data);
default:
g_assert_not_reached ();

View File

@@ -34,12 +34,10 @@
*
* `GskPathPoint` is an opaque type representing a point on a path.
*
* It can be queried for properties of the path at that point, such as
* its tangent or its curvature.
* It can be queried for properties of the path at that point, such as its
* tangent or its curvature.
*
* To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point],
* [method@Gsk.Path.get_start_point], [method@Gsk.Path.get_end_point]
* or [method@Gsk.PathMeasure.get_point].
* To obtain a `GskPathPoint`, use [method@Gsk.Path.get_closest_point].
*
* Note that `GskPathPoint` structs are meant to be stack-allocated, and
* don't a reference to the path object they are obtained from. It is the
@@ -87,8 +85,6 @@ gsk_path_point_free (GskPathPoint *point)
* same location.
*
* Return: `TRUE` if @point1 and @point2 are equal
*
* Since: 4.14
*/
gboolean
gsk_path_point_equal (const GskPathPoint *point1,
@@ -118,8 +114,6 @@ gsk_path_point_equal (const GskPathPoint *point1,
* Returns: -1 if @point1 is before @point2,
* 1 if @point1 is after @point2,
* 0 if they are equal
*
* Since: 4.14
*/
int
gsk_path_point_compare (const GskPathPoint *point1,

View File

@@ -1172,16 +1172,10 @@ create_default_texture (void)
return texture;
}
static GskRenderNode *
create_default_render_node_with_bounds (const graphene_rect_t *rect)
{
return gsk_color_node_new (&GDK_RGBA("FF00CC"), rect);
}
static GskRenderNode *
create_default_render_node (void)
{
return create_default_render_node_with_bounds (&GRAPHENE_RECT_INIT (0, 0, 50, 50));
return gsk_color_node_new (&GDK_RGBA("FF00CC"), &GRAPHENE_RECT_INIT (0, 0, 50, 50));
}
static GskPath *
@@ -2260,14 +2254,10 @@ parse_fill_node (GtkCssParser *parser,
GskRenderNode *result;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
if (child == NULL)
child = create_default_render_node ();
if (path == NULL)
path = create_default_path ();
if (child == NULL)
{
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
child = create_default_render_node_with_bounds (&bounds);
}
result = gsk_fill_node_new (child, path, rule);
@@ -2321,6 +2311,8 @@ parse_stroke_node (GtkCssParser *parser,
GskRenderNode *result;
parse_declarations (parser, context, declarations, G_N_ELEMENTS (declarations));
if (child == NULL)
child = create_default_render_node ();
if (path == NULL)
path = create_default_path ();
@@ -2335,13 +2327,6 @@ parse_stroke_node (GtkCssParser *parser,
}
gsk_stroke_set_dash_offset (stroke, dash_offset);
if (child == NULL)
{
graphene_rect_t bounds;
gsk_path_get_stroke_bounds (path, stroke, &bounds);
child = create_default_render_node_with_bounds (&bounds);
}
result = gsk_stroke_node_new (child, path, stroke);
gsk_path_unref (path);

View File

@@ -368,7 +368,7 @@ gsk_stroke_get_miter_limit (const GskStroke *self)
* gsk_stroke_set_dash:
* @self: a `GskStroke`
* @dash: (array length=n_dash) (transfer none) (nullable):
* the array of dashes
* the array of dashes
* @n_dash: number of elements in @dash
*
* Sets the dash pattern to use by this stroke.

View File

@@ -1,5 +1,5 @@
project('gtk', 'c',
version: '4.13.1',
version: '4.13.0',
default_options: [
'buildtype=debugoptimized',
'warning_level=1',

View File

@@ -295,8 +295,6 @@ node_parser_tests = [
'empty-transform.ref.node',
'fill.node',
'fill.ref.node',
'fill2.node',
'fill2.ref.node',
'glshader.node',
'glshader.ref.node',
'glshader.errors',

View File

@@ -1,6 +1,6 @@
fill {
child: color {
bounds: 1.22359 0 47.5528 45.2254;
bounds: 0 0 50 50;
color: rgb(255,0,204);
}
path: "\

View File

@@ -1,6 +1,6 @@
stroke {
child: color {
bounds: -2.77641 -4 55.5528 53.2254;
bounds: 0 0 50 50;
color: rgb(255,0,204);
}
path: "\

View File

@@ -1,4 +0,0 @@
fill {
path: "M 0 0 O 10 10 20 20 5";
fill-rule: even-odd;
}

View File

@@ -1,9 +0,0 @@
fill {
child: color {
bounds: 0 0 20 20;
color: rgb(255,0,204);
}
path: "\
M 0 0 O 10 10, 20 20, 5";
fill-rule: even-odd;
}

View File

@@ -1,10 +0,0 @@
stroke {
child: color { bounds: 0 0 100 100; color: red; }
path: "M 10, 10 L 90, 90 M 90, 10 L 10, 90";
line-width: 2.5;
line-cap: butt;
line-join: miter;
miter-limit: 3.1;
dash: 0 1 4.5 10;
dash-offset: 2.1;
}

View File

@@ -1,17 +0,0 @@
stroke {
child: color {
bounds: 0 0 100 100;
color: rgb(255,0,0);
}
path: "\
M 10 10\
L 90 90\
M 90 10\
L 10 90";
line-width: 2.5;
line-cap: butt;
line-join: miter;
miter-limit: 3.1;
dash: 0 1 4.5 10;
dash-offset: 2.1;
}

View File

@@ -25,18 +25,17 @@
#include <glib/gi18n-lib.h>
static gboolean
foreach_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
foreach_cb (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
switch (op)
switch (control->op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
gsk_path_builder_move_to (builder, end->x, end->y);
break;
case GSK_PATH_CLOSE:
@@ -44,24 +43,24 @@ foreach_cb (GskPathOperation op,
break;
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, end->x, end->y);
break;
case GSK_PATH_QUAD:
gsk_path_builder_quad_to (builder, pts[1].x, pts[1].y,
pts[2].x, pts[2].y);
gsk_path_builder_quad_to (builder, control->quad.control.x, control->quad.control.y,
end->x, end->y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_cubic_to (builder, pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
pts[3].x, pts[3].y);
gsk_path_builder_cubic_to (builder, control->cubic.control1.x, control->cubic.control1.y,
control->cubic.control2.x, control->cubic.control2.y,
end->x, end->y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
weight);
gsk_path_builder_conic_to (builder, control->conic.control.x, control->conic.control.y,
end->x, end->y,
control->conic.weight);
break;
default:

View File

@@ -35,17 +35,16 @@ typedef struct
} Statistics;
static gboolean
stats_cb (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
stats_cb (const graphene_point_t *start,
const graphene_point_t *end,
const GskPathControl *control,
gpointer user_data)
{
Statistics *stats = user_data;
stats->ops++;
switch (op)
switch (control->op)
{
case GSK_PATH_MOVE:
stats->contours++;