diff options
author | Benjamin Otte <otte@redhat.com> | 2020-12-03 00:47:54 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2020-12-03 00:47:54 +0100 |
commit | 55a242bd816893e8b3c777b053a3c5fc0266b5d6 (patch) | |
tree | f37db07ad554e499ad7b5b0785e9af53751cc394 | |
parent | 71cb7c2063a85d4f8d5424e466319f30be318913 (diff) | |
download | gtk+-55a242bd816893e8b3c777b053a3c5fc0266b5d6.tar.gz |
gsk: Add GskConicGradientNode
-rw-r--r-- | docs/reference/gsk/gsk4-sections.txt | 5 | ||||
-rw-r--r-- | gsk/broadway/gskbroadwayrenderer.c | 2 | ||||
-rw-r--r-- | gsk/gl/gskglrenderer.c | 1 | ||||
-rw-r--r-- | gsk/gskenums.h | 2 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 20 | ||||
-rw-r--r-- | gsk/gskrendernodeimpl.c | 338 | ||||
-rw-r--r-- | gsk/gskrendernodeparser.c | 50 | ||||
-rw-r--r-- | gsk/vulkan/gskvulkanrenderpass.c | 1 | ||||
-rw-r--r-- | gtk/inspector/recorder.c | 42 |
9 files changed, 461 insertions, 0 deletions
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt index f671732880..6cd1fa0d17 100644 --- a/docs/reference/gsk/gsk4-sections.txt +++ b/docs/reference/gsk/gsk4-sections.txt @@ -83,6 +83,11 @@ gsk_radial_gradient_node_get_hradius gsk_radial_gradient_node_get_vradius gsk_radial_gradient_node_get_center gsk_repeating_radial_gradient_node_new +gsk_conic_gradient_node_new +gsk_conic_gradient_node_get_n_color_stops +gsk_conic_gradient_node_get_color_stops +gsk_conic_gradient_node_get_center +gsk_conic_gradient_node_get_rotation gsk_border_node_new gsk_border_node_get_outline gsk_border_node_get_widths diff --git a/gsk/broadway/gskbroadwayrenderer.c b/gsk/broadway/gskbroadwayrenderer.c index 80a3f84968..5ac62e7ee0 100644 --- a/gsk/broadway/gskbroadwayrenderer.c +++ b/gsk/broadway/gskbroadwayrenderer.c @@ -264,6 +264,7 @@ collect_reused_child_nodes (GskRenderer *renderer, case GSK_RADIAL_GRADIENT_NODE: case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: case GSK_REPEAT_NODE: case GSK_BLEND_NODE: case GSK_CROSS_FADE_NODE: @@ -848,6 +849,7 @@ gsk_broadway_renderer_add_node (GskRenderer *renderer, case GSK_RADIAL_GRADIENT_NODE: case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: case GSK_REPEAT_NODE: case GSK_BLEND_NODE: case GSK_CROSS_FADE_NODE: diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index cd93966d5c..bb09be8bdd 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -3723,6 +3723,7 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self, case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: case GSK_CAIRO_NODE: default: { diff --git a/gsk/gskenums.h b/gsk/gskenums.h index 0cd0c284fc..243ab67cc8 100644 --- a/gsk/gskenums.h +++ b/gsk/gskenums.h @@ -32,6 +32,7 @@ * @GSK_REPEATING_LINEAR_GRADIENT_NODE: A node drawing a repeating linear gradient * @GSK_RADIAL_GRADIENT_NODE: A node drawing a radial gradient * @GSK_REPEATING_RADIAL_GRADIENT_NODE: A node drawing a repeating radial gradient + * @GSK_CONIC_GRADIENT_NODE: A node drawing a conic gradient * @GSK_BORDER_NODE: A node stroking a border around an area * @GSK_TEXTURE_NODE: A node drawing a #GdkTexture * @GSK_INSET_SHADOW_NODE: A node drawing an inset shadow @@ -61,6 +62,7 @@ typedef enum { GSK_REPEATING_LINEAR_GRADIENT_NODE, GSK_RADIAL_GRADIENT_NODE, GSK_REPEATING_RADIAL_GRADIENT_NODE, + GSK_CONIC_GRADIENT_NODE, GSK_BORDER_NODE, GSK_TEXTURE_NODE, GSK_INSET_SHADOW_NODE, diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index dba436afda..76771a9d8e 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -120,6 +120,7 @@ GskRenderNode * gsk_render_node_deserialize (GBytes #define GSK_TYPE_REPEATING_LINEAR_GRADIENT_NODE (gsk_repeating_linear_gradient_node_get_type()) #define GSK_TYPE_RADIAL_GRADIENT_NODE (gsk_radial_gradient_node_get_type()) #define GSK_TYPE_REPEATING_RADIAL_GRADIENT_NODE (gsk_repeating_radial_gradient_node_get_type()) +#define GSK_TYPE_CONIC_GRADIENT_NODE (gsk_conic_gradient_node_get_type()) #define GSK_TYPE_BORDER_NODE (gsk_border_node_get_type()) #define GSK_TYPE_INSET_SHADOW_NODE (gsk_inset_shadow_node_get_type()) #define GSK_TYPE_OUTSET_SHADOW_NODE (gsk_outset_shadow_node_get_type()) @@ -145,6 +146,7 @@ typedef struct _GskLinearGradientNode GskLinearGradientNode; typedef struct _GskRepeatingLinearGradientNode GskRepeatingLinearGradientNode; typedef struct _GskRadialGradientNode GskRadialGradientNode; typedef struct _GskRepeatingRadialGradientNode GskRepeatingRadialGradientNode; +typedef struct _GskConicGradientNode GskConicGradientNode; typedef struct _GskBorderNode GskBorderNode; typedef struct _GskInsetShadowNode GskInsetShadowNode; typedef struct _GskOutsetShadowNode GskOutsetShadowNode; @@ -217,6 +219,24 @@ GskRenderNode * gsk_repeating_linear_gradient_node_new (const graph gsize n_color_stops); GDK_AVAILABLE_IN_ALL +GType gsk_conic_gradient_node_get_type (void) G_GNUC_CONST; +GDK_AVAILABLE_IN_ALL +GskRenderNode * gsk_conic_gradient_node_new (const graphene_rect_t *bounds, + const graphene_point_t *center, + float rotation, + const GskColorStop *color_stops, + gsize n_color_stops); +GDK_AVAILABLE_IN_ALL +const graphene_point_t * gsk_conic_gradient_node_get_center (GskRenderNode *node); +GDK_AVAILABLE_IN_ALL +float gsk_conic_gradient_node_get_rotation (GskRenderNode *node); +GDK_AVAILABLE_IN_ALL +gsize gsk_conic_gradient_node_get_n_color_stops (GskRenderNode *node); +GDK_AVAILABLE_IN_ALL +const GskColorStop * gsk_conic_gradient_node_get_color_stops (GskRenderNode *node, + gsize *n_stops); + +GDK_AVAILABLE_IN_ALL GType gsk_radial_gradient_node_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL GskRenderNode * gsk_radial_gradient_node_new (const graphene_rect_t *bounds, diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index e5228d88c9..44fb918ddd 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -741,6 +741,327 @@ gsk_radial_gradient_node_get_end (GskRenderNode *node) return self->end; } +/*** GSK_CONIC_GRADIENT_NODE ***/ + +struct _GskConicGradientNode +{ + GskRenderNode render_node; + + graphene_point_t center; + float rotation; + + gsize n_stops; + GskColorStop *stops; +}; + +static void +gsk_conic_gradient_node_finalize (GskRenderNode *node) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + GskRenderNodeClass *parent_class = g_type_class_peek (g_type_parent (GSK_TYPE_CONIC_GRADIENT_NODE)); + + g_free (self->stops); + + parent_class->finalize (node); +} + +#define DEG_TO_RAD(x) ((x) * (G_PI / 180.f)) + +static void +_cairo_mesh_pattern_set_corner_rgba (cairo_pattern_t *pattern, + guint corner_num, + const GdkRGBA *rgba) +{ + cairo_mesh_pattern_set_corner_color_rgba (pattern, corner_num, rgba->red, rgba->green, rgba->blue, rgba->alpha); +} + +static void +project (double angle, + double radius, + double *x_out, + double *y_out) +{ + double x, y; + + x = radius * cos (angle); + y = radius * sin (angle); + if (copysign (x, 1.0) > copysign (y, 1.0)) + { + *x_out = copysign (radius, x); + *y_out = y * radius / copysign (x, 1.0); + } + else + { + *x_out = x * radius / copysign (y, 1.0); + *y_out = copysign (radius, y); + } +} + +static void +gsk_conic_gradient_node_add_patch (cairo_pattern_t *pattern, + float radius, + float start_angle, + const GdkRGBA *start_color, + float end_angle, + const GdkRGBA *end_color) +{ + double x, y; + + cairo_mesh_pattern_begin_patch (pattern); + + cairo_mesh_pattern_move_to (pattern, 0, 0); + project (start_angle, radius, &x, &y); + cairo_mesh_pattern_line_to (pattern, x, y); + project (end_angle, radius, &x, &y); + cairo_mesh_pattern_line_to (pattern, x, y); + cairo_mesh_pattern_line_to (pattern, 0, 0); + + _cairo_mesh_pattern_set_corner_rgba (pattern, 0, start_color); + _cairo_mesh_pattern_set_corner_rgba (pattern, 1, start_color); + _cairo_mesh_pattern_set_corner_rgba (pattern, 2, end_color); + _cairo_mesh_pattern_set_corner_rgba (pattern, 3, end_color); + + cairo_mesh_pattern_end_patch (pattern); +} + +static void +gdk_rgba_color_interpolate (GdkRGBA *dest, + const GdkRGBA *src1, + const GdkRGBA *src2, + double progress) +{ + double alpha = src1->alpha * (1.0 - progress) + src2->alpha * progress; + + dest->alpha = alpha; + if (alpha == 0) + { + dest->red = src1->red * (1.0 - progress) + src2->red * progress; + dest->green = src1->green * (1.0 - progress) + src2->green * progress; + dest->blue = src1->blue * (1.0 - progress) + src2->blue * progress; + } + else + { + dest->red = (src1->red * src1->alpha * (1.0 - progress) + src2->red * src2->alpha * progress) / alpha; + dest->green = (src1->green * src1->alpha * (1.0 - progress) + src2->green * src2->alpha * progress) / alpha; + dest->blue = (src1->blue * src1->alpha * (1.0 - progress) + src2->blue * src2->alpha * progress) / alpha; + } +} + +static void +gsk_conic_gradient_node_draw (GskRenderNode *node, + cairo_t *cr) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + cairo_pattern_t *pattern; + graphene_point_t corner; + float radius; + gsize i; + + pattern = cairo_pattern_create_mesh (); + graphene_rect_get_top_right (&node->bounds, &corner); + radius = graphene_point_distance (&self->center, &corner, NULL, NULL); + graphene_rect_get_bottom_right (&node->bounds, &corner); + radius = MAX (radius, graphene_point_distance (&self->center, &corner, NULL, NULL)); + graphene_rect_get_bottom_left (&node->bounds, &corner); + radius = MAX (radius, graphene_point_distance (&self->center, &corner, NULL, NULL)); + graphene_rect_get_top_left (&node->bounds, &corner); + radius = MAX (radius, graphene_point_distance (&self->center, &corner, NULL, NULL)); + + for (i = 0; i <= self->n_stops; i++) + { + GskColorStop *stop1 = &self->stops[MAX (i, 1) - 1]; + GskColorStop *stop2 = &self->stops[MIN (i, self->n_stops - 1)]; + double offset1 = i > 0 ? stop1->offset : 0; + double offset2 = i < self->n_stops ? stop2->offset : 1; + double start_angle, end_angle; + + offset1 = offset1 * 360 + self->rotation - 90; + offset2 = offset2 * 360 + self->rotation - 90; + + for (start_angle = offset1; start_angle < offset2; start_angle = end_angle) + { + GdkRGBA start_color, end_color; + end_angle = (floor (start_angle / 45) + 1) * 45; + end_angle = MIN (end_angle, offset2); + gdk_rgba_color_interpolate (&start_color, + &stop1->color, + &stop2->color, + (start_angle - offset1) / (offset2 - offset1)); + gdk_rgba_color_interpolate (&end_color, + &stop1->color, + &stop2->color, + (end_angle - offset1) / (offset2 - offset1)); + + gsk_conic_gradient_node_add_patch (pattern, + radius, + DEG_TO_RAD (start_angle), + &start_color, + DEG_TO_RAD (end_angle), + &end_color); + } + } + + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); + + gsk_cairo_rectangle (cr, &node->bounds); + cairo_translate (cr, self->center.x, self->center.y); + cairo_set_source (cr, pattern); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); +} + +static void +gsk_conic_gradient_node_diff (GskRenderNode *node1, + GskRenderNode *node2, + cairo_region_t *region) +{ + GskConicGradientNode *self1 = (GskConicGradientNode *) node1; + GskConicGradientNode *self2 = (GskConicGradientNode *) node2; + gsize i; + + if (!graphene_point_equal (&self1->center, &self2->center) || + self1->rotation != self2->rotation || + self1->n_stops != self2->n_stops) + { + gsk_render_node_diff_impossible (node1, node2, region); + return; + } + + for (i = 0; i < self1->n_stops; i++) + { + GskColorStop *stop1 = &self1->stops[i]; + GskColorStop *stop2 = &self2->stops[i]; + + if (stop1->offset != stop2->offset || + !gdk_rgba_equal (&stop1->color, &stop2->color)) + { + gsk_render_node_diff_impossible (node1, node2, region); + return; + } + } +} + +/** + * gsk_conic_gradient_node_new: + * @bounds: the bounds of the node + * @center: the center of the gradient + * @rotation: the rotation of the gradient in degrees + * @color_stops: (array length=n_color_stops): a pointer to an array of #GskColorStop defining the gradient + * The offsets of all color steps must be increasing. The first stop's offset must be >= 0 and the last + * stop's offset must be <= 1. + * @n_color_stops: the number of elements in @color_stops + * + * Creates a #GskRenderNode that draws a conic gradient. The conic gradient + * starts around @center in the direction of @rotation. A rotation of 0 means + * that the gradient points up. Color stops are then added clockwise. + * + * Returns: (transfer full) (type GskConicGradientNode): A new #GskRenderNode + */ +GskRenderNode * +gsk_conic_gradient_node_new (const graphene_rect_t *bounds, + const graphene_point_t *center, + float rotation, + const GskColorStop *color_stops, + gsize n_color_stops) +{ + GskConicGradientNode *self; + GskRenderNode *node; + gsize i; + + g_return_val_if_fail (bounds != NULL, NULL); + g_return_val_if_fail (center != NULL, NULL); + g_return_val_if_fail (color_stops != NULL, NULL); + g_return_val_if_fail (n_color_stops >= 2, NULL); + g_return_val_if_fail (color_stops[0].offset >= 0, NULL); + for (i = 1; i < n_color_stops; i++) + g_return_val_if_fail (color_stops[i].offset >= color_stops[i - 1].offset, NULL); + g_return_val_if_fail (color_stops[n_color_stops - 1].offset <= 1, NULL); + + self = gsk_render_node_alloc (GSK_CONIC_GRADIENT_NODE); + node = (GskRenderNode *) self; + + graphene_rect_init_from_rect (&node->bounds, bounds); + graphene_point_init_from_point (&self->center, center); + + self->rotation = rotation; + + self->n_stops = n_color_stops; + self->stops = g_malloc_n (n_color_stops, sizeof (GskColorStop)); + memcpy (self->stops, color_stops, n_color_stops * sizeof (GskColorStop)); + + return node; +} + +/** + * gsk_conic_gradient_node_get_n_color_stops: + * @node: (type GskConicGradientNode): a #GskRenderNode for a conic gradient + * + * Retrieves the number of color stops in the gradient. + * + * Returns: the number of color stops + */ +gsize +gsk_conic_gradient_node_get_n_color_stops (GskRenderNode *node) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + + return self->n_stops; +} + +/** + * gsk_conic_gradient_node_get_color_stops: + * @node: (type GskConicGradientNode): a #GskRenderNode for a conic gradient + * @n_stops: (out) (optional): the number of color stops in the returned array + * + * Retrieves the color stops in the gradient. + * + * Returns: (array length=n_stops): the color stops in the gradient + */ +const GskColorStop * +gsk_conic_gradient_node_get_color_stops (GskRenderNode *node, + gsize *n_stops) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + + if (n_stops != NULL) + *n_stops = self->n_stops; + + return self->stops; +} + +/** + * gsk_conic_gradient_node_get_center: + * @node: (type GskConicGradientNode): a #GskRenderNode for a conic gradient + * + * Retrieves the center pointer for the gradient. + * + * Returns: the center point for the gradient + */ +const graphene_point_t * +gsk_conic_gradient_node_get_center (GskRenderNode *node) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + + return &self->center; +} + +/** + * gsk_conic_gradient_node_get_rotation: + * @node: (type GskConicGradientNode): a #GskRenderNode for a conic gradient + * + * Retrieves the rotation for the gradient in degrees. + * + * Returns: the rotation for the gradient + */ +float +gsk_conic_gradient_node_get_rotation (GskRenderNode *node) +{ + GskConicGradientNode *self = (GskConicGradientNode *) node; + + return self->rotation; +} + /*** GSK_BORDER_NODE ***/ struct _GskBorderNode @@ -4752,6 +5073,7 @@ GSK_DEFINE_RENDER_NODE_TYPE (gsk_linear_gradient_node, GSK_LINEAR_GRADIENT_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_repeating_linear_gradient_node, GSK_REPEATING_LINEAR_GRADIENT_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_radial_gradient_node, GSK_RADIAL_GRADIENT_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_repeating_radial_gradient_node, GSK_REPEATING_RADIAL_GRADIENT_NODE) +GSK_DEFINE_RENDER_NODE_TYPE (gsk_conic_gradient_node, GSK_CONIC_GRADIENT_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_border_node, GSK_BORDER_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_texture_node, GSK_TEXTURE_NODE) GSK_DEFINE_RENDER_NODE_TYPE (gsk_inset_shadow_node, GSK_INSET_SHADOW_NODE) @@ -4888,6 +5210,22 @@ gsk_render_node_init_types_once (void) { const GskRenderNodeTypeInfo node_info = { + GSK_REPEATING_RADIAL_GRADIENT_NODE, + sizeof (GskRadialGradientNode), + NULL, + gsk_conic_gradient_node_finalize, + gsk_conic_gradient_node_draw, + NULL, + gsk_conic_gradient_node_diff, + }; + + GType node_type = gsk_render_node_type_register_static (I_("GskConicGradientNode"), &node_info); + gsk_render_node_types[GSK_CONIC_GRADIENT_NODE] = node_type; + } + + { + const GskRenderNodeTypeInfo node_info = + { GSK_BORDER_NODE, sizeof (GskBorderNode), NULL, diff --git a/gsk/gskrendernodeparser.c b/gsk/gskrendernodeparser.c index 61f94853a1..756147adb2 100644 --- a/gsk/gskrendernodeparser.c +++ b/gsk/gskrendernodeparser.c @@ -1071,6 +1071,40 @@ parse_repeating_radial_gradient_node (GtkCssParser *parser) } static GskRenderNode * +parse_conic_gradient_node (GtkCssParser *parser) +{ + graphene_rect_t bounds = GRAPHENE_RECT_INIT (0, 0, 50, 50); + graphene_point_t center = GRAPHENE_POINT_INIT (25, 25); + double rotation = 0.0; + GArray *stops = NULL; + const Declaration declarations[] = { + { "bounds", parse_rect, NULL, &bounds }, + { "center", parse_point, NULL, ¢er }, + { "rotation", parse_double, NULL, &rotation }, + { "stops", parse_stops, clear_stops, &stops }, + }; + GskRenderNode *result; + + parse_declarations (parser, declarations, G_N_ELEMENTS(declarations)); + if (stops == NULL) + { + GskColorStop from = { 0.0, GDK_RGBA("AAFF00") }; + GskColorStop to = { 1.0, GDK_RGBA("FF00CC") }; + + stops = g_array_new (FALSE, FALSE, sizeof (GskColorStop)); + g_array_append_val (stops, from); + g_array_append_val (stops, to); + } + + result = gsk_conic_gradient_node_new (&bounds, ¢er, rotation, + (GskColorStop *) stops->data, stops->len); + + g_array_free (stops, TRUE); + + return result; +} + +static GskRenderNode * parse_inset_shadow_node (GtkCssParser *parser) { GskRoundedRect outline = GSK_ROUNDED_RECT_INIT (0, 0, 50, 50); @@ -1797,6 +1831,7 @@ parse_node (GtkCssParser *parser, { "inset-shadow", parse_inset_shadow_node }, { "linear-gradient", parse_linear_gradient_node }, { "radial-gradient", parse_radial_gradient_node }, + { "conic-gradient", parse_conic_gradient_node }, { "opacity", parse_opacity_node }, { "outset-shadow", parse_outset_shadow_node }, { "repeat", parse_repeat_node }, @@ -2355,6 +2390,21 @@ render_node_print (Printer *p, } break; + case GSK_CONIC_GRADIENT_NODE: + { + start_node (p, "conic-gradient"); + + append_rect_param (p, "bounds", &node->bounds); + append_point_param (p, "center", gsk_conic_gradient_node_get_center (node)); + append_float_param (p, "rotation", gsk_conic_gradient_node_get_rotation (node), 0.0f); + + append_stops_param (p, "stops", gsk_conic_gradient_node_get_color_stops (node, NULL), + gsk_conic_gradient_node_get_n_color_stops (node)); + + end_node (p); + } + break; + case GSK_OPACITY_NODE: { start_node (p, "opacity"); diff --git a/gsk/vulkan/gskvulkanrenderpass.c b/gsk/vulkan/gskvulkanrenderpass.c index 103412487f..d81d38fa33 100644 --- a/gsk/vulkan/gskvulkanrenderpass.c +++ b/gsk/vulkan/gskvulkanrenderpass.c @@ -259,6 +259,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, case GSK_SHADOW_NODE: case GSK_RADIAL_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: default: FALLBACK ("Unsupported node '%s'", g_type_name_from_instance ((GTypeInstance *) node)); diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c index dd9a1de67e..7e07e4413a 100644 --- a/gtk/inspector/recorder.c +++ b/gtk/inspector/recorder.c @@ -133,6 +133,7 @@ create_list_model_for_render_node (GskRenderNode *node) case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_RADIAL_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: case GSK_BORDER_NODE: case GSK_INSET_SHADOW_NODE: case GSK_OUTSET_SHADOW_NODE: @@ -259,6 +260,8 @@ node_type_name (GskRenderNodeType type) return "Radial Gradient"; case GSK_REPEATING_RADIAL_GRADIENT_NODE: return "Repeating Radial Gradient"; + case GSK_CONIC_GRADIENT_NODE: + return "Conic Gradient"; case GSK_BORDER_NODE: return "Border"; case GSK_TEXTURE_NODE: @@ -308,6 +311,7 @@ node_name (GskRenderNode *node) case GSK_REPEATING_LINEAR_GRADIENT_NODE: case GSK_RADIAL_GRADIENT_NODE: case GSK_REPEATING_RADIAL_GRADIENT_NODE: + case GSK_CONIC_GRADIENT_NODE: case GSK_BORDER_NODE: case GSK_INSET_SHADOW_NODE: case GSK_OUTSET_SHADOW_NODE: @@ -729,6 +733,44 @@ populate_render_node_properties (GtkListStore *store, } break; + case GSK_CONIC_GRADIENT_NODE: + { + const graphene_point_t *center = gsk_conic_gradient_node_get_center (node); + const float rotation = gsk_conic_gradient_node_get_rotation (node); + const gsize n_stops = gsk_conic_gradient_node_get_n_color_stops (node); + const GskColorStop *stops = gsk_conic_gradient_node_get_color_stops (node, NULL); + gsize i; + GString *s; + GdkTexture *texture; + + tmp = g_strdup_printf ("%.2f, %.2f", center->x, center->y); + add_text_row (store, "Center", tmp); + g_free (tmp); + + tmp = g_strdup_printf ("%.2f", rotation); + add_text_row (store, "Rotation", tmp); + g_free (tmp); + + s = g_string_new (""); + for (i = 0; i < n_stops; i++) + { + tmp = gdk_rgba_to_string (&stops[i].color); + g_string_append_printf (s, "%.2f, %s\n", stops[i].offset, tmp); + g_free (tmp); + } + + texture = get_linear_gradient_texture (n_stops, stops); + gtk_list_store_insert_with_values (store, NULL, -1, + 0, "Color Stops", + 1, s->str, + 2, TRUE, + 3, texture, + -1); + g_string_free (s, TRUE); + g_object_unref (texture); + } + break; + case GSK_TEXT_NODE: { const PangoFont *font = gsk_text_node_get_font (node); |