diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkrenderborder.c | 209 | ||||
-rw-r--r-- | gtk/gtkrenderborderprivate.h | 4 | ||||
-rw-r--r-- | gtk/inspector/gtktreemodelrendernode.c | 1 |
3 files changed, 191 insertions, 23 deletions
diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c index 5a17516499..7f739c3d64 100644 --- a/gtk/gtkrenderborder.c +++ b/gtk/gtkrenderborder.c @@ -406,6 +406,44 @@ render_frame_fill (cairo_t *cr, } static void +snapshot_frame_fill (GtkSnapshot *snapshot, + const GskRoundedRect *outline, + const float border_width[4], + const GdkRGBA colors[4], + guint hidden_side) +{ + GskRoundedRect offset_outline; + GskRenderNode *node; + double off_x, off_y; + + if (hidden_side) + { + GdkRGBA real_colors[4]; + guint i; + + for (i = 0; i < 4; i++) + { + if (hidden_side & (1 << i)) + real_colors[i] = (GdkRGBA) { 0, 0, 0, 0 }; + else + real_colors[i] = colors[i]; + } + + snapshot_frame_fill (snapshot, outline, border_width, real_colors, 0); + return; + } + + gtk_snapshot_get_offset (snapshot, &off_x, &off_y); + gsk_rounded_rect_init_copy (&offset_outline, outline); + gsk_rounded_rect_offset (&offset_outline, off_x, off_y); + + node = gsk_border_node_new (&offset_outline, border_width, colors); + gsk_render_node_set_name (node, "Border"); + gtk_snapshot_append_node (snapshot, node); + gsk_render_node_unref (node); +} + +static void set_stroke_style (cairo_t *cr, double line_width, GtkBorderStyle style, @@ -540,6 +578,24 @@ render_frame_stroke (cairo_t *cr, } static void +snapshot_frame_stroke (GtkSnapshot *snapshot, + GskRoundedRect *outline, + const float border_width[4], + GdkRGBA colors[4], + guint hidden_side, + GtkBorderStyle stroke_style) +{ + double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] }; + cairo_t *cr; + + cr = gtk_snapshot_append_cairo_node (snapshot, + &outline->bounds, + "BorderStroke"); + render_frame_stroke (cr, outline, double_width, colors, hidden_side, stroke_style); + cairo_destroy (cr); +} + +static void color_shade (const GdkRGBA *color, gdouble factor, GdkRGBA *color_return) @@ -679,6 +735,128 @@ render_border (cairo_t *cr, cairo_restore (cr); } +static void +snapshot_border (GtkSnapshot *snapshot, + GskRoundedRect *border_box, + const float border_width[4], + GdkRGBA colors[4], + GtkBorderStyle border_style[4]) +{ + guint hidden_side = 0; + guint i, j; + + for (i = 0; i < 4; i++) + { + if (hidden_side & (1 << i)) + continue; + + /* NB: code below divides by this value */ + /* a border smaller than this will not noticably modify + * pixels on screen, and since we don't compare with 0, + * we'll use this value */ + if (border_width[i] < 1.0 / 1024) + continue; + + switch (border_style[i]) + { + case GTK_BORDER_STYLE_NONE: + case GTK_BORDER_STYLE_HIDDEN: + case GTK_BORDER_STYLE_SOLID: + break; + case GTK_BORDER_STYLE_INSET: + if (i == 1 || i == 2) + color_shade (&colors[i], 1.8, &colors[i]); + break; + case GTK_BORDER_STYLE_OUTSET: + if (i == 0 || i == 3) + color_shade (&colors[i], 1.8, &colors[i]); + break; + case GTK_BORDER_STYLE_DOTTED: + case GTK_BORDER_STYLE_DASHED: + { + guint dont_draw = hidden_side; + + for (j = 0; j < 4; j++) + { + if (border_style[j] == border_style[i]) + hidden_side |= (1 << j); + else + dont_draw |= (1 << j); + } + + snapshot_frame_stroke (snapshot, border_box, border_width, colors, dont_draw, border_style[i]); + } + break; + case GTK_BORDER_STYLE_DOUBLE: + { + GskRoundedRect other_box; + float other_border[4]; + guint dont_draw = hidden_side; + + for (j = 0; j < 4; j++) + { + if (border_style[j] == GTK_BORDER_STYLE_DOUBLE) + hidden_side |= (1 << j); + else + dont_draw |= (1 << j); + + other_border[j] = border_width[j] / 3; + } + + snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw); + + other_box = *border_box; + gsk_rounded_rect_shrink (&other_box, + 2 * other_border[GTK_CSS_TOP], + 2 * other_border[GTK_CSS_RIGHT], + 2 * other_border[GTK_CSS_BOTTOM], + 2 * other_border[GTK_CSS_LEFT]); + snapshot_frame_fill (snapshot, &other_box, other_border, colors, dont_draw); + } + break; + case GTK_BORDER_STYLE_GROOVE: + case GTK_BORDER_STYLE_RIDGE: + { + GskRoundedRect other_box; + GdkRGBA other_colors[4]; + guint dont_draw = hidden_side; + float other_border[4]; + + for (j = 0; j < 4; j++) + { + other_colors[j] = colors[j]; + if ((j == 0 || j == 3) ^ (border_style[j] == GTK_BORDER_STYLE_RIDGE)) + color_shade (&other_colors[j], 1.8, &other_colors[j]); + else + color_shade (&colors[j], 1.8, &colors[j]); + if (border_style[j] == GTK_BORDER_STYLE_GROOVE || + border_style[j] == GTK_BORDER_STYLE_RIDGE) + hidden_side |= (1 << j); + else + dont_draw |= (1 << j); + other_border[j] = border_width[j] / 2; + } + + snapshot_frame_fill (snapshot, border_box, other_border, colors, dont_draw); + + other_box = *border_box; + gsk_rounded_rect_shrink (&other_box, + other_border[GTK_CSS_TOP], + other_border[GTK_CSS_RIGHT], + other_border[GTK_CSS_BOTTOM], + other_border[GTK_CSS_LEFT]); + snapshot_frame_fill (snapshot, &other_box, other_border, other_colors, dont_draw); + } + break; + default: + g_assert_not_reached (); + break; + } + } + + snapshot_frame_fill (snapshot, border_box, border_width, colors, hidden_side); +} + gboolean gtk_css_style_render_has_border (GtkCssStyle *style) { @@ -744,13 +922,13 @@ gtk_css_style_render_border (GtkCssStyle *style, void gtk_css_style_snapshot_border (GtkCssStyle *style, - GtkSnapshot *state, + GtkSnapshot *snapshot, gdouble width, gdouble height, GtkJunctionSides junction) { GtkBorderImage border_image; - double border_width[4]; + float border_width[4]; graphene_rect_t bounds; cairo_t *cr; @@ -763,10 +941,12 @@ gtk_css_style_snapshot_border (GtkCssStyle *style, if (gtk_border_image_init (&border_image, style)) { - cr = gtk_snapshot_append_cairo_node (state, + double double_width[4] = { border_width[0], border_width[1], border_width[2], border_width[3] }; + + cr = gtk_snapshot_append_cairo_node (snapshot, &bounds, "Border Image"); - gtk_border_image_render (&border_image, border_width, cr, 0, 0, width, height); + gtk_border_image_render (&border_image, double_width, cr, 0, 0, width, height); cairo_destroy (cr); } else @@ -782,10 +962,6 @@ gtk_css_style_snapshot_border (GtkCssStyle *style, border_width[3] == 0) return; - cr = gtk_snapshot_append_cairo_node (state, - &bounds, - "Border"); - border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE)); border_style[1] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE)); border_style[2] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE)); @@ -799,9 +975,7 @@ gtk_css_style_snapshot_border (GtkCssStyle *style, _gtk_rounded_box_init_rect (&border_box, 0, 0, width, height); _gtk_rounded_box_apply_border_radius_for_style (&border_box, style, junction); - render_border (cr, &border_box, border_width, colors, border_style); - - cairo_destroy (cr); + snapshot_border (snapshot, &border_box, border_width, colors, border_style); } } @@ -904,20 +1078,19 @@ gtk_css_style_render_outline (GtkCssStyle *style, void gtk_css_style_snapshot_outline (GtkCssStyle *style, - GtkSnapshot *state, + GtkSnapshot *snapshot, gdouble width, gdouble height) { GtkBorderStyle border_style[4]; GskRoundedRect border_box; - double border_width[4]; + float border_width[4]; GdkRGBA colors[4]; border_style[0] = _gtk_css_border_style_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_STYLE)); if (border_style[0] != GTK_BORDER_STYLE_NONE) { cairo_rectangle_t rect; - cairo_t *cr; compute_outline_rect (style, 0, 0, width, height, &rect); @@ -930,13 +1103,7 @@ gtk_css_style_snapshot_outline (GtkCssStyle *style, _gtk_rounded_box_init_rect (&border_box, rect.x, rect.y, rect.width, rect.height); _gtk_rounded_box_apply_outline_radius_for_style (&border_box, style, GTK_JUNCTION_NONE); - cr = gtk_snapshot_append_cairo_node (state, - &GRAPHENE_RECT_INIT (rect.x, rect.y, rect.width, rect.height), - "Outline"); - - render_border (cr, &border_box, border_width, colors, border_style); - - cairo_destroy (cr); + snapshot_border (snapshot, &border_box, border_width, colors, border_style); } } diff --git a/gtk/gtkrenderborderprivate.h b/gtk/gtkrenderborderprivate.h index f89cdcb600..4de9d6da35 100644 --- a/gtk/gtkrenderborderprivate.h +++ b/gtk/gtkrenderborderprivate.h @@ -44,7 +44,7 @@ gboolean gtk_css_style_render_border_get_clip (GtkCssStyle gdouble height, GdkRectangle *out_clip) G_GNUC_WARN_UNUSED_RESULT; void gtk_css_style_snapshot_border (GtkCssStyle *style, - GtkSnapshot *state, + GtkSnapshot *snapshot, gdouble width, gdouble height, GtkJunctionSides junction); @@ -57,7 +57,7 @@ void gtk_css_style_render_outline (GtkCssStyle gdouble width, gdouble height); void gtk_css_style_snapshot_outline (GtkCssStyle *style, - GtkSnapshot *state, + GtkSnapshot *snapshot, gdouble width, gdouble height); gboolean gtk_css_style_render_outline_get_clip (GtkCssStyle *style, diff --git a/gtk/inspector/gtktreemodelrendernode.c b/gtk/inspector/gtktreemodelrendernode.c index fff0a06f41..96b0d944e9 100644 --- a/gtk/inspector/gtktreemodelrendernode.c +++ b/gtk/inspector/gtktreemodelrendernode.c @@ -527,6 +527,7 @@ append_node (GtkTreeModelRenderNode *nodemodel, case GSK_COLOR_NODE: case GSK_LINEAR_GRADIENT_NODE: case GSK_REPEATING_LINEAR_GRADIENT_NODE: + case GSK_BORDER_NODE: /* no children */ break; |