render: Move function

The extents computation belongs in the icon code, not in the style
context code.
This commit is contained in:
Benjamin Otte
2015-07-01 06:38:00 +02:00
parent 2f90e1a7d9
commit fe26e863ea
6 changed files with 118 additions and 111 deletions

View File

@@ -40,6 +40,7 @@
#include "gtkprivate.h"
#include "gtktypebuiltins.h"
#include "gtkcssshadowsvalueprivate.h"
#include "gtkrendericonprivate.h"
#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
@@ -1540,12 +1541,12 @@ gtk_image_size_allocate (GtkWidget *widget,
/* XXX: This is not strictly correct, we could compute the area
* actually occupied by the image, but I'm lazy...
*/
_gtk_style_context_get_icon_extents (gtk_widget_get_style_context (widget),
&clip,
allocation->x,
allocation->y,
allocation->width,
allocation->height);
gtk_css_style_get_icon_extents (gtk_style_context_lookup_style (gtk_widget_get_style_context (widget)),
&clip,
allocation->x,
allocation->y,
allocation->width,
allocation->height);
_gtk_widget_set_simple_clip (widget, &clip);
}

View File

@@ -26,6 +26,92 @@
#include "gtkcssstyleprivate.h"
#include "gtkcsstransformvalueprivate.h"
#include <math.h>
static void
gtk_cairo_rectangle_transform (cairo_rectangle_int_t *dest,
const cairo_rectangle_int_t *src,
const cairo_matrix_t *matrix)
{
double x1, x2, x3, x4;
double y1, y2, y3, y4;
g_return_if_fail (dest != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (matrix != NULL);
x1 = src->x;
y1 = src->y;
x2 = src->x + src->width;
y2 = src->y;
x3 = src->x + src->width;
y3 = src->y + src->height;
x4 = src->x;
y4 = src->y + src->height;
cairo_matrix_transform_point (matrix, &x1, &y1);
cairo_matrix_transform_point (matrix, &x2, &y2);
cairo_matrix_transform_point (matrix, &x3, &y3);
cairo_matrix_transform_point (matrix, &x4, &y4);
dest->x = floor (MIN (MIN (x1, x2), MIN (x3, x4)));
dest->y = floor (MIN (MIN (y1, y2), MIN (y3, y4)));
dest->width = ceil (MAX (MAX (x1, x2), MAX (x3, x4))) - dest->x;
dest->height = ceil (MAX (MAX (y1, y2), MAX (y3, y4))) - dest->y;
}
gboolean
gtk_css_style_get_icon_extents (GtkCssStyle *style,
GdkRectangle *extents,
gint x,
gint y,
gint width,
gint height)
{
cairo_matrix_t transform_matrix, matrix;
GtkBorder border;
GdkRectangle rect;
g_return_val_if_fail (GTK_IS_CSS_STYLE (style), FALSE);
g_return_val_if_fail (extents != NULL, FALSE);
if (_gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE)) == NULL)
{
extents->x = extents->y = extents->width = extents->height = 0;
return FALSE;
}
extents->x = x;
extents->y = y;
extents->width = width;
extents->height = height;
/* builtin images can't be transformed */
if (GTK_IS_CSS_IMAGE_BUILTIN (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE)))
return TRUE;
if (!_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
return TRUE;
cairo_matrix_init_translate (&matrix, x + width / 2.0, y + height / 2.0);
cairo_matrix_multiply (&matrix, &transform_matrix, &matrix);
/* need to round to full pixels */
rect.x = - (width + 1) / 2;
rect.y = - (height + 1) / 2;
rect.width = (width + 1) & ~1;
rect.height = (height + 1) & ~1;
gtk_cairo_rectangle_transform (extents, &rect, &matrix);
_gtk_css_shadows_value_get_extents (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW), &border);
extents->x -= border.left;
extents->y -= border.top;
extents->width += border.left + border.right;
extents->height += border.top + border.bottom;
return TRUE;
}
void
gtk_css_style_render_icon (GtkCssStyle *style,
cairo_t *cr,

View File

@@ -29,19 +29,26 @@
G_BEGIN_DECLS
void gtk_css_style_render_icon (GtkCssStyle *style,
cairo_t *cr,
double x,
double y,
double width,
double height,
GtkCssImageBuiltinType builtin_type);
gboolean gtk_css_style_get_icon_extents (GtkCssStyle *style,
GdkRectangle *extents,
gint x,
gint y,
gint width,
gint height);
void gtk_css_style_render_icon_surface (GtkCssStyle *style,
cairo_t *cr,
cairo_surface_t *surface,
double x,
double y);
void gtk_css_style_render_icon (GtkCssStyle *style,
cairo_t *cr,
double x,
double y,
double width,
double height,
GtkCssImageBuiltinType builtin_type);
void gtk_css_style_render_icon_surface (GtkCssStyle *style,
cairo_t *cr,
cairo_surface_t *surface,
double x,
double y);
G_END_DECLS

View File

@@ -34,6 +34,7 @@
#include "gtkimage.h"
#include "gtkintl.h"
#include "gtkprivate.h"
#include "gtkrendericonprivate.h"
#include "gtkstylecontext.h"
#include "gtkstylecontextprivate.h"
#include "gtkwidgetprivate.h"
@@ -202,11 +203,11 @@ gtk_spinner_size_allocate (GtkWidget *widget,
context = gtk_widget_get_style_context (widget);
size = MIN (allocation->width, allocation->height);
_gtk_style_context_get_icon_extents (context,
&clip,
allocation->x + (allocation->width - size) / 2,
allocation->y + (allocation->height - size) / 2,
size, size);
gtk_css_style_get_icon_extents (gtk_style_context_lookup_style (context),
&clip,
allocation->x + (allocation->width - size) / 2,
allocation->y + (allocation->height - size) / 2,
size, size);
gdk_rectangle_union (&clip, allocation, &clip);

View File

@@ -3063,87 +3063,6 @@ _gtk_style_context_get_changes (GtkStyleContext *context)
return context->priv->invalidating_context;
}
static void
gtk_cairo_rectangle_transform (cairo_rectangle_int_t *dest,
const cairo_rectangle_int_t *src,
const cairo_matrix_t *matrix)
{
double x1, x2, x3, x4;
double y1, y2, y3, y4;
g_return_if_fail (dest != NULL);
g_return_if_fail (src != NULL);
g_return_if_fail (matrix != NULL);
x1 = src->x;
y1 = src->y;
x2 = src->x + src->width;
y2 = src->y;
x3 = src->x + src->width;
y3 = src->y + src->height;
x4 = src->x;
y4 = src->y + src->height;
cairo_matrix_transform_point (matrix, &x1, &y1);
cairo_matrix_transform_point (matrix, &x2, &y2);
cairo_matrix_transform_point (matrix, &x3, &y3);
cairo_matrix_transform_point (matrix, &x4, &y4);
dest->x = floor (MIN (MIN (x1, x2), MIN (x3, x4)));
dest->y = floor (MIN (MIN (y1, y2), MIN (y3, y4)));
dest->width = ceil (MAX (MAX (x1, x2), MAX (x3, x4))) - dest->x;
dest->height = ceil (MAX (MAX (y1, y2), MAX (y3, y4))) - dest->y;
}
void
_gtk_style_context_get_icon_extents (GtkStyleContext *context,
GdkRectangle *extents,
gint x,
gint y,
gint width,
gint height)
{
cairo_matrix_t transform_matrix, matrix;
GtkBorder border;
GdkRectangle rect;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (extents != NULL);
if (_gtk_css_image_value_get_image (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE)) == NULL)
{
extents->x = extents->y = extents->width = extents->height = 0;
return;
}
extents->x = x;
extents->y = y;
extents->width = width;
extents->height = height;
/* builtin images can't be transformed */
if (GTK_IS_CSS_IMAGE_BUILTIN (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SOURCE)))
return;
if (!_gtk_css_transform_value_get_matrix (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix))
return;
cairo_matrix_init_translate (&matrix, x + width / 2.0, y + height / 2.0);
cairo_matrix_multiply (&matrix, &transform_matrix, &matrix);
/* need to round to full pixels */
rect.x = - (width + 1) / 2;
rect.y = - (height + 1) / 2;
rect.width = (width + 1) & ~1;
rect.height = (height + 1) & ~1;
gtk_cairo_rectangle_transform (extents, &rect, &matrix);
_gtk_css_shadows_value_get_extents (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_ICON_SHADOW), &border);
extents->x -= border.left;
extents->y -= border.top;
extents->width += border.left + border.right;
extents->height += border.top + border.bottom;
}
static AtkAttributeSet *
add_attribute (AtkAttributeSet *attributes,
AtkTextAttribute attr,

View File

@@ -57,13 +57,6 @@ void _gtk_style_context_get_cursor_color (GtkStyleContext
GdkRGBA *primary_color,
GdkRGBA *secondary_color);
void _gtk_style_context_get_icon_extents (GtkStyleContext *context,
GdkRectangle *extents,
gint x,
gint y,
gint width,
gint height);
/* Accessibility support */
AtkAttributeSet *_gtk_style_context_get_attributes (AtkAttributeSet *attributes,
GtkStyleContext *context,