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
* 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,6 +1914,10 @@ render_frame_internal (GtkThemingEngine *engine,
cairo_set_line_width (cr, border_width);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
gdk_cairo_set_source_rgba (cr, &border_color);
if (uniform_border)
{
if (border_width > 1)
{
x += (gdouble) border_width / 2;
@ -1903,8 +1937,17 @@ render_frame_internal (GtkThemingEngine *engine,
x, y, width, height,
SIDE_ALL & ~(hidden_side),
junction);
gdk_cairo_set_source_rgba (cr, &border_color);
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;
case GTK_BORDER_STYLE_INSET:
@ -1932,6 +1975,8 @@ render_frame_internal (GtkThemingEngine *engine,
m = MIN (width, height);
m /= 2;
if (uniform_border)
{
if (border_style == GTK_BORDER_STYLE_INSET)
gdk_cairo_set_source_rgba (cr, &lighter);
else
@ -1955,6 +2000,44 @@ render_frame_internal (GtkThemingEngine *engine,
(SIDE_TOP | SIDE_LEFT) & ~(hidden_side),
junction);
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)
{