Compare commits

..

1 Commits

Author SHA1 Message Date
Matthias Clasen
e155c3fe36 Move path point getters to GskPath
This is more in line with treating GskPathPoint as just
a struct, not an object. And gi-docgen already puts the
apis there anyway. As an extra bonus, the function names
get shorter.

Update all callers.
2023-08-14 10:16:48 -04:00
148 changed files with 5624 additions and 15882 deletions

View File

@@ -30,16 +30,8 @@ variables:
workflow:
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run branch pipelines if corresponding merge requests exist...
# (this avoids duplicate pipelines)
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
# ...but otherwise run branch pipelines
- if: $CI_COMMIT_BRANCH
# run tag pipelines
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH
default:
retry:
@@ -205,32 +197,21 @@ msys2-mingw64:
paths:
- "${CI_PROJECT_DIR}/_build/gtkdll.tar.gz"
macos-x86_64:
macos:
# Sadly, this fails regularly, and its failure is never enlightening
allow_failure: true
rules:
# run merge request pipelines
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# do not run in forks
- if: $CI_PROJECT_NAMESPACE == "GNOME"
stage: build
tags:
- macosintel
- macos
needs: []
variables:
MESON_FORCE_BACKTRACKE: 1
TMPDIR: /Users/Shared/work/tmp
SDKROOT: /opt/sdks/MacOSX10.13.4.sdk
CCACHE_DIR: /Users/Shared/work/ccache
PIP_CACHE_DIR: /Users/Shared/build/cache
PIPENV_CACHE_DIR: $PIP_CACHE_DIR
PYTHONPYCACHEPREFIX: $PIP_CACHE_DIR
before_script:
- bash .gitlab-ci/show-info-osx.sh
- python3 -m venv .venv
- ln -s /opt/cmake/CMake.app/Contents/bin/cmake .venv/bin
- ln -s /opt/ccache/ccache .venv/bin
- source .venv/bin/activate
- pip3 install meson==1.2.0
- pip3 install ninja==1.11.1
- pip3 install --user meson~=1.0
- pip3 install --user ninja
- export PATH=/Users/gitlabrunner/Library/Python/3.7/bin:$PATH
- export MESON_FORCE_BACKTRACE=1
script:
- meson setup ${COMMON_MESON_FLAGS}
-Dx11-backend=false

View File

@@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar
:: FIXME: make warnings fatal
pip3 install --upgrade --user meson~=0.64 || goto :error
meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
meson -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error
ninja -C _build || goto :error
goto :EOF

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

@@ -336,9 +336,6 @@
<file>panes.c</file>
<file>password_entry.c</file>
<file>path_fill.c</file>
<file>path_spinner.c</file>
<file>path_walk.c</file>
<file>path_text.c</file>
<file>peg_solitaire.c</file>
<file>pickers.c</file>
<file>printing.c</file>
@@ -424,13 +421,6 @@
<gresource prefix="/fontrendering">
<file>fontrendering.ui</file>
</gresource>
<gresource prefix="/path_walk">
<file>path_walk.ui</file>
<file compressed="true">path_world.txt</file>
</gresource>
<gresource prefix="/path_text">
<file>path_text.ui</file>
</gresource>
<gresource prefix="/org/gtk/Demo4">
<file>icons/16x16/actions/application-exit.png</file>
<file>icons/16x16/actions/document-new.png</file>

View File

@@ -840,24 +840,24 @@ gtk_gears_unrealize (GtkWidget *widget)
GtkGearsPrivate *priv = gtk_gears_get_instance_private ((GtkGears *) widget);
gtk_gl_area_make_current (glarea);
if (gtk_gl_area_get_error (glarea) == NULL)
{
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (gtk_gl_area_get_error (glarea) != NULL)
return;
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
/* Release the resources associated with OpenGL */
if (priv->gear_vbo[0] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[0]));
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->gear_vbo[1] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[1]));
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->gear_vbo[2] != 0)
glDeleteBuffers (1, &(priv->gear_vbo[2]));
if (priv->program != 0)
glDeleteProgram (priv->program);
}
if (priv->vao != 0)
glDeleteVertexArrays (1, &priv->vao);
if (priv->program != 0)
glDeleteProgram (priv->program);
priv->ModelViewProjectionMatrix_location = 0;
priv->NormalMatrix_location = 0;

View File

@@ -73,9 +73,6 @@ demos = files([
'panes.c',
'password_entry.c',
'path_fill.c',
'path_spinner.c',
'path_walk.c',
'path_text.c',
'peg_solitaire.c',
'pickers.c',
'printing.c',

View File

@@ -177,7 +177,7 @@ do_path_fill (GtkWidget *do_widget)
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Fill and Stroke");
gtk_window_set_title (GTK_WINDOW (window), "Path Fill");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_logo_paintable_new ();

View File

@@ -1,331 +0,0 @@
/* Path/Spinner
*
* This demo shows how to use GskPath to draw a simple animation
* that could be used as a spinner.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "paintable.h"
#define GTK_TYPE_SPINNER_PAINTABLE (gtk_spinner_paintable_get_type ())
G_DECLARE_FINAL_TYPE (GtkSpinnerPaintable, gtk_spinner_paintable, GTK, SPINNER_PAINTABLE, GObject)
struct _GtkSpinnerPaintable
{
GObject parent_instance;
gint64 start_time;
int width;
double angle;
double completion;
GskPath *circle;
GskPath *path;
GskStroke *stroke;
GdkRGBA color;
GdkRGBA circle_color;
#ifdef SHOW_CONTROLS
GskPath *controls;
GdkRGBA control_color;
#endif
};
struct _GtkSpinnerPaintableClass
{
GObjectClass parent_class;
};
static int
gtk_spinner_paintable_get_intrinsic_width (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static int
gtk_spinner_paintable_get_intrinsic_height (GdkPaintable *paintable)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
return self->width;
}
static void
gtk_spinner_paintable_snapshot (GdkPaintable *paintable,
GdkSnapshot *snapshot,
double width,
double height)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (paintable);
gtk_snapshot_append_stroke (snapshot, self->circle, self->stroke, &self->circle_color);
gtk_snapshot_append_stroke (snapshot, self->path, self->stroke, &self->color);
#ifdef SHOW_CONTROLS
GskStroke *stroke = gsk_stroke_new (1);
gtk_snapshot_append_stroke (snapshot, self->controls, stroke, &self->control_color);
gsk_stroke_free (stroke);
#endif
}
static GdkPaintableFlags
gtk_spinner_paintable_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_SIZE;
}
static void
gtk_spinner_paintable_paintable_init (GdkPaintableInterface *iface)
{
iface->get_intrinsic_width = gtk_spinner_paintable_get_intrinsic_width;
iface->get_intrinsic_height = gtk_spinner_paintable_get_intrinsic_height;
iface->snapshot = gtk_spinner_paintable_snapshot;
iface->get_flags = gtk_spinner_paintable_get_flags;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (GtkSpinnerPaintable, gtk_spinner_paintable, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
gtk_spinner_paintable_paintable_init))
static void
gtk_spinner_paintable_dispose (GObject *object)
{
GtkSpinnerPaintable *self = GTK_SPINNER_PAINTABLE (object);
gsk_path_unref (self->circle);
gsk_path_unref (self->path);
#ifdef SHOW_CONTROLS
gsk_path_unref (self->controls);
#endif
gsk_stroke_free (self->stroke);
G_OBJECT_CLASS (gtk_spinner_paintable_parent_class)->dispose (object);
}
static void
gtk_spinner_paintable_class_init (GtkSpinnerPaintableClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_spinner_paintable_dispose;
}
static void
gtk_spinner_paintable_init (GtkSpinnerPaintable *self)
{
}
static GdkPaintable *
gtk_spinner_paintable_new (void)
{
GtkSpinnerPaintable *self;
GskPathBuilder *builder;
self = g_object_new (GTK_TYPE_SPINNER_PAINTABLE, NULL);
builder = gsk_path_builder_new ();
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (50, 50), 40);
self->circle = gsk_path_builder_free_to_path (builder);
self->width = 100;
self->angle = 0;
self->completion = 1;
gdk_rgba_parse (&self->color, "green");
gdk_rgba_parse (&self->circle_color, "lightgray");
#ifdef SHOW_CONTROLS
gdk_rgba_parse (&self->control_color, "black");
#endif
self->stroke = gsk_stroke_new (5);
return GDK_PAINTABLE (self);
}
#ifdef SHOW_CONTROLS
static gboolean
add_controls (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
gpointer data)
{
GskPathBuilder *builder = data;
switch (op)
{
case GSK_PATH_MOVE:
gsk_path_builder_move_to (builder, pts[0].x, pts[0].y);
break;
case GSK_PATH_CLOSE:
case GSK_PATH_LINE:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
case GSK_PATH_ARC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
break;
case GSK_PATH_CUBIC:
gsk_path_builder_line_to (builder, pts[1].x, pts[1].y);
gsk_path_builder_line_to (builder, pts[2].x, pts[2].y);
gsk_path_builder_line_to (builder, pts[3].x, pts[3].y);
break;
default:
g_assert_not_reached ();
}
return TRUE;
}
#endif
static void
update_path (GtkSpinnerPaintable *self)
{
GskPathBuilder *builder;
GskPathPoint start, end;
GskTransform *t;
graphene_point_t p, p0, p1;
float start_angle, end_angle;
p = GRAPHENE_POINT_INIT (40, 0);
start_angle = self->angle;
end_angle = fmod (self->angle + 360 * self->completion / 100, 360);
t = gsk_transform_translate (
gsk_transform_rotate (
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
start_angle),
&GRAPHENE_POINT_INIT (-50, -50));
gsk_transform_transform_point (t, &p, &p0);
t = gsk_transform_translate (
gsk_transform_rotate (
gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (50, 50)),
end_angle),
&GRAPHENE_POINT_INIT (-50, -50));
gsk_transform_transform_point (t, &p, &p1);
g_clear_pointer (&self->path, gsk_path_unref);
gsk_path_get_closest_point (self->circle, &p0, INFINITY, &start);
gsk_path_get_closest_point (self->circle, &p1, INFINITY, &end);
builder = gsk_path_builder_new ();
gsk_path_builder_add_segment (builder, self->circle, &start, &end);
self->path = gsk_path_builder_free_to_path (builder);
#ifdef SHOW_CONTROLS
g_clear_pointer (&self->controls, gsk_path_unref);
builder = gsk_path_builder_new ();
gsk_path_foreach (self->path, -1, add_controls, builder);
self->controls = gsk_path_builder_free_to_path (builder);
#endif
gdk_paintable_invalidate_contents (GDK_PAINTABLE (self));
}
static void
gtk_spinner_paintable_set_completion (GtkSpinnerPaintable *self,
float completion)
{
self->completion = CLAMP (completion, 0, 100);
update_path (self);
}
static float
gtk_spinner_paintable_get_completion (GtkSpinnerPaintable *self)
{
return self->completion;
}
static void
gtk_spinner_paintable_set_frame_time (GtkSpinnerPaintable *self,
gint64 time)
{
double delta;
if (self->start_time == 0)
self->start_time = time;
delta = (time - self->start_time) / (double) G_TIME_SPAN_SECOND;
self->angle = fmod (60 * delta, 360);
update_path (self);
}
static gboolean
tick_cb (GtkWidget *widget,
GdkFrameClock *clock,
gpointer data)
{
GtkSpinnerPaintable *self = data;
gtk_spinner_paintable_set_frame_time (self, gdk_frame_clock_get_frame_time (clock));
return G_SOURCE_CONTINUE;
}
static gboolean
progress_timeout (gpointer data)
{
GtkSpinnerPaintable *self = data;
static float progress_delta = 0.5;
float progress;
progress = gtk_spinner_paintable_get_completion (self);
if (progress >= 100 || progress <= 0)
progress_delta = -progress_delta;
gtk_spinner_paintable_set_completion (self, progress + progress_delta);
return G_SOURCE_CONTINUE;
}
static void
unset_timeout (gpointer data)
{
g_source_remove (GPOINTER_TO_UINT (data));
}
GtkWidget *
do_path_spinner (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *picture;
GdkPaintable *paintable;
guint timeout_id;
window = gtk_window_new ();
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
gtk_window_set_title (GTK_WINDOW (window), "Spinner");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
paintable = gtk_spinner_paintable_new ();
picture = gtk_picture_new_for_paintable (paintable);
gtk_picture_set_content_fit (GTK_PICTURE (picture), GTK_CONTENT_FIT_CONTAIN);
gtk_picture_set_can_shrink (GTK_PICTURE (picture), FALSE);
g_object_unref (paintable);
gtk_widget_add_tick_callback (picture, tick_cb, paintable, NULL);
timeout_id = g_timeout_add (100, progress_timeout, paintable);
g_object_set_data_full (G_OBJECT (picture), "timeout", GUINT_TO_POINTER (timeout_id), unset_timeout);
gtk_window_set_child (GTK_WINDOW (window), picture);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,586 +0,0 @@
/* Path/Text
*
* This demo shows how to use GskPath to transform a path along another path.
*
* It also demonstrates that paths can be filled with more interesting
* content than just plain colors.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WIDGET (gtk_path_widget_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWidget, gtk_path_widget, GTK, PATH_WIDGET, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_TEXT,
PROP_EDITABLE,
N_PROPS
};
struct _GtkPathWidget
{
GtkWidget parent_instance;
char *text;
gboolean editable;
graphene_point_t points[4];
guint active_point;
GskPath *line_path;
GskPath *text_path;
GdkPaintable *background;
};
struct _GtkPathWidgetClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWidget, gtk_path_widget, GTK_TYPE_WIDGET)
static GskPath *
create_path_from_text (GtkWidget *widget,
const char *text,
graphene_point_t *out_offset)
{
PangoLayout *layout;
PangoFontDescription *desc;
GskPathBuilder *builder;
GskPath *result;
layout = gtk_widget_create_pango_layout (widget, text);
desc = pango_font_description_from_string ("sans bold 36");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
builder = gsk_path_builder_new ();
gsk_path_builder_add_layout (builder, layout);
result = gsk_path_builder_free_to_path (builder);
if (out_offset)
graphene_point_init (out_offset, 0, - pango_layout_get_baseline (layout) / (double) PANGO_SCALE);
g_object_unref (layout);
return result;
}
typedef struct
{
GskPathMeasure *measure;
GskPathBuilder *builder;
graphene_point_t offset;
double scale;
} GtkPathTransform;
static void
gtk_path_transform_point (GskPathMeasure *measure,
const graphene_point_t *pt,
const graphene_point_t *offset,
float scale,
graphene_point_t *res)
{
graphene_vec2_t tangent;
GskPathPoint point;
if (gsk_path_measure_get_point (measure, (pt->x + offset->x) * scale, &point))
{
GskPath *path = gsk_path_measure_get_path (measure);
gsk_path_point_get_position (&point, path, res);
gsk_path_point_get_tangent (&point, path, GSK_PATH_TO_END, &tangent);
res->x -= (pt->y + offset->y) * scale * graphene_vec2_get_y (&tangent);
res->y += (pt->y + offset->y) * scale * graphene_vec2_get_x (&tangent);
}
}
static gboolean
gtk_path_transform_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GtkPathTransform *transform = data;
switch (op)
{
case GSK_PATH_MOVE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[0], &transform->offset, transform->scale, &res);
gsk_path_builder_move_to (transform->builder, res.x, res.y);
}
break;
case GSK_PATH_LINE:
{
graphene_point_t res;
gtk_path_transform_point (transform->measure, &pts[1], &transform->offset, transform->scale, &res);
gsk_path_builder_line_to (transform->builder, res.x, res.y);
}
break;
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]);
gsk_path_builder_quad_to (transform->builder, res[0].x, res[0].y, res[1].x, res[1].y);
}
break;
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]);
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;
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);
}
break;
case GSK_PATH_CLOSE:
gsk_path_builder_close (transform->builder);
break;
default:
g_assert_not_reached();
return FALSE;
}
return TRUE;
}
static GskPath *
gtk_path_transform (GskPath *line_path,
GskPath *path,
const graphene_point_t *offset)
{
GskPathMeasure *measure = gsk_path_measure_new (line_path);
GtkPathTransform transform = { measure, gsk_path_builder_new (), *offset };
graphene_rect_t bounds;
gsk_path_get_bounds (path, &bounds);
if (bounds.origin.x + bounds.size.width > 0)
transform.scale = gsk_path_measure_get_length (measure) / (bounds.origin.x + bounds.size.width);
else
transform.scale = 1.0f;
gsk_path_foreach (path, -1, gtk_path_transform_op, &transform);
gsk_path_measure_unref (measure);
return gsk_path_builder_free_to_path (transform.builder);
}
static void
gtk_path_widget_clear_text_path (GtkPathWidget *self)
{
g_clear_pointer (&self->text_path, gsk_path_unref);
}
static void
gtk_path_widget_clear_paths (GtkPathWidget *self)
{
gtk_path_widget_clear_text_path (self);
g_clear_pointer (&self->line_path, gsk_path_unref);
}
static void
gtk_path_widget_create_text_path (GtkPathWidget *self)
{
GskPath *path;
graphene_point_t offset;
gtk_path_widget_clear_text_path (self);
path = create_path_from_text (GTK_WIDGET (self), self->text, &offset);
self->text_path = gtk_path_transform (self->line_path, path, &offset);
gsk_path_unref (path);
}
static void
gtk_path_widget_create_paths (GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
GskPathBuilder *builder;
gtk_path_widget_clear_paths (self);
if (width <= 0 || height <= 0)
return;
builder = gsk_path_builder_new ();
gsk_path_builder_move_to (builder,
self->points[0].x * width, self->points[0].y * height);
gsk_path_builder_cubic_to (builder,
self->points[1].x * width, self->points[1].y * height,
self->points[2].x * width, self->points[2].y * height,
self->points[3].x * width, self->points[3].y * height);
self->line_path = gsk_path_builder_free_to_path (builder);
gtk_path_widget_create_text_path (self);
}
static void
gtk_path_widget_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_path_widget_parent_class)->size_allocate (widget, width, height, baseline);
gtk_path_widget_create_paths (self);
}
static void
gtk_path_widget_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWidget *self = GTK_PATH_WIDGET (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
GskPath *path;
GskStroke *stroke;
gsize i;
/* frosted glass the background */
gtk_snapshot_push_blur (snapshot, 100);
gdk_paintable_snapshot (self->background, snapshot, width, height);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 0.6 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the text */
if (self->text_path)
{
gtk_snapshot_push_fill (snapshot, self->text_path, GSK_FILL_RULE_WINDING);
gdk_paintable_snapshot (self->background, snapshot, width, height);
/* ... with an emboss effect */
stroke = gsk_stroke_new (2.0);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT(1, 1));
gtk_snapshot_push_stroke (snapshot, self->text_path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 0.2 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gsk_stroke_free (stroke);
gtk_snapshot_pop (snapshot);
gtk_snapshot_pop (snapshot);
}
if (self->editable && self->line_path)
{
GskPathBuilder *builder;
/* draw the control line */
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, self->line_path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
/* draw the points */
builder = gsk_path_builder_new ();
for (i = 0; i < 4; i++)
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), POINT_SIZE);
}
path = gsk_path_builder_free_to_path (builder);
gtk_snapshot_push_fill (snapshot, path, GSK_FILL_RULE_WINDING);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 1, 1, 1, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
stroke = gsk_stroke_new (1.0);
gtk_snapshot_push_stroke (snapshot, path, stroke);
gsk_stroke_free (stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_path_unref (path);
}
}
static void
gtk_path_widget_set_text (GtkPathWidget *self,
const char *text)
{
if (g_strcmp0 (self->text, text) == 0)
return;
g_free (self->text);
self->text = g_strdup (text);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEXT]);
}
static void
gtk_path_widget_set_editable (GtkPathWidget *self,
gboolean editable)
{
if (self->editable == editable)
return;
self->editable = editable;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EDITABLE]);
}
static void
gtk_path_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
gtk_path_widget_set_text (self, g_value_get_string (value));
break;
case PROP_EDITABLE:
gtk_path_widget_set_editable (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
switch (prop_id)
{
case PROP_TEXT:
g_value_set_string (value, self->text);
break;
case PROP_EDITABLE:
g_value_set_boolean (value, self->editable);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_widget_dispose (GObject *object)
{
GtkPathWidget *self = GTK_PATH_WIDGET (object);
gtk_path_widget_clear_paths (self);
G_OBJECT_CLASS (gtk_path_widget_parent_class)->dispose (object);
}
static void
gtk_path_widget_class_init (GtkPathWidgetClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_widget_dispose;
object_class->set_property = gtk_path_widget_set_property;
object_class->get_property = gtk_path_widget_get_property;
widget_class->size_allocate = gtk_path_widget_allocate;
widget_class->snapshot = gtk_path_widget_snapshot;
properties[PROP_TEXT] =
g_param_spec_string ("text",
"text",
"Text transformed along a path",
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_EDITABLE] =
g_param_spec_boolean ("editable",
"editable",
"If the path can be edited by the user",
FALSE,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static void
drag_begin (GtkGestureDrag *gesture,
double x,
double y,
GtkPathWidget *self)
{
graphene_point_t mouse = GRAPHENE_POINT_INIT (x, y);
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
gsize i;
for (i = 0; i < 4; i++)
{
if (graphene_point_distance (&GRAPHENE_POINT_INIT (self->points[i].x * width, self->points[i].y * height), &mouse, NULL, NULL) <= POINT_SIZE)
{
self->active_point = i;
break;
}
}
if (i == 4)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
drag_update (GtkGestureDrag *drag,
double offset_x,
double offset_y,
GtkPathWidget *self)
{
double width = gtk_widget_get_width (GTK_WIDGET (self));
double height = gtk_widget_get_height (GTK_WIDGET (self));
double start_x, start_y;
gtk_gesture_drag_get_start_point (drag, &start_x, &start_y);
self->points[self->active_point] = GRAPHENE_POINT_INIT ((start_x + offset_x) / width,
(start_y + offset_y) / height);
self->points[self->active_point].x = CLAMP (self->points[self->active_point].x, 0, 1);
self->points[self->active_point].y = CLAMP (self->points[self->active_point].y, 0, 1);
gtk_path_widget_create_paths (self);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
pointer_motion (GtkEventControllerMotion *controller,
double x,
double y,
GtkPathWidget *self)
{
GskPathPoint point;
graphene_point_t pos;
if (gsk_path_get_closest_point (self->line_path,
&GRAPHENE_POINT_INIT (x, y),
INFINITY,
&point))
{
gsk_path_point_get_position (&point, self->line_path, &pos);
gtk_widget_queue_draw (GTK_WIDGET (self));
}
}
static void
pointer_leave (GtkEventControllerMotion *controller,
GtkPathWidget *self)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
gtk_path_widget_init (GtkPathWidget *self)
{
GtkEventController *controller;
controller = GTK_EVENT_CONTROLLER (gtk_gesture_drag_new ());
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_update), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
controller = GTK_EVENT_CONTROLLER (gtk_event_controller_motion_new ());
g_signal_connect (controller, "enter", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "motion", G_CALLBACK (pointer_motion), self);
g_signal_connect (controller, "leave", G_CALLBACK (pointer_leave), self);
gtk_widget_add_controller (GTK_WIDGET (self), controller);
self->points[0] = GRAPHENE_POINT_INIT (0.1, 0.9);
self->points[1] = GRAPHENE_POINT_INIT (0.3, 0.1);
self->points[2] = GRAPHENE_POINT_INIT (0.7, 0.1);
self->points[3] = GRAPHENE_POINT_INIT (0.9, 0.9);
self->background = GDK_PAINTABLE (gdk_texture_new_from_resource ("/sliding_puzzle/portland-rose.jpg"));
gtk_path_widget_set_text (self, "It's almost working");
}
GtkWidget *
gtk_path_widget_new (void)
{
GtkPathWidget *self;
self = g_object_new (GTK_TYPE_PATH_WIDGET, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_text (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WIDGET);
builder = gtk_builder_new_from_resource ("/path_text/path_text.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">Text along a Path</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkToggleButton" id="edit-toggle">
<property name="icon-name">document-edit-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer">
<property name="reveal-child" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<child>
<object class="GtkEntry" id="text">
<property name="text">Through the looking glass</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkPathWidget" id="view">
<property name="editable" bind-source="edit-toggle" bind-property="active" bind-flags="sync-create"></property>
<property name="text" bind-source="text" bind-property="text" bind-flags="sync-create"></property>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -1,373 +0,0 @@
/* Path/Walk
*
* This demo draws a world map and shows how to animate objects along a GskPath.
*
* The world map that is used here is a path with 211 lines and 1569 cubic
* Bėzier segments in 121 contours.
*/
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#define GTK_TYPE_PATH_WALK (gtk_path_walk_get_type ())
G_DECLARE_FINAL_TYPE (GtkPathWalk, gtk_path_walk, GTK, PATH_WALK, GtkWidget)
#define POINT_SIZE 8
enum {
PROP_0,
PROP_N_POINTS,
PROP_PATH,
N_PROPS
};
struct _GtkPathWalk
{
GtkWidget parent_instance;
GskPath *path;
GskPathMeasure *measure;
graphene_rect_t bounds;
GskPath *arrow_path;
guint n_points;
};
struct _GtkPathWalkClass
{
GtkWidgetClass parent_class;
};
static GParamSpec *properties[N_PROPS] = { NULL, };
G_DEFINE_TYPE (GtkPathWalk, gtk_path_walk, GTK_TYPE_WIDGET)
static void
rgba_init_from_hsla (GdkRGBA *rgba,
float hue,
float saturation,
float lightness,
float alpha)
{
float m1, m2;
if (lightness <= 0.5)
m2 = lightness * (1 + saturation);
else
m2 = lightness + saturation - lightness * saturation;
m1 = 2 * lightness - m2;
rgba->alpha = alpha;
if (saturation == 0)
{
rgba->red = lightness;
rgba->green = lightness;
rgba->blue = lightness;
}
else
{
hue = hue + 120;
while (hue > 360)
hue -= 360;
while (hue < 0)
hue += 360;
if (hue < 60)
rgba->red = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->red = m2;
else if (hue < 240)
rgba->red = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->red = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->green = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->green = m2;
else if (hue < 240)
rgba->green = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->green = m1;
hue -= 120;
if (hue < 0)
hue += 360;
if (hue < 60)
rgba->blue = m1 + (m2 - m1) * hue / 60;
else if (hue < 180)
rgba->blue = m2;
else if (hue < 240)
rgba->blue = m1 + (m2 - m1) * (240 - hue) / 60;
else
rgba->blue = m1;
}
}
static void
gtk_path_walk_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkPathWalk *self = GTK_PATH_WALK (widget);
double width = gtk_widget_get_width (widget);
double height = gtk_widget_get_height (widget);
float length, progress;
GskStroke *stroke;
guint i;
if (self->path == NULL)
return;
gtk_snapshot_save (snapshot);
stroke = gsk_stroke_new (2.0);
gtk_snapshot_push_stroke (snapshot, self->path, stroke);
gtk_snapshot_append_color (snapshot, &(GdkRGBA) { 0, 0, 0, 1 }, &GRAPHENE_RECT_INIT (0, 0, width, height));
gtk_snapshot_pop (snapshot);
gsk_stroke_free (stroke);
length = gsk_path_measure_get_length (self->measure);
progress = 25.f * gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget)) / G_USEC_PER_SEC;
stroke = gsk_stroke_new (1.0);
for (i = 0; i < self->n_points; i++)
{
GskPathPoint point;
graphene_point_t position;
float angle;
GdkRGBA color;
float distance;
distance = i * length / self->n_points;
distance = fmod (distance + progress, length);
gsk_path_measure_get_point (self->measure, distance, &point);
gsk_path_point_get_position (&point, self->path, &position);
angle = gsk_path_point_get_rotation (&point, self->path, GSK_PATH_FROM_START);
rgba_init_from_hsla (&color, 360.f * i / self->n_points, 1, 0.5, 1);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &position);
gtk_snapshot_rotate (snapshot, angle);
gtk_snapshot_append_fill (snapshot, self->arrow_path, GSK_FILL_RULE_EVEN_ODD, &color);
gtk_snapshot_append_stroke (snapshot, self->arrow_path, stroke, &(GdkRGBA) { 0, 0, 0, 1 });
gtk_snapshot_restore (snapshot);
}
gsk_stroke_free (stroke);
gtk_snapshot_restore (snapshot);
}
static void
gtk_path_walk_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkPathWalk *self = GTK_PATH_WALK (widget);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = (int) ceilf (self->bounds.size.width);
else
*minimum = *natural = (int) ceilf (self->bounds.size.height);
}
static void
gtk_path_walk_set_n_points (GtkPathWalk *self,
gsize n_points)
{
if (self->n_points == n_points)
return;
self->n_points = n_points;
gtk_widget_queue_draw (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_POINTS]);
}
static void
gtk_path_walk_set_path (GtkPathWalk *self,
GskPath *path)
{
if (self->path == path)
return;
g_clear_pointer (&self->path, gsk_path_unref);
graphene_rect_init (&self->bounds, 0, 0, 0, 0);
if (path)
{
GskStroke *stroke;
self->path = gsk_path_ref (path);
stroke = gsk_stroke_new (2.0);
gsk_path_get_stroke_bounds (path, stroke, &self->bounds);
gsk_stroke_free (stroke);
self->measure = gsk_path_measure_new (self->path);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PATH]);
}
static void
gtk_path_walk_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
switch (prop_id)
{
case PROP_N_POINTS:
gtk_path_walk_set_n_points (self, g_value_get_uint (value));
break;
case PROP_PATH:
gtk_path_walk_set_path (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_walk_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
switch (prop_id)
{
case PROP_N_POINTS:
g_value_set_uint (value, self->n_points);
break;
case PROP_PATH:
g_value_set_boxed (value, self->path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_path_walk_dispose (GObject *object)
{
GtkPathWalk *self = GTK_PATH_WALK (object);
g_clear_pointer (&self->path, gsk_path_unref);
g_clear_pointer (&self->measure, gsk_path_measure_unref);
g_clear_pointer (&self->arrow_path, gsk_path_unref);
G_OBJECT_CLASS (gtk_path_walk_parent_class)->dispose (object);
}
static void
gtk_path_walk_class_init (GtkPathWalkClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = gtk_path_walk_dispose;
object_class->set_property = gtk_path_walk_set_property;
object_class->get_property = gtk_path_walk_get_property;
widget_class->snapshot = gtk_path_walk_snapshot;
widget_class->measure = gtk_path_walk_measure;
properties[PROP_N_POINTS] =
g_param_spec_uint ("n-points",
NULL, NULL,
1, G_MAXUINT,
500,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
properties[PROP_PATH] =
g_param_spec_boxed ("path",
NULL, NULL,
GSK_TYPE_PATH,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPS, properties);
}
static gboolean
tick_tick_tick (GtkWidget *self,
GdkFrameClock *frame_clock,
gpointer unused)
{
gtk_widget_queue_draw (GTK_WIDGET (self));
return G_SOURCE_CONTINUE;
}
static void
gtk_path_walk_init (GtkPathWalk *self)
{
/* Data taken from
* https://commons.wikimedia.org/wiki/Maps_of_the_world#/media/File:Simplified_blank_world_map_without_Antartica_(no_borders).svg
*/
GBytes *data = g_resources_lookup_data ("/path_walk/path_world.txt", 0, NULL);
GskPath *path = gsk_path_parse (g_bytes_get_data (data, NULL));
g_bytes_unref (data);
gtk_path_walk_set_path (self, path);
gsk_path_unref (path);
self->arrow_path = gsk_path_parse ("M 5 0 L 0 -5. 0 -2, -5 -2, -5 2, 0 2, 0 5 Z");
self->n_points = 500;
gtk_widget_add_tick_callback (GTK_WIDGET (self), tick_tick_tick, NULL, NULL);
}
GtkWidget *
gtk_path_walk_new (void)
{
GtkPathWalk *self;
self = g_object_new (GTK_TYPE_PATH_WALK, NULL);
return GTK_WIDGET (self);
}
GtkWidget *
do_path_walk (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkBuilder *builder;
g_type_ensure (GTK_TYPE_PATH_WALK);
builder = gtk_builder_new_from_resource ("/path_walk/path_walk.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *) &window);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_window_present (GTK_WINDOW (window));
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="title" translatable="yes">World Map</property>
<property name="titlebar">
<object class="GtkHeaderBar">
<child type="end">
<object class="GtkSpinButton">
<property name="adjustment">
<object class="GtkAdjustment" id="adjustment">
<property name="lower">0</property>
<property name="upper">5000</property>
<property name="value">500</property>
</object>
</property>
</object>
</child>
</object>
</property>
<property name="child">
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkPathWalk" id="view">
<property name="n-points" bind-source="adjustment" bind-property="value"/>
<property name="hexpand">true</property>
<property name="vexpand">true</property>
</object>
</child>
</object>
</property>
</object>
</interface>

File diff suppressed because one or more lines are too long

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

@@ -32,34 +32,13 @@ show_class_hierarchy = true
base_url = "https://gitlab.gnome.org/GNOME/gtk/-/blob/main/"
[extra]
content_files = [
"paths.md",
]
content_images = [
"gtk-logo.svg",
"images/arc-dark.png",
"images/arc-light.png",
"images/caps-dark.png",
"images/caps-light.png",
"images/conic-light.png",
"images/conic-dark.png",
"images/cubic-dark.png",
"images/cubic-light.png",
"images/curvature-dark.png",
"images/curvature-light.png",
"images/directions-dark.png",
"images/directions-light.png",
"images/fill-even-odd.png",
"images/fill-winding.png",
"images/join-dark.png",
"images/join-light.png",
"images/line-dark.png",
"images/line-light.png",
"images/path-dark.png",
"images/path-light.png",
"images/quad-dark.png",
"images/quad-light.png",
"images/stroke-miter.png",
"images/stroke-round.png",
]
urlmap_file = "urlmap.js"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="arcto.svg"
inkscape:export-filename="cubic-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="399.39592"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 58.033485,123.96862 C 75.231194,113.95411 92.489919,103.26728 107.81401,113.89786"
id="path3"
sodipodi:nodetypes="cc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.20061772;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cx="-16.837238"
cy="154.55043"
rx="35.832706"
ry="17.920988"
transform="matrix(0.86643544,-0.49928912,0.59215321,0.8058254,0,0)" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="M 57.432798,124.38759 86.59638,102.1496 107.25717,113.71009"
id="path1"
sodipodi:nodetypes="ccc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-9"
cx="86.580566"
cy="102.81618"
r="1.5" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 45.061871,134.70541 12.60825,-10.20893"
id="path4-4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 35.405008,142.35717 8.95641,-7.26298"
id="path4-8-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61-1"
cx="57.597607"
cy="124.23325"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6-5"
cx="108.01463"
cy="114.17829"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="conic.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.5197952"
inkscape:cx="397.75096"
inkscape:cy="525.39974"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#8b8b8b;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.52304,196.79607 c 27.88945,-10.42358 28.400227,-11.25919 57.24918,-4.59693"
id="path5-7-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#848484;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.150275,196.9925 c 28.059619,-18.89157 28.355331,-21.42218 57.249175,-4.59693"
id="path5"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.439496,197.17632 30.328009,-21.33704 28.506125,16.61621"
id="path6" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.25585,197.17683 c 29.459015,-15.97487 29.941733,-16.52508 57.24918,-4.59693"
id="path5-7"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="95.69075"
cy="175.70657"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="123.73506"
cy="192.49165"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="cubic.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.73794"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.680232,196.81045 31.85267,-27.20583 3.379138,46.6055 23.3915,-31.31401"
id="path6"
sodipodi:nodetypes="cccc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.857856,197.15027 c 31.390863,-27.80022 35.053874,18.93262 59.490604,-13.30694"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="97.246689"
cy="169.65689"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="101.05927"
cy="215.75879"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6-3"
cx="124.97194"
cy="184.30319"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="curvature.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0746575"
inkscape:cx="396.87064"
inkscape:cy="561.57428"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 61.499887,117.85302 0.05055,-14.89554"
id="path3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
d="m 47.704374,176.11887 c 0,0 -17.048386,-67.06278 9.674156,-72.76426 29.478854,-6.289566 30.433539,55.72526 58.46942,50.81836"
id="path1"
sodipodi:nodetypes="csc" />
<ellipse
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2"
cy="117.87344"
cx="61.445835"
rx="14.692688"
ry="14.525347" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9"
cx="61.42588"
cy="117.79034"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,328 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="directions.svg"
inkscape:export-filename="directions-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.0746575"
inkscape:cx="371.28108"
inkscape:cy="266.59657"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="marker5"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="0.5"
markerHeight="0.5"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path5" />
</marker>
<marker
style="overflow:visible"
id="marker3"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3" />
</marker>
<marker
style="overflow:visible"
id="Triangle"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135" />
</marker>
<marker
style="overflow:visible"
id="marker3-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3-5" />
</marker>
<marker
style="overflow:visible"
id="Triangle-0"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9" />
</marker>
<marker
style="overflow:visible"
id="marker5-9"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="0.5"
markerHeight="0.5"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path5-8" />
</marker>
<marker
style="overflow:visible"
id="marker3-8-4"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path3-5-4" />
</marker>
<marker
style="overflow:visible"
id="Triangle-0-7"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="2"
markerHeight="2"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9-6" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;marker-end:url(#marker5)"
d="m 27.834229,78.180655 c 21.653076,9.584156 38.648414,3.28592 57.704513,-16.91815 26.702288,3.84691 38.178308,6.290079 51.837088,35.267113"
id="path1"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;marker-end:url(#marker5-9)"
d="m 91.839025,170.91959 c -22.098283,1.18425 -24.17615,-37.34309 2.699778,-37.47998 20.898567,-0.10644 38.726427,9.19795 51.837087,35.26711"
id="path1-8"
sodipodi:nodetypes="csc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3);marker-end:url(#Triangle)"
d="M 52.087008,92.522138 119.92974,29.398044"
id="path2"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3-8);marker-end:url(#Triangle-0)"
d="M 39.037646,53.839137 130.44855,69.048774"
id="path2-3"
sodipodi:nodetypes="cc"
inkscape:transform-center-x="-71.02355"
inkscape:transform-center-y="28.680447" />
<path
style="fill:none;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;marker-start:url(#marker3-8-4);marker-end:url(#Triangle-0-7)"
d="M 48.764932,133.73955 141.43055,133.1318"
id="path2-3-1"
sodipodi:nodetypes="cc"
inkscape:transform-center-x="-74.875204"
inkscape:transform-center-y="16.143612" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="99.90786"
y="24.737305"
id="text4"><tspan
sodipodi:role="line"
id="tspan4"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.2"
x="99.90786"
y="24.737305">GSK_PATH_FROM_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="142.84389"
y="128.82414"
id="text4-5"><tspan
sodipodi:role="line"
id="tspan4-7"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke-width:0.2"
x="142.84389"
y="128.82414">GSK_PATH_FROM_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="29.309605"
y="100.65614"
id="text5"><tspan
sodipodi:role="line"
id="tspan5"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88055556px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="29.309605"
y="100.65614">GSK_PATH_TO_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="141.82414"
id="text5-8"><tspan
sodipodi:role="line"
id="tspan5-8"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="141.82414">GSK_PATH_TO_START</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="135.70834"
y="70.811882"
id="text6"><tspan
sodipodi:role="line"
id="tspan6"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="135.70834"
y="70.811882">GSK_PATH_TO_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="142.84389"
y="141.82416"
id="text6-6"><tspan
sodipodi:role="line"
id="tspan6-2"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="142.84389"
y="141.82416">GSK_PATH_TO_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="48.774254"
id="text7"><tspan
sodipodi:role="line"
id="tspan7"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="48.774254">GSK_PATH_FROM_END</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
x="14.843884"
y="128.82414"
id="text7-5"><tspan
sodipodi:role="line"
id="tspan7-9"
style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:3.88056px;font-family:Cantarell;-inkscape-font-specification:'Cantarell, Light';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.2"
x="14.843884"
y="128.82414">GSK_PATH_FROM_END</tspan></text>
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7"
cx="85.343727"
cy="61.691891"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2-8-9-7-0"
cx="93.787331"
cy="133.30902"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="line.svg"
inkscape:export-filename="line-light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.73794"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 66.150275,196.9925 40.275255,-5.24977"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="106.42249"
cy="191.8156"
r="1.5" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg1"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
sodipodi:docname="path.svg"
inkscape:export-filename="path-dark.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.75989759"
inkscape:cx="398.07996"
inkscape:cy="466.51023"
inkscape:window-width="1920"
inkscape:window-height="1123"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showgrid="false" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 52.936092,207.66575 12.60825,-10.20893"
id="path4"
sodipodi:nodetypes="cc" />
<path
style="fill:#f90048;stroke:#a2a2a2;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:1, 3;stroke-dashoffset:0;stroke-opacity:1"
d="m 43.279229,215.31751 8.95641,-7.26298"
id="path4-8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="M 66.150275,196.9925 C 86.276878,182.17569 104.9512,180.54783 123.39945,192.39557"
id="path5"
sodipodi:nodetypes="cc" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7"
cx="95.69075"
cy="175.70657"
r="1.5" />
<circle
style="fill:#818181;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-61"
cx="65.471832"
cy="197.19359"
r="1.5" />
<circle
style="fill:#ff0404;fill-opacity:1;stroke:#000064;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none"
id="path2-8-7-6"
cx="123.73506"
cy="192.49165"
r="1.5" />
<path
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
d="m 65.439496,197.17632 30.328009,-21.33704 28.506125,16.61621"
id="path6" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,7 +1,3 @@
gsk_expand_content_md_files = [
'paths.md',
]
if get_option('documentation')
gsk4_toml = configure_file(
input: 'gsk4.toml.in',
@@ -25,7 +21,7 @@ if get_option('documentation')
'@INPUT1@',
],
depends: [ gdk_gir[0] ],
depend_files: [ gsk_expand_content_md_files ],
depend_files: [ expand_content_md_files ],
build_by_default: true,
install: true,
install_dir: docs_dir,

View File

@@ -1,174 +0,0 @@
Title: Paths
Slug: paths
GSK provides a path API that can be used to render more complex
shapes than lines or rounded rectangles. It is comparable to cairos
[path API](https://www.cairographics.org/manual/cairo-Paths.html),
with some notable differences.
In general, a path consists of one or more connected **_contours_**,
each of which may have multiple **_operations_**, and may or may not be closed.
Operations can be straight lines or curves of various kinds. At the points
where the operations connect, the path can have sharp turns.
<figure>
<picture>
<source srcset="path-dark.png" media="(prefers-color-scheme: dark)">
<img alt="A path with multiple contours" src="path-light.png">
</picture>
<figcaption>A path with one closed, and one open contour</figcaption>
</figure>
The central object of the GSK path API is the immutable [struct@Gsk.Path]
struct, which contains path data in compact form suitable for rendering.
## Creating Paths
Since `GskPath` is immutable, the auxiliary [struct@Gsk.PathBuilder] struct
can be used to construct a path piece by piece. The pieces are specified with
points, some of which will be on the path, while others are just **_control points_**
that are used to influence the shape of the resulting path.
<figure>
<picture>
<source srcset="cubic-dark.png" media="(prefers-color-scheme: dark)">
<img alt="An cubic Bézier" src="cubic-light.png">
</picture>
<figcaption>A cubic Bézier operation, with 2 control points</figcaption>
</figure>
The `GskPathBuilder` API has three distinct groups of functions:
- Functions for building contours from individual operations, like [method@Gsk.PathBuilder.move_to],
[method@Gsk.PathBuilder.line_to], [method@Gsk.PathBuilder.cubic_to], [method@Gsk.PathBuilder.close]. `GskPathBuilder` maintains a **_current point_**, so these methods all
take one less points than necessary for the operation (e.g. `gsk_path_builder_line_to`
only takes a single point and draws a line from the current point to the new point).
- Functions for adding complete contours, such as [method@Gsk.PathBuilder.add_rect],
[method@Gsk.PathBuilder.add_rounded_rect], [method@Gsk.PathBuilder.add_circle].
- Adding parts of a preexisting path. Functions in this group include
[method@Gsk.PathBuilder.add_path] and [method@Gsk.PathBuilder.add_segment].
When you are done with building a path, you can convert the accumulated path
data into a `GskPath` struct with [method@Gsk.PathBuilder.free_to_path].
A sometimes convenient alternative is to create a path from a serialized form,
with [func@Gsk.Path.parse]. This function interprets strings in SVG path syntax,
such as:
M 100 100 C 100 200 200 200 200 100 Z
## Rendering with Paths
There are two main ways to render with paths. The first is to **_fill_** the
interior of a path with a color or more complex content, such as a gradient.
GSK supports different ways of determining what part of the plane are interior
to the path, which can be selected with a [enum@Gsk.FillRule] value.
<figure>
<picture>
<img alt="A filled path" src="fill-winding.png">
</picture>
<figcaption>A path filled with GSK_FILL_RULE_WINDING</figcaption>
</figure>
<figure>
<picture>
<img alt="A filled path" src="fill-even-odd.png">
</picture>
<figcaption>The same path, filled with GSK_FILL_RULE_EVEN_ODD</figcaption>
</figure>
To fill a path, use [gtk_snapshot_append_fill()](../gtk4/method.Snapshot.append_fill.html)
or the more general [gtk_snapshot_push_fill()](../gtk4/method.Snapshot.push_fill.html).
Alternatively, a path can be **_stroked_**, which means to emulate drawing
with an idealized pen along the path. The result of stroking a path is another
path (the **_stroke path_**), which is then filled.
The stroke operation can be influenced with the [struct@Gsk.Stroke] struct
that collects various stroke parameters, such as the line width, the style
of line joins and line caps, and a dash pattern.
<figure>
<picture>
<img alt="A stroked path" src="stroke-miter.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_MITER</figcaption>
</figure>
<figure>
<picture>
<img alt="A stroked path" src="stroke-round.png">
</picture>
<figcaption>The same path, stroked with GSK_LINE_JOIN_ROUND</figcaption>
</figure>
To stroke a path, use
[gtk_snapshot_append_stroke()](../gtk4/method.Snapshot.append_stroke.html)
or [gtk_snapshot_push_stroke()](../gtk4/method.Snapshot.push_stroke.html).
## Hit testing
When paths are rendered as part of an interactive interface, it is sometimes
necessary to determine whether the mouse points is over the path. GSK provides
[method@Gsk.Path.in_fill] for this purpose.
## Path length
An important property of paths is their **_length_**. Computing it efficiently
requires caching, therefore GSK provides a separate [struct@Gsk.PathMeasure] object
to deal with path lengths. After constructing a `GskPathMeasure` object for a path,
it can be used to determine the length of the path with [method@Gsk.PathMeasure.get_length]
and locate points at a given distance into the path with [method@Gsk.PathMeasure.get_point].
## Other Path APIs
Paths have uses beyond rendering, for example as trajectories in animations.
In such uses, it is often important to access properties of paths, such as
their tangents at certain points. GSK provides an abstract representation
for points on a path in the form of the [struct@Gsk.PathPoint] struct.
You can query properties of a path at certain point once you have a
`GskPathPoint` representing that point.
`GskPathPoint` structs can be compared for equality with [method@Gsk.PathPoint.equal]
and ordered wrt. to which one comes first, using [method@Gsk.PathPoint.compare].
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 query properties of the path at a point, use [method@Gsk.PathPoint.get_position],
[method@Gsk.PathPoint.get_tangent], [method@Gsk.PathPoint.get_rotation],
[method@Gsk.PathPoint.get_curvature] and [method@Gsk.PathPoint.get_distance].
Some of the properties can have different values for the path going into
the point and the path leaving the point, typically at points where the
path takes sharp turns. Examples for this are tangents (which can have up
to 4 different values) and curvatures (which can have two different values).
<figure>
<picture>
<source srcset="directions-dark.png" media="(prefers-color-scheme: dark)">
<img alt="Path Tangents" src="directions-light.png">
</picture>
<figcaption>Path Tangents</figcaption>
</figure>
## Going beyond GskPath
Lots of powerful functionality can be implemented for paths:
- Finding intersections
- Offsetting curves
- Turning stroke outlines into paths
- Molding curves (making them pass through a given point)
GSK does not provide API for all of these, but it does offer a way to get at
the underlying Bézier curves, so you can implement such functionality yourself.
You can use [method@Gsk.Path.foreach] to iterate over the operations of the
path, and get the points needed to reconstruct or modify the path piece by piece.
See e.g. the [Primer on Bézier curves](https://pomax.github.io/bezierinfo/)
for inspiration of useful things to explore.

View File

@@ -44,10 +44,6 @@ segments.
Allow cubic Bézier curves to be used in the generated path.
``--allow-conic``
Allow conic Bézier curves to be used in the generated path.
Showing
^^^^^^^
@@ -69,10 +65,6 @@ of the path is filled.
The color that is used to render the background behind the path.
If not specified, white is used.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.
@@ -138,10 +130,6 @@ The interior of the path is filled.
The file to save the PNG image to.
If not specified, "path.png" is used.
``--fill``
Fill the path (this is the default).
``--stroke``
Stroke the path instead of filling it.

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

@@ -25,12 +25,10 @@
#include "gdkprivate.h"
/* HACK: So we don't need to include any (not-yet-created) GSK or GTK headers */
GdkSnapshot * gtk_snapshot_new (void);
void gtk_snapshot_push_debug (GdkSnapshot *snapshot,
const char *message,
...) G_GNUC_PRINTF (2, 3);
void gtk_snapshot_pop (GdkSnapshot *snapshot);
GdkPaintable * gtk_snapshot_free_to_paintable (GdkSnapshot *snapshot);
/**
* GdkPaintable:
@@ -104,21 +102,9 @@ gdk_paintable_default_snapshot (GdkPaintable *paintable,
static GdkPaintable *
gdk_paintable_default_get_current_image (GdkPaintable *paintable)
{
int width, height;
GdkSnapshot *snapshot;
g_warning ("FIXME: implement by snapshotting at default size and returning a GskRendererNodePaintable");
/* No need to check whether the paintable is static, as
* gdk_paintable_get_current_image () takes care of that already. */
width = gdk_paintable_get_intrinsic_width (paintable);
height = gdk_paintable_get_intrinsic_height (paintable);
if (width <= 0 || height <= 0)
return gdk_paintable_new_empty (width, height);
snapshot = gtk_snapshot_new ();
gdk_paintable_snapshot (paintable, snapshot, width, height);
return gtk_snapshot_free_to_paintable (snapshot);
return paintable;
}
static GdkPaintableFlags

View File

@@ -331,7 +331,7 @@ _gdk_macos_monitor_reconfigure (GdkMacosMonitor *self)
gdk_monitor_set_physical_size (GDK_MONITOR (self), width_mm, height_mm);
gdk_monitor_set_scale_factor (GDK_MONITOR (self), scale_factor);
gdk_monitor_set_refresh_rate (GDK_MONITOR (self), refresh_rate);
gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), subpixel_layout);
gdk_monitor_set_subpixel_layout (GDK_MONITOR (self), GDK_SUBPIXEL_LAYOUT_UNKNOWN);
self->workarea = [screen visibleFrame];

View File

@@ -93,8 +93,7 @@ gdk_wayland_app_launch_context_get_startup_notify_id (GAppLaunchContext *context
id = app_launch_data.token;
wl_event_queue_destroy (event_queue);
}
else if (display->gtk_shell &&
gtk_shell1_get_version (display->gtk_shell) >= GTK_SHELL1_NOTIFY_LAUNCH_SINCE_VERSION)
else if (gtk_shell1_get_version (display->gtk_shell) >= GTK_SHELL1_NOTIFY_LAUNCH_SINCE_VERSION)
{
id = g_uuid_string_random ();
gtk_shell1_notify_launch (display->gtk_shell, id);

View File

@@ -127,6 +127,3 @@ libgdk_wayland = static_library('gdk-wayland',
link_with: [ libwayland_cursor, ],
dependencies: [ gdk_deps, gdk_wayland_deps ],
)
# Used to generate pkg-config Requires
wayland_public_deps = [wlclientdep]

View File

@@ -201,7 +201,7 @@ gdk_x11_clipboard_formats_to_targets (GdkContentFormats *formats)
continue;
if (g_str_equal (mime_types[i], special_targets[j].mime_type))
targets = g_slist_prepend (targets, (gpointer) g_intern_static_string (special_targets[j].x_target));
targets = g_slist_prepend (targets, (gpointer) g_intern_string (special_targets[j].x_target));
}
targets = g_slist_prepend (targets, (gpointer) mime_types[i]);
}
@@ -238,8 +238,6 @@ gdk_x11_clipboard_formats_to_atoms (GdkDisplay *display,
for (l = targets; l; l = l->next)
atoms[i++] = gdk_x11_get_xatom_by_name_for_display (display, l->data);
g_slist_free (targets);
return atoms;
}

View File

@@ -86,5 +86,3 @@ libgdk_x11 = static_library('gdk-x11',
] + common_cflags,
dependencies: [ gdk_deps, gdk_x11_deps, ],
)
x11_public_deps = [x11_dep]

View File

@@ -22,7 +22,6 @@
#include <gsk/gskenums.h>
#include <gsk/gskpath.h>
#include <gsk/gskpathbuilder.h>
#include <gsk/gskpathmeasure.h>
#include <gsk/gskpathpoint.h>
#include <gsk/gskrenderer.h>
#include <gsk/gskrendernode.h>

View File

@@ -61,7 +61,7 @@ struct _GskContourClass
GskContour * (* reverse) (const GskContour *contour);
int (* get_winding) (const GskContour *contour,
const graphene_point_t *point);
gsize (* get_n_ops) (const GskContour *contour);
gsize (* get_n_points) (const GskContour *contour);
gboolean (* get_closest_point) (const GskContour *contour,
const graphene_point_t *point,
float threshold,
@@ -76,25 +76,12 @@ struct _GskContourClass
graphene_vec2_t *tangent);
float (* get_curvature) (const GskContour *contour,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center);
void (* add_segment) (const GskContour *contour,
GskPathBuilder *builder,
gboolean emit_move_to,
GskRealPathPoint *start,
GskRealPathPoint *end);
gpointer (* init_measure) (const GskContour *contour,
float tolerance,
float *out_length);
void (* free_measure) (const GskContour *contour,
gpointer measure_data);
void (* get_point) (const GskContour *contour,
gpointer measure_data,
float distance,
GskRealPathPoint *result);
float (* get_distance) (const GskContour *contour,
GskRealPathPoint *point,
gpointer measure_data);
};
/* {{{ Utilities */
@@ -132,8 +119,6 @@ struct _GskStandardContour
GskPathFlags flags;
GskBoundingBox bounds;
gsize n_ops;
gsize n_points;
graphene_point_t *points;
@@ -144,13 +129,9 @@ static gsize
gsk_standard_contour_compute_size (gsize n_ops,
gsize n_points)
{
gsize align = MAX (G_ALIGNOF (graphene_point_t),
MAX (G_ALIGNOF (gpointer),
G_ALIGNOF (GskStandardContour)));
gsize s = sizeof (GskStandardContour)
+ sizeof (gskpathop) * n_ops
+ sizeof (graphene_point_t) * n_points;
return s + (align - (s % align));
return sizeof (GskStandardContour)
+ sizeof (gskpathop) * n_ops
+ sizeof (graphene_point_t) * n_points;
}
static void
@@ -201,7 +182,6 @@ static gboolean
add_reverse (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data)
{
GskPathBuilder *builder = user_data;
@@ -213,7 +193,7 @@ add_reverse (GskPathOperation op,
if (op == GSK_PATH_CLOSE)
op = GSK_PATH_LINE;
gsk_curve_init_foreach (&c, op, pts, n_pts, weight);
gsk_curve_init_foreach (&c, op, pts, n_pts);
gsk_curve_reverse (&c, &r);
gsk_curve_builder_to (&r, builder);
@@ -270,7 +250,7 @@ gsk_standard_contour_print (const GskContour *contour,
const graphene_point_t *pt = gsk_pathop_points (self->ops[i]);
switch (gsk_pathop_op (self->ops[i]))
{
{
case GSK_PATH_MOVE:
g_string_append (string, "M ");
_g_string_append_point (string, &pt[0]);
@@ -301,19 +281,10 @@ gsk_standard_contour_print (const GskContour *contour,
_g_string_append_point (string, &pt[3]);
break;
case GSK_PATH_CONIC:
g_string_append (string, " O ");
_g_string_append_point (string, &pt[1]);
g_string_append (string, ", ");
_g_string_append_point (string, &pt[3]);
g_string_append (string, ", ");
_g_string_append_double (string, pt[2].x);
break;
default:
g_assert_not_reached();
return;
}
}
}
}
@@ -322,32 +293,68 @@ gsk_standard_contour_get_bounds (const GskContour *contour,
GskBoundingBox *bounds)
{
const GskStandardContour *self = (const GskStandardContour *) contour;
gsize i;
if (self->n_points == 0)
return FALSE;
*bounds = self->bounds;
gsk_bounding_box_init (bounds, &self->points[0], &self->points[0]);
for (i = 1; i < self->n_points; i ++)
gsk_bounding_box_expand (bounds, &self->points[i]);
return bounds->max.x > bounds->min.x && bounds->max.y > bounds->min.y;
}
static gboolean
add_stroke_bounds (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
gpointer user_data)
{
struct {
GskBoundingBox *bounds;
float lw;
float mw;
} *data = user_data;
GskBoundingBox bounds;
for (int i = 1; i < n_pts - 1; i++)
{
gsk_bounding_box_init (&bounds,
&GRAPHENE_POINT_INIT (pts[i].x - data->lw/2, pts[i].y - data->lw/2),
&GRAPHENE_POINT_INIT (pts[i].x + data->lw/2, pts[i].y + data->lw/2));
gsk_bounding_box_union (&bounds, data->bounds, data->bounds);
}
gsk_bounding_box_init (&bounds,
&GRAPHENE_POINT_INIT (pts[n_pts - 1].x - data->mw/2, pts[n_pts - 1].y - data->mw/2),
&GRAPHENE_POINT_INIT (pts[n_pts - 1].x + data->mw/2, pts[n_pts - 1].y + data->mw/2));
gsk_bounding_box_union (&bounds, data->bounds, data->bounds);
return TRUE;
}
static gboolean
gsk_standard_contour_get_stroke_bounds (const GskContour *contour,
const GskStroke *stroke,
GskBoundingBox *bounds)
{
GskStandardContour *self = (GskStandardContour *) contour;
float extra;
struct {
GskBoundingBox *bounds;
float lw;
float mw;
} data;
if (self->n_points == 0)
return FALSE;
data.bounds = bounds;
data.lw = stroke->line_width;
data.mw = gsk_stroke_get_join_width (stroke);
extra = MAX (stroke->line_width, gsk_stroke_get_join_width (stroke));
gsk_bounding_box_init (bounds,
&GRAPHENE_POINT_INIT (self->points[0].x - data.mw/2, self->points[0].y - data.mw/2),
&GRAPHENE_POINT_INIT (self->points[0].x + data.mw/2, self->points[0].y + data.mw/2));
gsk_bounding_box_init (bounds, &GRAPHENE_POINT_INIT (self->bounds.min.x - extra,
self->bounds.min.y - extra),
&GRAPHENE_POINT_INIT (self->bounds.max.x + extra,
self->bounds.max.y + extra));
gsk_standard_contour_foreach (contour, GSK_PATH_TOLERANCE_DEFAULT, add_stroke_bounds, &data);
return TRUE;
}
@@ -373,9 +380,6 @@ gsk_standard_contour_get_winding (const GskContour *contour,
GskStandardContour *self = (GskStandardContour *) contour;
int winding = 0;
if (!gsk_bounding_box_contains_point (&self->bounds, point))
return 0;
for (gsize i = 0; i < self->n_ops; i ++)
{
GskCurve c;
@@ -402,7 +406,7 @@ gsk_standard_contour_get_winding (const GskContour *contour,
}
static gsize
gsk_standard_contour_get_n_ops (const GskContour *contour)
gsk_standard_contour_get_n_points (const GskContour *contour)
{
GskStandardContour *self = (GskStandardContour *) contour;
@@ -505,8 +509,7 @@ gsk_standard_contour_get_tangent (const GskContour *contour,
idx = point->idx;
t = point->t;
if (t == 0 && (direction == GSK_PATH_FROM_START ||
direction == GSK_PATH_TO_START))
if (t == 0 && direction == GSK_PATH_START)
{
/* Look at the previous segment */
if (idx > 1)
@@ -520,8 +523,7 @@ gsk_standard_contour_get_tangent (const GskContour *contour,
t = 1;
}
}
else if (t == 1 && (direction == GSK_PATH_TO_END ||
direction == GSK_PATH_FROM_END))
else if (t == 1 && direction == GSK_PATH_END)
{
/* Look at the next segment */
if (idx < self->n_ops - 1)
@@ -538,43 +540,21 @@ gsk_standard_contour_get_tangent (const GskContour *contour,
gsk_curve_init (&curve, self->ops[idx]);
gsk_curve_get_tangent (&curve, t, tangent);
if (direction == GSK_PATH_TO_START || direction == GSK_PATH_FROM_END)
graphene_vec2_negate (tangent, tangent);
}
static float
gsk_standard_contour_get_curvature (const GskContour *contour,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center)
{
GskStandardContour *self = (GskStandardContour *) contour;
GskCurve curve;
gsize idx;
float t;
if (G_UNLIKELY (point->idx == 0))
return 0;
idx = point->idx;
t = point->t;
if (t == 0 && idx > 1 &&
(direction == GSK_PATH_FROM_START || direction == GSK_PATH_TO_START))
{
idx--;
t = 1;
}
else if (t == 1 && idx + 1 < self->n_ops &&
(direction == GSK_PATH_FROM_END || direction == GSK_PATH_TO_END))
{
idx++;
t = 0;
}
gsk_curve_init (&curve, self->ops[idx]);
return gsk_curve_get_curvature (&curve, t, center);
gsk_curve_init (&curve, self->ops[point->idx]);
return gsk_curve_get_curvature (&curve, point->t, center);
}
static void
@@ -603,8 +583,6 @@ gsk_standard_contour_add_segment (const GskContour *contour,
GskStandardContour *self = (GskStandardContour *) contour;
GskCurve c, c1, c2;
g_assert (start->idx < self->n_ops);
gsk_curve_init (&c, self->ops[start->idx]);
if (start->idx == end->idx)
@@ -644,252 +622,6 @@ gsk_standard_contour_add_segment (const GskContour *contour,
}
}
typedef struct
{
gsize idx;
float t;
float length;
} CurvePoint;
static void
add_measure (const GskCurve *curve,
float length,
float tolerance,
float t1,
float l1,
GArray *array)
{
GskCurve c;
float ll, l0;
float t0;
float tt, ll0;
CurvePoint *p = &g_array_index (array, CurvePoint, array->len - 1);
gsize idx = p->idx;
/* Check if we can add (t1, length + l1) without further
* splitting. We check two things:
* - Is the curve close to a straight line (length-wise) ?
* - Does the roundtrip length<>t not deviate too much ?
*/
if (curve->op == GSK_PATH_LINE ||
curve->op == GSK_PATH_CLOSE)
goto done;
t0 = (p->t + t1) / 2;
if (t0 == p->t || t0 == t1)
goto done;
gsk_curve_split (curve, t0, &c, NULL);
l0 = gsk_curve_get_length (&c);
ll = (p->length + length + l1) / 2;
tt = gsk_curve_at_length (curve, l0, 0.001);
gsk_curve_split (curve, tt, &c, NULL);
ll0 = gsk_curve_get_length (&c);
if (fabsf (length + l0 - ll) < tolerance &&
fabsf (ll0 - l0) < tolerance)
{
done:
g_array_append_val (array, ((CurvePoint){ idx, t1, length + l1 }));
}
else
{
add_measure (curve, length, tolerance, t0, l0, array);
add_measure (curve, length, tolerance, t1, l1, array);
}
}
static int
cmpfloat (const void *p1, const void *p2)
{
const float *f1 = p1;
const float *f2 = p2;
return *f1 < *f2 ? -1 : (*f1 > *f2 ? 1 : 0);
}
static gpointer
gsk_standard_contour_init_measure (const GskContour *contour,
float tolerance,
float *out_length)
{
const GskStandardContour *self = (const GskStandardContour *) contour;
GArray *array;
float length;
array = g_array_new (FALSE, FALSE, sizeof (CurvePoint));
length = 0;
for (gsize i = 1; i < self->n_ops; i++)
{
GskCurve curve;
float l;
float t[3];
int n;
gsk_curve_init (&curve, self->ops[i]);
g_array_append_val (array, ((CurvePoint) { i, 0, length }));
n = gsk_curve_get_curvature_points (&curve, t);
qsort (t, n, sizeof (float), cmpfloat);
for (int j = 0; j < n; j++)
{
l = gsk_curve_get_length_to (&curve, t[j]);
add_measure (&curve, length, tolerance, t[j], l, array);
}
l = gsk_curve_get_length (&curve);
add_measure (&curve, length, tolerance, 1, l, array);
length += l;
}
*out_length = length;
#if 0
g_print ("%lu ops, %u measure points\n", self->n_ops, array->len);
for (gsize i = 0; i < array->len; i++)
{
CurvePoint *pp = &g_array_index (array, CurvePoint, i);
const char *opname[] = { "M", "Z", "L", "Q", "C" };
GskPathOperation op = gsk_pathop_op (self->ops[pp->idx]);
g_print ("%lu %s %g -> %g\n", pp->idx, opname[op], pp->t, pp->length);
}
#endif
return array;
}
static void
gsk_standard_contour_free_measure (const GskContour *contour,
gpointer data)
{
g_array_free (data, TRUE);
}
static void
gsk_standard_contour_get_point (const GskContour *contour,
gpointer measure_data,
float distance,
GskRealPathPoint *result)
{
const GskStandardContour *self = (const GskStandardContour *) contour;
GArray *array = measure_data;
gsize i0, i1;
CurvePoint *p0, *p1;
if (self->n_ops == 1)
{
result->idx = 0;
result->t = 1;
return;
}
i0 = 0;
i1 = array->len - 1;
while (i0 + 1 < i1)
{
gsize i = (i0 + i1) / 2;
CurvePoint *p = &g_array_index (array, CurvePoint, i);
if (p->length < distance)
i0 = i;
else if (p->length > distance)
i1 = i;
else
{
result->idx = p->idx;
result->t = p->t;
return;
}
}
p0 = &g_array_index (array, CurvePoint, i0);
p1 = &g_array_index (array, CurvePoint, i1);
if (distance >= p1->length)
{
if (p1->idx == self->n_ops - 1)
{
result->idx = p1->idx;
result->t = 1;
}
else
{
result->idx = p1->idx + 1;
result->t = 0;
}
}
else
{
float fraction, t0;
g_assert (p0->idx == p1->idx || p0->t == 1);
t0 = p0->idx == p1->idx ? p0->t : 0;
result->idx = p1->idx;
fraction = (distance - p0->length) / (p1->length - p0->length);
g_assert (fraction >= 0.f && fraction <= 1.f);
result->t = t0 * (1 - fraction) + p1->t * fraction;
g_assert (result->t >= 0.f && result->t <= 1.f);
}
}
static float
gsk_standard_contour_get_distance (const GskContour *contour,
GskRealPathPoint *point,
gpointer measure_data)
{
GArray *array = measure_data;
gsize i0, i1;
CurvePoint *p0, *p1;
float fraction, t0;
if (G_UNLIKELY (point->idx == 0))
return 0;
i0 = 0;
i1 = array->len - 1;
while (i0 + 1 < i1)
{
gsize i = (i0 + i1) / 2;
CurvePoint *p = &g_array_index (array, CurvePoint, i);
if (p->idx > point->idx)
i1 = i;
else if (p->idx < point->idx)
i0 = i;
else if (p->t > point->t)
i1 = i;
else if (p->t < point->t)
i0 = i;
else
return p->length;
}
p0 = &g_array_index (array, CurvePoint, i0);
p1 = &g_array_index (array, CurvePoint, i1);
g_assert (p0->idx == p1->idx || p0->t == 1);
t0 = p0->idx == p1->idx ? p0->t : 0;
g_assert (p1->idx == point->idx);
g_assert (t0 <= point->t && point->t <= p1->t);
fraction = (point->t - t0) / (p1->t - t0);
g_assert (fraction >= 0.f && fraction <= 1.f);
return p0->length * (1 - fraction) + p1->length * fraction;
}
static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
{
sizeof (GskStandardContour),
@@ -904,16 +636,12 @@ static const GskContourClass GSK_STANDARD_CONTOUR_CLASS =
gsk_standard_contour_foreach,
gsk_standard_contour_reverse,
gsk_standard_contour_get_winding,
gsk_standard_contour_get_n_ops,
gsk_standard_contour_get_n_points,
gsk_standard_contour_get_closest_point,
gsk_standard_contour_get_position,
gsk_standard_contour_get_tangent,
gsk_standard_contour_get_curvature,
gsk_standard_contour_add_segment,
gsk_standard_contour_init_measure,
gsk_standard_contour_free_measure,
gsk_standard_contour_get_point,
gsk_standard_contour_get_distance,
};
/* You must ensure the contour has enough size allocated,
@@ -930,6 +658,7 @@ gsk_standard_contour_init (GskContour *contour,
{
GskStandardContour *self = (GskStandardContour *) contour;
gsize i;
self->contour.klass = &GSK_STANDARD_CONTOUR_CLASS;
@@ -940,13 +669,11 @@ gsk_standard_contour_init (GskContour *contour,
memcpy (self->points, points, sizeof (graphene_point_t) * n_points);
offset += self->points - points;
for (gsize i = 0; i < n_ops; i++)
self->ops[i] = gsk_pathop_encode (gsk_pathop_op (ops[i]),
gsk_pathop_points (ops[i]) + offset);
gsk_bounding_box_init (&self->bounds, &self->points[0], &self->points[0]);
for (gsize i = 1; i < self->n_points; i ++)
gsk_bounding_box_expand (&self->bounds, &self->points[i]);
for (i = 0; i < n_ops; i++)
{
self->ops[i] = gsk_pathop_encode (gsk_pathop_op (ops[i]),
gsk_pathop_points (ops[i]) + offset);
}
}
GskContour *
@@ -1062,9 +789,9 @@ gsk_contour_get_closest_point (const GskContour *self,
}
gsize
gsk_contour_get_n_ops (const GskContour *self)
gsk_contour_get_n_points (const GskContour *self)
{
return self->klass->get_n_ops (self);
return self->klass->get_n_points (self);
}
void
@@ -1087,10 +814,9 @@ gsk_contour_get_tangent (const GskContour *self,
float
gsk_contour_get_curvature (const GskContour *self,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center)
{
return self->klass->get_curvature (self, point, direction, center);
return self->klass->get_curvature (self, point, center);
}
void
@@ -1103,38 +829,6 @@ gsk_contour_add_segment (const GskContour *self,
self->klass->add_segment (self, builder, emit_move_to, start, end);
}
gpointer
gsk_contour_init_measure (const GskContour *self,
float tolerance,
float *out_length)
{
return self->klass->init_measure (self, tolerance, out_length);
}
void
gsk_contour_free_measure (const GskContour *self,
gpointer data)
{
self->klass->free_measure (self, data);
}
void
gsk_contour_get_point (const GskContour *self,
gpointer measure_data,
float distance,
GskRealPathPoint *result)
{
self->klass->get_point (self, measure_data, distance, result);
}
float
gsk_contour_get_distance (const GskContour *self,
GskRealPathPoint *point,
gpointer measure_data)
{
return self->klass->get_distance (self, point, measure_data);
}
/* }}} */
/* vim:set foldmethod=marker expandtab: */

View File

@@ -57,7 +57,7 @@ void gsk_contour_get_start_end (const GskContou
graphene_point_t *end);
int gsk_contour_get_winding (const GskContour *self,
const graphene_point_t *point);
gsize gsk_contour_get_n_ops (const GskContour *self);
gsize gsk_contour_get_n_points (const GskContour *self);
gboolean gsk_contour_get_closest_point (const GskContour *self,
const graphene_point_t *point,
float threshold,
@@ -72,7 +72,6 @@ void gsk_contour_get_tangent (const GskContou
graphene_vec2_t *tangent);
float gsk_contour_get_curvature (const GskContour *self,
GskRealPathPoint *point,
GskPathDirection direction,
graphene_point_t *center);
void gsk_contour_add_segment (const GskContour *self,
GskPathBuilder *builder,
@@ -80,17 +79,5 @@ void gsk_contour_add_segment (const GskContou
GskRealPathPoint *start,
GskRealPathPoint *end);
gpointer gsk_contour_init_measure (const GskContour *self,
float tolerance,
float *out_length);
void gsk_contour_free_measure (const GskContour *self,
gpointer data);
void gsk_contour_get_point (const GskContour *self,
gpointer measure_data,
float distance,
GskRealPathPoint *result);
float gsk_contour_get_distance (const GskContour *self,
GskRealPathPoint *point,
gpointer measure_data);
G_END_DECLS

View File

@@ -1,213 +0,0 @@
/* Legendre-Gauss values,
* see https://pomax.github.io/bezierinfo/legendre-gauss.html
*/
#if 0
/* n = 64 */
static const double T[] = {
-0.0243502926634244325089558428537156614268871093149758091634531663960566965166295288529853061657116894882370493013671717560479926679408068852617342586968190919443025679363843727751902756254975073084367002129407854253246662805532069172532219089321005870178809284335033318073251039701073379759,
0.0243502926634244325089558428537156614268871093149758091634531663960566965166295288529853061657116894882370493013671717560479926679408068852617342586968190919443025679363843727751902756254975073084367002129407854253246662805532069172532219089321005870178809284335033318073251039701073379759,
-0.0729931217877990394495429419403374932441261816687788533563163323377395217254429050181833064967505478802134768007678458612956459126148837496307967995621683597067400860540057918571357609346700883624064782909888895547912499697295335516804810990011835717296819569741981551097569810739977931249,
0.0729931217877990394495429419403374932441261816687788533563163323377395217254429050181833064967505478802134768007678458612956459126148837496307967995621683597067400860540057918571357609346700883624064782909888895547912499697295335516804810990011835717296819569741981551097569810739977931249,
-0.1214628192961205544703764634922478782186836383371912940423495826006931832245070944213952236889690237679661122848626352437115925113582515415979746598665681268376919737373113667247142315234607397986222184384307059013512155412722263090766858403726100735651684437098923088469949297570988091677,
0.1214628192961205544703764634922478782186836383371912940423495826006931832245070944213952236889690237679661122848626352437115925113582515415979746598665681268376919737373113667247142315234607397986222184384307059013512155412722263090766858403726100735651684437098923088469949297570988091677,
-0.1696444204239928180373136297482698441999902667343778505894178746884342357796505591325925801106834127602396624627746208498838190598644711533868179088757129652678801285453336384132061358206434768209251779433993367981112053126660575920785488821886662635718276505127786854167528795165050389903,
0.1696444204239928180373136297482698441999902667343778505894178746884342357796505591325925801106834127602396624627746208498838190598644711533868179088757129652678801285453336384132061358206434768209251779433993367981112053126660575920785488821886662635718276505127786854167528795165050389903,
-0.217423643740007084149648748988822617578485831141222348630380401885689634737659235537163737740243604800759921292790013642836998201691226098978544332296437547642195961469059807833597096166848933098833151166287901339013986496737408125314858259377210847115061960167857239951500335854820530586,
0.217423643740007084149648748988822617578485831141222348630380401885689634737659235537163737740243604800759921292790013642836998201691226098978544332296437547642195961469059807833597096166848933098833151166287901339013986496737408125314858259377210847115061960167857239951500335854820530586,
-0.2646871622087674163739641725100201179804131362950932439559895448126206429452852982016450901649805445999078728714943692622330016257776575354105370883948495294882935681426154386660616476411740312465060150591301869544672050088454083442813632094277160007745547301572849406353682760306061929911,
0.2646871622087674163739641725100201179804131362950932439559895448126206429452852982016450901649805445999078728714943692622330016257776575354105370883948495294882935681426154386660616476411740312465060150591301869544672050088454083442813632094277160007745547301572849406353682760306061929911,
-0.3113228719902109561575126985601568835577153578680501269954571709858169098868398268719654999460149709757804582988077747605532896065842023340674450299515989484487746153929299031759475919924980452933324186984188982046762542556035347023744560814177013801414889023264804693830155588690576492164,
0.3113228719902109561575126985601568835577153578680501269954571709858169098868398268719654999460149709757804582988077747605532896065842023340674450299515989484487746153929299031759475919924980452933324186984188982046762542556035347023744560814177013801414889023264804693830155588690576492164,
-0.357220158337668115950442615046202531626264464640909112021237019340099177403802509741325589540743874845093675632547750287037622834793938695456980400958079292460482315821150714268593539935795231095157602025909339384694681190969656053235824652679875951093689200190014853543993102190088381483,
0.357220158337668115950442615046202531626264464640909112021237019340099177403802509741325589540743874845093675632547750287037622834793938695456980400958079292460482315821150714268593539935795231095157602025909339384694681190969656053235824652679875951093689200190014853543993102190088381483,
-0.4022701579639916036957667712601588487132652056150208082760431843129087214967261515969669708970990221669508217089555714806012046537594438323569293594638517933840725639831594134038262580440842200076281605641993773325072728778928440394419613403725280285705765326861533477990551765453978736181,
0.4022701579639916036957667712601588487132652056150208082760431843129087214967261515969669708970990221669508217089555714806012046537594438323569293594638517933840725639831594134038262580440842200076281605641993773325072728778928440394419613403725280285705765326861533477990551765453978736181,
-0.4463660172534640879849477147589151892067507578262501763082606820212937626970791295735937384813941473610238854736863966831464694923749954564921955859791688348936235671762050333408576202492209167272366373825152067680845198006626563761196191045700093968519269790165913301841545609485952718504,
0.4463660172534640879849477147589151892067507578262501763082606820212937626970791295735937384813941473610238854736863966831464694923749954564921955859791688348936235671762050333408576202492209167272366373825152067680845198006626563761196191045700093968519269790165913301841545609485952718504,
-0.4894031457070529574785263070219213908493732974637398373316540793240315585537584844752851087115581833443158831657759501916744927211636581386025171070582998790865902140901838128045602667002106847665927788023098753138400106615804847725751247952878407027140260429761863258319891988431055536872,
0.4894031457070529574785263070219213908493732974637398373316540793240315585537584844752851087115581833443158831657759501916744927211636581386025171070582998790865902140901838128045602667002106847665927788023098753138400106615804847725751247952878407027140260429761863258319891988431055536872,
-0.531279464019894545658013903544455247408525588734180238053268047166041778398245121448843253296460411619816073385211875151397248937264089998182375345915413219579220233566173902955487674957069948591213673456625912506280248298229907928060620469290406581396192419570799497688513058132396498814,
0.531279464019894545658013903544455247408525588734180238053268047166041778398245121448843253296460411619816073385211875151397248937264089998182375345915413219579220233566173902955487674957069948591213673456625912506280248298229907928060620469290406581396192419570799497688513058132396498814,
-0.5718956462026340342838781166591886431831910060912509932273284719418912212643223327597417735844776972648163821225207266145263395898251858906124801356522395225326954546582593857056725545247314092886133249957455688586118199388064447508712958637376347457406936802691416300157802889354368128467,
0.5718956462026340342838781166591886431831910060912509932273284719418912212643223327597417735844776972648163821225207266145263395898251858906124801356522395225326954546582593857056725545247314092886133249957455688586118199388064447508712958637376347457406936802691416300157802889354368128467,
-0.6111553551723932502488529710185489186961245593079718443367976666933088374650288148448667879830703867726577720666491772560110368248450475818132595468834493579434418252468978282181164008820769765174450056817468275783966537351796625224747700783378315186174632657840114512887287754747902924865,
0.6111553551723932502488529710185489186961245593079718443367976666933088374650288148448667879830703867726577720666491772560110368248450475818132595468834493579434418252468978282181164008820769765174450056817468275783966537351796625224747700783378315186174632657840114512887287754747902924865,
-0.6489654712546573398577612319934048855296904334732011728792502624366057598865738239773166627826358871699142531853930525866830933399401844502541092962631127742267449897116125748014270680393024011359139031312062573520509858894743036198986443014969748157931850178889912972291202354657382925509,
0.6489654712546573398577612319934048855296904334732011728792502624366057598865738239773166627826358871699142531853930525866830933399401844502541092962631127742267449897116125748014270680393024011359139031312062573520509858894743036198986443014969748157931850178889912972291202354657382925509,
-0.6852363130542332425635583710313763019356410785396718681324042749913611976548967332647625541234155413035075739348863233240851709341392873173633850612006618690218164007761541855237208605116527909791956398350719463021018362527198358286721239529091637248252469435642287693207506339068528700205,
0.6852363130542332425635583710313763019356410785396718681324042749913611976548967332647625541234155413035075739348863233240851709341392873173633850612006618690218164007761541855237208605116527909791956398350719463021018362527198358286721239529091637248252469435642287693207506339068528700205,
-0.7198818501716108268489402178319472447581380033149019526220473151184468592486433646042300919262498902882179891494724046747921544602557246455427317830132976771174504209146835854012577372395960646854355024460204286901035470812684876587693044068989973704915078171158689213412715251485203442313,
0.7198818501716108268489402178319472447581380033149019526220473151184468592486433646042300919262498902882179891494724046747921544602557246455427317830132976771174504209146835854012577372395960646854355024460204286901035470812684876587693044068989973704915078171158689213412715251485203442313,
-0.7528199072605318966118637748856939855517142713220871932461987761167722639636968539390413583009467924995905147153923286347693864945784890119950315095740891764880991728646942920208355501445550654259850385377192973526980795946453961077798744753892199929235882097232836682421729944934586281945,
0.7528199072605318966118637748856939855517142713220871932461987761167722639636968539390413583009467924995905147153923286347693864945784890119950315095740891764880991728646942920208355501445550654259850385377192973526980795946453961077798744753892199929235882097232836682421729944934586281945,
-0.7839723589433414076102205252137682840564141249898259334132759617476816578705098509357116190608002325895348207611752987335385494893726027026038902508685496606160441965948835252795524014713290879877269643684102005605450140247125536147801312017065532602835003540212221564314236937509990182173,
0.7839723589433414076102205252137682840564141249898259334132759617476816578705098509357116190608002325895348207611752987335385494893726027026038902508685496606160441965948835252795524014713290879877269643684102005605450140247125536147801312017065532602835003540212221564314236937509990182173,
-0.8132653151227975597419233380863033406981418225655972166956485149356586346082019870309280128411412936411423614767918756843380999442447282903502051218203273573634847203121451086379808399639198510674436238195505371716160648058477202993836014352158139813219612968106205248494087577632573534973,
0.8132653151227975597419233380863033406981418225655972166956485149356586346082019870309280128411412936411423614767918756843380999442447282903502051218203273573634847203121451086379808399639198510674436238195505371716160648058477202993836014352158139813219612968106205248494087577632573534973,
-0.840629296252580362751691544695873302982489823801755353928202683075593465893922171840726147868117503717663799561956411215937924134571068943700343442753760445948626598735504632170407243376224222403038093781056024445977626666740664628412660960413062370047183186652885532589557452614451434048,
0.840629296252580362751691544695873302982489823801755353928202683075593465893922171840726147868117503717663799561956411215937924134571068943700343442753760445948626598735504632170407243376224222403038093781056024445977626666740664628412660960413062370047183186652885532589557452614451434048,
-0.8659993981540928197607833850701575024125019187582496425664279511808356713122188567857456842034906362573453815878913951040194915987006979015304835979058725276345799813088989383312475641092775164460639450521468294104011206574786429237252678172922104036725327539940502197291939132802457917836,
0.8659993981540928197607833850701575024125019187582496425664279511808356713122188567857456842034906362573453815878913951040194915987006979015304835979058725276345799813088989383312475641092775164460639450521468294104011206574786429237252678172922104036725327539940502197291939132802457917836,
-0.8893154459951141058534040382728516224291944615104521893194744566084811090577722526400445910623711480590529533188832105988657269430913287263821624762648137092066620632787986348052306840101775313644572400860845559833367997001666659907951051347410546710134120144598833115095140475669485797579,
0.8893154459951141058534040382728516224291944615104521893194744566084811090577722526400445910623711480590529533188832105988657269430913287263821624762648137092066620632787986348052306840101775313644572400860845559833367997001666659907951051347410546710134120144598833115095140475669485797579,
-0.9105221370785028057563806680083298610134880848883640292531723714467102234556291968179018775780308458024302103848451312741663820589200520720207891653884985710130867134073520525932445557074805974235006810370309087879564826639263972805682465506594098949560288847385983395160311034445386606259,
0.9105221370785028057563806680083298610134880848883640292531723714467102234556291968179018775780308458024302103848451312741663820589200520720207891653884985710130867134073520525932445557074805974235006810370309087879564826639263972805682465506594098949560288847385983395160311034445386606259,
-0.9295691721319395758214901545592256073474270144297154975928116833612430986265594515998834499355844736686512805129688214992047597092114291955925880175797899765980745854426738149516325837607227287481909072315347776012991222301207304052068204069335766550173941103055407746774520789612843561385,
0.9295691721319395758214901545592256073474270144297154975928116833612430986265594515998834499355844736686512805129688214992047597092114291955925880175797899765980745854426738149516325837607227287481909072315347776012991222301207304052068204069335766550173941103055407746774520789612843561385,
-0.9464113748584028160624814913472647952793949717952331902317789712973664402149436591260928179188420533516264142755452159723722786167537167514691534968355366202934342465086995943893699962972237343218079763936958985487264411542890941861254842843026890160131607678957282346112697993618567018237,
0.9464113748584028160624814913472647952793949717952331902317789712973664402149436591260928179188420533516264142755452159723722786167537167514691534968355366202934342465086995943893699962972237343218079763936958985487264411542890941861254842843026890160131607678957282346112697993618567018237,
-0.9610087996520537189186141218971572067621146110378459494461586158623919945488992563976780806866203786216001498788310714552847469661399216303755820947005848739467276644122915754949838610353627723679982220628115164983443994552616161584523205789167087822341423097206088828267065770404672828066,
0.9610087996520537189186141218971572067621146110378459494461586158623919945488992563976780806866203786216001498788310714552847469661399216303755820947005848739467276644122915754949838610353627723679982220628115164983443994552616161584523205789167087822341423097206088828267065770404672828066,
-0.9733268277899109637418535073522726680261452944551741758819139781978152256958453749994966038154125547612207903105020176172420237675899907788807087542221018040460410464083361271842759039530092449625891215101984663282728542290395875313124045226564547294745437773482395329023327909760431499638,
0.9733268277899109637418535073522726680261452944551741758819139781978152256958453749994966038154125547612207903105020176172420237675899907788807087542221018040460410464083361271842759039530092449625891215101984663282728542290395875313124045226564547294745437773482395329023327909760431499638,
-0.9833362538846259569312993021568311169452475066237403837464872131233426128415470535606559721330818003585532628124845662897410684694651251174207713020897795837892725294581710205598344576799985346970638130204876060998657059283079767876980544166132523941283823202290746667358872631036031924711,
0.9833362538846259569312993021568311169452475066237403837464872131233426128415470535606559721330818003585532628124845662897410684694651251174207713020897795837892725294581710205598344576799985346970638130204876060998657059283079767876980544166132523941283823202290746667358872631036031924711,
-0.9910133714767443207393823834433031136413494453907904852225427459378131658644129997345108950133770434340330151289100150097018332483423277136039914249575686591612502752158650205954671083696496347591169012794322303027309768195334920157669446268175983954105533989275308193580349506657360682085,
0.9910133714767443207393823834433031136413494453907904852225427459378131658644129997345108950133770434340330151289100150097018332483423277136039914249575686591612502752158650205954671083696496347591169012794322303027309768195334920157669446268175983954105533989275308193580349506657360682085,
-0.9963401167719552793469245006763991232098575063402266121352522199507030568202208530946066801021703916301511794658310735397567341036554686814952726523955953805437164277655915410358813984246580862850974195805395101678543649116458555272523253307828290553873260588621490898443701779725568118502,
0.9963401167719552793469245006763991232098575063402266121352522199507030568202208530946066801021703916301511794658310735397567341036554686814952726523955953805437164277655915410358813984246580862850974195805395101678543649116458555272523253307828290553873260588621490898443701779725568118502,
-0.9993050417357721394569056243456363119697121916756087760628072954617646543505331997843242376462639434945376776512170265314011232493020401570891594274831367800115383317335285468800574240152992751785027563437707875403545865305271045717258142571193695943317890367167086616955235477529427992282,
0.9993050417357721394569056243456363119697121916756087760628072954617646543505331997843242376462639434945376776512170265314011232493020401570891594274831367800115383317335285468800574240152992751785027563437707875403545865305271045717258142571193695943317890367167086616955235477529427992282
};
static const double C[] = {
0.0486909570091397203833653907347499124426286922838743305086688042456914190998246107310291565645676057401607079939845156005172257043376703767287395573765236401039685866479381075274920900511719320271157129622463682509122641788910270632229694394595885032921037399187298767076084601033342936131,
0.0486909570091397203833653907347499124426286922838743305086688042456914190998246107310291565645676057401607079939845156005172257043376703767287395573765236401039685866479381075274920900511719320271157129622463682509122641788910270632229694394595885032921037399187298767076084601033342936131,
0.0485754674415034269347990667839781136875565447049294857111516761025158193093697039229163427633930410186232149083923688162761488505704450697417589593116703853157329164894580165517236877241308351214870169600093357854651930986960906313726182992933363325614247750209880050786299287510692780499,
0.0485754674415034269347990667839781136875565447049294857111516761025158193093697039229163427633930410186232149083923688162761488505704450697417589593116703853157329164894580165517236877241308351214870169600093357854651930986960906313726182992933363325614247750209880050786299287510692780499,
0.048344762234802957169769527158017809703692550609501080629442201445249828946429202156764153264348308119169811534137999799779908820312744765416129733427088646813066886130539178187597540312913636916139844188190193872629488730769015964208394624398401975043997268903006190530430762197842013971,
0.048344762234802957169769527158017809703692550609501080629442201445249828946429202156764153264348308119169811534137999799779908820312744765416129733427088646813066886130539178187597540312913636916139844188190193872629488730769015964208394624398401975043997268903006190530430762197842013971,
0.0479993885964583077281261798713460699543167134714936209446323930933335214619650277588138568504103427609283146728470455041360837549685364869161566863222680599110109210456299588352028330169041000166382937545505655464884266691630625402297821494221827392164049587946530563778771030124675514431,
0.0479993885964583077281261798713460699543167134714936209446323930933335214619650277588138568504103427609283146728470455041360837549685364869161566863222680599110109210456299588352028330169041000166382937545505655464884266691630625402297821494221827392164049587946530563778771030124675514431,
0.0475401657148303086622822069442231716408252512625387521584740318784735191312349586041971325618543660076682369564304738487584849740943805934034367382833518752314207901993991333786062812015195073547884746598535775062676699885664167707011249029305697669004958515813436770491520105115843742005,
0.0475401657148303086622822069442231716408252512625387521584740318784735191312349586041971325618543660076682369564304738487584849740943805934034367382833518752314207901993991333786062812015195073547884746598535775062676699885664167707011249029305697669004958515813436770491520105115843742005,
0.0469681828162100173253262857545810751998975284738125649829240886861900500181800807437012381630302198876925642461830694029139318555787845567143614289552410495903601238284556145544858090965965782916339169651505119399637862876053945518410353459767034026687936026945199383607112976484520939933,
0.0469681828162100173253262857545810751998975284738125649829240886861900500181800807437012381630302198876925642461830694029139318555787845567143614289552410495903601238284556145544858090965965782916339169651505119399637862876053945518410353459767034026687936026945199383607112976484520939933,
0.0462847965813144172959532492322611849696503075324468007778340818364698861774606986244241539105685321088517142947579291476238551538798963436740600968513359005801910700069462154098456091711311098901749803777735222026075473081311483686560830539773763176758567914860207820170792365910140063798,
0.0462847965813144172959532492322611849696503075324468007778340818364698861774606986244241539105685321088517142947579291476238551538798963436740600968513359005801910700069462154098456091711311098901749803777735222026075473081311483686560830539773763176758567914860207820170792365910140063798,
0.0454916279274181444797709969712690588873234618023998968168834081606504637618082102750954507142497706775055424364453740562113890878382679420378787427100982909191308430750899201141096789461078632697297091763378573830284133736378128577579722120264252594541491899441765769262904055702701625378,
0.0454916279274181444797709969712690588873234618023998968168834081606504637618082102750954507142497706775055424364453740562113890878382679420378787427100982909191308430750899201141096789461078632697297091763378573830284133736378128577579722120264252594541491899441765769262904055702701625378,
0.0445905581637565630601347100309448432940237999912217256432193286861948363377761089569585678875932857237669096941854082976565514031401996407675401022860761183118504326746863327792604337217763335682212515058414863183914930810334329596384915832703655935958010948424747251920190851700662833367,
0.0445905581637565630601347100309448432940237999912217256432193286861948363377761089569585678875932857237669096941854082976565514031401996407675401022860761183118504326746863327792604337217763335682212515058414863183914930810334329596384915832703655935958010948424747251920190851700662833367,
0.0435837245293234533768278609737374809227888974971180150532193925502569499020021803936448815937567079991401855477391110804568848623412043870399620479222000249538880795788245633051476595555730388360811011823841525667998427392843673284072004068821750061964976796287623004834501604656318714989,
0.0435837245293234533768278609737374809227888974971180150532193925502569499020021803936448815937567079991401855477391110804568848623412043870399620479222000249538880795788245633051476595555730388360811011823841525667998427392843673284072004068821750061964976796287623004834501604656318714989,
0.0424735151236535890073397679088173661655466481806496697314607722055245433487169327182398988553670128358787507582463602377168227019625334754497484024668087975720049504975593281010888062806587161032924284354938115463233015024659299046001504100674918329532481611571863222497170398830691222425,
0.0424735151236535890073397679088173661655466481806496697314607722055245433487169327182398988553670128358787507582463602377168227019625334754497484024668087975720049504975593281010888062806587161032924284354938115463233015024659299046001504100674918329532481611571863222497170398830691222425,
0.0412625632426235286101562974736380477399306355305474105429034779122704951178045914463267035032832336161816547420067160277921114474557623647771372636679857599931025531633255548770293397336318597716427093310378312957479805159734598610664983115148350548735211568465338522875618805992499897174,
0.0412625632426235286101562974736380477399306355305474105429034779122704951178045914463267035032832336161816547420067160277921114474557623647771372636679857599931025531633255548770293397336318597716427093310378312957479805159734598610664983115148350548735211568465338522875618805992499897174,
0.0399537411327203413866569261283360739186769506703336301114037026981570543670430333260307390357287606111017588757685176701688554806178713759519003171090525332423003042251947304213502522332118258365256241174986409729902714098049024753746340158430732115642207673265332738358717839602955875715,
0.0399537411327203413866569261283360739186769506703336301114037026981570543670430333260307390357287606111017588757685176701688554806178713759519003171090525332423003042251947304213502522332118258365256241174986409729902714098049024753746340158430732115642207673265332738358717839602955875715,
0.0385501531786156291289624969468089910127871122017180319662378854088005271323682681394418540442928363090545214563022868422017877042243007014244875098498616146404178795110038170109976252865902624380463581094085479557660525450020049773872343621719025128277593787164021147974906095237533202082,
0.0385501531786156291289624969468089910127871122017180319662378854088005271323682681394418540442928363090545214563022868422017877042243007014244875098498616146404178795110038170109976252865902624380463581094085479557660525450020049773872343621719025128277593787164021147974906095237533202082,
0.0370551285402400460404151018095833750834649453056563021747536272028091562122966687178302646649066832960609370472485057031765338738734008482025086366647963664178752038995704175623165041724901843573087856883034472545386037691055680911138721623610172486110313241291773258491882452773847899443,
0.0370551285402400460404151018095833750834649453056563021747536272028091562122966687178302646649066832960609370472485057031765338738734008482025086366647963664178752038995704175623165041724901843573087856883034472545386037691055680911138721623610172486110313241291773258491882452773847899443,
0.0354722132568823838106931467152459479480946310024100946926514848199381113651392962399922996268087884509143420993419937430515415557908457195618550238075571721209638845910166697234073788332647695349442265578792857058786796417110738673392400570019770741873271724201517438135222598792344040215,
0.0354722132568823838106931467152459479480946310024100946926514848199381113651392962399922996268087884509143420993419937430515415557908457195618550238075571721209638845910166697234073788332647695349442265578792857058786796417110738673392400570019770741873271724201517438135222598792344040215,
0.0338051618371416093915654821107254310210499263140045346675500650400323727745785853730452808963944098691936344225349051741060036935288424090581463711756382878498537611980973238606529148664990420534952057130296232922368792280098852092993207644225150541876980292972087619863453425206929192216,
0.0338051618371416093915654821107254310210499263140045346675500650400323727745785853730452808963944098691936344225349051741060036935288424090581463711756382878498537611980973238606529148664990420534952057130296232922368792280098852092993207644225150541876980292972087619863453425206929192216,
0.032057928354851553585467504347898716966221573881398062250169407854535275399124366530227987935629046729162364779969274126431870966979526186907589490002269660893281421728773647001279141626157958271220102615163092206489916992120482595587916535390136003611498634162765724522022671474313619317,
0.032057928354851553585467504347898716966221573881398062250169407854535275399124366530227987935629046729162364779969274126431870966979526186907589490002269660893281421728773647001279141626157958271220102615163092206489916992120482595587916535390136003611498634162765724522022671474313619317,
0.030234657072402478867974059819548659158281397768481241636026542045969161851838118212761980885178641520596873511042783163461341979185470882574743804555268086640389062237383427702813367624714014426121485626242067362445894463989335423458464954799181190120473168677930333898873084606011285311,
0.030234657072402478867974059819548659158281397768481241636026542045969161851838118212761980885178641520596873511042783163461341979185470882574743804555268086640389062237383427702813367624714014426121485626242067362445894463989335423458464954799181190120473168677930333898873084606011285311,
0.0283396726142594832275113052002373519812075841257543359907955185084500175712880712901834579816476269393013386531176072296695948860841466158639973753393323262188023471133258509422081952937349849822864752636994881600343083839805990853930436233762729622213044478376753949590318846038229829528,
0.0283396726142594832275113052002373519812075841257543359907955185084500175712880712901834579816476269393013386531176072296695948860841466158639973753393323262188023471133258509422081952937349849822864752636994881600343083839805990853930436233762729622213044478376753949590318846038229829528,
0.0263774697150546586716917926252251856755993308422457184496156736853021592428967790284780487213653480867620409279447766944383920384284787790772384251090745670478105870527396429136326932261251511732466974897397268573168068852344129736214469830280087710575094607457344820944885011053938108899,
0.0263774697150546586716917926252251856755993308422457184496156736853021592428967790284780487213653480867620409279447766944383920384284787790772384251090745670478105870527396429136326932261251511732466974897397268573168068852344129736214469830280087710575094607457344820944885011053938108899,
0.0243527025687108733381775504090689876499784155133784119819985685535536787083770723737264828464464223276155821319330210193549896426801083040150047332857692873011433649334477370145389017577189505240415125600908800786897201425473757275187332157593198572919772969833130729981971352463730545469,
0.0243527025687108733381775504090689876499784155133784119819985685535536787083770723737264828464464223276155821319330210193549896426801083040150047332857692873011433649334477370145389017577189505240415125600908800786897201425473757275187332157593198572919772969833130729981971352463730545469,
0.0222701738083832541592983303841550024229592905997594051455205429744914460867081990116647982811451138592401156680063927909718825845915896692701716212710541472344073624315399429951255221519263275095347974129106415903376085208797420439500915674568159744176912567285070988940509294826076696882,
0.0222701738083832541592983303841550024229592905997594051455205429744914460867081990116647982811451138592401156680063927909718825845915896692701716212710541472344073624315399429951255221519263275095347974129106415903376085208797420439500915674568159744176912567285070988940509294826076696882,
0.0201348231535302093723403167285438970895266801007919519220072343276769828211923597982299498416998597995443052252531684909219367615574440281549241161294448697202959593344989612626641188010558013085389491205901106884167596038790695150496733123662891637942237462337673353651179115491957031948,
0.0201348231535302093723403167285438970895266801007919519220072343276769828211923597982299498416998597995443052252531684909219367615574440281549241161294448697202959593344989612626641188010558013085389491205901106884167596038790695150496733123662891637942237462337673353651179115491957031948,
0.0179517157756973430850453020011193688971673570364158572977184273569247295870620984743089140579199272107974903016785911970727080884655646148340637373001805876560334052431930062983734905886704331100259778249929425439377011315288821865303197904492848823994202996722656114004109123107733596987,
0.0179517157756973430850453020011193688971673570364158572977184273569247295870620984743089140579199272107974903016785911970727080884655646148340637373001805876560334052431930062983734905886704331100259778249929425439377011315288821865303197904492848823994202996722656114004109123107733596987,
0.0157260304760247193219659952975397944260290098431565121528943932284210502164124556525745628476326997189475680077625258949765335021586482683126547283634704087193102431454662772463321304938516661086261262080252305539171654570677889578063634007609097342035360186636479612243231917699790225637,
0.0157260304760247193219659952975397944260290098431565121528943932284210502164124556525745628476326997189475680077625258949765335021586482683126547283634704087193102431454662772463321304938516661086261262080252305539171654570677889578063634007609097342035360186636479612243231917699790225637,
0.0134630478967186425980607666859556841084257719773496708184682785221983598894666268489697837056105038485845901773961664652581563686185523959473293683490869846700009741156668864960127745507806046701586435579547632680339906665338521813319281296935586498194608460412423723103161161922347608637,
0.0134630478967186425980607666859556841084257719773496708184682785221983598894666268489697837056105038485845901773961664652581563686185523959473293683490869846700009741156668864960127745507806046701586435579547632680339906665338521813319281296935586498194608460412423723103161161922347608637,
0.011168139460131128818590493019208135072778797816827287215251362273969701224836131369547661822970774719521543690039908073147476182135228738610704246958518755712518444434075738269866120460156365855324768445411463643114925829148750923090201475035559533993035986264487097245733097728698218563,
0.011168139460131128818590493019208135072778797816827287215251362273969701224836131369547661822970774719521543690039908073147476182135228738610704246958518755712518444434075738269866120460156365855324768445411463643114925829148750923090201475035559533993035986264487097245733097728698218563,
0.0088467598263639477230309146597306476951762660792204997984715769296110380005985367341694286322550520156167431790573509593010611842062630262878798782558974712042810219159674181580449655112696028911646066461502678711637780164986283350190669684468398617127841853445303466680698660632269500149,
0.0088467598263639477230309146597306476951762660792204997984715769296110380005985367341694286322550520156167431790573509593010611842062630262878798782558974712042810219159674181580449655112696028911646066461502678711637780164986283350190669684468398617127841853445303466680698660632269500149,
0.0065044579689783628561173603999812667711317610549523400952448792575685125717613068203530526491113296049409911387320826711045787146267036866881961532403342811327869183281273743976710008917886491097375367147212074243884772614562628844975421736416404173672075979097191581386023407454532945934,
0.0065044579689783628561173603999812667711317610549523400952448792575685125717613068203530526491113296049409911387320826711045787146267036866881961532403342811327869183281273743976710008917886491097375367147212074243884772614562628844975421736416404173672075979097191581386023407454532945934,
0.0041470332605624676352875357285514153133028192536848024628763661431834776690157393776820933106187137592011723199002845429836606307797425496666456172753165824787973801175029578301513761259541022471768825518482406145696380621686627285992715643614469568410535180218496973657001203470470418364,
0.0041470332605624676352875357285514153133028192536848024628763661431834776690157393776820933106187137592011723199002845429836606307797425496666456172753165824787973801175029578301513761259541022471768825518482406145696380621686627285992715643614469568410535180218496973657001203470470418364,
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733,
0.0017832807216964329472960791449719331799593472719279556695308063655858546954239803486698215802150348282744786016134857283616955449868451969230490863774274598030023211055562492709717566919237924255297982774711177411074145151155610163293142044147991553384925940046957893721166251082473659733
};
#else
/* n = 32 */
static double T[] = {
-0.0483076656877383162348125704405021636908472517308488971677937345463685926042778777794060365911173780988289503411375793689757446357461295741679964108035347980667582792392651327368009453047606446744575790523465655622949909588624860214137051585425884056992683442137333250625173849291299678673,
0.0483076656877383162348125704405021636908472517308488971677937345463685926042778777794060365911173780988289503411375793689757446357461295741679964108035347980667582792392651327368009453047606446744575790523465655622949909588624860214137051585425884056992683442137333250625173849291299678673,
-0.1444719615827964934851863735988106522038459913156355521379528938242184438164519731102406769974924713989580220758441301598578946580142268413547299935841673092513202403499286272686350814272974392746706128556678811982653393383080797337231702069432462445053984587997153683967433095128570624414,
0.1444719615827964934851863735988106522038459913156355521379528938242184438164519731102406769974924713989580220758441301598578946580142268413547299935841673092513202403499286272686350814272974392746706128556678811982653393383080797337231702069432462445053984587997153683967433095128570624414,
-0.2392873622521370745446032091655015206088554219602530155470960995597029133039943915553593695844147813728958071901224632260145752503694970545640339873418480550362677768010887468668377893757173424222709744116861683634989914911762187599464033126988486345234374380695224452457957624756811128321,
0.2392873622521370745446032091655015206088554219602530155470960995597029133039943915553593695844147813728958071901224632260145752503694970545640339873418480550362677768010887468668377893757173424222709744116861683634989914911762187599464033126988486345234374380695224452457957624756811128321,
-0.3318686022821276497799168057301879961957751368050598360182296306285376829657438169809731852312743263005943551508559377834274303920771100489026913715847854727626540340157368609696698131829681988642689780208633461925468064919389286805624602715005948661328152252049795463242055567997437182143,
0.3318686022821276497799168057301879961957751368050598360182296306285376829657438169809731852312743263005943551508559377834274303920771100489026913715847854727626540340157368609696698131829681988642689780208633461925468064919389286805624602715005948661328152252049795463242055567997437182143,
-0.4213512761306353453641194361724264783358772886324433305416613404557190462549837315607633055675740638739884093394574651160978879545562247406839036854173715776910866941643197988581928900702286425821151586000969947406313405310082646561917980302543820974679501841964453794193724645925031841919,
0.4213512761306353453641194361724264783358772886324433305416613404557190462549837315607633055675740638739884093394574651160978879545562247406839036854173715776910866941643197988581928900702286425821151586000969947406313405310082646561917980302543820974679501841964453794193724645925031841919,
-0.5068999089322293900237474743778212301802836995994354639743662809707712640478764442266190213124522047999876916596854537447047905434649918210338296049592120273725464263651562560829050004258268002241145951271730860506703690843719936432852920782304931272053564539127514959875734718036950073563,
0.5068999089322293900237474743778212301802836995994354639743662809707712640478764442266190213124522047999876916596854537447047905434649918210338296049592120273725464263651562560829050004258268002241145951271730860506703690843719936432852920782304931272053564539127514959875734718036950073563,
-0.5877157572407623290407454764018268584509401154544205727031788473129228586684474311408145102018661764979429510790747919023774933113319119601088669936958908618326367715806216053155906936017362413244183150445492317940727345571648726363597097311647731726438279098059670236086983675374932643925,
0.5877157572407623290407454764018268584509401154544205727031788473129228586684474311408145102018661764979429510790747919023774933113319119601088669936958908618326367715806216053155906936017362413244183150445492317940727345571648726363597097311647731726438279098059670236086983675374932643925,
-0.6630442669302152009751151686632383689770222859605053010170834964924461749232229404368981536611965356686820332804126742949900731319113817214392193185613161549689934301410316417342588149871686184296988807305719690974644891055567340650986465615021143958920599684258616066247948224049997371166,
0.6630442669302152009751151686632383689770222859605053010170834964924461749232229404368981536611965356686820332804126742949900731319113817214392193185613161549689934301410316417342588149871686184296988807305719690974644891055567340650986465615021143958920599684258616066247948224049997371166,
-0.732182118740289680387426665091267146630270483506629100821139573270385253587797727611292298988652560055905228466313310601075333829094630570926240639601009902567982815376254840388565733846030450161774620971196087756484387383432502715118096615117242484073636640563609696801484680439912327302,
0.732182118740289680387426665091267146630270483506629100821139573270385253587797727611292298988652560055905228466313310601075333829094630570926240639601009902567982815376254840388565733846030450161774620971196087756484387383432502715118096615117242484073636640563609696801484680439912327302,
-0.7944837959679424069630972989704289020954794016388354532507582449720593922816426654241878967890821228397041480126630294067578180914548706957761322921470535094589673860419616615738928385807346185892317514562489971543238450942224396667500582904031225063621511429185567036727089257387570529468,
0.7944837959679424069630972989704289020954794016388354532507582449720593922816426654241878967890821228397041480126630294067578180914548706957761322921470535094589673860419616615738928385807346185892317514562489971543238450942224396667500582904031225063621511429185567036727089257387570529468,
-0.849367613732569970133693004967742538954886793049759233100219598613724656141562558741881463752754991143937635778596582088915769685796612254240615386941355933272723068952531445772190363422003834495043219316062885999846179078139659341918527603834809670576387535564876596379488780285979062125,
0.849367613732569970133693004967742538954886793049759233100219598613724656141562558741881463752754991143937635778596582088915769685796612254240615386941355933272723068952531445772190363422003834495043219316062885999846179078139659341918527603834809670576387535564876596379488780285979062125,
-0.8963211557660521239653072437192122684789964967957595765636154129650249794910409173494503783167666654202705333374285522819507600044591355080910768854012859468015827508424619812224062460791781333400979810176198916239783226706506012473250929962326307746466256167673927887144428859779028909399,
0.8963211557660521239653072437192122684789964967957595765636154129650249794910409173494503783167666654202705333374285522819507600044591355080910768854012859468015827508424619812224062460791781333400979810176198916239783226706506012473250929962326307746466256167673927887144428859779028909399,
-0.9349060759377396891709191348354093255286714322828372184584037398118161947182932855418880831417927728359606280450921427988850058691931014887248988124656348299653052688344696135840215712191162135178273756415771123010111796122671724143565383396162107206772781551029308751511942924942333859805,
0.9349060759377396891709191348354093255286714322828372184584037398118161947182932855418880831417927728359606280450921427988850058691931014887248988124656348299653052688344696135840215712191162135178273756415771123010111796122671724143565383396162107206772781551029308751511942924942333859805,
-0.9647622555875064307738119281182749603888952204430187193220113218370995254867038008243801877562227002840740910741483519987441236283464394249183812395373150090695515823078220949436846111682404866338388944248976976566275875721000356873959697266702651250019105084704924793016185368873243713355,
0.9647622555875064307738119281182749603888952204430187193220113218370995254867038008243801877562227002840740910741483519987441236283464394249183812395373150090695515823078220949436846111682404866338388944248976976566275875721000356873959697266702651250019105084704924793016185368873243713355,
-0.9856115115452683354001750446309019786323957143358063182107821705820305847193755946663846485510970266115353839862364606643634021712823093784875255943834038377710426488328772047833289470320023596895438028281274741367781028592272459887917924171204666683239464005128153533797603112851826904814,
0.9856115115452683354001750446309019786323957143358063182107821705820305847193755946663846485510970266115353839862364606643634021712823093784875255943834038377710426488328772047833289470320023596895438028281274741367781028592272459887917924171204666683239464005128153533797603112851826904814,
-0.9972638618494815635449811286650407271385376637294611593011185457862359083917418520130456693085426416474280482200936551645510686196373231416035137741332968299789863385253514914078766236061488136738023162574655835389902337937054326098485227311719825229066712510246574949376367552421728646398,
0.9972638618494815635449811286650407271385376637294611593011185457862359083917418520130456693085426416474280482200936551645510686196373231416035137741332968299789863385253514914078766236061488136738023162574655835389902337937054326098485227311719825229066712510246574949376367552421728646398
};
static double C[] = {
0.0965400885147278005667648300635757947368606312355700687323182099577497758679466512968173871061464644599963197828969869820251559172455698832434930732077927850876632725829187045819145660710266452161095406358159608874152584850413283587913891015545638518881205600825069096855488296437485836866,
0.0965400885147278005667648300635757947368606312355700687323182099577497758679466512968173871061464644599963197828969869820251559172455698832434930732077927850876632725829187045819145660710266452161095406358159608874152584850413283587913891015545638518881205600825069096855488296437485836866,
0.0956387200792748594190820022041311005948905081620055509529898509437067444366006256133614167190847508238474888230077112990752876436158047205555474265705582078453283640212465537132165041268773645168746774530146140911679782502276289938840330631903789120176765314495900053061764438990021439069,
0.0956387200792748594190820022041311005948905081620055509529898509437067444366006256133614167190847508238474888230077112990752876436158047205555474265705582078453283640212465537132165041268773645168746774530146140911679782502276289938840330631903789120176765314495900053061764438990021439069,
0.0938443990808045656391802376681172600361000757462364500506275696355695118623098075097804207682530277555307864917078828352419853248607668520631751470962234105835015158485760721979732297206950719908744248285672032436598213262204039212897239890934116841559005147755270269705682414708355646603,
0.0938443990808045656391802376681172600361000757462364500506275696355695118623098075097804207682530277555307864917078828352419853248607668520631751470962234105835015158485760721979732297206950719908744248285672032436598213262204039212897239890934116841559005147755270269705682414708355646603,
0.0911738786957638847128685771116370625448614132753900053231278739777031520613017513597426417145878622654027367650308019870251963114683369110451524174258161390823876554910693202594383388549640738095422966058367070348943662290656339592299608558384147559830707904449930677260444604329157917977,
0.0911738786957638847128685771116370625448614132753900053231278739777031520613017513597426417145878622654027367650308019870251963114683369110451524174258161390823876554910693202594383388549640738095422966058367070348943662290656339592299608558384147559830707904449930677260444604329157917977,
0.0876520930044038111427714627518022875484497217017572223192228034747061150211380239263021665771581379364685191248848158059408000065275041643745927401342920150588893827207354226012701872322225514682178439577327346929209121046816487338309068375228210705166692551938339727096609740531893725675,
0.0876520930044038111427714627518022875484497217017572223192228034747061150211380239263021665771581379364685191248848158059408000065275041643745927401342920150588893827207354226012701872322225514682178439577327346929209121046816487338309068375228210705166692551938339727096609740531893725675,
0.0833119242269467552221990746043486115387468839428344598401864047287594069244380966536255650452315042012372905572506028852130723585016898197140339352228963465326746426938359210160503509807644396182380868089959855742801355208471205261406307895519604387550841954817025499019984032594036141439,
0.0833119242269467552221990746043486115387468839428344598401864047287594069244380966536255650452315042012372905572506028852130723585016898197140339352228963465326746426938359210160503509807644396182380868089959855742801355208471205261406307895519604387550841954817025499019984032594036141439,
0.078193895787070306471740918828306671039786798482159190307481553869493700115196435401943819761440851294456424770323467367505109006517482028994114252939401250416132320553639542341400437522236191275346323130525969269563653003188829786549728825182082678498917784036375053244425839341945385297,
0.078193895787070306471740918828306671039786798482159190307481553869493700115196435401943819761440851294456424770323467367505109006517482028994114252939401250416132320553639542341400437522236191275346323130525969269563653003188829786549728825182082678498917784036375053244425839341945385297,
0.0723457941088485062253993564784877916043369833018248707397632823511765345816800402874475958591657429073027694582930574378890633404841054620298756279975430795706338162404545590689277985270140590721779502609564199074051863640176937117952488466002340085264819537808079947788437998042296495822,
0.0723457941088485062253993564784877916043369833018248707397632823511765345816800402874475958591657429073027694582930574378890633404841054620298756279975430795706338162404545590689277985270140590721779502609564199074051863640176937117952488466002340085264819537808079947788437998042296495822,
0.0658222227763618468376500637069387728775364473732465153710916696852412442018627316280044447764609054151761388378861151807154113495715653711918644796313239555117970398473141615070299152284100887258072240524028885129828725430021172354299810423059697133688823072212214503334259555369485963074,
0.0658222227763618468376500637069387728775364473732465153710916696852412442018627316280044447764609054151761388378861151807154113495715653711918644796313239555117970398473141615070299152284100887258072240524028885129828725430021172354299810423059697133688823072212214503334259555369485963074,
0.0586840934785355471452836373001708867501204674575467587150032786132877518019090643743123653437052116901895704813134467814193905269714480573030647540887991405215103758723074481312705449946311993670933802369300463315125015975216910705047901943865293781921122370996257470349807212516159332678,
0.0586840934785355471452836373001708867501204674575467587150032786132877518019090643743123653437052116901895704813134467814193905269714480573030647540887991405215103758723074481312705449946311993670933802369300463315125015975216910705047901943865293781921122370996257470349807212516159332678,
0.0509980592623761761961632446895216952601847767397628437069071236525030510385137821267442193868358292147899714519363571211100873456269865150186456681043804358654826791768545393024953758025593924464295555854744882720755747096079325496814455853004350452095212995888025282619932613606999567133,
0.0509980592623761761961632446895216952601847767397628437069071236525030510385137821267442193868358292147899714519363571211100873456269865150186456681043804358654826791768545393024953758025593924464295555854744882720755747096079325496814455853004350452095212995888025282619932613606999567133,
0.0428358980222266806568786466061255284928108575989407395620219408911043916962572261359138025961596979511472539467367407419206021900868371610612953162236233351132214438513203223655531564777278515080476421262443325932320214191168239648611793958596884827086182431203349730049744697408543115307,
0.0428358980222266806568786466061255284928108575989407395620219408911043916962572261359138025961596979511472539467367407419206021900868371610612953162236233351132214438513203223655531564777278515080476421262443325932320214191168239648611793958596884827086182431203349730049744697408543115307,
0.0342738629130214331026877322523727069948402029116274337814057454192310522168984446294442724624445760666244242305266023810860790282088335398182296698622433517061843276344829146573593201201081743714879684153735672789104567624853712011151505225193933019375481618760594889854480408562043658635,
0.0342738629130214331026877322523727069948402029116274337814057454192310522168984446294442724624445760666244242305266023810860790282088335398182296698622433517061843276344829146573593201201081743714879684153735672789104567624853712011151505225193933019375481618760594889854480408562043658635,
0.0253920653092620594557525897892240292875540475469487209362512822192154788532376645960457016338988332029324531233401833547954942765653767672102838323550828207273795044402516181251040411735351747299230615776597356956641506445501689924551185923348003766988424170511157069264716719906995309826,
0.0253920653092620594557525897892240292875540475469487209362512822192154788532376645960457016338988332029324531233401833547954942765653767672102838323550828207273795044402516181251040411735351747299230615776597356956641506445501689924551185923348003766988424170511157069264716719906995309826,
0.0162743947309056706051705622063866181795429637952095664295931749613369651752917857651844425586692833071042366002861684552859449530958901379260437604156888337987656773068694383447504913457771896770689760342192010638946676879735404121702279005140285599424477022083127753774756520463311689155,
0.0162743947309056706051705622063866181795429637952095664295931749613369651752917857651844425586692833071042366002861684552859449530958901379260437604156888337987656773068694383447504913457771896770689760342192010638946676879735404121702279005140285599424477022083127753774756520463311689155,
0.0070186100094700966004070637388531825133772207289396032320082356192151241454178686953297376907573215077936155545790593837513204206518026084505878987243348925784479817181234617862457418214505322067610482902501455504204433524520665822704844582452877416001060465891907497519632353148380799619,
0.0070186100094700966004070637388531825133772207289396032320082356192151241454178686953297376907573215077936155545790593837513204206518026084505878987243348925784479817181234617862457418214505322067610482902501455504204433524520665822704844582452877416001060465891907497519632353148380799619
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,6 @@ typedef union _GskCurve GskCurve;
typedef struct _GskLineCurve GskLineCurve;
typedef struct _GskQuadCurve GskQuadCurve;
typedef struct _GskCubicCurve GskCubicCurve;
typedef struct _GskConicCurve GskConicCurve;
struct _GskLineCurve
{
@@ -66,28 +65,12 @@ struct _GskCubicCurve
graphene_point_t coeffs[4];
};
struct _GskConicCurve
{
GskPathOperation op;
gboolean has_coefficients;
/* points[0], points[1], points[3] are the control points,
* points[2].x is the weight
*/
graphene_point_t points[4];
graphene_point_t num[3];
graphene_point_t denom[3];
};
union _GskCurve
{
GskPathOperation op;
GskLineCurve line;
GskQuadCurve quad;
GskCubicCurve cubic;
GskConicCurve conic;
};
typedef enum {
@@ -105,7 +88,6 @@ typedef gboolean (* GskCurveAddLineFunc) (const graphene_point_t *from,
typedef gboolean (* GskCurveAddCurveFunc) (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer user_data);
void gsk_curve_init (GskCurve *curve,
@@ -113,8 +95,7 @@ void gsk_curve_init (GskCurve
void gsk_curve_init_foreach (GskCurve *curve,
GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight);
gsize n_pts);
void gsk_curve_print (const GskCurve *curve,
GString *string);
@@ -164,9 +145,6 @@ void gsk_curve_get_bounds (const GskCurve
void gsk_curve_get_tight_bounds (const GskCurve *curve,
GskBoundingBox *bounds);
void gsk_curve_get_derivative_at (const GskCurve *curve,
float t,
graphene_point_t *value);
int gsk_curve_get_crossing (const GskCurve *curve,
const graphene_point_t *point);
gboolean gsk_curve_get_closest_point (const GskCurve *curve,
@@ -174,16 +152,6 @@ gboolean gsk_curve_get_closest_point (const GskCurve
float threshold,
float *out_dist,
float *out_t);
float gsk_curve_get_length (const GskCurve *curve);
float gsk_curve_get_length_to (const GskCurve *curve,
float t);
float gsk_curve_at_length (const GskCurve *curve,
float distance,
float epsilon);
int gsk_curve_get_curvature_points (const GskCurve * curve,
float t[3]);
G_END_DECLS

View File

@@ -220,15 +220,12 @@ typedef enum {
*
* The default line cap style is `GSK_LINE_CAP_BUTT`.
*
* New entries may be added in future versions.
* <picture>
* <source srcset="caps-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Line Cap Styles" src="caps-light.png">
* </picture>
*
* <figure>
* <picture>
* <source srcset="caps-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Line Cap Styles" src="caps-light.png">
* </picture>
* <figcaption>GSK_LINE_CAP_BUTT, GSK_LINE_CAP_ROUND, GSK_LINE_CAP_SQUARE</figcaption>
* </figure>
* New entries may be added in future versions.
*
* Since: 4.14
*/
@@ -250,15 +247,12 @@ typedef enum {
*
* The default line join style is `GSK_LINE_JOIN_MITER`.
*
* New entries may be added in future versions.
* <picture>
* <source srcset="join-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Line Join Styles" src="join-light.png">
* </picture>
*
* <figure>
* <picture>
* <source srcset="join-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Line Join Styles" src="join-light.png">
* </picture>
* <figcaption>GSK_LINE_JOINT_MITER, GSK_LINE_JOINT_ROUND, GSK_LINE_JOIN_BEVEL</figcaption>
* </figure>
* New entries may be added in future versions.
*
* Since: 4.14
*/
@@ -281,11 +275,8 @@ typedef enum {
* @GSK_PATH_CUBIC: A curve-to operation describing a cubic Bézier curve with 4
* points describing the start point, the two control points and the end point
* of the curve.
* @GSK_PATH_CONIC: A rational quadratic Bézier curve with 3 points describing
* the start point, control point and end point of the curve. A weight for the
* curve will be passed, too.
*
* Path operations are used to describe the segments of a `GskPath`.
* Path operations are used to described segments of a `GskPath`.
*
* More values may be added in the future.
*
@@ -297,39 +288,21 @@ typedef enum {
GSK_PATH_LINE,
GSK_PATH_QUAD,
GSK_PATH_CUBIC,
GSK_PATH_CONIC,
} GskPathOperation;
/**
* GskPathDirection:
* @GSK_PATH_FROM_START: The tangent in path direction of the incoming side
* of the path
* @GSK_PATH_TO_START: The tangent against path direction of the incoming side
* of the path
* @GSK_PATH_TO_END: The tangent in path direction of the outgoing side
* of the path
* @GSK_PATH_FROM_END: The tangent against path direction of the outgoing
* side of the path
* @GSK_PATH_START: The side that leads to the start of the path
* @GSK_PATH_END: The side that leads to the end of the path
*
* The values of the `GskPathDirection` enum are used to pick one
* of the four tangents at a given point on the path.
*
* Note that the directions for @GSK_PATH_FROM_START/@GSK_PATH_TO_END and
* @GSK_PATH_TO_START/@GSK_PATH_FROM_END will coincide for smooth points.
* Only sharp turns will exhibit four different directions.
*
* <picture>
* <source srcset="directions-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Path Tangents" src="directions-light.png">
* </picture>
* of the two sides of the path that at a given point on the path.
*
* Since: 4.14
*/
typedef enum {
GSK_PATH_FROM_START,
GSK_PATH_TO_START,
GSK_PATH_TO_END,
GSK_PATH_FROM_END,
GSK_PATH_START,
GSK_PATH_END
} GskPathDirection;
/**

View File

@@ -177,9 +177,8 @@ 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)
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* see [func@Gsk.Path.parse] for a summary of the syntax.
* The string is compatible with
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData).
*
* Since: 4.14
*/
@@ -234,7 +233,6 @@ static gboolean
gsk_path_to_cairo_add_op (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer cr)
{
switch (op)
@@ -251,12 +249,21 @@ gsk_path_to_cairo_add_op (GskPathOperation op,
cairo_line_to (cr, pts[1].x, pts[1].y);
break;
case GSK_PATH_QUAD:
{
double x, y;
cairo_get_current_point (cr, &x, &y);
cairo_curve_to (cr,
1/3.f * x + 2/3.f * pts[1].x, 1/3.f * y + 2/3.f * pts[1].y,
2/3.f * pts[1].x + 1/3.f * pts[2].x, 2/3.f * pts[1].y + 1/3.f * pts[2].y,
pts[2].x, pts[2].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);
break;
case GSK_PATH_QUAD:
case GSK_PATH_CONIC:
default:
g_assert_not_reached ();
return FALSE;
@@ -368,7 +375,7 @@ gsk_path_is_closed (GskPath *self)
* If the path is empty, `FALSE` is returned and @bounds are set to
* graphene_rect_zero(). This is different from the case where the path
* is a single point at the origin, where the @bounds will also be set to
* the zero rectangle but `TRUE` will be returned.
* the zero rectangle but 0 will be returned.
*
* Returns: `TRUE` if the path has bounds, `FALSE` if the path is known
* to be empty and have no bounds.
@@ -421,7 +428,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
@@ -553,7 +559,7 @@ gsk_path_get_end_point (GskPath *self,
return FALSE;
res->contour = self->n_contours - 1;
res->idx = gsk_contour_get_n_ops (self->contours[self->n_contours - 1]) - 1;
res->idx = gsk_contour_get_n_points (self->contours[self->n_contours - 1]) - 1;
res->t = 1;
return TRUE;
@@ -618,17 +624,10 @@ gsk_path_get_closest_point (GskPath *self,
*
* Calls @func for every operation of the path.
*
* Note that this may only approximate @self, because paths can contain
* optimizations for various specialized contours, and depending on the
* @flags, the path may be decomposed into simpler curves than the ones
* that it contained originally.
*
* This function serves two purposes:
*
* - When the @flags allow everything, it provides access to the raw,
* unmodified data of the path.
* - When the @flags disallow certain operations, it provides
* an approximation of the path using just the allowed operations.
* Note that this only approximates @self, because paths can contain
* optimizations for various specialized contours, and depending on
* the @flags, the path may be decomposed into simpler curves than
* the ones that it contained originally.
*
* Returns: `FALSE` if @func returned FALSE`, `TRUE` otherwise.
*
@@ -672,7 +671,6 @@ gsk_path_foreach_trampoline_add_line (const graphene_point_t *from,
return trampoline->func (GSK_PATH_LINE,
(graphene_point_t[2]) { *from, *to },
2,
0.f,
trampoline->user_data);
}
@@ -680,19 +678,17 @@ static gboolean
gsk_path_foreach_trampoline_add_curve (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
return trampoline->func (op, pts, n_pts, weight, trampoline->user_data);
return trampoline->func (op, pts, n_pts, trampoline->user_data);
}
static gboolean
gsk_path_foreach_trampoline (GskPathOperation op,
const graphene_point_t *pts,
gsize n_pts,
float weight,
gpointer data)
{
GskPathForeachTrampoline *trampoline = data;
@@ -702,14 +698,14 @@ gsk_path_foreach_trampoline (GskPathOperation 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 (op, pts, n_pts, 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 (op, pts, n_pts, trampoline->user_data);
else if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CUBIC)
{
return trampoline->func (GSK_PATH_CUBIC,
@@ -722,7 +718,6 @@ gsk_path_foreach_trampoline (GskPathOperation op,
pts[2],
},
4,
weight,
trampoline->user_data);
}
@@ -738,31 +733,10 @@ 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 (op, pts, n_pts, trampoline->user_data);
gsk_curve_init (&curve, gsk_pathop_encode (GSK_PATH_CUBIC, pts));
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CONIC))
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_curve,
trampoline);
return gsk_curve_decompose (&curve,
trampoline->tolerance,
gsk_path_foreach_trampoline_add_line,
trampoline);
}
case GSK_PATH_CONIC:
{
GskCurve curve;
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_CONIC)
return trampoline->func (op, pts, n_pts, weight, 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] } ));
if (trampoline->flags & (GSK_PATH_FOREACH_ALLOW_QUAD|GSK_PATH_FOREACH_ALLOW_CUBIC))
if (trampoline->flags & GSK_PATH_FOREACH_ALLOW_QUAD)
return gsk_curve_decompose_curve (&curve,
trampoline->flags,
trampoline->tolerance,
@@ -781,9 +755,8 @@ gsk_path_foreach_trampoline (GskPathOperation op,
}
}
#define ALLOW_ANY (GSK_PATH_FOREACH_ALLOW_QUAD | \
GSK_PATH_FOREACH_ALLOW_CUBIC | \
GSK_PATH_FOREACH_ALLOW_CONIC)
#define ALLOW_ANY (GSK_PATH_FOREACH_ALLOW_QUAD| \
GSK_PATH_FOREACH_ALLOW_CUBIC)
gboolean
gsk_path_foreach_with_tolerance (GskPath *self,
@@ -941,7 +914,7 @@ parse_command (const char **p,
if (*cmd == 'X')
allowed = "mM";
else
allowed = "mMhHvVzZlLcCsStTqQaAoO";
allowed = "mMhHvVzZlLcCsStTqQoOaA";
skip_whitespace (p);
s = _strchr (allowed, **p);
@@ -954,6 +927,81 @@ parse_command (const char **p,
return FALSE;
}
static gboolean
parse_string (const char **p,
const char *s)
{
int len = strlen (s);
if (strncmp (*p, s, len) != 0)
return FALSE;
(*p) += len;
return TRUE;
}
static gboolean
parse_rectangle (const char **p,
double *x,
double *y,
double *w,
double *h)
{
const char *o = *p;
double w2;
/* Check for M%g,%gh%gv%gh%gz without any intervening whitespace */
if (parse_coordinate_pair (p, x, y) &&
parse_string (p, "h") &&
parse_coordinate (p, w) &&
parse_string (p, "v") &&
parse_coordinate (p, h) &&
parse_string (p, "h") &&
parse_coordinate (p, &w2) &&
parse_string (p, "z") &&
w2 == - *w)
{
skip_whitespace (p);
return TRUE;
}
*p = o;
return FALSE;
}
static gboolean
parse_circle (const char **p,
double *sx,
double *sy,
double *r)
{
const char *o = *p;
double r1, r2, r3, mx, my, ex, ey;
/* Check for M%g,%gA%g,%g,0,1,0,%g,%gA%g,%g,0,1,0,%g,%g
* without any intervening whitespace
*/
if (parse_coordinate_pair (p, sx, sy) &&
parse_string (p, "A") &&
parse_coordinate_pair (p, r, &r1) &&
parse_string (p, "0 0 0") &&
parse_coordinate_pair (p, &mx, &my) &&
parse_string (p, "A") &&
parse_coordinate_pair (p, &r2, &r3) &&
parse_string (p, "0 0 0") &&
parse_coordinate_pair (p, &ex, &ey) &&
parse_string (p, "z") &&
*r == r1 && r1 == r2 && r2 == r3 &&
*sx == ex && *sy == ey)
{
skip_whitespace (p);
return TRUE;
}
*p = o;
return FALSE;
}
/**
* gsk_path_parse:
* @string: a string
@@ -961,7 +1009,7 @@ parse_command (const char **p,
* This is a convenience function that constructs a `GskPath`
* from a serialized form.
*
* The string is expected to be in (a superset of)
* The string is expected to be in
* [SVG path syntax](https://www.w3.org/TR/SVG11/paths.html#PathData),
* as e.g. produced by [method@Gsk.Path.to_string].
*
@@ -977,14 +1025,12 @@ parse_command (const char **p,
* - `T x2 y2` Add a quadratic Bézier, using the reflection of the previous segments' control point as control point
* - `S x2 y2 x3 y3` Add a cubic Bézier, using the reflection of the previous segments' second control point as first control point
* - `A rx ry r l s x y` Add an elliptical arc from the current point to `(x, y)` with radii rx and ry. See the SVG documentation for how the other parameters influence the arc.
* - `O x1 y1 x2 y2 w` Add a rational quadratic Bézier from the current point to `(x2, y2)` with control point `(x1, y1)` and weight `w`.
*
* All the commands have lowercase variants that interpret coordinates
* relative to the current point.
*
* The `O` command is an extension that is not supported in SVG.
*
* Returns: (nullable): a new `GskPath`, or `NULL` if @string could not be parsed
* Returns: (nullable): a new `GskPath`, or `NULL`
* if @string could not be parsed
*
* Since: 4.14
*/
@@ -1038,9 +1084,31 @@ gsk_path_parse (const char *string)
case 'M':
case 'm':
{
double x1, y1;
double x1, y1, w, h, r;
if (parse_coordinate_pair (&p, &x1, &y1))
if (parse_rectangle (&p, &x1, &y1, &w, &h))
{
gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (x1, y1, w, h));
if (_strchr ("zZX", prev_cmd))
{
path_x = x1;
path_y = y1;
}
x = x1;
y = y1;
}
else if (parse_circle (&p, &x1, &y1, &r))
{
gsk_path_builder_add_circle (builder, &GRAPHENE_POINT_INIT (x1 - r, y1), r);
if (_strchr ("zZX", prev_cmd))
{
path_x = x1;
path_y = y1;
}
x = x1;
y = y1;
}
else if (parse_coordinate_pair (&p, &x1, &y1))
{
if (cmd == 'm')
{
@@ -1288,37 +1356,6 @@ gsk_path_parse (const char *string)
}
break;
case 'O':
case 'o':
{
double x1, y1, x2, y2, weight;
if (parse_coordinate_pair (&p, &x1, &y1) &&
parse_coordinate_pair (&p, &x2, &y2) &&
parse_nonnegative_number (&p, &weight))
{
if (cmd == 'c')
{
x1 += x;
y1 += y;
x2 += x;
y2 += y;
}
if (_strchr ("zZ", prev_cmd))
{
gsk_path_builder_move_to (builder, x, y);
path_x = x;
path_y = y;
}
gsk_path_builder_conic_to (builder, x1, y1, x2, y2, weight);
x = x2;
y = y2;
}
else
goto error;
}
break;
case 'A':
case 'a':
{
@@ -1376,3 +1413,95 @@ error:
return NULL;
}
/**
* gsk_path_get_position:
* @self: a `GskPath`
* @point: a `GskPathPoint` on @path
* @position: (out caller-allocates): Return location for
* the coordinates of the point
*
* Gets the position of the point.
*
* Since: 4.14
*/
void
gsk_path_get_position (GskPath *self,
const GskPathPoint *point,
graphene_point_t *position)
{
GskRealPathPoint *p = (GskRealPathPoint *) point;
g_return_if_fail (self != NULL);
g_return_if_fail (point != NULL);
g_return_if_fail (position != NULL);
g_return_if_fail (p->contour < self->n_contours);
gsk_contour_get_position (self->contours[p->contour], p, position);
}
/**
* gsk_path_get_tangent:
* @self: a `GskPath`
* @point: a `GskPathPoint` on @path
* @direction: the direction for which to return the tangent
* @tangent: (out caller-allocates): Return location for
* the tangent at the point
*
* Gets the tangent of the path at the point.
*
* Note that certain points on a path may not have a single
* tangent, such as sharp turns. At such points, there are
* two tangents -- the direction of the path going into the
* point, and the direction coming out of it. The @direction
* argument lets you choose which one to get.
*
* Since: 4.14
*/
void
gsk_path_get_tangent (GskPath *self,
const GskPathPoint *point,
GskPathDirection direction,
graphene_vec2_t *tangent)
{
GskRealPathPoint *p = (GskRealPathPoint *) point;
g_return_if_fail (self != NULL);
g_return_if_fail (point != NULL);
g_return_if_fail (tangent != NULL);
g_return_if_fail (p->contour < self->n_contours);
gsk_contour_get_tangent (self->contours[p->contour], p, direction, tangent);
}
/**
* gsk_path_get_curvature:
* @self: a `GskPath`
* @point: a `GskPathPoint` on @path
* @center: (out caller-allocates) (nullable): Return location for
* the center of the osculating circle
*
* Calculates the curvature of the path at the point.
*
* Optionally, returns the center of the osculating circle as well.
*
* If the curvature is infinite (at line segments), zero is returned,
* and @center is not modified.
*
* Returns: The curvature of the path at the given point
*
* Since: 4.14
*/
float
gsk_path_get_curvature (GskPath *self,
const GskPathPoint *point,
graphene_point_t *center)
{
GskRealPathPoint *p = (GskRealPathPoint *) point;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (point != NULL, 0);
g_return_val_if_fail (p->contour < self->n_contours, 0);
return gsk_contour_get_curvature (self->contours[p->contour], p, center);
}

View File

@@ -33,15 +33,14 @@ G_BEGIN_DECLS
* @GSK_PATH_FOREACH_ALLOW_ONLY_LINES: The default behavior, only allow lines.
* @GSK_PATH_FOREACH_ALLOW_QUAD: Allow emission of `GSK_PATH_QUAD` operations
* @GSK_PATH_FOREACH_ALLOW_CUBIC: Allow emission of `GSK_PATH_CUBIC` operations.
* @GSK_PATH_FOREACH_ALLOW_CONIC: Allow emission of `GSK_PATH_CONIC` operations.
* @GSK_PATH_FOREACH_ALLOW_ANY: Allow emission of any kind of operation.
*
* Flags that can be passed to gsk_path_foreach() to influence what
* kinds of operations the path is decomposed into.
* Flags that can be passed to gsk_path_foreach() to enable additional
* features.
*
* By default, [method@Gsk.Path.foreach] will only emit a path with all
* operations flattened to straight lines to allow for maximum compatibility.
* The only operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and
* `GSK_PATH_CLOSE`.
* By default, [method@Gsk.Path.foreach] will only emit a path with all operations
* flattened to straight lines to allow for maximum compatibility. The only
* operations emitted will be `GSK_PATH_MOVE`, `GSK_PATH_LINE` and `GSK_PATH_CLOSE`.
*
* Since: 4.14
*/
@@ -50,35 +49,24 @@ typedef enum
GSK_PATH_FOREACH_ALLOW_ONLY_LINES = 0,
GSK_PATH_FOREACH_ALLOW_QUAD = (1 << 0),
GSK_PATH_FOREACH_ALLOW_CUBIC = (1 << 1),
GSK_PATH_FOREACH_ALLOW_CONIC = (1 << 2),
} GskPathForeachFlags;
/**
* GskPathForeachFunc:
* @op: The operation
* @op: The operation to perform
* @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
* @user_data: The user data provided with the function
*
* Prototype of the callback to iterate through the operations of
* Prototype of the callback to iterate throught 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.
*
* Each contour of the path starts with a @GSK_PATH_MOVE operation.
* Closed contours end with a @GSK_PATH_CLOSE operation.
*
* Returns: %TRUE to continue iterating the path, %FALSE to
* Returns: %TRUE to continue evaluating 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,
gpointer user_data);
#define GSK_TYPE_PATH (gsk_path_get_type ())
@@ -137,6 +125,22 @@ gboolean gsk_path_get_closest_point (GskPath
float threshold,
GskPathPoint *result);
GDK_AVAILABLE_IN_4_14
void gsk_path_get_position (GskPath *self,
const GskPathPoint *point,
graphene_point_t *position);
GDK_AVAILABLE_IN_4_14
void gsk_path_get_tangent (GskPath *self,
const GskPathPoint *point,
GskPathDirection direction,
graphene_vec2_t *tangent);
GDK_AVAILABLE_IN_4_14
float gsk_path_get_curvature (GskPath *self,
const GskPathPoint *point,
graphene_point_t *center);
GDK_AVAILABLE_IN_4_14
gboolean gsk_path_foreach (GskPath *self,
GskPathForeachFlags flags,

View File

@@ -25,6 +25,7 @@
#include "gskpathprivate.h"
#include "gskcontourprivate.h"
#include "gsksplineprivate.h"
/**
* GskPathBuilder:
@@ -64,7 +65,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 +241,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 +311,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
*
@@ -443,8 +442,6 @@ gsk_path_builder_add_cairo_path (GskPathBuilder *self,
*
* Adds @rect as a new contour to the path built by the builder.
*
* The path is going around the rectangle in clockwise direction.
*
* If the width or height of the rectangle is negative, the start
* point will be on the right or bottom, respectively.
*
@@ -480,10 +477,8 @@ gsk_path_builder_add_rect (GskPathBuilder *self,
*
* Adds @rect as a new contour to the path built in @self.
*
* The path is going around the rectangle in clockwise direction.
*
* Since: 4.14
*/
**/
void
gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
const GskRoundedRect *rect)
@@ -503,46 +498,64 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_TOP_RIGHT].width,
rect->bounds.origin.y);
/* topright corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height);
gsk_path_builder_svg_arc_to (self,
rect->corner[GSK_CORNER_TOP_RIGHT].width,
rect->corner[GSK_CORNER_TOP_RIGHT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_RIGHT].height);
/* right */
gsk_path_builder_line_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_RIGHT].height);
/* bottomright corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x + rect->bounds.size.width,
rect->bounds.origin.y + rect->bounds.size.height,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->bounds.origin.y + rect->bounds.size.height);
gsk_path_builder_svg_arc_to (self,
rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->corner[GSK_CORNER_BOTTOM_RIGHT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->bounds.size.width - rect->corner[GSK_CORNER_BOTTOM_RIGHT].width,
rect->bounds.origin.y + rect->bounds.size.height);
/* bottom */
gsk_path_builder_line_to (self,
rect->bounds.origin.x + rect->corner[GSK_CORNER_BOTTOM_LEFT].width,
rect->bounds.origin.y + rect->bounds.size.height);
/* bottomleft corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height);
gsk_path_builder_svg_arc_to (self,
rect->corner[GSK_CORNER_BOTTOM_LEFT].width,
rect->corner[GSK_CORNER_BOTTOM_LEFT].height,
0, FALSE, TRUE,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->bounds.size.height - rect->corner[GSK_CORNER_BOTTOM_LEFT].height);
/* left */
gsk_path_builder_line_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y + rect->corner[GSK_CORNER_TOP_LEFT].height);
/* topleft corner */
gsk_path_builder_arc_to (self,
rect->bounds.origin.x,
rect->bounds.origin.y,
rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->bounds.origin.y);
gsk_path_builder_svg_arc_to (self,
rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->corner[GSK_CORNER_TOP_LEFT].height,
0, FALSE, TRUE,
rect->bounds.origin.x + rect->corner[GSK_CORNER_TOP_LEFT].width,
rect->bounds.origin.y);
/* done */
gsk_path_builder_close (self);
self->current_point = current;
}
static gboolean
circle_contour_curve (const graphene_point_t pts[4],
gpointer data)
{
GskPathBuilder *self = data;
gsk_path_builder_cubic_to (self,
pts[1].x, pts[1].y,
pts[2].x, pts[2].y,
pts[3].x, pts[3].y);
return TRUE;
}
/**
* gsk_path_builder_add_circle:
* @self: a `GskPathBuilder`
@@ -551,8 +564,6 @@ gsk_path_builder_add_rounded_rect (GskPathBuilder *self,
*
* Adds a circle with the @center and @radius.
*
* The path is going around the circle in clockwise direction.
*
* Since: 4.14
*/
void
@@ -569,23 +580,11 @@ gsk_path_builder_add_circle (GskPathBuilder *self,
current = self->current_point;
gsk_path_builder_move_to (self, center->x + radius, center->y);
// bottom right quarter
gsk_path_builder_arc_to (self,
center->x + radius, center->y + radius,
center->x, center->y + radius);
// bottom left quarter
gsk_path_builder_arc_to (self,
center->x - radius, center->y + radius,
center->x - radius, center->y);
// top left quarter
gsk_path_builder_arc_to (self,
center->x - radius, center->y - radius,
center->x, center->y - radius);
// top right quarter
gsk_path_builder_arc_to (self,
center->x + radius, center->y - radius,
center->x + radius, center->y);
// done
gsk_spline_decompose_arc (center, radius,
GSK_PATH_TOLERANCE_DEFAULT,
0, 2 * M_PI,
circle_contour_curve, self);
gsk_path_builder_close (self);
self->current_point = current;
}
@@ -624,8 +623,8 @@ gsk_path_builder_move_to (GskPathBuilder *self,
* @x: x offset
* @y: y offset
*
* Starts a new contour by placing the pen at @x, @y
* relative to the current point.
* Starts a new contour by placing the pen at @x, @y relative to the current
* point.
*
* This is the relative version of [method@Gsk.PathBuilder.move_to].
*
@@ -652,11 +651,6 @@ gsk_path_builder_rel_move_to (GskPathBuilder *self,
* Draws a line from the current point to @x, @y and makes it
* the new current point.
*
* <picture>
* <source srcset="line-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Line To" src="line-light.png">
* </picture>
*
* Since: 4.14
*/
void
@@ -684,8 +678,8 @@ gsk_path_builder_line_to (GskPathBuilder *self,
* @x: x offset
* @y: y offset
*
* Draws a line from the current point to a point offset from it
* by @x, @y and makes it the new current point.
* Draws a line from the current point to a point offset to it by @x, @y
* and makes it the new current point.
*
* This is the relative version of [method@Gsk.PathBuilder.line_to].
*
@@ -716,11 +710,6 @@ gsk_path_builder_rel_line_to (GskPathBuilder *self,
*
* After this, @x2, @y2 will be the new current point.
*
* <picture>
* <source srcset="quad-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Quad To" src="quad-light.png">
* </picture>
*
* Since: 4.14
*/
void
@@ -790,11 +779,6 @@ gsk_path_builder_rel_quad_to (GskPathBuilder *self,
*
* After this, @x3, @y3 will be the new current point.
*
* <picture>
* <source srcset="cubic-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Cubic To" src="cubic-light.png">
* </picture>
*
* Since: 4.14
*/
void
@@ -830,9 +814,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].
*
@@ -858,163 +840,6 @@ gsk_path_builder_rel_cubic_to (GskPathBuilder *self,
self->current_point.y + y3);
}
/**
* gsk_path_builder_conic_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of control point
* @y1: y coordinate of control point
* @x2: x coordinate of the end of the curve
* @y2: y coordinate of the end of the curve
* @weight: weight of the control point, must be greater than zero
*
* 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.
*
* 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.
*
* Conic curves can be used to draw ellipses and circles. They are also known as
* rational quadratic Bézier curves.
*
* After this, @x2, @y2 will be the new current point.
*
* <picture>
* <source srcset="conic-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Conic To" src="conic-light.png">
* </picture>
*
* Since: 4.14
*/
void
gsk_path_builder_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight)
{
g_return_if_fail (self != NULL);
g_return_if_fail (weight > 0);
self->flags &= ~GSK_PATH_FLAT;
gsk_path_builder_append_current (self,
GSK_PATH_CONIC,
3, (graphene_point_t[3]) {
GRAPHENE_POINT_INIT (x1, y1),
GRAPHENE_POINT_INIT (weight, 0),
GRAPHENE_POINT_INIT (x2, y2)
});
}
/**
* gsk_path_builder_rel_conic_to:
* @self: a `GskPathBuilder`
* @x1: x offset of control point
* @y1: y offset of control point
* @x2: x offset of the end of the curve
* @y2: y offset of the end of the curve
* @weight: weight of the curve, must be greater than zero
*
* 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.
*
* This is the relative version of [method@Gsk.PathBuilder.conic_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight)
{
g_return_if_fail (self != NULL);
g_return_if_fail (weight > 0);
gsk_path_builder_conic_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2,
weight);
}
/**
* gsk_path_builder_arc_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of first control point
* @y1: y coordinate of first control point
* @x2: x coordinate of second control point
* @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.
*
* After this, @x3, @y3 will be the new current point.
*
* Note: Two points and their tangents do not determine
* a unique ellipse, so GSK just picks one. If you need more
* precise control, use [method@Gsk.PathBuilder.conic_to]
* or [method@Gsk.PathBuilder.svg_arc_to].
*
* <picture>
* <source srcset="arc-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Arc To" src="arc-light.png">
* </picture>
*
* Since: 4.14
*/
void
gsk_path_builder_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2)
{
g_return_if_fail (self != NULL);
gsk_path_builder_conic_to (self, x1, y1, x2, y2, M_SQRT1_2);
}
/**
* gsk_path_builder_rel_arc_to:
* @self: a `GskPathBuilder`
* @x1: x coordinate of first control point
* @y1: y coordinate of first control point
* @x2: x coordinate of second control point
* @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.
*
* This is the relative version of [method@Gsk.PathBuilder.arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2)
{
g_return_if_fail (self != NULL);
gsk_path_builder_arc_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2);
}
/**
* gsk_path_builder_close:
* @self: a `GskPathBuilder`
@@ -1023,9 +848,9 @@ gsk_path_builder_rel_arc_to (GskPathBuilder *self,
*
* Note that this is different from calling [method@Gsk.PathBuilder.line_to]
* with the start point in that the contour will be closed. A closed
* contour behaves differently from an open one. When stroking, its
* start and end point are considered connected, so they will be
* joined via the line join, and not ended with line caps.
* contour behaves different from an open one when stroking its start
* and end point are considered connected, so they will be joined
* via the line join, and not ended with line caps.
*
* Since: 4.14
*/
@@ -1092,27 +917,6 @@ _sincos (double angle,
#endif
}
/**
* gsk_path_builder_svg_arc_to:
* @self: a `GskPathBuilder`
* @rx: X radius
* @ry: Y radius
* @x_axis_rotation: the rotation of the ellipsis
* @large_arc: whether to add the large arc
* @positive_sweep: whether to sweep in the positive direction
* @x: the X coordinate of the endpoint
* @y: the Y coordinate of the endpoint
*
* Implements arc-to according to the SVG spec.
*
* A convenience function that implements the
* [SVG arc_to](https://www.w3.org/TR/SVG11/paths.html#PathDataEllipticalArcCommands)
* functionality.
*
* After this, @x, @y will be the new current point.
*
* Since: 4.14
*/
void
gsk_path_builder_svg_arc_to (GskPathBuilder *self,
float rx,
@@ -1145,8 +949,6 @@ gsk_path_builder_svg_arc_to (GskPathBuilder *self,
double th_half;
double t;
g_return_if_fail (self != NULL);
if (self->points->len > 0)
{
current = &g_array_index (self->points, graphene_point_t, self->points->len - 1);
@@ -1246,184 +1048,13 @@ gsk_path_builder_svg_arc_to (GskPathBuilder *self,
}
}
/**
* gsk_path_builder_rel_svg_arc_to:
* @self: a `GskPathBuilder`
* @rx: X radius
* @ry: Y radius
* @x_axis_rotation: the rotation of the ellipsis
* @large_arc: whether to add the large arc
* @positive_sweep: whether to sweep in the positive direction
* @x: the X coordinate of the endpoint
* @y: the Y coordinate of the endpoint
*
* Implements arc-to according to the SVG spec.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.svg_arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y)
{
gsk_path_builder_svg_arc_to (self,
rx, ry,
x_axis_rotation,
large_arc,
positive_sweep,
self->current_point.x + x,
self->current_point.y + y);
}
/* Return the angle between t1 and t2 in radians, such that
* 0 means straight continuation
* < 0 means right turn
* > 0 means left turn
*/
static float
angle_between (const graphene_vec2_t *t1,
const graphene_vec2_t *t2)
{
float angle = atan2 (graphene_vec2_get_y (t2), graphene_vec2_get_x (t2))
- atan2 (graphene_vec2_get_y (t1), graphene_vec2_get_x (t1));
if (angle > M_PI)
angle -= 2 * M_PI;
if (angle < - M_PI)
angle += 2 * M_PI;
return angle;
}
#define RAD_TO_DEG(r) ((r)*180.f/M_PI)
#define DEG_TO_RAD(d) ((d)*M_PI/180.f)
static float
angle_between_points (const graphene_point_t *c,
const graphene_point_t *a,
const graphene_point_t *b)
{
graphene_vec2_t t1, t2;
graphene_vec2_init (&t1, a->x - c->x, a->y - c->y);
graphene_vec2_init (&t2, b->x - c->x, b->y - c->y);
return (float) RAD_TO_DEG (angle_between (&t1, &t2));
}
/**
* gsk_path_builder_html_arc_to:
* @self: a `GskPathBuilder`
* @x1: X coordinate of first control point
* @y1: Y coordinate of first control point
* @x2: X coordinate of second control point
* @y2: Y coordinate of second control point
* @radius: Radius of the circle
*
* Implements arc-to according to the HTML Canvas spec.
*
* A convenience function that implements the
* [HTML arc_to](https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-arcto-dev)
* functionality.
*
* After this, the current point will be the point where
* the circle with the given radius touches the line from
* @x1, @y1 to @x2, @y2.
*
* Since: 4.14
*/
void
gsk_path_builder_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius)
{
float angle, b;
graphene_vec2_t t;
graphene_point_t p, q;
g_return_if_fail (self != NULL);
g_return_if_fail (radius > 0);
angle = angle_between_points (&GRAPHENE_POINT_INIT (x1, y1),
&self->current_point,
&GRAPHENE_POINT_INIT (x2, y2));
if (fabsf (angle) < 3)
{
gsk_path_builder_line_to (self, x2, y2);
return;
}
b = radius / tanf (fabsf ((float) DEG_TO_RAD (angle / 2)));
graphene_vec2_init (&t, self->current_point.x - x1, self->current_point.y - y1);
graphene_vec2_normalize (&t, &t);
p.x = x1 + b * graphene_vec2_get_x (&t);
p.y = y1 + b * graphene_vec2_get_y (&t);
graphene_vec2_init (&t, x2 - x1, y2 - y1);
graphene_vec2_normalize (&t, &t);
q.x = x1 + b * graphene_vec2_get_x (&t);
q.y = y1 + b * graphene_vec2_get_y (&t);
gsk_path_builder_line_to (self, p.x, p.y);
gsk_path_builder_svg_arc_to (self, radius, radius, 0, FALSE, angle < 0, q.x, q.y);
}
/**
* gsk_path_builder_rel_html_arc_to:
* @self: a `GskPathBuilder`
* @x1: X coordinate of first control point
* @y1: Y coordinate of first control point
* @x2: X coordinate of second control point
* @y2: Y coordinate of second control point
* @radius: Radius of the circle
*
* Implements arc-to according to the HTML Canvas spec.
*
* All coordinates are given relative to the current point.
*
* This is the relative version of [method@Gsk.PathBuilder.html_arc_to].
*
* Since: 4.14
*/
void
gsk_path_builder_rel_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius)
{
gsk_path_builder_html_arc_to (self,
self->current_point.x + x1,
self->current_point.y + y1,
self->current_point.x + x2,
self->current_point.y + y2,
radius);
}
/**
* gsk_path_builder_add_layout:
* @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
*/
@@ -1478,7 +1109,6 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
const GskContour *contour;
gsize n_contours = gsk_path_get_n_contours (path);
graphene_point_t current;
gsize n_ops;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
@@ -1490,7 +1120,6 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
current = self->current_point;
contour = gsk_path_get_contour (path, s->contour);
n_ops = gsk_contour_get_n_ops (contour);
if (s->contour == e->contour)
{
@@ -1501,32 +1130,27 @@ gsk_path_builder_add_segment (GskPathBuilder *self,
}
else if (n_contours == 1)
{
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, n_ops - 1, 1 });
gsk_contour_add_segment (contour, self, n_ops <= 1,
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, gsk_contour_get_n_points (contour) - 1, 1 });
gsk_contour_add_segment (contour, self, FALSE,
&(GskRealPathPoint) { s->contour, 1, 0 },
e);
goto out;
}
}
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, n_ops - 1, 1. });
gsk_contour_add_segment (contour, self, TRUE,
s,
&(GskRealPathPoint) { s->contour, gsk_contour_get_n_points (contour) - 1, 1 });
for (gsize i = (s->contour + 1) % n_contours; i != e->contour; i = (i + 1) % n_contours)
gsk_path_builder_add_contour (self, gsk_contour_dup (gsk_path_get_contour (path, i)));
contour = gsk_path_get_contour (path, e->contour);
n_ops = gsk_contour_get_n_ops (contour);
if (n_ops > 1)
gsk_contour_add_segment (contour, self, TRUE,
&(GskRealPathPoint) { e->contour, 1, 0 },
e);
gsk_contour_add_segment (contour, self, FALSE,
&(GskRealPathPoint) { e->contour, 1, 0 },
e);
out:
gsk_path_builder_end_current (self);

View File

@@ -120,70 +120,6 @@ void gsk_path_builder_rel_cubic_to (GskPathBuilder
float y2,
float x3,
float y3);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_conic_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float weight);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_svg_arc_to (GskPathBuilder *self,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_rel_html_arc_to (GskPathBuilder *self,
float x1,
float y1,
float x2,
float y2,
float radius);
GDK_AVAILABLE_IN_4_14
void gsk_path_builder_close (GskPathBuilder *self);

View File

@@ -1,328 +0,0 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gskpathmeasure.h"
#include "gskpathbuilder.h"
#include "gskpathpointprivate.h"
#include "gskpathprivate.h"
/**
* GskPathMeasure:
*
* `GskPathMeasure` is an object that allows measurements
* on `GskPath`s such as determining the length of the path.
*
* Many measuring operations require sampling the path length
* at intermediate points. Therefore, a `GskPathMeasure` has
* a tolerance that determines what precision is required
* for such approximations.
*
* A `GskPathMeasure` struct is a reference counted struct
* and should be treated as opaque.
*/
typedef struct _GskContourMeasure GskContourMeasure;
struct _GskContourMeasure
{
float length;
gpointer contour_data;
};
struct _GskPathMeasure
{
/*< private >*/
guint ref_count;
GskPath *path;
float tolerance;
float length;
gsize n_contours;
GskContourMeasure measures[];
};
G_DEFINE_BOXED_TYPE (GskPathMeasure, gsk_path_measure,
gsk_path_measure_ref,
gsk_path_measure_unref)
/**
* gsk_path_measure_new:
* @path: the path to measure
*
* Creates a measure object for the given @path with the
* default tolerance.
*
* Returns: a new `GskPathMeasure` representing @path
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_new (GskPath *path)
{
return gsk_path_measure_new_with_tolerance (path, GSK_PATH_TOLERANCE_DEFAULT);
}
/**
* gsk_path_measure_new_with_tolerance:
* @path: the path to measure
* @tolerance: the tolerance for measuring operations
*
* Creates a measure object for the given @path and @tolerance.
*
* Returns: a new `GskPathMeasure` representing @path
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_new_with_tolerance (GskPath *path,
float tolerance)
{
GskPathMeasure *self;
gsize i, n_contours;
g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (tolerance > 0, NULL);
n_contours = gsk_path_get_n_contours (path);
self = g_malloc0 (sizeof (GskPathMeasure) + n_contours * sizeof (GskContourMeasure));
self->ref_count = 1;
self->path = gsk_path_ref (path);
self->tolerance = tolerance;
self->n_contours = n_contours;
for (i = 0; i < n_contours; i++)
{
self->measures[i].contour_data = gsk_contour_init_measure (gsk_path_get_contour (path, i),
self->tolerance,
&self->measures[i].length);
self->length += self->measures[i].length;
}
return self;
}
/**
* gsk_path_measure_ref:
* @self: a `GskPathMeasure`
*
* Increases the reference count of a `GskPathMeasure` by one.
*
* Returns: the passed in `GskPathMeasure`.
*
* Since: 4.14
*/
GskPathMeasure *
gsk_path_measure_ref (GskPathMeasure *self)
{
g_return_val_if_fail (self != NULL, NULL);
self->ref_count++;
return self;
}
/**
* gsk_path_measure_unref:
* @self: a `GskPathMeasure`
*
* Decreases the reference count of a `GskPathMeasure` by one.
*
* If the resulting reference count is zero, frees the object.
*
* Since: 4.14
*/
void
gsk_path_measure_unref (GskPathMeasure *self)
{
gsize i;
g_return_if_fail (self != NULL);
g_return_if_fail (self->ref_count > 0);
self->ref_count--;
if (self->ref_count > 0)
return;
for (i = 0; i < self->n_contours; i++)
{
gsk_contour_free_measure (gsk_path_get_contour (self->path, i),
self->measures[i].contour_data);
}
gsk_path_unref (self->path);
g_free (self);
}
/**
* gsk_path_measure_get_path:
* @self: a `GskPathMeasure`
*
* Returns the path that the measure was created for.
*
* Returns: (transfer none): the path of @self
*
* Since: 4.14
*/
GskPath *
gsk_path_measure_get_path (GskPathMeasure *self)
{
return self->path;
}
/**
* gsk_path_measure_get_tolerance:
* @self: a `GskPathMeasure`
*
* Returns the tolerance that the measure was created with.
*
* Returns: the tolerance of @self
*
* Since: 4.14
*/
float
gsk_path_measure_get_tolerance (GskPathMeasure *self)
{
return self->tolerance;
}
/**
* gsk_path_measure_get_length:
* @self: a `GskPathMeasure`
*
* Gets the length of the path being measured.
*
* The length is cached, so this function does not do any work.
*
* Returns: The length of the path measured by @self
*
* Since: 4.14
*/
float
gsk_path_measure_get_length (GskPathMeasure *self)
{
g_return_val_if_fail (self != NULL, 0);
return self->length;
}
static float
gsk_path_measure_clamp_distance (GskPathMeasure *self,
float distance)
{
if (isnan (distance))
return 0;
return CLAMP (distance, 0, self->length);
}
/**
* gsk_path_measure_get_point:
* @self: a `GskPathMeasure`
* @distance: the distance
* @result: (out caller-allocates): return location for the result
*
* Sets @result to the point at the given distance into the path.
*
* An empty path has no points, so `FALSE` is returned in that case.
*
* Returns: `TRUE` if @result was set
*
* Since: 4.14
*/
gboolean
gsk_path_measure_get_point (GskPathMeasure *self,
float distance,
GskPathPoint *result)
{
GskRealPathPoint *res = (GskRealPathPoint *) result;
gsize i;
const GskContour *contour;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (result != NULL, FALSE);
if (self->n_contours == 0)
return FALSE;
distance = gsk_path_measure_clamp_distance (self, distance);
for (i = 0; i < self->n_contours - 1; i++)
{
if (distance < self->measures[i].length)
break;
distance -= self->measures[i].length;
}
g_assert (0 <= i && i < self->n_contours);
distance = CLAMP (distance, 0, self->measures[i].length);
contour = gsk_path_get_contour (self->path, i);
gsk_contour_get_point (contour, self->measures[i].contour_data, distance, res);
res->contour = i;
return TRUE;
}
/**
* gsk_path_point_get_distance:
* @point: a `GskPathPoint on the path
* @measure: a `GskPathMeasure` for the path
*
* Returns the distance from the beginning of the path
* to @point.
*
* Returns: the distance of @point
*
* Since: 4.14
*/
float
gsk_path_point_get_distance (const GskPathPoint *point,
GskPathMeasure *measure)
{
GskRealPathPoint *p = (GskRealPathPoint *)point;
const GskContour *contour;
float contour_offset = 0;
g_return_val_if_fail (point != NULL, 0);
g_return_val_if_fail (measure != NULL, 0);
g_return_val_if_fail (p->contour < measure->n_contours, 0);
contour = gsk_path_get_contour (measure->path, p->contour);
for (gsize i = 0; i < measure->n_contours; i++)
{
if (contour == gsk_path_get_contour (measure->path, i))
return contour_offset + gsk_contour_get_distance (contour,
p,
measure->measures[i].contour_data);
contour_offset += measure->measures[i].length;
}
g_return_val_if_reached (0);
}

View File

@@ -1,62 +0,0 @@
/*
* Copyright © 2020 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#pragma once
#if !defined (__GSK_H_INSIDE__) && !defined (GTK_COMPILATION)
#error "Only <gsk/gsk.h> can be included directly."
#endif
#include <gsk/gskpath.h>
#include <gsk/gskpathpoint.h>
G_BEGIN_DECLS
#define GSK_TYPE_PATH_MEASURE (gsk_path_measure_get_type ())
GDK_AVAILABLE_IN_4_14
GType gsk_path_measure_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_new (GskPath *path);
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_new_with_tolerance (GskPath *path,
float tolerance);
GDK_AVAILABLE_IN_4_14
GskPathMeasure * gsk_path_measure_ref (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
void gsk_path_measure_unref (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
GskPath * gsk_path_measure_get_path (GskPathMeasure *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
float gsk_path_measure_get_tolerance (GskPathMeasure *self) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_14
float gsk_path_measure_get_length (GskPathMeasure *self);
GDK_AVAILABLE_IN_4_14
gboolean gsk_path_measure_get_point (GskPathMeasure *self,
float distance,
GskPathPoint *result);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskPathMeasure, gsk_path_measure_unref)
G_END_DECLS

View File

@@ -50,13 +50,6 @@ void gsk_path_builder_pathop_reverse_to (GskPathBuilder
/* IMPLEMENTATION */
/* Note:
*
* The weight of conics is encoded as p[2].x, and the endpoint is p[3].
* This is important, since contours store the points of adjacent
* operations overlapping, so we can't put the weight at the end.
*/
#define GSK_PATHOP_OPERATION_MASK (0x7)
static inline gskpathop
@@ -89,23 +82,17 @@ 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 (gsk_pathop_op (pop), gsk_pathop_points (pop), 1, 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_op (pop), gsk_pathop_points (pop), 2, user_data);
case GSK_PATH_QUAD:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 3, 0, user_data);
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 3, user_data);
case GSK_PATH_CUBIC:
return func (gsk_pathop_op (pop), gsk_pathop_points (pop), 4, 0, 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_op (pop), gsk_pathop_points (pop), 4, user_data);
default:
g_assert_not_reached ();
@@ -141,10 +128,6 @@ gsk_path_builder_pathop_to (GskPathBuilder *builder,
gsk_path_builder_cubic_to (builder, pts[1].x, pts[1].y, pts[2].x, pts[2].y, pts[3].x, pts[3].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[3].x, pts[3].y, pts[2].x);
break;
default:
g_assert_not_reached ();
break;
@@ -179,10 +162,6 @@ gsk_path_builder_pathop_reverse_to (GskPathBuilder *builder,
gsk_path_builder_cubic_to (builder, pts[2].x, pts[2].y, pts[1].x, pts[1].y, pts[0].x, pts[0].y);
break;
case GSK_PATH_CONIC:
gsk_path_builder_conic_to (builder, pts[1].x, pts[1].y, pts[0].x, pts[0].y, pts[2].x);
break;
default:
g_assert_not_reached ();
break;

View File

@@ -19,27 +19,21 @@
#include "config.h"
#include <math.h>
#include "gskpathpointprivate.h"
#include "gskcontourprivate.h"
#include "gdk/gdkprivate.h"
#define RAD_TO_DEG(x) ((x) / (G_PI / 180.f))
/**
* GskPathPoint:
*
* `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 +81,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 +110,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,
@@ -146,154 +136,3 @@ gsk_path_point_compare (const GskPathPoint *point1,
return 0;
}
/**
* gsk_path_point_get_position:
* @point: a `GskPathPoint`
* @path: the path that @point is on
* @position: (out caller-allocates): Return location for
* the coordinates of the point
*
* Gets the position of the point.
*
* Since: 4.14
*/
void
gsk_path_point_get_position (const GskPathPoint *point,
GskPath *path,
graphene_point_t *position)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (position != NULL);
g_return_if_fail (self->contour < gsk_path_get_n_contours (path));
contour = gsk_path_get_contour (path, self->contour),
gsk_contour_get_position (contour, self, position);
}
/**
* gsk_path_point_get_tangent:
* @point: a `GskPathPoint`
* @path: the path that @point is on
* @direction: the direction for which to return the tangent
* @tangent: (out caller-allocates): Return location for
* the tangent at the point
*
* Gets the tangent of the path at the point.
*
* Note that certain points on a path may not have a single
* tangent, such as sharp turns. At such points, there are
* two tangents -- the direction of the path going into the
* point, and the direction coming out of it. The @direction
* argument lets you choose which one to get.
*
* If you want to orient something in the direction of the
* path, [method@Gsk.PathPoint.get_rotation] may be more
* convenient to use.
*
* Since: 4.14
*/
void
gsk_path_point_get_tangent (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_vec2_t *tangent)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_if_fail (self != NULL);
g_return_if_fail (path != NULL);
g_return_if_fail (tangent != NULL);
g_return_if_fail (self->contour < gsk_path_get_n_contours (path));
contour = gsk_path_get_contour (path, self->contour),
gsk_contour_get_tangent (contour, self, direction, tangent);
}
/**
* gsk_path_point_get_rotation:
* @point: a `GskPathPoint`
* @path: the path that @point is on
* @direction: the direction for which to return the rotation
*
* Gets the direction of the tangent at a given point.
*
* This is a convenience variant of [method@Gsk.PathPoint.get_tangent]
* that returns the angle between the tangent and the X axis. The angle
* can e.g. be used in
* [gtk_snapshot_rotate()](../gtk4/method.Snapshot.rotate.html).
*
* Returns: the angle between the tangent and the X axis, in degrees
*
* Since: 4.14
*/
float
gsk_path_point_get_rotation (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
graphene_vec2_t tangent;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (path != NULL, 0);
g_return_val_if_fail (self->contour < gsk_path_get_n_contours (path), 0);
gsk_path_point_get_tangent (point, path, direction, &tangent);
return RAD_TO_DEG (atan2f (graphene_vec2_get_y (&tangent),
graphene_vec2_get_x (&tangent)));
}
/**
* gsk_path_point_get_curvature:
* @point: a `GskPathPoint`
* @path: the path that @point is on
* @direction: the direction for which to return the curvature
* @center: (out caller-allocates) (nullable): Return location for
* the center of the osculating circle
*
* Calculates the curvature of the path at the point.
*
* Optionally, returns the center of the osculating circle as well.
* The curvature is the inverse of the radius of the osculating circle.
*
* Lines have a curvature of zero (indicating an osculating circle of
* infinite radius. In this case, the @center is not modified.
*
* Note that certain points on a path may not have a single curvature,
* such as sharp turns. At such points, there are two curvatures --
* the (limit of) the curvature of the path going into the point,
* and the (limit of) the curvature of the path coming out of it.
* The @direction argument lets you choose which one to get.
*
* <picture>
* <source srcset="curvature-dark.png" media="(prefers-color-scheme: dark)">
* <img alt="Osculating circle" src="curvature-light.png">
* </picture>
* Returns: The curvature of the path at the given point
*
* Since: 4.14
*/
float
gsk_path_point_get_curvature (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_point_t *center)
{
GskRealPathPoint *self = (GskRealPathPoint *) point;
const GskContour *contour;
g_return_val_if_fail (self != NULL, 0);
g_return_val_if_fail (path != NULL, 0);
g_return_val_if_fail (self->contour < gsk_path_get_n_contours (path), 0);
contour = gsk_path_get_contour (path, self->contour);
return gsk_contour_get_curvature (contour, self, direction, center);
}

View File

@@ -56,30 +56,4 @@ GDK_AVAILABLE_IN_4_14
int gsk_path_point_compare (const GskPathPoint *point1,
const GskPathPoint *point2);
GDK_AVAILABLE_IN_4_14
void gsk_path_point_get_position (const GskPathPoint *point,
GskPath *path,
graphene_point_t *position);
GDK_AVAILABLE_IN_4_14
void gsk_path_point_get_tangent (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_vec2_t *tangent);
GDK_AVAILABLE_IN_4_14
float gsk_path_point_get_rotation (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction);
GDK_AVAILABLE_IN_4_14
float gsk_path_point_get_curvature (const GskPathPoint *point,
GskPath *path,
GskPathDirection direction,
graphene_point_t *center);
GDK_AVAILABLE_IN_4_14
float gsk_path_point_get_distance (const GskPathPoint *point,
GskPathMeasure *measure);
G_END_DECLS

View File

@@ -56,5 +56,15 @@ gboolean gsk_path_foreach_with_tolerance (GskPath
void gsk_path_builder_add_contour (GskPathBuilder *builder,
GskContour *contour);
void gsk_path_builder_svg_arc_to (GskPathBuilder *builder,
float rx,
float ry,
float x_axis_rotation,
gboolean large_arc,
gboolean positive_sweep,
float x,
float y);
G_END_DECLS

View File

@@ -26,13 +26,3 @@ gsk_rect_intersects (const graphene_rect_t *r1,
return TRUE;
}
static inline void
gsk_rect_to_float (const graphene_rect_t *rect,
float values[4])
{
values[0] = rect->origin.x;
values[1] = rect->origin.y;
values[2] = rect->size.width;
values[3] = rect->size.height;
}

View File

@@ -3841,12 +3841,11 @@ gsk_color_matrix_node_class_init (gpointer g_class,
* Creates a `GskRenderNode` that will drawn the @child with
* @color_matrix.
*
* In particular, the node will transform colors by applying
* In particular, the node will transform the operation
*
* pixel = transpose(color_matrix) * pixel + color_offset
* pixel = color_matrix * pixel + color_offset
*
* for every pixel. The transformation operates on unpremultiplied
* colors, with color components ordered R, G, B, A.
* for every pixel.
*
* Returns: (transfer full) (type GskColorMatrixNode): A new `GskRenderNode`
*/

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 *
@@ -2158,52 +2152,6 @@ clear_path (gpointer inout_path)
g_clear_pointer ((GskPath **) inout_path, gsk_path_unref);
}
static gboolean
parse_dash (GtkCssParser *parser,
Context *context,
gpointer out_dash)
{
GArray *dash;
double d;
/* because CSS does this, too */
if (gtk_css_parser_try_ident (parser, "none"))
{
*((GArray **) out_dash) = NULL;
return TRUE;
}
dash = g_array_new (FALSE, FALSE, sizeof (float));
while (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_NUMBER) ||
gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_SIGNLESS_INTEGER))
{
if (!gtk_css_parser_consume_number (parser, &d))
{
g_array_free (dash, TRUE);
return FALSE;
}
g_array_append_vals (dash, (float[1]) { d }, 1);
}
if (dash->len == 0)
{
gtk_css_parser_error_syntax (parser, "Empty dash array");
g_array_free (dash, TRUE);
return FALSE;
}
*((GArray **) out_dash) = dash;
return TRUE;
}
static void
clear_dash (gpointer inout_array)
{
g_clear_pointer ((GArray **) inout_array, g_array_unref);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
@@ -2260,14 +2208,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);
@@ -2304,8 +2248,6 @@ parse_stroke_node (GtkCssParser *parser,
int line_cap = GSK_LINE_CAP_BUTT;
int line_join = GSK_LINE_JOIN_MITER;
double miter_limit = 4.0;
GArray *dash = NULL;
double dash_offset = 0.0;
GskStroke *stroke;
const Declaration declarations[] = {
@@ -2314,13 +2256,13 @@ parse_stroke_node (GtkCssParser *parser,
{ "line-width", parse_positive_double, NULL, &line_width },
{ "line-cap", parse_line_cap, NULL, &line_cap },
{ "line-join", parse_line_join, NULL, &line_join },
{ "miter-limit", parse_positive_double, NULL, &miter_limit },
{ "dash", parse_dash, clear_dash, &dash },
{ "dash-offset", parse_double, NULL, &dash_offset}
{ "miter-limit", parse_positive_double, NULL, &miter_limit }
};
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 ();
@@ -2328,19 +2270,6 @@ parse_stroke_node (GtkCssParser *parser,
gsk_stroke_set_line_cap (stroke, line_cap);
gsk_stroke_set_line_join (stroke, line_join);
gsk_stroke_set_miter_limit (stroke, miter_limit);
if (dash)
{
gsk_stroke_set_dash (stroke, (float *) dash->data, dash->len);
g_array_free (dash, TRUE);
}
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);
@@ -3351,34 +3280,6 @@ append_path_param (Printer *p,
g_free (str);
}
static void
append_dash_param (Printer *p,
const char *param_name,
const float *dash,
gsize n_dash)
{
_indent (p);
g_string_append (p->str, "dash: ");
if (n_dash == 0)
{
g_string_append (p->str, "none");
}
else
{
gsize i;
string_append_double (p->str, dash[0]);
for (i = 1; i < n_dash; i++)
{
g_string_append_c (p->str, ' ');
string_append_double (p->str, dash[i]);
}
}
g_string_append (p->str, ";\n");
}
static void
render_node_print (Printer *p,
GskRenderNode *node)
@@ -3567,8 +3468,6 @@ render_node_print (Printer *p,
case GSK_STROKE_NODE:
{
const GskStroke *stroke;
const float *dash;
gsize n_dash;
start_node (p, "stroke", node_name);
@@ -3580,10 +3479,6 @@ render_node_print (Printer *p,
append_enum_param (p, "line-cap", GSK_TYPE_LINE_CAP, gsk_stroke_get_line_cap (stroke));
append_enum_param (p, "line-join", GSK_TYPE_LINE_JOIN, gsk_stroke_get_line_join (stroke));
append_float_param (p, "miter-limit", gsk_stroke_get_miter_limit (stroke), 4.0f);
dash = gsk_stroke_get_dash (stroke, &n_dash);
if (dash)
append_dash_param (p, "dash", dash, n_dash);
append_float_param (p, "dash-offset", gsk_stroke_get_dash_offset (stroke), 0.0f);
end_node (p);
}

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.
@@ -428,7 +428,8 @@ gsk_stroke_set_dash (GskStroke *self,
/**
* gsk_stroke_get_dash:
* @self: a `GskStroke`
* @n_dash: (out): number of elements in the array returned
* @n_dash: (out caller-allocates): number of elements
* in the array returned
*
* Gets the dash array in use or `NULL` if dashing is disabled.
*

View File

@@ -857,8 +857,7 @@ normalize_angle (float angle)
* @next: (nullable) (transfer full): the next transform
* @angle: the rotation angle, in degrees (clockwise)
*
* Rotates @next @angle degrees in 2D - or in 3D-speak, around the Z axis.
* The rotation happens around the origin point of (0, 0).
* Rotates @next @angle degrees in 2D - or in 3D-speak, around the z axis.
*
* Returns: (nullable): The new transform
*/

View File

@@ -27,7 +27,6 @@
typedef struct _GskPath GskPath;
typedef struct _GskPathBuilder GskPathBuilder;
typedef struct _GskPathMeasure GskPathMeasure;
typedef struct _GskPathPoint GskPathPoint;
typedef struct _GskRenderer GskRenderer;
typedef struct _GskRenderNode GskRenderNode;

View File

@@ -28,7 +28,6 @@ gsk_public_sources = files([
'gskglshader.c',
'gskpath.c',
'gskpathbuilder.c',
'gskpathmeasure.c',
'gskpathpoint.c',
'gskrenderer.c',
'gskrendernode.c',
@@ -76,7 +75,6 @@ gsk_public_headers = files([
'gskglshader.h',
'gskpath.h',
'gskpathbuilder.h',
'gskpathmeasure.h',
'gskpathpoint.h',
'gskrenderer.h',
'gskrendernode.h',
@@ -110,6 +108,10 @@ if have_vulkan
endif
gsk_private_vulkan_shaders = []
# This is an odd split because we use configure_file() below to workaround
# a limitation in meson preventing using custom_target() with gnome.compile_resources()
# and that requires file paths, but we also need to have dependencies during development
# on constantly regenerated files.
gsk_private_vulkan_compiled_shaders = []
gsk_private_vulkan_compiled_shaders_deps = []
gsk_private_vulkan_shader_headers = []
@@ -157,7 +159,7 @@ if get_variable('broadway_enabled')
])
endif
gsk_resources_xml = custom_target(output: 'gsk.resources.xml',
gsk_resources_xml = configure_file(output: 'gsk.resources.xml',
input: 'gen-gsk-gresources-xml.py',
command: [
find_program('gen-gsk-gresources-xml.py'),
@@ -193,6 +195,7 @@ gsk_deps = [
pango_dep,
cairo_dep,
cairo_csi_dep,
pixbuf_dep,
libgdk_dep,
]

View File

@@ -43,11 +43,11 @@ gsk_vulkan_blend_mode_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanBlendModeOp *self = (GskVulkanBlendModeOp *) op;
GskVulkanBlendModeInstance *instance = (GskVulkanBlendModeInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->bounds, instance->rect);
gsk_rect_to_float (&self->top.rect, instance->top_rect);
gsk_rect_to_float (&self->bottom.rect, instance->bottom_rect);
gsk_rect_to_float (&self->top.tex_rect, instance->top_tex_rect);
gsk_rect_to_float (&self->bottom.tex_rect, instance->bottom_tex_rect);
gsk_vulkan_rect_to_float (&self->bounds, instance->rect);
gsk_vulkan_rect_to_float (&self->top.rect, instance->top_rect);
gsk_vulkan_rect_to_float (&self->bottom.rect, instance->bottom_rect);
gsk_vulkan_rect_to_float (&self->top.tex_rect, instance->top_tex_rect);
gsk_vulkan_rect_to_float (&self->bottom.tex_rect, instance->bottom_tex_rect);
instance->top_tex_id = self->top.image_descriptor;
instance->bottom_tex_id = self->bottom.image_descriptor;

View File

@@ -41,8 +41,8 @@ gsk_vulkan_blur_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanBlurOp *self = (GskVulkanBlurOp *) op;
GskVulkanBlurInstance *instance = (GskVulkanBlurInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_rect_to_float (&self->tex_rect, instance->tex_rect);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_rect_to_float (&self->tex_rect, instance->tex_rect);
instance->tex_id = self->image_descriptor;
instance->radius = self->radius;
}

View File

@@ -43,11 +43,11 @@ gsk_vulkan_cross_fade_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanCrossFadeOp *self = (GskVulkanCrossFadeOp *) op;
GskVulkanCrossFadeInstance *instance = (GskVulkanCrossFadeInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->bounds, instance->rect);
gsk_rect_to_float (&self->start.rect, instance->start_rect);
gsk_rect_to_float (&self->end.rect, instance->end_rect);
gsk_rect_to_float (&self->start.tex_rect, instance->start_tex_rect);
gsk_rect_to_float (&self->end.tex_rect, instance->end_tex_rect);
gsk_vulkan_rect_to_float (&self->bounds, instance->rect);
gsk_vulkan_rect_to_float (&self->start.rect, instance->start_rect);
gsk_vulkan_rect_to_float (&self->end.rect, instance->end_rect);
gsk_vulkan_rect_to_float (&self->start.tex_rect, instance->start_tex_rect);
gsk_vulkan_rect_to_float (&self->end.tex_rect, instance->end_tex_rect);
instance->start_tex_id = self->start.image_descriptor;
instance->end_tex_id = self->end.image_descriptor;

View File

@@ -42,8 +42,8 @@ gsk_vulkan_glyph_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanGlyphOp *self = (GskVulkanGlyphOp *) op;
GskVulkanGlyphInstance *instance = (GskVulkanGlyphInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_rect_to_float (&self->tex_rect, instance->tex_rect);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_rect_to_float (&self->tex_rect, instance->tex_rect);
instance->tex_id = self->image_descriptor;
gsk_vulkan_rgba_to_float (&self->color, instance->color);
}

View File

@@ -51,7 +51,7 @@ gsk_vulkan_linear_gradient_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanLinearGradientOp *self = (GskVulkanLinearGradientOp *) op;
GskVulkanLinearInstance *instance = (GskVulkanLinearInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_rect_to_float (&self->rect, instance->rect);
gsk_vulkan_point_to_float (&self->start, instance->start);
gsk_vulkan_point_to_float (&self->end, instance->end);
instance->repeating = self->repeating;

View File

@@ -60,11 +60,11 @@ gsk_vulkan_mask_op_collect_vertex_data (GskVulkanOp *op,
GskVulkanMaskOp *self = (GskVulkanMaskOp *) op;
GskVulkanMaskInstance *instance = (GskVulkanMaskInstance *) (data + ((GskVulkanShaderOp *) op)->vertex_offset);
gsk_rect_to_float (&self->source.rect, instance->source_rect);
gsk_rect_to_float (&self->source.tex_rect, instance->source_tex_rect);
gsk_vulkan_rect_to_float (&self->source.rect, instance->source_rect);
gsk_vulkan_rect_to_float (&self->source.tex_rect, instance->source_tex_rect);
instance->source_id = self->source.image_descriptor;
gsk_rect_to_float (&self->mask.rect, instance->mask_rect);
gsk_rect_to_float (&self->mask.tex_rect, instance->mask_tex_rect);
gsk_vulkan_rect_to_float (&self->mask.rect, instance->mask_rect);
gsk_vulkan_rect_to_float (&self->mask.tex_rect, instance->mask_tex_rect);
instance->mask_id = self->mask.image_descriptor;
instance->mask_mode = self->mask_mode;
}

View File

@@ -2,7 +2,6 @@
#include "gskdebugprivate.h"
#include "gskrectprivate.h"
#include "gskroundedrectprivate.h"
#include <gdk/gdk.h>
@@ -38,6 +37,16 @@ gsk_vulkan_normalize_tex_coords (graphene_rect_t *tex_coords,
rect->size.height / tex->size.height);
}
static inline void
gsk_vulkan_rect_to_float (const graphene_rect_t *rect,
float values[4])
{
values[0] = rect->origin.x;
values[1] = rect->origin.y;
values[2] = rect->size.width;
values[3] = rect->size.height;
}
static inline void
gsk_vulkan_rgba_to_float (const GdkRGBA *rgba,
float values[4])

View File

@@ -1,11 +1,9 @@
#extension GL_EXT_nonuniform_qualifier : enable
layout(set = 0, binding = 0) uniform sampler2D textures[50000];
layout(set = 1, binding = 0) readonly buffer FloatBuffers {
float floats[];
} buffers[50000];
#define get_sampler(id) textures[nonuniformEXT (id)]
#define get_buffer(id) buffers[nonuniformEXT (id)]
#define get_float(id) get_buffer(0).floats[nonuniformEXT (id)]
#define get_sampler(id) textures[id]
#define get_buffer(id) buffers[id]
#define get_float(id) get_buffer(0).floats[id]

View File

@@ -93,12 +93,12 @@ foreach shader: gsk_private_vulkan_shaders
endforeach
foreach shader: gsk_private_vulkan_vertex_shaders
shader_header = custom_target(output: '@0@.h'.format(shader),
input: shader,
command: [
find_program('generate-header.py'),
'@INPUT@',
],
capture: true)
shader_header = configure_file(output: '@0@.h'.format(shader),
input: shader,
command: [
find_program('generate-header.py'),
'@INPUT@',
],
capture: true)
gsk_private_vulkan_shader_headers += shader_header
endforeach

View File

@@ -459,8 +459,7 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
*
* Creates render nodes for rendering @layout in the given foregound @color
* and appends them to the current node of @snapshot without changing the
* current node. The current theme's foreground color for a widget can be
* obtained with [method@Gtk.Widget.get_color].
* current node.
*
* Note that if the layout does not produce any visible output, then nodes
* may not be added to the @snapshot.

View File

@@ -566,7 +566,7 @@ gtk_about_dialog_class_init (GtkAboutDialogClass *klass)
* A logo for the about box.
*
* If it is `NULL`, the default window icon set with
* [func@Gtk.Window.set_default_icon_name] will be used.
* [id@gtk_window_set_default_icon_name] will be used.
*/
props[PROP_LOGO] =
g_param_spec_object ("logo", NULL, NULL,

View File

@@ -45,7 +45,6 @@ static GdkContentProvider *
double x,
double y,
GtkColorDialogButton *self);
static void activated (GtkColorDialogButton *self);
static void button_clicked (GtkColorDialogButton *self);
static void update_button_sensitivity
(GtkColorDialogButton *self);
@@ -97,17 +96,8 @@ enum
NUM_PROPERTIES
};
/* Signals */
enum
{
SIGNAL_ACTIVATE = 1,
NUM_SIGNALS
};
static GParamSpec *properties[NUM_PROPERTIES];
static unsigned int color_dialog_button_signals[NUM_SIGNALS] = { 0 };
G_DEFINE_TYPE (GtkColorDialogButton, gtk_color_dialog_button, GTK_TYPE_WIDGET)
static void
@@ -118,8 +108,6 @@ gtk_color_dialog_button_init (GtkColorDialogButton *self)
GtkDragSource *source;
GtkDropTarget *dest;
g_signal_connect_swapped (self, "activate", G_CALLBACK (activated), self);
self->color = GDK_RGBA ("00000000");
self->button = gtk_button_new ();
@@ -290,27 +278,6 @@ gtk_color_dialog_button_class_init (GtkColorDialogButtonClass *class)
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
/**
* GtkColorDialogButton::activate:
* @widget: the object which received the signal
*
* Emitted when the color dialog button is activated.
*
* The `::activate` signal on `GtkColorDialogButton` is an action signal
* and emitting it causes the button to pop up its dialog.
*
* Since: 4.14
*/
color_dialog_button_signals[SIGNAL_ACTIVATE] =
g_signal_new (I_ ("activate"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
gtk_widget_class_set_activate_signal (widget_class, color_dialog_button_signals[SIGNAL_ACTIVATE]);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "colorbutton");
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
@@ -399,12 +366,6 @@ color_chosen (GObject *source,
update_button_sensitivity (self);
}
static void
activated (GtkColorDialogButton *self)
{
gtk_widget_activate (self->button);
}
static void
button_clicked (GtkColorDialogButton *self)
{

View File

@@ -1728,18 +1728,5 @@ typedef enum { /*< prefix=GTK_ACCESSIBLE_SORT >*/
GTK_ACCESSIBLE_SORT_OTHER
} GtkAccessibleSort;
/**
* GtkPopoverMenuFlags:
* @GTK_POPOVER_MENU_NESTED: Create submenus as nested
* popovers. Without this flag, submenus are created as
* sliding pages that replace the main menu.
*
* Flags that affect how [class@Gtk.PopoverMenu] widgets built from
* a [class@Gio.MenuModel] are created and displayed.
*/
typedef enum { /*< prefix=GTK_POPOVER_MENU >*/
GTK_POPOVER_MENU_NESTED = 1 << 0
} GtkPopoverMenuFlags;
G_END_DECLS

View File

@@ -89,7 +89,7 @@
* ## GtkExpression in GObject properties
*
* In order to use a `GtkExpression` as a `GObject` property, you must use the
* [func@Gtk.param_spec_expression] when creating a `GParamSpec` to install in the
* [id@gtk_param_spec_expression] when creating a `GParamSpec` to install in the
* `GObject` class being defined; for instance:
*
* ```c
@@ -103,8 +103,8 @@
* ```
*
* When implementing the `GObjectClass.set_property` and `GObjectClass.get_property`
* virtual functions, you must use [func@Gtk.value_get_expression], to retrieve the
* stored `GtkExpression` from the `GValue` container, and [func@Gtk.value_set_expression],
* virtual functions, you must use [id@gtk_value_get_expression], to retrieve the
* stored `GtkExpression` from the `GValue` container, and [id@gtk_value_set_expression],
* to store the `GtkExpression` into the `GValue`; for instance:
*
* ```c

View File

@@ -43,8 +43,6 @@
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
@class FilterComboBox;
typedef struct {
GtkFileChooserNative *self;
@@ -70,33 +68,31 @@ typedef struct {
NSMutableArray *filters;
NSMutableArray *filter_names;
FilterComboBox *filter_popup_button;
NSComboBox *filter_combo_box;
GSList *files;
int response;
} FileChooserQuartzData;
@interface FilterComboBox : NSPopUpButton
@interface FilterComboBox : NSObject<NSComboBoxDelegate>
{
FileChooserQuartzData *data;
}
- (id) initWithData:(FileChooserQuartzData *) quartz_data;
- (void) popUpButtonSelectionChanged:(id) sender;
- (void)comboBoxSelectionDidChange:(NSNotification *)notification;
@end
@implementation FilterComboBox
- (id) initWithData:(FileChooserQuartzData *) quartz_data
{
[super initWithFrame:NSMakeRect(0, 0, 200, 24)];
[self setTarget:self];
[self setAction:@selector(popUpButtonSelectionChanged:)];
[super init];
data = quartz_data;
return self;
}
- (void)popUpButtonSelectionChanged:(id)sender
- (void)comboBoxSelectionDidChange:(NSNotification *)notification
{
NSInteger selected_index = [data->filter_popup_button indexOfSelectedItem];
NSInteger selected_index = [data->filter_combo_box indexOfSelectedItem];
NSArray *filter = [data->filters objectAtIndex:selected_index];
// check for empty strings in filter -> indicates all filetypes should be allowed!
if ([filter containsObject:@""])
@@ -306,8 +302,10 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
if (data->filters)
{
// when filters have been provided, a combobox needs to be added
data->filter_popup_button = [[FilterComboBox alloc] initWithData:data];
[data->filter_popup_button addItemsWithTitles:data->filter_names];
data->filter_combo_box = [[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
[data->filter_combo_box addItemsWithObjectValues:data->filter_names];
[data->filter_combo_box setEditable:NO];
[data->filter_combo_box setDelegate:[[FilterComboBox alloc] initWithData:data]];
if (data->self->current_filter)
{
@@ -331,18 +329,16 @@ filechooser_quartz_launch (FileChooserQuartzData *data)
g_object_unref (filters);
if (current_filter_index != GTK_INVALID_LIST_POSITION)
[data->filter_popup_button selectItemAtIndex:current_filter_index];
[data->filter_combo_box selectItemAtIndex:current_filter_index];
else
[data->filter_popup_button selectItemAtIndex:0];
[data->filter_combo_box selectItemAtIndex:0];
}
else
{
[data->filter_popup_button selectItemAtIndex:0];
[data->filter_combo_box selectItemAtIndex:0];
}
[data->filter_popup_button popUpButtonSelectionChanged:NULL];
[data->filter_popup_button setToolTip:[NSString stringWithUTF8String:_("Select which types of files are shown")]];
[data->panel setAccessoryView:data->filter_popup_button];
[data->filter_combo_box setToolTip:[NSString stringWithUTF8String:_("Select which types of files are shown")]];
[data->panel setAccessoryView:data->filter_combo_box];
if ([data->panel isKindOfClass:[NSOpenPanel class]] && [data->panel respondsToSelector:@selector(setAccessoryViewDisclosed:)])
{
[(id<CanSetAccessoryViewDisclosed>) data->panel setAccessoryViewDisclosed:YES];
@@ -582,3 +578,4 @@ gtk_file_chooser_native_quartz_hide (GtkFileChooserNative *self)
}
data->panel = NULL;
}

View File

@@ -758,6 +758,8 @@ gtk_file_filter_get_attributes (GtkFileFilter *filter)
#ifdef GDK_WINDOWING_MACOS
#import <Foundation/Foundation.h>
NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
@@ -771,8 +773,9 @@ NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
{
case FILTER_RULE_MIME_TYPE:
{
// GContentType from GIO use UTI on macOS since glib version 2.51
NSString *uti_nsstring = [NSString stringWithUTF8String: rule->u.content_types[0]];
// convert mime-types to UTI
NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.content_types[0]];
NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, (CFStringRef) mime_type_nsstring, NULL);
if (uti_nsstring == NULL)
{
[array release];

View File

@@ -32,7 +32,7 @@
#include "gtkwidgetprivate.h"
#include "gtktypebuiltins.h"
static void activated (GtkFontDialogButton *self);
static void button_clicked (GtkFontDialogButton *self);
static void update_button_sensitivity
(GtkFontDialogButton *self);
@@ -100,17 +100,8 @@ enum
NUM_PROPERTIES
};
/* Signals */
enum
{
SIGNAL_ACTIVATE = 1,
NUM_SIGNALS
};
static GParamSpec *properties[NUM_PROPERTIES];
static unsigned int font_dialog_button_signals[NUM_SIGNALS] = { 0 };
G_DEFINE_TYPE (GtkFontDialogButton, gtk_font_dialog_button, GTK_TYPE_WIDGET)
static void
@@ -119,8 +110,6 @@ gtk_font_dialog_button_init (GtkFontDialogButton *self)
GtkWidget *box;
PangoFontDescription *font_desc;
g_signal_connect_swapped (self, "activate", G_CALLBACK (activated), self);
self->button = gtk_button_new ();
g_signal_connect_swapped (self->button, "clicked", G_CALLBACK (button_clicked), self);
self->font_label = gtk_label_new (_("Font"));
@@ -394,27 +383,6 @@ gtk_font_dialog_button_class_init (GtkFontDialogButtonClass *class)
g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
/**
* GtkFontDialogButton::activate:
* @widget: The object which received the signal
*
* Emitted when the font dialog button is activated.
*
* The `::activate` signal on `GtkFontDialogButton` is an action signal
* and emitting it causes the button to pop up its dialog.
*
* Since: 4.14
*/
font_dialog_button_signals[SIGNAL_ACTIVATE] =
g_signal_new (I_ ("activate"),
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
0,
NULL, NULL,
NULL,
G_TYPE_NONE, 0);
gtk_widget_class_set_activate_signal (widget_class, font_dialog_button_signals[SIGNAL_ACTIVATE]);
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
gtk_widget_class_set_css_name (widget_class, "fontbutton");
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GROUP);
@@ -531,12 +499,6 @@ font_and_features_chosen (GObject *source,
update_button_sensitivity (self);
}
static void
activated (GtkFontDialogButton *self)
{
gtk_widget_activate (self->button);
}
static void
button_clicked (GtkFontDialogButton *self)
{

View File

@@ -121,7 +121,7 @@ static GParamSpec *properties[N_PROPS] = { NULL, };
* @self: a `GtkListBase`
* @across: position in pixels in the direction cross to the list
* @along: position in pixels in the direction of the list
* @pos: (out): set to the looked up position
* @pos: (out caller-allocates): set to the looked up position
* @area: (out caller-allocates) (optional): set to the area occupied
* by the returned position
*
@@ -1519,7 +1519,7 @@ gtk_list_base_allocate_children (GtkListBase *self,
GtkListBasePrivate *priv = gtk_list_base_get_instance_private (self);
GtkListTile *tile;
int dx, dy;
gtk_list_base_get_adjustment_values (self, OPPOSITE_ORIENTATION (priv->orientation), &dx, NULL, NULL);
gtk_list_base_get_adjustment_values (self, priv->orientation, &dy, NULL, NULL);

View File

@@ -247,7 +247,7 @@ static gboolean do_setlocale = TRUE;
/**
* gtk_disable_setlocale:
*
* Prevents [func@Gtk.init] and [func@Gtk.init_check] from automatically calling
* Prevents [id@gtk_init] and [id@gtk_init_check] from automatically calling
* `setlocale (LC_ALL, "")`.
*
* You would want to use this function if you wanted to set the locale for

View File

@@ -1353,35 +1353,35 @@ gtk_menu_button_get_use_underline (GtkMenuButton *menu_button)
}
static GList *
get_menu_bars (GtkWidget *toplevel)
get_menu_bars (GtkWindow *window)
{
return g_object_get_data (G_OBJECT (toplevel), "gtk-menu-bar-list");
return g_object_get_data (G_OBJECT (window), "gtk-menu-bar-list");
}
static void
set_menu_bars (GtkWidget *toplevel,
set_menu_bars (GtkWindow *window,
GList *menubars)
{
g_object_set_data (G_OBJECT (toplevel), I_("gtk-menu-bar-list"), menubars);
g_object_set_data (G_OBJECT (window), I_("gtk-menu-bar-list"), menubars);
}
static void
add_to_toplevel (GtkWidget *toplevel,
GtkMenuButton *button)
add_to_window (GtkWindow *window,
GtkMenuButton *button)
{
GList *menubars = get_menu_bars (toplevel);
GList *menubars = get_menu_bars (window);
set_menu_bars (toplevel, g_list_prepend (menubars, button));
set_menu_bars (window, g_list_prepend (menubars, button));
}
static void
remove_from_toplevel (GtkWidget *toplevel,
GtkMenuButton *button)
remove_from_window (GtkWindow *window,
GtkMenuButton *button)
{
GList *menubars = get_menu_bars (toplevel);
GList *menubars = get_menu_bars (window);
menubars = g_list_remove (menubars, button);
set_menu_bars (toplevel, menubars);
set_menu_bars (window, menubars);
}
static void
@@ -1394,7 +1394,7 @@ gtk_menu_button_root (GtkWidget *widget)
if (button->primary)
{
GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
add_to_toplevel (toplevel, button);
add_to_window (GTK_WINDOW (toplevel), button);
}
}
@@ -1404,7 +1404,7 @@ gtk_menu_button_unroot (GtkWidget *widget)
GtkWidget *toplevel;
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
remove_from_toplevel (toplevel, GTK_MENU_BUTTON (widget));
remove_from_window (GTK_WINDOW (toplevel), GTK_MENU_BUTTON (widget));
GTK_WIDGET_CLASS (gtk_menu_button_parent_class)->unroot (widget);
}
@@ -1437,9 +1437,9 @@ gtk_menu_button_set_primary (GtkMenuButton *menu_button,
if (toplevel)
{
if (menu_button->primary)
add_to_toplevel (GTK_WIDGET (toplevel), menu_button);
add_to_window (GTK_WINDOW (toplevel), menu_button);
else
remove_from_toplevel (GTK_WIDGET (toplevel), menu_button);
remove_from_window (GTK_WINDOW (toplevel), menu_button);
}
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_PRIMARY]);

View File

@@ -5409,9 +5409,7 @@ gtk_notebook_real_switch_page (GtkNotebook *notebook,
if (notebook->cur_page)
{
GtkRoot *root = gtk_widget_get_root (GTK_WIDGET (notebook));
GtkWidget *focus = NULL;
if (root)
focus = gtk_root_get_focus (root);
GtkWidget *focus = gtk_root_get_focus (root);
if (focus)
child_has_focus = gtk_widget_is_ancestor (focus, notebook->cur_page->child);
gtk_widget_unset_state_flags (notebook->cur_page->tab_widget, GTK_STATE_FLAG_CHECKED);

View File

@@ -70,31 +70,30 @@
* # CSS nodes
*
* ```
* popover.background[.menu]
* popover[.menu]
* ├── arrow
* ╰── contents
* ╰── contents.background
* ╰── <child>
* ```
*
* `GtkPopover` has a main node with name `popover`, an arrow with name `arrow`,
* and another node for the content named `contents`. The `popover` node always
* gets the `.background` style class. It also gets the `.menu` style class
* if the popover is menu-like, e.g. is a [class@Gtk.PopoverMenu].
* The contents child node always gets the .background style class
* and the popover itself gets the .menu style class if the popover
* is menu-like (i.e. `GtkPopoverMenu`).
*
* Particular uses of `GtkPopover`, such as touch selection popups or
* magnifiers in `GtkEntry` or `GtkTextView` get style classes like
* `.touch-selection` or `.magnifier` to differentiate from plain popovers.
* .touch-selection or .magnifier to differentiate from plain popovers.
*
* When styling a popover directly, the `popover` node should usually
* When styling a popover directly, the popover node should usually
* not have any background. The visible part of the popover can have
* a shadow. To specify it in CSS, set the box-shadow of the `contents` node.
* a shadow. To specify it in CSS, set the box-shadow of the contents node.
*
* Note that, in order to accomplish appropriate arrow visuals, `GtkPopover`
* uses custom drawing for the `arrow` node. This makes it possible for the
* uses custom drawing for the arrow node. This makes it possible for the
* arrow to change its shape dynamically, but it also limits the possibilities
* of styling it using CSS. In particular, the `arrow` gets drawn over the
* `content` node's border and shadow, so they look like one shape, which
* means that the border width of the `content` node and the `arrow` node should
* of styling it using CSS. In particular, the arrow gets drawn over the
* content node's border and shadow, so they look like one shape, which
* means that the border width of the content node and the arrow node should
* be the same. The arrow also does not support any border shape other than
* solid, no border-radius, only one border width (border-bottom-width is
* used) and no box-shadow.

View File

@@ -38,6 +38,7 @@
#include "gtkscrolledwindow.h"
#include "gtkviewport.h"
/**
* GtkPopoverMenu:
*
@@ -49,7 +50,6 @@
* `GtkPopoverMenu` treats its children like menus and allows switching
* between them. It can open submenus as traditional, nested submenus,
* or in a more touch-friendly sliding fashion.
* The property [property@Gtk.PopoverMenu:flags] controls this appearance.
*
* `GtkPopoverMenu` is meant to be used primarily with menu models,
* using [ctor@Gtk.PopoverMenu.new_from_model]. If you need to put
@@ -128,21 +128,14 @@
*
* Menu items will also show accelerators, which are usually associated
* with actions via [method@Gtk.Application.set_accels_for_action],
* [method@WidgetClass.add_binding_action] or
* [id@gtk_widget_class_add_binding_action] or
* [method@Gtk.ShortcutController.add_shortcut].
*
* # CSS Nodes
*
* `GtkPopoverMenu` is just a subclass of `GtkPopover` that adds custom content
* to it, therefore it has the same CSS nodes. It is one of the cases that add
* a `.menu` style class to the main `popover` node.
*
* Menu items have nodes with name `button` and class `.model`. If a section
* display-hint is set, the section gets a node `box` with class `horizontal`
* plus a class with the same text as the display hint. Note that said box may
* not be the direct ancestor of the item `button`s. Thus, for example, to style
* items in an `inline-buttons` section, select `.inline-buttons button.model`.
* Other things that may be of interest to style in menus include `label` nodes.
* a .menu style class to the popover's main node.
*
* # Accessibility
*
@@ -173,8 +166,7 @@ struct _GtkPopoverMenuClass
enum {
PROP_VISIBLE_SUBMENU = 1,
PROP_MENU_MODEL,
PROP_FLAGS
PROP_MENU_MODEL
};
static void gtk_popover_menu_buildable_iface_init (GtkBuildableIface *iface);
@@ -411,10 +403,6 @@ gtk_popover_menu_get_property (GObject *object,
g_value_set_object (value, gtk_popover_menu_get_menu_model (menu));
break;
case PROP_FLAGS:
g_value_set_flags (value, gtk_popover_menu_get_flags (menu));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -439,10 +427,6 @@ gtk_popover_menu_set_property (GObject *object,
gtk_popover_menu_set_menu_model (menu, g_value_get_object (value));
break;
case PROP_FLAGS:
gtk_popover_menu_set_flags (menu, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -524,6 +508,7 @@ gtk_popover_menu_focus (GtkWidget *widget,
return FALSE;
}
static void
add_tab_bindings (GtkWidgetClass *widget_class,
GdkModifierType modifiers,
@@ -543,7 +528,7 @@ add_arrow_bindings (GtkWidgetClass *widget_class,
GtkDirectionType direction)
{
guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
gtk_widget_class_add_binding_signal (widget_class, keysym, 0,
"move-focus",
"(i)", direction);
@@ -624,23 +609,6 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass)
G_TYPE_MENU_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GtkPopoverMenu:flags: (attributes org.gtk.Property.get=gtk_popover_menu_get_flags org.gtk.Property.set=gtk_popover_menu_set_flags)
*
* The flags that @popover uses to create/display a menu from its model.
*
* If a model is set and the flags change, contents are rebuilt, so if setting
* properties individually, set flags before model to avoid a redundant rebuild.
*
* Since: 4.14
*/
g_object_class_install_property (object_class,
PROP_FLAGS,
g_param_spec_flags ("flags", NULL, NULL,
GTK_TYPE_POPOVER_MENU_FLAGS, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS
| G_PARAM_EXPLICIT_NOTIFY));
add_arrow_bindings (widget_class, GDK_KEY_Up, GTK_DIR_UP);
add_arrow_bindings (widget_class, GDK_KEY_Down, GTK_DIR_DOWN);
add_arrow_bindings (widget_class, GDK_KEY_Left, GTK_DIR_LEFT);
@@ -690,20 +658,6 @@ gtk_popover_menu_buildable_iface_init (GtkBuildableIface *iface)
iface->add_child = gtk_popover_menu_buildable_add_child;
}
static void
gtk_popover_menu_rebuild_contents (GtkPopoverMenu *popover)
{
GtkWidget *stack;
GtkWidget *child;
stack = gtk_popover_menu_get_stack (popover);
while ((child = gtk_widget_get_first_child (stack)))
gtk_stack_remove (GTK_STACK (stack), child);
if (popover->model)
gtk_menu_section_box_new_toplevel (popover, popover->model, popover->flags);
}
/**
* gtk_popover_menu_new:
*
@@ -814,7 +768,7 @@ gtk_popover_menu_new_from_model_full (GMenuModel *model,
g_return_val_if_fail (model == NULL || G_IS_MENU_MODEL (model), NULL);
popover = gtk_popover_menu_new ();
gtk_popover_menu_set_flags (GTK_POPOVER_MENU (popover), flags);
GTK_POPOVER_MENU (popover)->flags = flags;
gtk_popover_menu_set_menu_model (GTK_POPOVER_MENU (popover), model);
return popover;
@@ -840,41 +794,20 @@ gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
if (g_set_object (&popover->model, model))
{
gtk_popover_menu_rebuild_contents (popover);
GtkWidget *stack;
GtkWidget *child;
stack = gtk_popover_menu_get_stack (popover);
while ((child = gtk_widget_get_first_child (stack)))
gtk_stack_remove (GTK_STACK (stack), child);
if (model)
gtk_menu_section_box_new_toplevel (popover, model, popover->flags);
g_object_notify (G_OBJECT (popover), "menu-model");
}
}
/**
* gtk_popover_menu_set_flags: (attributes org.gtk.Method.set_property=flags)
* @popover: a `GtkPopoverMenu`
* @flags: a set of `GtkPopoverMenuFlags`
*
* Sets the flags that @popover uses to create/display a menu from its model.
*
* If a model is set and the flags change, contents are rebuilt, so if setting
* properties individually, set flags before model to avoid a redundant rebuild.
*
* Since: 4.14
*/
void
gtk_popover_menu_set_flags (GtkPopoverMenu *popover,
GtkPopoverMenuFlags flags)
{
g_return_if_fail (GTK_IS_POPOVER_MENU (popover));
if (popover->flags == flags)
return;
popover->flags = flags;
/* This shouldnt happen IRL, but notify test unsets :child, so dodge error */
if (gtk_popover_get_child (GTK_POPOVER (popover)) != NULL)
gtk_popover_menu_rebuild_contents (popover);
g_object_notify (G_OBJECT (popover), "flags");
}
/**
* gtk_popover_menu_get_menu_model: (attributes org.gtk.Method.get_property=menu-model)
* @popover: a `GtkPopoverMenu`
@@ -891,24 +824,6 @@ gtk_popover_menu_get_menu_model (GtkPopoverMenu *popover)
return popover->model;
}
/**
* gtk_popover_menu_get_flags: (attributes org.gtk.Method.get_property=flags)
* @popover: a `GtkPopoverMenu`
*
* Returns the flags that @popover uses to create/display a menu from its model.
*
* Returns: the `GtkPopoverMenuFlags`
*
* Since: 4.14
*/
GtkPopoverMenuFlags
gtk_popover_menu_get_flags (GtkPopoverMenu *popover)
{
g_return_val_if_fail (GTK_IS_POPOVER_MENU (popover), 0);
return popover->flags;
}
/**
* gtk_popover_menu_add_child:
* @popover: a `GtkPopoverMenu`

View File

@@ -37,6 +37,19 @@ GType gtk_popover_menu_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_popover_menu_new_from_model (GMenuModel *model);
/**
* GtkPopoverMenuFlags:
* @GTK_POPOVER_MENU_NESTED: Create submenus as nested
* popovers. Without this flag, submenus are created as
* sliding pages that replace the main menu.
*
* Flags that affect how popover menus are created from
* a menu model.
*/
typedef enum {
GTK_POPOVER_MENU_NESTED = 1 << 0
} GtkPopoverMenuFlags;
GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_popover_menu_new_from_model_full (GMenuModel *model,
GtkPopoverMenuFlags flags);
@@ -47,12 +60,6 @@ void gtk_popover_menu_set_menu_model (GtkPopoverMenu *popover,
GDK_AVAILABLE_IN_ALL
GMenuModel *gtk_popover_menu_get_menu_model (GtkPopoverMenu *popover);
GDK_AVAILABLE_IN_4_14
void gtk_popover_menu_set_flags (GtkPopoverMenu *popover,
GtkPopoverMenuFlags flags);
GDK_AVAILABLE_IN_4_14
GtkPopoverMenuFlags gtk_popover_menu_get_flags (GtkPopoverMenu *popover);
GDK_AVAILABLE_IN_ALL
gboolean gtk_popover_menu_add_child (GtkPopoverMenu *popover,
GtkWidget *child,

View File

@@ -29,7 +29,6 @@
#error "Only <gtk/gtk.h> can be included directly."
#endif
#include <gtk/gtkborder.h>
#include <gtk/gtkwidget.h>

View File

@@ -113,9 +113,10 @@ gtk_section_model_default_init (GtkSectionModelInterface *iface)
* gtk_section_model_get_section:
* @self: a `GtkSectionModel`
* @position: the position of the item to query
* @out_start: (out): the position of the first item in the section
* @out_end: (out): the position of the first item not part of the section
* anymore.
* @out_start: (out caller-allocates): the position of the first
* item in the section
* @out_end: (out caller-allocates): the position of the first
* item not part of the section anymore.
*
* Query the section that covers the given position. The number of
* items in the section can be computed by `out_end - out_start`.

Some files were not shown because too many files have changed in this diff Show More