[gtk+] themingengine: Draw border with GtkRoundedBox
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] themingengine: Draw border with GtkRoundedBox
- Date: Sat, 11 Jun 2011 07:31:02 +0000 (UTC)
commit 40dfcfcbc48be481bb9c9048af805f3f6e115dbf
Author: Benjamin Otte <otte redhat com>
Date: Sat Jun 11 06:13:00 2011 +0200
themingengine: Draw border with GtkRoundedBox
gtk/gtkthemingengine.c | 344 +++++-------------------------------------------
1 files changed, 35 insertions(+), 309 deletions(-)
---
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index b35119d..67c790a 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -1373,132 +1373,6 @@ color_shade (const GdkRGBA *color,
}
static void
-_cairo_ellipsis (cairo_t *cr,
- double xc, double yc,
- double xradius, double yradius,
- double angle1, double angle2)
-{
- if (xradius <= 0.0 || yradius <= 0.0)
- {
- /* stolen from cairo sources */
- cairo_line_to (cr, xc, yc); /* might become a move_to */
- cairo_line_to (cr, xc, yc);
- return;
- }
-
- cairo_save (cr);
- cairo_translate (cr, xc, yc);
- cairo_scale (cr, xradius, yradius);
- cairo_arc (cr, 0, 0, 1.0, angle1, angle2);
- cairo_restore (cr);
-}
-
-static void
-_cairo_round_rectangle_sides (cairo_t *cr,
- const GtkCssBorderRadius *border_radius,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height,
- guint sides)
-{
- cairo_new_sub_path (cr);
-
- if (sides & SIDE_RIGHT)
- {
- _cairo_ellipsis (cr,
- x + width - border_radius->top_right.horizontal,
- y + border_radius->top_right.vertical,
- border_radius->top_right.horizontal,
- border_radius->top_right.vertical,
- - G_PI / 4, 0);
- _cairo_ellipsis (cr,
- x + width - border_radius->bottom_right.horizontal,
- y + height - border_radius->bottom_right.vertical,
- border_radius->bottom_right.horizontal,
- border_radius->bottom_right.vertical,
- 0, G_PI / 4);
- }
-
- if (sides & SIDE_BOTTOM)
- {
- _cairo_ellipsis (cr,
- x + width - border_radius->bottom_right.horizontal,
- y + height - border_radius->bottom_right.vertical,
- border_radius->bottom_right.horizontal,
- border_radius->bottom_right.vertical,
- G_PI / 4, G_PI / 2);
- _cairo_ellipsis (cr,
- x + border_radius->bottom_left.horizontal,
- y + height - border_radius->bottom_left.vertical,
- border_radius->bottom_left.horizontal,
- border_radius->bottom_left.vertical,
- G_PI / 2, 3 * (G_PI / 4));
- }
- else
- cairo_move_to (cr, x, y + height);
-
- if (sides & SIDE_LEFT)
- {
- _cairo_ellipsis (cr,
- x + border_radius->bottom_left.horizontal,
- y + height - border_radius->bottom_left.vertical,
- border_radius->bottom_left.horizontal,
- border_radius->bottom_left.vertical,
- 3 * (G_PI / 4), G_PI);
- _cairo_ellipsis (cr,
- x + border_radius->top_left.horizontal,
- y + border_radius->top_left.vertical,
- border_radius->top_left.horizontal,
- border_radius->top_left.vertical,
- G_PI, G_PI + G_PI / 4);
- }
- else
- cairo_move_to (cr, x, y);
-
- if (sides & SIDE_TOP)
- {
- _cairo_ellipsis (cr,
- x + border_radius->top_left.horizontal,
- y + border_radius->top_left.vertical,
- border_radius->top_left.horizontal,
- border_radius->top_left.vertical,
- 5 * (G_PI / 4), 3 * (G_PI / 2));
- _cairo_ellipsis (cr,
- x + width - border_radius->top_right.horizontal,
- y + border_radius->top_right.vertical,
- border_radius->top_right.horizontal,
- border_radius->top_right.vertical,
- 3 * (G_PI / 2), - G_PI / 4);
- }
-}
-
-static void
-_cairo_uneven_frame (cairo_t *cr,
- const GtkCssBorderRadius *border_radius,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height,
- GtkBorder *border)
-{
- cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
- cairo_set_line_width (cr, 1);
-
- _cairo_round_rectangle_sides (cr, border_radius,
- x, y,
- width, height,
- SIDE_ALL);
-
- _cairo_round_rectangle_sides (cr, border_radius,
- x + border->left,
- y + border->top,
- width - border->left - border->right,
- height - border->top - border->bottom,
- SIDE_ALL);
-}
-
-static void
render_background_internal (GtkThemingEngine *engine,
cairo_t *cr,
gdouble x,
@@ -1746,42 +1620,6 @@ gtk_theming_engine_render_background (GtkThemingEngine *engine,
junction);
}
-/* Renders the small triangle on corners so
- * frames with 0 radius have a 3D-like effect
- */
-static void
-_cairo_corner_triangle (cairo_t *cr,
- gdouble x,
- gdouble y,
- gint size)
-{
- gint i;
-
- cairo_move_to (cr, x + 0.5, y + size - 0.5);
- cairo_line_to (cr, x + size - 0.5, y + size - 0.5);
- cairo_line_to (cr, x + size - 0.5, y + 0.5);
-
- for (i = 1; i < size - 1; i++)
- {
- cairo_move_to (cr, x + size - 0.5, y + i + 0.5);
- cairo_line_to (cr, x + (size - i) - 0.5, y + i + 0.5);
- }
-}
-
-static void
-gtk_themeing_engine_apply_junction_to_radius (GtkCssBorderRadius *border_radius,
- GtkJunctionSides junction)
-{
- if (junction & GTK_JUNCTION_CORNER_TOPLEFT)
- border_radius->top_left.horizontal = border_radius->top_left.vertical = 0;
- if (junction & GTK_JUNCTION_CORNER_TOPRIGHT)
- border_radius->top_right.horizontal = border_radius->top_right.vertical = 0;
- if (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT)
- border_radius->bottom_right.horizontal = border_radius->bottom_right.vertical = 0;
- if (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT)
- border_radius->bottom_left.horizontal = border_radius->bottom_left.vertical = 0;
-}
-
static void
render_frame_internal (GtkThemingEngine *engine,
cairo_t *cr,
@@ -1796,14 +1634,11 @@ render_frame_internal (GtkThemingEngine *engine,
GdkRGBA lighter;
GdkRGBA border_color;
GtkBorderStyle border_style;
- gint border_width;
- GtkCssBorderCornerRadius *top_left_radius, *top_right_radius;
- GtkCssBorderCornerRadius *bottom_left_radius, *bottom_right_radius;
- GtkCssBorderRadius border_radius = { { 0, }, };
- gdouble progress, d1, d2;
+ GtkRoundedBox border_box, padding_box;
+ gdouble progress;
gboolean running;
GtkBorder border;
- gboolean uniform_border;
+ double min_size;
state = gtk_theming_engine_get_state (engine);
@@ -1812,35 +1647,9 @@ render_frame_internal (GtkThemingEngine *engine,
gtk_theming_engine_get (engine, state,
"border-style", &border_style,
- /* Can't use border-radius as it's an int for
- * backwards compat */
- "border-top-left-radius", &top_left_radius,
- "border-top-right-radius", &top_right_radius,
- "border-bottom-right-radius", &bottom_right_radius,
- "border-bottom-left-radius", &bottom_left_radius,
NULL);
- if (top_left_radius)
- border_radius.top_left = *top_left_radius;
- g_free (top_left_radius);
- if (top_right_radius)
- border_radius.top_right = *top_right_radius;
- g_free (top_right_radius);
- if (bottom_right_radius)
- border_radius.bottom_right = *bottom_right_radius;
- g_free (bottom_right_radius);
- if (bottom_left_radius)
- border_radius.bottom_left = *bottom_left_radius;
- g_free (bottom_left_radius);
-
- gtk_themeing_engine_apply_junction_to_radius (&border_radius, junction);
-
running = gtk_theming_engine_state_is_running (engine, GTK_STATE_PRELIGHT, &progress);
- border_width = MIN (MIN (border.top, border.bottom),
- MIN (border.left, border.right));
- uniform_border = (border.top == border.bottom &&
- border.top == border.left &&
- border.top == border.right);
if (running)
{
@@ -1865,142 +1674,59 @@ render_frame_internal (GtkThemingEngine *engine,
cairo_save (cr);
- color_shade (&border_color, 1.8, &lighter);
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+
+ _gtk_rounded_box_init_rect (&border_box, 0, 0, width, height);
+ _gtk_rounded_box_apply_border_radius (&border_box, engine, state, junction);
+ padding_box = border_box;
+ _gtk_rounded_box_shrink (&padding_box, border.top, border.right, border.bottom, border.left);
switch (border_style)
{
case GTK_BORDER_STYLE_NONE:
break;
case GTK_BORDER_STYLE_SOLID:
- cairo_set_line_width (cr, border_width);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
-
gdk_cairo_set_source_rgba (cr, &border_color);
- cairo_save (cr);
- _cairo_uneven_frame (cr, &border_radius,
- x, y, width, height,
- &border);
+ _gtk_rounded_box_path (&border_box, cr);
+ _gtk_rounded_box_path (&padding_box, cr);
cairo_fill (cr);
- cairo_restore (cr);
break;
case GTK_BORDER_STYLE_INSET:
case GTK_BORDER_STYLE_OUTSET:
- cairo_set_line_width (cr, border_width);
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
-
- if (border_width > 1)
- {
- d1 = (gdouble) border_width / 2;
- d2 = border_width;
- }
- else
- {
- d1 = 0.5;
- d2 = 1;
- }
+ color_shade (&border_color, 1.8, &lighter);
+ min_size = MIN (width, height) / 2;
cairo_save (cr);
- if (uniform_border)
- {
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &lighter);
- else
- gdk_cairo_set_source_rgba (cr, &border_color);
-
- _cairo_round_rectangle_sides (cr, &border_radius,
- x + d1, y + d1,
- width - d2, height - d2,
- (SIDE_BOTTOM | SIDE_RIGHT) & ~(hidden_side));
- cairo_stroke (cr);
-
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &border_color);
- else
- gdk_cairo_set_source_rgba (cr, &lighter);
+ _gtk_rounded_box_path (&border_box, cr);
+ _gtk_rounded_box_path (&padding_box, cr);
+ cairo_clip (cr);
- _cairo_round_rectangle_sides (cr, &border_radius,
- x + d1, y + d1,
- width - d2, height - d2,
- (SIDE_TOP | SIDE_LEFT) & ~(hidden_side));
- cairo_stroke (cr);
- }
+ if (border_style == GTK_BORDER_STYLE_INSET)
+ gdk_cairo_set_source_rgba (cr, &border_color);
else
- {
- cairo_save (cr);
-
- /* Bottom/right */
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &lighter);
- else
- gdk_cairo_set_source_rgba (cr, &border_color);
-
- _cairo_uneven_frame (cr, &border_radius,
- x, y, width, height,
- &border);
- cairo_fill (cr);
-
- /* Top/left */
- cairo_move_to (cr, x, y);
- cairo_line_to (cr, x + width, y);
- cairo_line_to (cr,
- x + width - border.right - border_radius.top_right.horizontal / 2,
- y + border.top + border_radius.top_right.vertical / 2);
- cairo_line_to (cr,
- x + width - border.right - border_radius.bottom_right.horizontal / 2,
- y + height - border.bottom - border_radius.bottom_right.vertical / 2);
- cairo_line_to (cr,
- x + border.left + border_radius.bottom_left.horizontal / 2,
- y + height - border.bottom - border_radius.bottom_left.vertical / 2);
- cairo_line_to (cr, x, y + height);
- cairo_close_path (cr);
-
- cairo_clip (cr);
-
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &border_color);
- else
- gdk_cairo_set_source_rgba (cr, &lighter);
-
- _cairo_uneven_frame (cr, &border_radius,
- x, y, width, height,
- &border);
- cairo_fill (cr);
- cairo_restore (cr);
- }
-
- if (border_width > 1)
- {
- /* overprint top/right and bottom/left corner
- * triangles if there are square corners there,
- * to give the box a 3D-like appearance.
- */
- cairo_save (cr);
-
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &lighter);
- else
- gdk_cairo_set_source_rgba (cr, &border_color);
-
- cairo_set_line_width (cr, 1);
-
- if ((junction & GTK_JUNCTION_CORNER_TOPRIGHT) != 0)
- _cairo_corner_triangle (cr,
- x + width - border_width, y,
- border_width);
+ gdk_cairo_set_source_rgba (cr, &lighter);
+ cairo_move_to (cr, 0, 0);
+ cairo_line_to (cr, 0, height);
+ cairo_line_to (cr, min_size, height - min_size);
+ cairo_line_to (cr, width - min_size, min_size);
+ cairo_line_to (cr, width, 0);
+ cairo_fill (cr);
- if ((junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) != 0)
- _cairo_corner_triangle (cr,
- x, y + height - border_width,
- border_width);
- cairo_stroke (cr);
- cairo_restore (cr);
- }
+ if (border_style == GTK_BORDER_STYLE_INSET)
+ gdk_cairo_set_source_rgba (cr, &lighter);
+ else
+ gdk_cairo_set_source_rgba (cr, &border_color);
+ cairo_move_to (cr, width, height);
+ cairo_line_to (cr, 0, height);
+ cairo_line_to (cr, min_size, height - min_size);
+ cairo_line_to (cr, width - min_size, min_size);
+ cairo_line_to (cr, width, 0);
+ cairo_fill (cr);
cairo_restore (cr);
- break;
}
cairo_restore (cr);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]