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.
This commit is contained in:
Carlos Garnacho 2011-03-29 00:59:49 +02:00
parent 6834bace95
commit ae22476931

View File

@ -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 /* Set the appropriate matrix for
* patterns coming from the style context * patterns coming from the style context
*/ */
@ -1836,6 +1862,7 @@ render_frame_internal (GtkThemingEngine *engine,
gdouble progress, d1, d2, m; gdouble progress, d1, d2, m;
gboolean running; gboolean running;
GtkBorder border; GtkBorder border;
gboolean uniform_border;
state = gtk_theming_engine_get_state (engine); 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); running = gtk_theming_engine_state_is_running (engine, GTK_STATE_PRELIGHT, &progress);
border_width = MIN (MIN (border.top, border.bottom), border_width = MIN (MIN (border.top, border.bottom),
MIN (border.left, border.right)); MIN (border.left, border.right));
uniform_border = (border.top == border.bottom &&
border.top == border.left &&
border.top == border.right);
if (running) if (running)
{ {
@ -1884,6 +1914,10 @@ render_frame_internal (GtkThemingEngine *engine,
cairo_set_line_width (cr, border_width); cairo_set_line_width (cr, border_width);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
gdk_cairo_set_source_rgba (cr, &border_color);
if (uniform_border)
{
if (border_width > 1) if (border_width > 1)
{ {
x += (gdouble) border_width / 2; x += (gdouble) border_width / 2;
@ -1903,8 +1937,17 @@ render_frame_internal (GtkThemingEngine *engine,
x, y, width, height, x, y, width, height,
SIDE_ALL & ~(hidden_side), SIDE_ALL & ~(hidden_side),
junction); junction);
gdk_cairo_set_source_rgba (cr, &border_color);
cairo_stroke (cr); cairo_stroke (cr);
}
else
{
cairo_save (cr);
_cairo_uneven_frame (cr, (gdouble) radius,
x, y, width, height,
&border, junction);
cairo_fill (cr);
cairo_restore (cr);
}
break; break;
case GTK_BORDER_STYLE_INSET: case GTK_BORDER_STYLE_INSET:
@ -1932,6 +1975,8 @@ render_frame_internal (GtkThemingEngine *engine,
m = MIN (width, height); m = MIN (width, height);
m /= 2; m /= 2;
if (uniform_border)
{
if (border_style == GTK_BORDER_STYLE_INSET) if (border_style == GTK_BORDER_STYLE_INSET)
gdk_cairo_set_source_rgba (cr, &lighter); gdk_cairo_set_source_rgba (cr, &lighter);
else else
@ -1955,6 +2000,44 @@ render_frame_internal (GtkThemingEngine *engine,
(SIDE_TOP | SIDE_LEFT) & ~(hidden_side), (SIDE_TOP | SIDE_LEFT) & ~(hidden_side),
junction); junction);
cairo_stroke (cr); cairo_stroke (cr);
}
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, (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) if (border_width > 1)
{ {