X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkthemingbackground.c;h=579d2be4dea32abe70be40ad73cd70fa39cd87b1;hb=7c2a752b3724ad9ac88b7abfecc63e4e0eb7eb54;hp=4cdb39152745238e370df1830391dde95869ad1b;hpb=0ccb7db2452bc446d59afad3b0f448995bece5f2;p=~andy%2Fgtk diff --git a/gtk/gtkthemingbackground.c b/gtk/gtkthemingbackground.c index 4cdb39152..579d2be4d 100644 --- a/gtk/gtkthemingbackground.c +++ b/gtk/gtkthemingbackground.c @@ -42,80 +42,21 @@ */ #include "fallback-c89.c" -typedef struct { - cairo_rectangle_t image_rect; - GtkRoundedBox clip_box; - - gint idx; -} GtkThemingBackgroundLayer; - -static void -_gtk_theming_background_layer_apply_origin (GtkThemingBackground *bg, - GtkThemingBackgroundLayer *layer) -{ - cairo_rectangle_t image_rect; - GtkCssValue *value = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_ORIGIN); - GtkCssArea origin = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (value, layer->idx)); - - /* The default size of the background image depends on the - background-origin value as this affects the top left - and the bottom right corners. */ - switch (origin) { - case GTK_CSS_AREA_BORDER_BOX: - image_rect.x = 0; - image_rect.y = 0; - image_rect.width = bg->paint_area.width; - image_rect.height = bg->paint_area.height; - break; - case GTK_CSS_AREA_CONTENT_BOX: - image_rect.x = bg->border.left + bg->padding.left; - image_rect.y = bg->border.top + bg->padding.top; - image_rect.width = bg->paint_area.width - bg->border.left - bg->border.right - bg->padding.left - bg->padding.right; - image_rect.height = bg->paint_area.height - bg->border.top - bg->border.bottom - bg->padding.top - bg->padding.bottom; - break; - case GTK_CSS_AREA_PADDING_BOX: - default: - image_rect.x = bg->border.left; - image_rect.y = bg->border.top; - image_rect.width = bg->paint_area.width - bg->border.left - bg->border.right; - image_rect.height = bg->paint_area.height - bg->border.top - bg->border.bottom; - break; - } - - /* XXX: image_rect might have negative width/height here. - * Do we need to do something about it? */ - layer->image_rect = image_rect; -} - -static void -_gtk_theming_background_apply_clip (GtkThemingBackground *bg, - GtkRoundedBox *box, - GtkCssArea clip) +static const GtkRoundedBox * +gtk_theming_background_get_box (GtkThemingBackground *bg, + GtkCssArea area) { - if (clip == GTK_CSS_AREA_PADDING_BOX) + switch (area) { - _gtk_rounded_box_shrink (box, - bg->border.top, bg->border.right, - bg->border.bottom, bg->border.left); - } - else if (clip == GTK_CSS_AREA_CONTENT_BOX) - { - _gtk_rounded_box_shrink (box, - bg->border.top + bg->padding.top, - bg->border.right + bg->padding.right, - bg->border.bottom + bg->padding.bottom, - bg->border.left + bg->padding.left); - } -} - -static void -_gtk_theming_background_layer_apply_clip (GtkThemingBackground *bg, - GtkThemingBackgroundLayer *layer) -{ - GtkCssValue *value = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_CLIP); - GtkCssArea clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (value, layer->idx)); - - _gtk_theming_background_apply_clip (bg, &layer->clip_box, clip); + case GTK_CSS_AREA_BORDER_BOX: + return &bg->border_box; + case GTK_CSS_AREA_PADDING_BOX: + return &bg->padding_box; + case GTK_CSS_AREA_CONTENT_BOX: + return &bg->content_box; + default: + g_return_val_if_reached (&bg->border_box); + } } static void @@ -123,18 +64,14 @@ _gtk_theming_background_paint_color (GtkThemingBackground *bg, cairo_t *cr, GtkCssValue *background_image) { - GtkRoundedBox clip_box; gint n_values = _gtk_css_array_value_get_n_values (background_image); GtkCssArea clip = _gtk_css_area_value_get (_gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_CLIP), n_values - 1)); - clip_box = bg->border_box; - _gtk_theming_background_apply_clip (bg, &clip_box, clip); - cairo_save (cr); - _gtk_rounded_box_path (&clip_box, cr); + _gtk_rounded_box_path (gtk_theming_background_get_box (bg, clip), cr); cairo_clip (cr); gdk_cairo_set_source_rgba (cr, &bg->bg_color); @@ -145,30 +82,37 @@ _gtk_theming_background_paint_color (GtkThemingBackground *bg, static void _gtk_theming_background_paint_layer (GtkThemingBackground *bg, - GtkThemingBackgroundLayer *layer, + guint idx, cairo_t *cr) { GtkCssRepeatStyle hrepeat, vrepeat; const GtkCssValue *pos, *repeat; GtkCssImage *image; + const GtkRoundedBox *origin; double image_width, image_height; double width, height; - pos = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION), layer->idx); - repeat = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT), layer->idx); + pos = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_POSITION), idx); + repeat = _gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_REPEAT), idx); hrepeat = _gtk_css_background_repeat_value_get_x (repeat); vrepeat = _gtk_css_background_repeat_value_get_y (repeat); image = _gtk_css_image_value_get_image ( _gtk_css_array_value_get_nth ( _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_IMAGE), - layer->idx)); - width = layer->image_rect.width; - height = layer->image_rect.height; + idx)); + origin = gtk_theming_background_get_box ( + bg, + _gtk_css_area_value_get ( + _gtk_css_array_value_get_nth ( + _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_ORIGIN), + idx))); + width = origin->box.width; + height = origin->box.height; if (image == NULL || width <= 0 || height <= 0) return; - _gtk_css_bg_size_value_compute_size (_gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE), layer->idx), + _gtk_css_bg_size_value_compute_size (_gtk_css_array_value_get_nth (_gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_SIZE), idx), image, width, height, @@ -187,11 +131,18 @@ _gtk_theming_background_paint_layer (GtkThemingBackground *bg, cairo_save (cr); - _gtk_rounded_box_path (&layer->clip_box, cr); + _gtk_rounded_box_path ( + gtk_theming_background_get_box ( + bg, + _gtk_css_area_value_get ( + _gtk_css_array_value_get_nth ( + _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_CLIP), + idx))), + cr); cairo_clip (cr); - cairo_translate (cr, layer->image_rect.x, layer->image_rect.y); + cairo_translate (cr, origin->box.x, origin->box.y); if (hrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT && vrepeat == GTK_CSS_REPEAT_STYLE_NO_REPEAT) { @@ -321,26 +272,15 @@ _gtk_theming_background_apply_shadow (GtkThemingBackground *bg, &bg->padding_box); } -static void -_gtk_theming_background_init_layer (GtkThemingBackground *bg, - GtkThemingBackgroundLayer *layer, - gint idx) -{ - layer->idx = idx; - layer->clip_box = bg->border_box; - - _gtk_theming_background_layer_apply_clip (bg, layer); - _gtk_theming_background_layer_apply_origin (bg, layer); -} - static void _gtk_theming_background_init_context (GtkThemingBackground *bg) { - bg->flags = gtk_style_context_get_state (bg->context); + GtkStateFlags flags = gtk_style_context_get_state (bg->context); + GtkBorder border, padding; - gtk_style_context_get_border (bg->context, bg->flags, &bg->border); - gtk_style_context_get_padding (bg->context, bg->flags, &bg->padding); - gtk_style_context_get_background_color (bg->context, bg->flags, &bg->bg_color); + gtk_style_context_get_border (bg->context, flags, &border); + gtk_style_context_get_padding (bg->context, flags, &padding); + gtk_style_context_get_background_color (bg->context, flags, &bg->bg_color); /* In the CSS box model, by default the background positioning area is * the padding-box, i.e. all the border-box minus the borders themselves, @@ -355,8 +295,13 @@ _gtk_theming_background_init_context (GtkThemingBackground *bg) bg->padding_box = bg->border_box; _gtk_rounded_box_shrink (&bg->padding_box, - bg->border.top, bg->border.right, - bg->border.bottom, bg->border.left); + border.top, border.right, + border.bottom, border.left); + + bg->content_box = bg->padding_box; + _gtk_rounded_box_shrink (&bg->content_box, + padding.top, padding.right, + padding.bottom, padding.left); } void @@ -406,7 +351,6 @@ _gtk_theming_background_render (GtkThemingBackground *bg, cairo_t *cr) { gint idx; - GtkThemingBackgroundLayer layer; GtkCssValue *background_image; background_image = _gtk_style_context_peek_property (bg->context, GTK_CSS_PROPERTY_BACKGROUND_IMAGE); @@ -418,8 +362,7 @@ _gtk_theming_background_render (GtkThemingBackground *bg, for (idx = _gtk_css_array_value_get_n_values (background_image) - 1; idx >= 0; idx--) { - _gtk_theming_background_init_layer (bg, &layer, idx); - _gtk_theming_background_paint_layer (bg, &layer, cr); + _gtk_theming_background_paint_layer (bg, idx, cr); } _gtk_theming_background_apply_shadow (bg, cr);