From 2b029af78fff9731ccdb3df6fd834bea68fcae53 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 25 Nov 2020 16:21:50 +0100 Subject: [PATCH] gsk: Add GskStroke It's unused in this commit. This just prepares the new object. --- gsk/gsk.h | 1 + gsk/gskenums.h | 43 ++++++- gsk/gskstroke.c | 267 +++++++++++++++++++++++++++++++++++++++++ gsk/gskstroke.h | 66 ++++++++++ gsk/gskstrokeprivate.h | 53 ++++++++ gsk/gsktypes.h | 1 + gsk/meson.build | 2 + 7 files changed, 430 insertions(+), 3 deletions(-) create mode 100644 gsk/gskstroke.c create mode 100644 gsk/gskstroke.h create mode 100644 gsk/gskstrokeprivate.h diff --git a/gsk/gsk.h b/gsk/gsk.h index 2adfa3aec0..a5b530f291 100644 --- a/gsk/gsk.h +++ b/gsk/gsk.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/gsk/gskenums.h b/gsk/gskenums.h index 3a68d7d09a..0bd84b843d 100644 --- a/gsk/gskenums.h +++ b/gsk/gskenums.h @@ -1,5 +1,5 @@ /* GSK - The GTK Scene Kit - * Copyright 2016 Endless + * Copyright 2016 Endless * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -50,7 +50,7 @@ * @GSK_BLUR_NODE: A node that applies a blur * @GSK_DEBUG_NODE: Debug information that does not affect the rendering * @GSK_GL_SHADER_NODE: A node that uses OpenGL fragment shaders to render - + * The type of a node determines what the node is rendering. */ typedef enum { @@ -196,6 +196,44 @@ typedef enum { GSK_FILL_RULE_EVEN_ODD } GskFillRule; +/** + * GskLineCap: + * @GSK_LINE_CAP_BUTT: Start and stop the line exactly at the start + * and end point + * @GSK_LINE_CAP_ROUND: Use a round ending, the center of the circle + * is the start or end point. + * @GSK_LINE_CAP_SQUARE: use squared ending, the center of the square + * is the start or end point. + * + * Specifies how to render the start and end points of contours or + * dashes when stroking. + * + * The default line cap style is @GSK_LINE_CAP_BUTT. + */ +typedef enum { + GSK_LINE_CAP_BUTT, + GSK_LINE_CAP_ROUND, + GSK_LINE_CAP_SQUARE +} GskLineCap; + +/** + * GskLineJoin: + * @GSK_LINE_JOIN_MITER: Use a sharp, angled corner + * @GSK_LINE_JOIN_ROUND: Use a round join, the center of the circle is + * the joint point + * @GSK_LINE_JOIN_BEVEL: use a cut-off join, the join is cut off at half + * the line width from the joint point + * + * Specifies how to render the junction of two lines when stroking. + * + * The default line join style is @GSK_LINE_JOIN_MITER. + **/ +typedef enum { + GSK_LINE_JOIN_MITER, + GSK_LINE_JOIN_ROUND, + GSK_LINE_JOIN_BEVEL +} GskLineJoin; + /** * GskSerializationError: * @GSK_SERIALIZATION_UNSUPPORTED_FORMAT: The format can not be identified @@ -280,5 +318,4 @@ typedef enum GSK_GL_UNIFORM_TYPE_VEC4, } GskGLUniformType; - #endif /* __GSK_TYPES_H__ */ diff --git a/gsk/gskstroke.c b/gsk/gskstroke.c new file mode 100644 index 0000000000..0752929a58 --- /dev/null +++ b/gsk/gskstroke.c @@ -0,0 +1,267 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gskstrokeprivate.h" + +/** + * GskStroke: + * + * A `GskStroke` describes the attributes that are used when stroking a path. + */ + +G_DEFINE_BOXED_TYPE (GskStroke, gsk_stroke, + gsk_stroke_copy, + gsk_stroke_free) + + +/** + * gsk_stroke_new: + * @line_width: line width of the stroke. Must be > 0 + * + * Creates a new `GskStroke` with the given @line_width. + * + * Returns: a new `GskStroke` + **/ +GskStroke * +gsk_stroke_new (float line_width) +{ + GskStroke *self; + + g_return_val_if_fail (line_width > 0, NULL); + + self = g_new0 (GskStroke, 1); + + self->line_width = line_width; + + return self; +} + +/** + * gsk_stroke_copy: + * @other: `GskStroke` to copy + * + * Creates a copy of the given @other stroke. + * + * Returns: a new `GskStroke`. Use [method@Gsk.Stroke.free] to free it. + **/ +GskStroke * +gsk_stroke_copy (const GskStroke *other) +{ + GskStroke *self; + + g_return_val_if_fail (other != NULL, NULL); + + self = g_new (GskStroke, 1); + + gsk_stroke_init_copy (self, other); + + return self; +} + +/** + * gsk_stroke_free: + * @self: a `GskStroke` + * + * Frees a `GskStroke`. + **/ +void +gsk_stroke_free (GskStroke *self) +{ + if (self == NULL) + return; + + gsk_stroke_clear (self); + + g_free (self); +} + +void +gsk_stroke_to_cairo (const GskStroke *self, + cairo_t *cr) +{ + cairo_set_line_width (cr, self->line_width); + + /* gcc can optimize that to a direct case. This catches later additions to the enum */ + switch (self->line_cap) + { + case GSK_LINE_CAP_BUTT: + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + break; + case GSK_LINE_CAP_ROUND: + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + break; + case GSK_LINE_CAP_SQUARE: + cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + break; + default: + g_assert_not_reached (); + break; + } + + /* gcc can optimize that to a direct case. This catches later additions to the enum */ + switch (self->line_join) + { + case GSK_LINE_JOIN_MITER: + cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); + break; + case GSK_LINE_JOIN_ROUND: + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + break; + case GSK_LINE_JOIN_BEVEL: + cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL); + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * gsk_stroke_equal: + * @stroke1: the first `GskStroke` + * @stroke2: the second `GskStroke` + * + * Checks if two strokes are identical. + * + * Returns: %TRUE if the two strokes are equal, %FALSE otherwise + **/ +gboolean +gsk_stroke_equal (gconstpointer stroke1, + gconstpointer stroke2) +{ + const GskStroke *self1 = stroke1; + const GskStroke *self2 = stroke2; + + if (self1->line_width != self2->line_width || + self1->line_cap != self2->line_cap || + self1->line_join != self2->line_join) + return FALSE; + + return TRUE; +} + +/** + * gsk_stroke_set_line_width: + * @self: a `GskStroke` + * @line_width: width of the line in pixels + * + * Sets the line width to be used when stroking. + * + * The line width must be > 0. + **/ +void +gsk_stroke_set_line_width (GskStroke *self, + float line_width) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (line_width > 0); + + self->line_width = line_width; +} + +/** + * gsk_stroke_get_line_width: + * @self: a `GskStroke` + * + * Gets the line width used. + * + * Returns: The line width + **/ +float +gsk_stroke_get_line_width (const GskStroke *self) +{ + g_return_val_if_fail (self != NULL, 0.0); + + return self->line_width; +} + +/** + * gsk_stroke_set_line_cap: + * @self: a `GskStroke` + * @line_cap: the `GskLineCap` + * + * Sets the line cap to be used when stroking. + * + * See `GskLineCap` for details. + **/ +void +gsk_stroke_set_line_cap (GskStroke *self, + GskLineCap line_cap) +{ + g_return_if_fail (self != NULL); + + self->line_cap = line_cap; +} + +/** + * gsk_stroke_get_line_cap: + * @self: a `GskStroke` + * + * Gets the line cap used. + * + * See `GskLineCap` for details. + * + * Returns: The line cap + **/ +GskLineCap +gsk_stroke_get_line_cap (const GskStroke *self) +{ + g_return_val_if_fail (self != NULL, 0.0); + + return self->line_cap; +} + +/** + * gsk_stroke_set_line_join: + * @self: a `GskStroke` + * @line_join: The line join to use + * + * Sets the line join to be used when stroking. + * + * See `GskLineJoin` for details. + **/ +void +gsk_stroke_set_line_join (GskStroke *self, + GskLineJoin line_join) +{ + g_return_if_fail (self != NULL); + + self->line_join = line_join; +} + +/** + * gsk_stroke_get_line_join: + * @self: a `GskStroke` + * + * Gets the line join used. + * + * See `GskLineJoin` for details. + * + * Returns: The line join + **/ +GskLineJoin +gsk_stroke_get_line_join (const GskStroke *self) +{ + g_return_val_if_fail (self != NULL, 0.0); + + return self->line_join; +} + diff --git a/gsk/gskstroke.h b/gsk/gskstroke.h new file mode 100644 index 0000000000..df9295adf6 --- /dev/null +++ b/gsk/gskstroke.h @@ -0,0 +1,66 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + +#ifndef __GSK_STROKE_H__ +#define __GSK_STROKE_H__ + +#if !defined (__GSK_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only can be included directly." +#endif + + +#include + +G_BEGIN_DECLS + +#define GSK_TYPE_STROKE (gsk_stroke_get_type ()) + +GDK_AVAILABLE_IN_ALL +GType gsk_stroke_get_type (void) G_GNUC_CONST; +GDK_AVAILABLE_IN_ALL +GskStroke * gsk_stroke_new (float line_width); +GDK_AVAILABLE_IN_ALL +GskStroke * gsk_stroke_copy (const GskStroke *other); +GDK_AVAILABLE_IN_ALL +void gsk_stroke_free (GskStroke *self); + +GDK_AVAILABLE_IN_ALL +gboolean gsk_stroke_equal (gconstpointer stroke1, + gconstpointer stroke2); + +GDK_AVAILABLE_IN_ALL +void gsk_stroke_set_line_width (GskStroke *self, + float line_width); +GDK_AVAILABLE_IN_ALL +float gsk_stroke_get_line_width (const GskStroke *self); +GDK_AVAILABLE_IN_ALL +void gsk_stroke_set_line_cap (GskStroke *self, + GskLineCap line_cap); +GDK_AVAILABLE_IN_ALL +GskLineCap gsk_stroke_get_line_cap (const GskStroke *self); +GDK_AVAILABLE_IN_ALL +void gsk_stroke_set_line_join (GskStroke *self, + GskLineJoin line_join); +GDK_AVAILABLE_IN_ALL +GskLineJoin gsk_stroke_get_line_join (const GskStroke *self); + + +G_END_DECLS + +#endif /* __GSK_STROKE_H__ */ diff --git a/gsk/gskstrokeprivate.h b/gsk/gskstrokeprivate.h new file mode 100644 index 0000000000..c6e5c8dc16 --- /dev/null +++ b/gsk/gskstrokeprivate.h @@ -0,0 +1,53 @@ +/* + * 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 . + * + * Authors: Benjamin Otte + */ + + +#ifndef __GSK_STROKE_PRIVATE_H__ +#define __GSK_STROKE_PRIVATE_H__ + +#include "gskstroke.h" + +G_BEGIN_DECLS + +struct _GskStroke +{ + float line_width; + GskLineCap line_cap; + GskLineJoin line_join; +}; + +static inline void +gsk_stroke_init_copy (GskStroke *stroke, + const GskStroke *other) +{ + *stroke = *other; +} + +static inline void +gsk_stroke_clear (GskStroke *stroke) +{ +} + +void gsk_stroke_to_cairo (const GskStroke *self, + cairo_t *cr); + +G_END_DECLS + +#endif /* __GSK_STROKE_PRIVATE_H__ */ + diff --git a/gsk/gsktypes.h b/gsk/gsktypes.h index 863ef651c2..fdf06b5ffc 100644 --- a/gsk/gsktypes.h +++ b/gsk/gsktypes.h @@ -28,6 +28,7 @@ typedef struct _GskPath GskPath; typedef struct _GskRenderer GskRenderer; +typedef struct _GskStroke GskStroke; typedef struct _GskTransform GskTransform; #endif /* __GSK_TYPES_H__ */ diff --git a/gsk/meson.build b/gsk/meson.build index ef5a59e4b7..4463dcd26c 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -31,6 +31,7 @@ gsk_public_sources = files([ 'gskrendernodeimpl.c', 'gskrendernodeparser.c', 'gskroundedrect.c', + 'gskstroke.c', 'gsktransform.c', 'gl/gskglrenderer.c', ]) @@ -70,6 +71,7 @@ gsk_public_headers = files([ 'gskrenderer.h', 'gskrendernode.h', 'gskroundedrect.h', + 'gskstroke.h', 'gsktransform.h', 'gsktypes.h', 'gsk-autocleanup.h',