css: Port border rendering

This commit is contained in:
Matthias Clasen 2024-06-16 17:05:31 -04:00
parent 12e67c644c
commit 8b3957f20f

View File

@ -270,11 +270,11 @@ gtk_border_image_render (GtkBorderImage *image,
source_width, source_height); source_width, source_height);
gtk_border_image_compute_slice_size (horizontal_slice, gtk_border_image_compute_slice_size (horizontal_slice,
source_width, source_width,
gtk_css_number_value_get (_gtk_css_border_value_get_left (image->slice), source_width), gtk_css_number_value_get (_gtk_css_border_value_get_left (image->slice), source_width),
gtk_css_number_value_get (_gtk_css_border_value_get_right (image->slice), source_width)); gtk_css_number_value_get (_gtk_css_border_value_get_right (image->slice), source_width));
gtk_border_image_compute_slice_size (vertical_slice, gtk_border_image_compute_slice_size (vertical_slice,
source_height, source_height,
gtk_css_number_value_get (_gtk_css_border_value_get_top (image->slice), source_height), gtk_css_number_value_get (_gtk_css_border_value_get_top (image->slice), source_height),
gtk_css_number_value_get (_gtk_css_border_value_get_bottom (image->slice), source_height)); gtk_css_number_value_get (_gtk_css_border_value_get_bottom (image->slice), source_height));
gtk_border_image_compute_border_size (horizontal_border, gtk_border_image_compute_border_size (horizontal_border,
@ -291,7 +291,7 @@ gtk_border_image_render (GtkBorderImage *image,
border_width[GTK_CSS_BOTTOM], border_width[GTK_CSS_BOTTOM],
_gtk_css_border_value_get_top (image->width), _gtk_css_border_value_get_top (image->width),
_gtk_css_border_value_get_bottom(image->width)); _gtk_css_border_value_get_bottom(image->width));
for (v = 0; v < 3; v++) for (v = 0; v < 3; v++)
{ {
if (vertical_slice[v].size == 0 || if (vertical_slice[v].size == 0 ||
@ -335,18 +335,18 @@ static void
snapshot_frame_fill (GtkSnapshot *snapshot, snapshot_frame_fill (GtkSnapshot *snapshot,
const GskRoundedRect *outline, const GskRoundedRect *outline,
const float border_width[4], const float border_width[4],
const GdkRGBA colors[4], const GdkColor colors[4],
guint hidden_side) guint hidden_side)
{ {
if (hidden_side) if (hidden_side)
{ {
GdkRGBA real_colors[4]; GdkColor real_colors[4];
guint i; guint i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
if (hidden_side & (1 << i)) if (hidden_side & (1 << i))
real_colors[i] = (GdkRGBA) { 0, 0, 0, 0 }; gdk_color_init_from_rgba (&real_colors[i], &(GdkRGBA) { 0, 0, 0, 0 });
else else
real_colors[i] = colors[i]; real_colors[i] = colors[i];
} }
@ -355,7 +355,7 @@ snapshot_frame_fill (GtkSnapshot *snapshot,
return; return;
} }
gtk_snapshot_append_border (snapshot, outline, border_width, colors); gtk_snapshot_append_border2 (snapshot, outline, border_width, colors);
} }
static void static void
@ -409,7 +409,7 @@ static void
render_frame_stroke (cairo_t *cr, render_frame_stroke (cairo_t *cr,
const GskRoundedRect *border_box, const GskRoundedRect *border_box,
const double border_width[4], const double border_width[4],
GdkRGBA colors[4], GdkColor colors[4],
guint hidden_side, guint hidden_side,
GtkBorderStyle stroke_style) GtkBorderStyle stroke_style)
{ {
@ -417,9 +417,9 @@ render_frame_stroke (cairo_t *cr,
GskRoundedRect stroke_box; GskRoundedRect stroke_box;
guint i; guint i;
different_colors = !gdk_rgba_equal (&colors[0], &colors[1]) || different_colors = !gdk_color_equal (&colors[0], &colors[1]) ||
!gdk_rgba_equal (&colors[0], &colors[2]) || !gdk_color_equal (&colors[0], &colors[2]) ||
!gdk_rgba_equal (&colors[0], &colors[3]); !gdk_color_equal (&colors[0], &colors[3]);
different_borders = border_width[0] != border_width[1] || different_borders = border_width[0] != border_width[1] ||
border_width[0] != border_width[2] || border_width[0] != border_width[2] ||
border_width[0] != border_width[3] ; border_width[0] != border_width[3] ;
@ -437,13 +437,13 @@ render_frame_stroke (cairo_t *cr,
/* FAST PATH: /* FAST PATH:
* Mostly expected to trigger for focus rectangles */ * Mostly expected to trigger for focus rectangles */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
length += _gtk_rounded_box_guess_length (&stroke_box, i); length += _gtk_rounded_box_guess_length (&stroke_box, i);
} }
gsk_rounded_rect_path (&stroke_box, cr); gsk_rounded_rect_path (&stroke_box, cr);
gdk_cairo_set_source_rgba (cr, &colors[0]); gdk_cairo_set_source_color (cr, &colors[0]);
set_stroke_style (cr, border_width[0], stroke_style, length); set_stroke_style (cr, border_width[0], stroke_style, length);
cairo_stroke (cr); cairo_stroke (cr);
} }
@ -480,7 +480,7 @@ render_frame_stroke (cairo_t *cr,
_gtk_rounded_box_path_side (&stroke_box, cr, i); _gtk_rounded_box_path_side (&stroke_box, cr, i);
gdk_cairo_set_source_rgba (cr, &colors[i]); gdk_cairo_set_source_color (cr, &colors[i]);
set_stroke_style (cr, set_stroke_style (cr,
border_width[i], border_width[i],
stroke_style, stroke_style,
@ -496,36 +496,36 @@ static void
snapshot_frame_stroke (GtkSnapshot *snapshot, snapshot_frame_stroke (GtkSnapshot *snapshot,
const GskRoundedRect *outline, const GskRoundedRect *outline,
const float border_width[4], const float border_width[4],
GdkRGBA colors[4], GdkColor colors[4],
guint hidden_side, guint hidden_side,
GtkBorderStyle stroke_style) GtkBorderStyle stroke_style)
{ {
double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] }; double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] };
cairo_t *cr; cairo_t *cr;
cr = gtk_snapshot_append_cairo (snapshot, cr = gtk_snapshot_append_cairo (snapshot, &outline->bounds);
&outline->bounds);
render_frame_stroke (cr, outline, double_width, colors, hidden_side, stroke_style); render_frame_stroke (cr, outline, double_width, colors, hidden_side, stroke_style);
cairo_destroy (cr); cairo_destroy (cr);
} }
static void static void
color_shade (const GdkRGBA *color, color_shade (const GdkColor *color,
double factor, double factor,
GdkRGBA *color_return) GdkColor *color_return)
{ {
GdkHSLA hsla; GdkColor c;
_gdk_hsla_init_from_rgba (&hsla, color); gdk_color_convert (&c, GDK_COLOR_STATE_HSL, color);
_gdk_hsla_shade (&hsla, &hsla, factor); c.values[1] = CLAMP (c.values[1] * factor, 0, 1);
_gdk_rgba_init_from_hsla (color_return, &hsla); c.values[2] = CLAMP (c.values[2] * factor, 0, 1);
gdk_color_convert (color_return, color->color_state, &c);
} }
static void static void
snapshot_border (GtkSnapshot *snapshot, snapshot_border (GtkSnapshot *snapshot,
const GskRoundedRect *border_box, const GskRoundedRect *border_box,
const float border_width[4], const float border_width[4],
GdkRGBA colors[4], GdkColor colors[4],
GtkBorderStyle border_style[4]) GtkBorderStyle border_style[4])
{ {
guint hidden_side = 0; guint hidden_side = 0;
@ -569,7 +569,7 @@ snapshot_border (GtkSnapshot *snapshot,
else else
dont_draw |= (1 << j); dont_draw |= (1 << j);
} }
snapshot_frame_stroke (snapshot, border_box, border_width, colors, dont_draw, border_style[i]); snapshot_frame_stroke (snapshot, border_box, border_width, colors, dont_draw, border_style[i]);
} }
break; break;
@ -585,12 +585,12 @@ snapshot_border (GtkSnapshot *snapshot,
hidden_side |= (1 << j); hidden_side |= (1 << j);
else else
dont_draw |= (1 << j); dont_draw |= (1 << j);
other_border[j] = border_width[j] / 3; other_border[j] = border_width[j] / 3;
} }
snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw); snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw);
other_box = *border_box; other_box = *border_box;
gsk_rounded_rect_shrink (&other_box, gsk_rounded_rect_shrink (&other_box,
2 * other_border[GTK_CSS_TOP], 2 * other_border[GTK_CSS_TOP],
@ -604,7 +604,7 @@ snapshot_border (GtkSnapshot *snapshot,
case GTK_BORDER_STYLE_RIDGE: case GTK_BORDER_STYLE_RIDGE:
{ {
GskRoundedRect other_box; GskRoundedRect other_box;
GdkRGBA other_colors[4]; GdkColor other_colors[4];
guint dont_draw = hidden_side; guint dont_draw = hidden_side;
float other_border[4]; float other_border[4];
@ -622,9 +622,9 @@ snapshot_border (GtkSnapshot *snapshot,
dont_draw |= (1 << j); dont_draw |= (1 << j);
other_border[j] = border_width[j] / 2; other_border[j] = border_width[j] / 2;
} }
snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw); snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw);
other_box = *border_box; other_box = *border_box;
gsk_rounded_rect_shrink (&other_box, gsk_rounded_rect_shrink (&other_box,
other_border[GTK_CSS_TOP], other_border[GTK_CSS_TOP],
@ -639,7 +639,7 @@ snapshot_border (GtkSnapshot *snapshot,
break; break;
} }
} }
snapshot_frame_fill (snapshot, border_box, border_width, colors, hidden_side); snapshot_frame_fill (snapshot, border_box, border_width, colors, hidden_side);
} }
@ -675,7 +675,7 @@ gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
else else
{ {
GtkBorderStyle border_style[4]; GtkBorderStyle border_style[4];
GdkRGBA colors[4]; GdkColor colors[4];
graphene_simd4f_t alpha_test_vector; graphene_simd4f_t alpha_test_vector;
/* Optimize the most common case of "This widget has no border" */ /* Optimize the most common case of "This widget has no border" */
@ -683,12 +683,12 @@ gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
gtk_css_boxes_get_padding_rect (boxes))) gtk_css_boxes_get_padding_rect (boxes)))
return; return;
colors[0] = *gtk_css_color_value_get_rgba (border->border_top_color ? border->border_top_color : boxes->style->core->color); gdk_color_init_from_css (&colors[0], gtk_css_color_value_get_color (border->border_top_color ? border->border_top_color : boxes->style->core->color));
colors[1] = *gtk_css_color_value_get_rgba (border->border_right_color ? border->border_right_color : boxes->style->core->color); gdk_color_init_from_css (&colors[1], gtk_css_color_value_get_color (border->border_right_color ? border->border_top_color : boxes->style->core->color));
colors[2] = *gtk_css_color_value_get_rgba (border->border_bottom_color ? border->border_bottom_color : boxes->style->core->color); gdk_color_init_from_css (&colors[2], gtk_css_color_value_get_color (border->border_bottom_color ? border->border_top_color : boxes->style->core->color));
colors[3] = *gtk_css_color_value_get_rgba (border->border_left_color ? border->border_left_color : boxes->style->core->color); gdk_color_init_from_css (&colors[3], gtk_css_color_value_get_color (border->border_left_color ? border->border_top_color : boxes->style->core->color));
alpha_test_vector = graphene_simd4f_init (colors[0].alpha, colors[1].alpha, colors[2].alpha, colors[3].alpha); alpha_test_vector = graphene_simd4f_init (colors[0].values[3], colors[1].values[3], colors[2].values[3], colors[3].values[3]);
if (graphene_simd4f_is_zero4 (alpha_test_vector)) if (graphene_simd4f_is_zero4 (alpha_test_vector))
return; return;
@ -703,16 +703,17 @@ gtk_css_style_snapshot_border (GtkCssBoxes *boxes,
border_width[3] = gtk_css_number_value_get (border->border_left_width, 100); border_width[3] = gtk_css_number_value_get (border->border_left_width, 100);
gtk_snapshot_push_debug (snapshot, "CSS border"); gtk_snapshot_push_debug (snapshot, "CSS border");
if (border_style[0] <= GTK_BORDER_STYLE_SOLID && if (border_style[0] <= GTK_BORDER_STYLE_SOLID &&
border_style[1] <= GTK_BORDER_STYLE_SOLID && border_style[1] <= GTK_BORDER_STYLE_SOLID &&
border_style[2] <= GTK_BORDER_STYLE_SOLID && border_style[2] <= GTK_BORDER_STYLE_SOLID &&
border_style[3] <= GTK_BORDER_STYLE_SOLID) border_style[3] <= GTK_BORDER_STYLE_SOLID)
{ {
/* The most common case of a solid border */ /* The most common case of a solid border */
gtk_snapshot_append_border (snapshot, gtk_snapshot_append_border2 (snapshot,
gtk_css_boxes_get_border_box (boxes), gtk_css_boxes_get_border_box (boxes),
border_width, border_width,
colors); colors);
} }
else else
{ {
@ -733,15 +734,17 @@ gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
GtkCssOutlineValues *outline = boxes->style->outline; GtkCssOutlineValues *outline = boxes->style->outline;
GtkBorderStyle border_style[4]; GtkBorderStyle border_style[4];
float border_width[4]; float border_width[4];
GdkRGBA colors[4]; GdkColor colors[4];
border_style[0] = _gtk_css_border_style_value_get (outline->outline_style); border_style[0] = _gtk_css_border_style_value_get (outline->outline_style);
if (border_style[0] != GTK_BORDER_STYLE_NONE) if (border_style[0] != GTK_BORDER_STYLE_NONE)
{ {
const GdkRGBA *color = gtk_css_color_value_get_rgba (outline->outline_color ? GdkColor color;
outline->outline_color :
boxes->style->core->color); gdk_color_init_from_css (&color, gtk_css_color_value_get_color (outline->outline_color ?
if (gdk_rgba_is_clear (color)) outline->outline_color :
boxes->style->core->color));
if (gdk_color_is_clear (&color))
return; return;
border_width[0] = gtk_css_number_value_get (outline->outline_width, 100); border_width[0] = gtk_css_number_value_get (outline->outline_width, 100);
@ -751,7 +754,7 @@ gtk_css_style_snapshot_outline (GtkCssBoxes *boxes,
border_style[1] = border_style[2] = border_style[3] = border_style[0]; border_style[1] = border_style[2] = border_style[3] = border_style[0];
border_width[3] = border_width[2] = border_width[1] = border_width[0]; border_width[3] = border_width[2] = border_width[1] = border_width[0];
colors[0] = colors[1] = colors[2] = colors[3] = *color; colors[0] = colors[1] = colors[2] = colors[3] = color;
gtk_snapshot_push_debug (snapshot, "CSS outline"); gtk_snapshot_push_debug (snapshot, "CSS outline");
snapshot_border (snapshot, snapshot_border (snapshot,