[gtk+] theming: Implement non-uniform border-width in the theming engine.
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] theming: Implement non-uniform border-width in the theming engine.
- Date: Tue, 29 Mar 2011 17:41:08 +0000 (UTC)
commit ae22476931519c8f3846a3995da77b53ef90e38c
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Mar 29 00:59:49 2011 +0200
theming: Implement non-uniform border-width in the theming engine.
The border-width CSS parameter takes up to 4 values, but it was
being ignored by the theming engine until now.
gtk/gtkthemingengine.c | 155 +++++++++++++++++++++++++++++++++++++-----------
1 files changed, 119 insertions(+), 36 deletions(-)
---
diff --git a/gtk/gtkthemingengine.c b/gtk/gtkthemingengine.c
index a207b32..10bb949 100644
--- a/gtk/gtkthemingengine.c
+++ b/gtk/gtkthemingengine.c
@@ -1455,6 +1455,32 @@ _cairo_round_rectangle_sides (cairo_t *cr,
}
}
+static void
+_cairo_uneven_frame (cairo_t *cr,
+ gdouble radius,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ GtkBorder *border,
+ GtkJunctionSides junction)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_line_width (cr, 1);
+
+ _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ x, y,
+ width, height,
+ SIDE_ALL, junction);
+
+ _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ x + border->left,
+ y + border->top,
+ width - border->left - border->right,
+ height - border->top - border->bottom,
+ SIDE_ALL, junction);
+}
+
/* Set the appropriate matrix for
* patterns coming from the style context
*/
@@ -1836,6 +1862,7 @@ render_frame_internal (GtkThemingEngine *engine,
gdouble progress, d1, d2, m;
gboolean running;
GtkBorder border;
+ gboolean uniform_border;
state = gtk_theming_engine_get_state (engine);
@@ -1850,6 +1877,9 @@ render_frame_internal (GtkThemingEngine *engine,
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)
{
@@ -1884,28 +1914,41 @@ render_frame_internal (GtkThemingEngine *engine,
cairo_set_line_width (cr, border_width);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
- if (border_width > 1)
+ gdk_cairo_set_source_rgba (cr, &border_color);
+
+ if (uniform_border)
{
- x += (gdouble) border_width / 2;
- y += (gdouble) border_width / 2;
- width -= border_width;
- height -= border_width;
+ if (border_width > 1)
+ {
+ x += (gdouble) border_width / 2;
+ y += (gdouble) border_width / 2;
+ width -= border_width;
+ height -= border_width;
+ }
+ else if (border_width == 1)
+ {
+ x += 0.5;
+ y += 0.5;
+ width -= 1;
+ height -= 1;
+ }
+
+ _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ x, y, width, height,
+ SIDE_ALL & ~(hidden_side),
+ junction);
+ cairo_stroke (cr);
}
- else if (border_width == 1)
+ else
{
- x += 0.5;
- y += 0.5;
- width -= 1;
- height -= 1;
+ cairo_save (cr);
+ _cairo_uneven_frame (cr, (gdouble) radius,
+ x, y, width, height,
+ &border, junction);
+ cairo_fill (cr);
+ cairo_restore (cr);
}
- _cairo_round_rectangle_sides (cr, (gdouble) radius,
- x, y, width, height,
- SIDE_ALL & ~(hidden_side),
- junction);
- gdk_cairo_set_source_rgba (cr, &border_color);
- cairo_stroke (cr);
-
break;
case GTK_BORDER_STYLE_INSET:
case GTK_BORDER_STYLE_OUTSET:
@@ -1932,29 +1975,69 @@ render_frame_internal (GtkThemingEngine *engine,
m = MIN (width, height);
m /= 2;
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &lighter);
- else
- gdk_cairo_set_source_rgba (cr, &border_color);
+ 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, (gdouble) radius,
- x + d1, y + d1,
- width - d2, height - d2,
- (SIDE_BOTTOM | SIDE_RIGHT) & ~(hidden_side),
- junction);
- cairo_stroke (cr);
+ _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ x + d1, y + d1,
+ width - d2, height - d2,
+ (SIDE_BOTTOM | SIDE_RIGHT) & ~(hidden_side),
+ junction);
+ 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);
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, &border_color);
+ _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ x + d1, y + d1,
+ width - d2, height - d2,
+ (SIDE_TOP | SIDE_LEFT) & ~(hidden_side),
+ junction);
+ cairo_stroke (cr);
+ }
else
- gdk_cairo_set_source_rgba (cr, &lighter);
+ {
+ cairo_save (cr);
- _cairo_round_rectangle_sides (cr, (gdouble) radius,
- x + d1, y + d1,
- width - d2, height - d2,
- (SIDE_TOP | SIDE_LEFT) & ~(hidden_side),
- junction);
- cairo_stroke (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, (gdouble) radius,
+ x, y, width, height,
+ &border, junction);
+ 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 - radius / 2, y + border.top + radius / 2);
+ cairo_line_to (cr, x + width - border.right - radius / 2, y + height - border.bottom - radius / 2);
+ cairo_line_to (cr, x + border.left + radius / 2, y + height - border.bottom - radius / 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, (gdouble) radius,
+ x, y, width, height,
+ &border, junction);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
if (border_width > 1)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]