#include <gtk/gtkintl.h>
#include "gtkprivate.h"
-#include "gtk9slice.h"
+#include "gtkborderimageprivate.h"
#include "gtkpango.h"
+#include "gtkshadowprivate.h"
+#include "gtkcsstypesprivate.h"
+#include "gtkthemingengineprivate.h"
/**
* SECTION:gtkthemingengine
static GdkPixbuf * gtk_theming_engine_render_icon_pixbuf (GtkThemingEngine *engine,
const GtkIconSource *source,
GtkIconSize size);
+static void gtk_theming_engine_render_icon (GtkThemingEngine *engine,
+ cairo_t *cr,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y);
G_DEFINE_TYPE (GtkThemingEngine, gtk_theming_engine, G_TYPE_OBJECT)
object_class->set_property = gtk_theming_engine_impl_set_property;
object_class->get_property = gtk_theming_engine_impl_get_property;
+ klass->render_icon = gtk_theming_engine_render_icon;
klass->render_check = gtk_theming_engine_render_check;
klass->render_option = gtk_theming_engine_render_option;
klass->render_arrow = gtk_theming_engine_render_arrow;
*
* Since: 3.0
**/
-G_CONST_RETURN GtkWidgetPath *
+const GtkWidgetPath *
gtk_theming_engine_get_path (GtkThemingEngine *engine)
{
GtkThemingEnginePrivate *priv;
gdouble width,
gdouble height)
{
- GdkRGBA *fg_color, *bg_color, *border_color;
+ GdkRGBA fg_color, bg_color;
GtkStateFlags flags;
gint exterior_size, interior_size, thickness, pad;
GtkBorderStyle border_style;
- GtkBorder *border;
+ GtkBorder border;
gint border_width;
flags = gtk_theming_engine_get_state (engine);
cairo_save (cr);
+ gtk_theming_engine_get_color (engine, flags, &fg_color);
+ gtk_theming_engine_get_background_color (engine, flags, &bg_color);
+ gtk_theming_engine_get_border (engine, flags, &border);
+
gtk_theming_engine_get (engine, flags,
- "color", &fg_color,
- "background-color", &bg_color,
- "border-color", &border_color,
"border-style", &border_style,
- "border-width", &border,
NULL);
- border_width = MIN (MIN (border->top, border->bottom),
- MIN (border->left, border->right));
+ border_width = MIN (MIN (border.top, border.bottom),
+ MIN (border.left, border.right));
exterior_size = MIN (width, height);
if (exterior_size % 2 == 0) /* Ensure odd */
if (border_style == GTK_BORDER_STYLE_SOLID)
{
+ GdkRGBA border_color;
+
cairo_set_line_width (cr, border_width);
+ gtk_theming_engine_get_border_color (engine, flags, &border_color);
cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
- gdk_cairo_set_source_rgba (cr, bg_color);
+ gdk_cairo_set_source_rgba (cr, &bg_color);
cairo_fill_preserve (cr);
- if (border_color)
- gdk_cairo_set_source_rgba (cr, border_color);
- else
- gdk_cairo_set_source_rgba (cr, fg_color);
-
+ gdk_cairo_set_source_rgba (cr, &border_color);
cairo_stroke (cr);
}
- gdk_cairo_set_source_rgba (cr, fg_color);
+ gdk_cairo_set_source_rgba (cr, &fg_color);
if (flags & GTK_STATE_FLAG_INCONSISTENT)
{
}
cairo_restore (cr);
-
- gdk_rgba_free (fg_color);
- gdk_rgba_free (bg_color);
- gdk_rgba_free (border_color);
- gtk_border_free (border);
}
static void
gdouble height)
{
GtkStateFlags flags;
- GdkRGBA *fg_color, *bg_color, *border_color;
+ GdkRGBA fg_color, bg_color;
gint exterior_size, interior_size, pad, thickness, border_width;
GtkBorderStyle border_style;
- GtkBorder *border;
+ GtkBorder border;
flags = gtk_theming_engine_get_state (engine);
cairo_save (cr);
+ gtk_theming_engine_get_color (engine, flags, &fg_color);
+ gtk_theming_engine_get_background_color (engine, flags, &bg_color);
+ gtk_theming_engine_get_border (engine, flags, &border);
+
gtk_theming_engine_get (engine, flags,
- "color", &fg_color,
- "background-color", &bg_color,
- "border-color", &border_color,
"border-style", &border_style,
- "border-width", &border,
NULL);
exterior_size = MIN (width, height);
- border_width = MIN (MIN (border->top, border->bottom),
- MIN (border->left, border->right));
+ border_width = MIN (MIN (border.top, border.bottom),
+ MIN (border.left, border.right));
if (exterior_size % 2 == 0) /* Ensure odd */
exterior_size -= 1;
if (border_style == GTK_BORDER_STYLE_SOLID)
{
+ GdkRGBA border_color;
+
cairo_set_line_width (cr, border_width);
+ gtk_theming_engine_get_border_color (engine, flags, &border_color);
cairo_new_sub_path (cr);
cairo_arc (cr,
(exterior_size - 1) / 2.,
0, 2 * G_PI);
- gdk_cairo_set_source_rgba (cr, bg_color);
+ gdk_cairo_set_source_rgba (cr, &bg_color);
cairo_fill_preserve (cr);
- if (border_color)
- gdk_cairo_set_source_rgba (cr, border_color);
- else
- gdk_cairo_set_source_rgba (cr, fg_color);
-
+ gdk_cairo_set_source_rgba (cr, &border_color);
cairo_stroke (cr);
}
- gdk_cairo_set_source_rgba (cr, fg_color);
+ gdk_cairo_set_source_rgba (cr, &fg_color);
/* FIXME: thickness */
thickness = 1;
}
cairo_restore (cr);
-
- gdk_rgba_free (fg_color);
- gdk_rgba_free (bg_color);
- gdk_rgba_free (border_color);
- gtk_border_free (border);
}
static void
gdouble size)
{
GtkStateFlags flags;
- GdkRGBA *fg_color;
+ GdkRGBA fg_color;
cairo_save (cr);
flags = gtk_theming_engine_get_state (engine);
-
- gtk_theming_engine_get (engine, flags,
- "color", &fg_color,
- NULL);
+ gtk_theming_engine_get_color (engine, flags, &fg_color);
if (flags & GTK_STATE_FLAG_INSENSITIVE)
{
}
add_path_arrow (cr, angle, x, y, size);
- gdk_cairo_set_source_rgba (cr, fg_color);
+ gdk_cairo_set_source_rgba (cr, &fg_color);
cairo_fill (cr);
cairo_restore (cr);
-
- gdk_rgba_free (fg_color);
}
static void
}
static void
-_cairo_round_rectangle_sides (cairo_t *cr,
- gdouble radius,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height,
- guint sides,
- GtkJunctionSides junction)
+_cairo_ellipsis (cairo_t *cr,
+ double xc, double yc,
+ double xradius, double yradius,
+ double angle1, double angle2)
{
- radius = CLAMP (radius, 0, MIN (width / 2, height / 2));
+ if (xradius <= 0.0 || yradius <= 0.0)
+ {
+ /* stolen from cairo sources */
+ cairo_line_to (cr, xc, yc); /* might become a move_to */
+ cairo_line_to (cr, xc, yc);
+ return;
+ }
+
+ cairo_save (cr);
+ cairo_translate (cr, xc, yc);
+ cairo_scale (cr, xradius, yradius);
+ cairo_arc (cr, 0, 0, 1.0, angle1, angle2);
+ cairo_restore (cr);
+}
+
+static void
+_cairo_round_rectangle_sides (cairo_t *cr,
+ const GtkCssBorderRadius *border_radius,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ guint sides)
+{
+ cairo_new_sub_path (cr);
if (sides & SIDE_RIGHT)
{
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_TOPRIGHT))
- cairo_move_to (cr, x + width, y);
- else
- {
- cairo_new_sub_path (cr);
- cairo_arc (cr, x + width - radius, y + radius, radius, - G_PI / 4, 0);
- }
-
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT))
- cairo_line_to (cr, x + width, y + height);
- else
- cairo_arc (cr, x + width - radius, y + height - radius, radius, 0, G_PI / 4);
+ _cairo_ellipsis (cr,
+ x + width - border_radius->top_right.horizontal,
+ y + border_radius->top_right.vertical,
+ border_radius->top_right.horizontal,
+ border_radius->top_right.vertical,
+ - G_PI / 4, 0);
+ _cairo_ellipsis (cr,
+ x + width - border_radius->bottom_right.horizontal,
+ y + height - border_radius->bottom_right.vertical,
+ border_radius->bottom_right.horizontal,
+ border_radius->bottom_right.vertical,
+ 0, G_PI / 4);
}
if (sides & SIDE_BOTTOM)
{
- if (radius != 0 &&
- ! (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT))
- {
- if ((sides & SIDE_RIGHT) == 0)
- cairo_new_sub_path (cr);
-
- cairo_arc (cr, x + width - radius, y + height - radius, radius, G_PI / 4, G_PI / 2);
- }
- else if ((sides & SIDE_RIGHT) == 0)
- cairo_move_to (cr, x + width, y + height);
-
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT))
- cairo_line_to (cr, x, y + height);
- else
- cairo_arc (cr, x + radius, y + height - radius, radius, G_PI / 2, 3 * (G_PI / 4));
+ _cairo_ellipsis (cr,
+ x + width - border_radius->bottom_right.horizontal,
+ y + height - border_radius->bottom_right.vertical,
+ border_radius->bottom_right.horizontal,
+ border_radius->bottom_right.vertical,
+ G_PI / 4, G_PI / 2);
+ _cairo_ellipsis (cr,
+ x + border_radius->bottom_left.horizontal,
+ y + height - border_radius->bottom_left.vertical,
+ border_radius->bottom_left.horizontal,
+ border_radius->bottom_left.vertical,
+ G_PI / 2, 3 * (G_PI / 4));
}
else
cairo_move_to (cr, x, y + height);
if (sides & SIDE_LEFT)
{
- if (radius != 0 &&
- ! (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT))
- {
- if ((sides & SIDE_BOTTOM) == 0)
- cairo_new_sub_path (cr);
-
- cairo_arc (cr, x + radius, y + height - radius, radius, 3 * (G_PI / 4), G_PI);
- }
- else if ((sides & SIDE_BOTTOM) == 0)
- cairo_move_to (cr, x, y + height);
-
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_TOPLEFT))
- cairo_line_to (cr, x, y);
- else
- cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI + G_PI / 4);
+ _cairo_ellipsis (cr,
+ x + border_radius->bottom_left.horizontal,
+ y + height - border_radius->bottom_left.vertical,
+ border_radius->bottom_left.horizontal,
+ border_radius->bottom_left.vertical,
+ 3 * (G_PI / 4), G_PI);
+ _cairo_ellipsis (cr,
+ x + border_radius->top_left.horizontal,
+ y + border_radius->top_left.vertical,
+ border_radius->top_left.horizontal,
+ border_radius->top_left.vertical,
+ G_PI, G_PI + G_PI / 4);
}
+ else
+ cairo_move_to (cr, x, y);
if (sides & SIDE_TOP)
{
- if (radius != 0 &&
- ! (junction & GTK_JUNCTION_CORNER_TOPLEFT))
- {
- if ((sides & SIDE_LEFT) == 0)
- cairo_new_sub_path (cr);
-
- cairo_arc (cr, x + radius, y + radius, radius, 5 * (G_PI / 4), 3 * (G_PI / 2));
- }
- else if ((sides & SIDE_LEFT) == 0)
- cairo_move_to (cr, x, y);
-
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_TOPRIGHT))
- cairo_line_to (cr, x + width, y);
- else
- cairo_arc (cr, x + width - radius, y + radius, radius, 3 * (G_PI / 2), - G_PI / 4);
+ _cairo_ellipsis (cr,
+ x + border_radius->top_left.horizontal,
+ y + border_radius->top_left.vertical,
+ border_radius->top_left.horizontal,
+ border_radius->top_left.vertical,
+ 5 * (G_PI / 4), 3 * (G_PI / 2));
+ _cairo_ellipsis (cr,
+ x + width - border_radius->top_right.horizontal,
+ y + border_radius->top_right.vertical,
+ border_radius->top_right.horizontal,
+ border_radius->top_right.vertical,
+ 3 * (G_PI / 2), - G_PI / 4);
}
}
-/* Set the appropriate matrix for
- * patterns coming from the style context
- */
static void
-style_pattern_set_matrix (cairo_pattern_t *pattern,
- gdouble width,
- gdouble height)
-{
- cairo_matrix_t matrix;
- gint w, h;
-
- if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SURFACE)
- {
- cairo_surface_t *surface;
-
- cairo_pattern_get_surface (pattern, &surface);
- w = cairo_image_surface_get_width (surface);
- h = cairo_image_surface_get_height (surface);
- }
- else
- w = h = 1;
+_cairo_uneven_frame (cairo_t *cr,
+ const GtkCssBorderRadius *border_radius,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ GtkBorder *border)
+{
+ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
+ cairo_set_line_width (cr, 1);
- cairo_matrix_init_scale (&matrix, (gdouble) w / width, (gdouble) h / height);
- cairo_pattern_set_matrix (pattern, &matrix);
+ _cairo_round_rectangle_sides (cr, border_radius,
+ x, y,
+ width, height,
+ SIDE_ALL);
+
+ _cairo_round_rectangle_sides (cr, border_radius,
+ x + border->left,
+ y + border->top,
+ width - border->left - border->right,
+ height - border->top - border->bottom,
+ SIDE_ALL);
}
static void
gdouble height,
GtkJunctionSides junction)
{
- GdkRGBA *bg_color;
+ GdkRGBA bg_color;
cairo_pattern_t *pattern;
GtkStateFlags flags;
gboolean running;
gdouble progress, alpha = 1;
- GtkBorder *border;
- gint radius, border_width;
+ GtkBorder border;
+ GtkCssBorderCornerRadius *top_left_radius, *top_right_radius;
+ GtkCssBorderCornerRadius *bottom_left_radius, *bottom_right_radius;
+ GtkCssBorderRadius border_radius = { { 0, }, };
+ gint border_width;
GtkBorderStyle border_style;
gdouble mat_w, mat_h;
- cairo_matrix_t identity;
/* Use unmodified size for pattern scaling */
mat_w = width;
flags = gtk_theming_engine_get_state (engine);
- cairo_matrix_init_identity (&identity);
+ gtk_theming_engine_get_background_color (engine, flags, &bg_color);
+ gtk_theming_engine_get_border (engine, flags, &border);
gtk_theming_engine_get (engine, flags,
"background-image", &pattern,
- "background-color", &bg_color,
- "border-radius", &radius,
- "border-width", &border,
+ /* Can't use border-radius as it's an int for
+ * backwards compat */
+ "border-top-left-radius", &top_left_radius,
+ "border-top-right-radius", &top_right_radius,
+ "border-bottom-right-radius", &bottom_right_radius,
+ "border-bottom-left-radius", &bottom_left_radius,
"border-style", &border_style,
NULL);
- border_width = MIN (MIN (border->top, border->bottom),
- MIN (border->left, border->right));
+ if (top_left_radius)
+ border_radius.top_left = *top_left_radius;
+ g_free (top_left_radius);
+ if (top_right_radius)
+ border_radius.top_right = *top_right_radius;
+ g_free (top_right_radius);
+ if (bottom_right_radius)
+ border_radius.bottom_right = *bottom_right_radius;
+ g_free (bottom_right_radius);
+ if (bottom_left_radius)
+ border_radius.bottom_left = *bottom_left_radius;
+ g_free (bottom_left_radius);
+
+ border_width = MIN (MIN (border.top, border.bottom),
+ MIN (border.left, border.right));
if (border_width > 1 &&
border_style == GTK_BORDER_STYLE_NONE)
{
- cairo_set_line_width (cr, border_width);
-
x += (gdouble) border_width / 2;
y += (gdouble) border_width / 2;
width -= border_width;
}
else
{
- x += border->left;
- y += border->top;
- width -= border->left + border->right;
- height -= border->top + border->bottom;
+ x += border.left;
+ y += border.top;
+ width -= border.left + border.right;
+ height -= border.top + border.bottom;
}
if (width <= 0 || height <= 0)
return;
cairo_save (cr);
+ cairo_set_line_width (cr, border_width);
cairo_translate (cr, x, y);
running = gtk_theming_engine_state_is_running (engine, GTK_STATE_PRELIGHT, &progress);
{
cairo_pattern_t *other_pattern;
GtkStateFlags other_flags;
- GdkRGBA *other_bg;
+ GdkRGBA other_bg;
cairo_pattern_t *new_pattern = NULL;
if (flags & GTK_STATE_FLAG_PRELIGHT)
else
other_flags = flags | GTK_STATE_FLAG_PRELIGHT;
+ gtk_theming_engine_get_background_color (engine, other_flags, &other_bg);
gtk_theming_engine_get (engine, other_flags,
"background-image", &other_pattern,
- "background-color", &other_bg,
NULL);
if (pattern && other_pattern)
/* Different pattern types, or different color
* stop counts, alpha blend both patterns.
*/
- _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ _cairo_round_rectangle_sides (cr, &border_radius,
0, 0, width, height,
- SIDE_ALL, junction);
+ SIDE_ALL);
- style_pattern_set_matrix (other_pattern, mat_w, mat_h);
+ cairo_scale (cr, mat_w, mat_h);
cairo_set_source (cr, other_pattern);
+ cairo_scale (cr, 1.0 / mat_w, 1.0 / mat_h);
cairo_fill_preserve (cr);
- cairo_pattern_set_matrix (other_pattern, &identity);
-
/* Set alpha for posterior drawing
* of the target pattern
*/
if (pattern)
{
p = pattern;
- c = other_bg;
+ c = &other_bg;
progress = 1 - progress;
}
else
{
p = other_pattern;
- c = bg_color;
+ c = &bg_color;
}
if (cairo_pattern_get_type (p) == CAIRO_PATTERN_TYPE_LINEAR)
}
else
{
- const GdkRGBA *color, *other_color;
-
/* Merge just colors */
- color = bg_color;
- other_color = other_bg;
-
- new_pattern = cairo_pattern_create_rgba (CLAMP (color->red + ((other_color->red - color->red) * progress), 0, 1),
- CLAMP (color->green + ((other_color->green - color->green) * progress), 0, 1),
- CLAMP (color->blue + ((other_color->blue - color->blue) * progress), 0, 1),
- CLAMP (color->alpha + ((other_color->alpha - color->alpha) * progress), 0, 1));
+ new_pattern = cairo_pattern_create_rgba (CLAMP (bg_color.red + ((other_bg.red - bg_color.red) * progress), 0, 1),
+ CLAMP (bg_color.green + ((other_bg.green - bg_color.green) * progress), 0, 1),
+ CLAMP (bg_color.blue + ((other_bg.blue - bg_color.blue) * progress), 0, 1),
+ CLAMP (bg_color.alpha + ((other_bg.alpha - bg_color.alpha) * progress), 0, 1));
}
if (new_pattern)
if (other_pattern)
cairo_pattern_destroy (other_pattern);
-
- if (other_bg)
- gdk_rgba_free (other_bg);
}
- _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ _cairo_round_rectangle_sides (cr, &border_radius,
0, 0, width, height,
- SIDE_ALL, junction);
+ SIDE_ALL);
if (pattern)
{
- style_pattern_set_matrix (pattern, mat_w, mat_h);
+ cairo_scale (cr, mat_w, mat_h);
cairo_set_source (cr, pattern);
+ cairo_scale (cr, 1.0 / mat_w, 1.0 / mat_h);
}
else
- gdk_cairo_set_source_rgba (cr, bg_color);
+ gdk_cairo_set_source_rgba (cr, &bg_color);
if (alpha == 1)
{
else
{
cairo_save (cr);
- _cairo_round_rectangle_sides (cr, (gdouble) radius,
+ _cairo_round_rectangle_sides (cr, &border_radius,
0, 0, width, height,
- SIDE_ALL, junction);
+ SIDE_ALL);
cairo_clip (cr);
cairo_paint_with_alpha (cr, alpha);
}
if (pattern)
- {
- cairo_pattern_set_matrix (pattern, &identity);
- cairo_pattern_destroy (pattern);
- }
+ cairo_pattern_destroy (pattern);
cairo_restore (cr);
-
- gdk_rgba_free (bg_color);
- gtk_border_free (border);
}
static void
}
}
+static void
+gtk_themeing_engine_apply_junction_to_radius (GtkCssBorderRadius *border_radius,
+ GtkJunctionSides junction)
+{
+ if (junction & GTK_JUNCTION_CORNER_TOPLEFT)
+ border_radius->top_left.horizontal = border_radius->top_left.vertical = 0;
+ if (junction & GTK_JUNCTION_CORNER_TOPRIGHT)
+ border_radius->top_right.horizontal = border_radius->top_right.vertical = 0;
+ if (junction & GTK_JUNCTION_CORNER_BOTTOMRIGHT)
+ border_radius->bottom_right.horizontal = border_radius->bottom_right.vertical = 0;
+ if (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT)
+ border_radius->bottom_left.horizontal = border_radius->bottom_left.vertical = 0;
+}
+
static void
render_frame_internal (GtkThemingEngine *engine,
cairo_t *cr,
{
GtkStateFlags state;
GdkRGBA lighter;
- GdkRGBA *border_color;
+ GdkRGBA border_color;
GtkBorderStyle border_style;
- gint border_width, radius;
+ gint border_width;
+ GtkCssBorderCornerRadius *top_left_radius, *top_right_radius;
+ GtkCssBorderCornerRadius *bottom_left_radius, *bottom_right_radius;
+ GtkCssBorderRadius border_radius = { { 0, }, };
gdouble progress, d1, d2, m;
gboolean running;
- GtkBorder *border;
+ GtkBorder border;
+ gboolean uniform_border;
state = gtk_theming_engine_get_state (engine);
+
+ gtk_theming_engine_get_border_color (engine, state, &border_color);
+ gtk_theming_engine_get_border (engine, state, &border);
+
gtk_theming_engine_get (engine, state,
- "border-color", &border_color,
"border-style", &border_style,
- "border-width", &border,
- "border-radius", &radius,
+ /* Can't use border-radius as it's an int for
+ * backwards compat */
+ "border-top-left-radius", &top_left_radius,
+ "border-top-right-radius", &top_right_radius,
+ "border-bottom-right-radius", &bottom_right_radius,
+ "border-bottom-left-radius", &bottom_left_radius,
NULL);
+ if (top_left_radius)
+ border_radius.top_left = *top_left_radius;
+ g_free (top_left_radius);
+ if (top_right_radius)
+ border_radius.top_right = *top_right_radius;
+ g_free (top_right_radius);
+ if (bottom_right_radius)
+ border_radius.bottom_right = *bottom_right_radius;
+ g_free (bottom_right_radius);
+ if (bottom_left_radius)
+ border_radius.bottom_left = *bottom_left_radius;
+ g_free (bottom_left_radius);
+
+ gtk_themeing_engine_apply_junction_to_radius (&border_radius, junction);
+
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));
+ 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)
{
GtkStateFlags other_state;
- GdkRGBA *other_color;
+ GdkRGBA other_color;
if (state & GTK_STATE_FLAG_PRELIGHT)
{
else
other_state = state | GTK_STATE_FLAG_PRELIGHT;
- gtk_theming_engine_get (engine, other_state,
- "border-color", &other_color,
- NULL);
-
- border_color->red = CLAMP (border_color->red + ((other_color->red - border_color->red) * progress), 0, 1);
- border_color->green = CLAMP (border_color->green + ((other_color->green - border_color->green) * progress), 0, 1);
- border_color->blue = CLAMP (border_color->blue + ((other_color->blue - border_color->blue) * progress), 0, 1);
- border_color->alpha = CLAMP (border_color->alpha + ((other_color->alpha - border_color->alpha) * progress), 0, 1);
+ gtk_theming_engine_get_border_color (engine, other_state, &other_color);
- gdk_rgba_free (other_color);
+ border_color.red = CLAMP (border_color.red + ((other_color.red - border_color.red) * progress), 0, 1);
+ border_color.green = CLAMP (border_color.green + ((other_color.green - border_color.green) * progress), 0, 1);
+ border_color.blue = CLAMP (border_color.blue + ((other_color.blue - border_color.blue) * progress), 0, 1);
+ border_color.alpha = CLAMP (border_color.alpha + ((other_color.alpha - border_color.alpha) * progress), 0, 1);
}
cairo_save (cr);
- color_shade (border_color, 1.8, &lighter);
+ color_shade (&border_color, 1.8, &lighter);
switch (border_style)
{
cairo_set_line_width (cr, border_width);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
- 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;
- }
+ gdk_cairo_set_source_rgba (cr, &border_color);
- _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);
+ cairo_save (cr);
+ _cairo_uneven_frame (cr, &border_radius,
+ x, y, width, height,
+ &border);
+ cairo_fill (cr);
+ cairo_restore (cr);
break;
case GTK_BORDER_STYLE_INSET:
case GTK_BORDER_STYLE_OUTSET:
cairo_set_line_width (cr, border_width);
-
- if (radius == 0)
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
- else
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
if (border_width > 1)
{
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, &border_radius,
+ x + d1, y + d1,
+ width - d2, height - d2,
+ (SIDE_BOTTOM | SIDE_RIGHT) & ~(hidden_side));
+ cairo_stroke (cr);
- if (border_style == GTK_BORDER_STYLE_INSET)
- gdk_cairo_set_source_rgba (cr, border_color);
+ if (border_style == GTK_BORDER_STYLE_INSET)
+ gdk_cairo_set_source_rgba (cr, &border_color);
+ else
+ gdk_cairo_set_source_rgba (cr, &lighter);
+
+ _cairo_round_rectangle_sides (cr, &border_radius,
+ x + d1, y + d1,
+ width - d2, height - d2,
+ (SIDE_TOP | SIDE_LEFT) & ~(hidden_side));
+ 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, &border_radius,
+ x, y, width, height,
+ &border);
+ 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 - border_radius.top_right.horizontal / 2,
+ y + border.top + border_radius.top_right.vertical / 2);
+ cairo_line_to (cr,
+ x + width - border.right - border_radius.bottom_right.horizontal / 2,
+ y + height - border.bottom - border_radius.bottom_right.vertical / 2);
+ cairo_line_to (cr,
+ x + border.left + border_radius.bottom_left.horizontal / 2,
+ y + height - border.bottom - border_radius.bottom_left.vertical / 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, &border_radius,
+ x, y, width, height,
+ &border);
+ cairo_fill (cr);
+ cairo_restore (cr);
+ }
if (border_width > 1)
{
if (border_style == GTK_BORDER_STYLE_INSET)
gdk_cairo_set_source_rgba (cr, &lighter);
else
- gdk_cairo_set_source_rgba (cr, border_color);
+ gdk_cairo_set_source_rgba (cr, &border_color);
cairo_set_line_width (cr, 1);
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_TOPRIGHT) != 0)
+ if ((junction & GTK_JUNCTION_CORNER_TOPRIGHT) != 0)
_cairo_corner_triangle (cr,
x + width - border_width, y,
border_width);
- if (radius == 0 ||
- (junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) != 0)
+ if ((junction & GTK_JUNCTION_CORNER_BOTTOMLEFT) != 0)
_cairo_corner_triangle (cr,
x, y + height - border_width,
border_width);
}
cairo_restore (cr);
-
- if (border_color)
- gdk_rgba_free (border_color);
-
- gtk_border_free (border);
}
static void
gdouble height)
{
GtkStateFlags flags;
- Gtk9Slice *slice;
GtkBorderStyle border_style;
GtkJunctionSides junction;
+ GtkBorderImage *border_image;
+ GtkBorder border;
flags = gtk_theming_engine_get_state (engine);
junction = gtk_theming_engine_get_junction_sides (engine);
+ gtk_theming_engine_get_border (engine, flags, &border);
gtk_theming_engine_get (engine, flags,
- "border-image", &slice,
+ "border-image", &border_image,
"border-style", &border_style,
NULL);
- if (slice)
+ if (border_image != NULL)
{
- _gtk_9slice_render (slice, cr, x, y, width, height);
- _gtk_9slice_unref (slice);
+ _gtk_border_image_render (border_image, &border,
+ cr, x, y, width, height);
+ _gtk_border_image_unref (border_image);
}
else if (border_style != GTK_BORDER_STYLE_NONE)
render_frame_internal (engine, cr,
gdouble height)
{
GtkStateFlags flags;
- GdkRGBA *outline_color, *fg_color;
+ GdkRGBA outline_color, fg_color;
double vertical_overshoot;
int diameter;
double radius;
cairo_save (cr);
flags = gtk_theming_engine_get_state (engine);
- gtk_theming_engine_get (engine, flags,
- "color", &fg_color,
- NULL);
- gtk_theming_engine_get (engine, flags,
- "border-color", &outline_color,
- NULL);
+ gtk_theming_engine_get_color (engine, flags, &fg_color);
+ gtk_theming_engine_get_border_color (engine, flags, &outline_color);
running = gtk_theming_engine_state_is_running (engine, GTK_STATE_ACTIVE, &progress);
is_rtl = (gtk_theming_engine_get_direction (engine) == GTK_TEXT_DIR_RTL);
cairo_set_line_width (cr, line_width);
- gdk_cairo_set_source_rgba (cr, fg_color);
+ gdk_cairo_set_source_rgba (cr, &fg_color);
cairo_fill_preserve (cr);
- gdk_cairo_set_source_rgba (cr, outline_color);
+ gdk_cairo_set_source_rgba (cr, &outline_color);
cairo_stroke (cr);
cairo_restore (cr);
-
- gdk_rgba_free (fg_color);
- gdk_rgba_free (outline_color);
}
static void
gdouble height)
{
GtkStateFlags flags;
- GdkRGBA *color;
+ GdkRGBA color;
gint line_width;
gint8 *dash_list;
cairo_save (cr);
flags = gtk_theming_engine_get_state (engine);
- gtk_theming_engine_get (engine, flags,
- "color", &color,
- NULL);
+ gtk_theming_engine_get_color (engine, flags, &color);
gtk_theming_engine_get_style (engine,
"focus-line-width", &line_width,
width - line_width,
height - line_width);
- gdk_cairo_set_source_rgba (cr, color);
+ gdk_cairo_set_source_rgba (cr, &color);
cairo_stroke (cr);
cairo_restore (cr);
- gdk_rgba_free (color);
g_free (dash_list);
}
gdouble x1,
gdouble y1)
{
- GdkRGBA *bg_color, darker, lighter;
+ GdkRGBA bg_color, darker, lighter;
GtkStateFlags flags;
gint i, thickness, thickness_dark, thickness_light, len;
cairo_matrix_t matrix;
flags = gtk_theming_engine_get_state (engine);
cairo_save (cr);
- gtk_theming_engine_get (engine, flags,
- "background-color", &bg_color,
- NULL);
- color_shade (bg_color, 0.7, &darker);
- color_shade (bg_color, 1.3, &lighter);
+ gtk_theming_engine_get_background_color (engine, flags, &bg_color);
+ color_shade (&bg_color, 0.7, &darker);
+ color_shade (&bg_color, 1.3, &lighter);
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
cairo_set_line_width (cr, 1);
}
cairo_restore (cr);
+}
- gdk_rgba_free (bg_color);
+static void
+prepare_context_for_layout (cairo_t *cr,
+ gdouble x,
+ gdouble y,
+ PangoLayout *layout)
+{
+ const PangoMatrix *matrix;
+
+ matrix = pango_context_get_matrix (pango_layout_get_context (layout));
+
+ cairo_move_to (cr, x, y);
+
+ if (matrix)
+ {
+ cairo_matrix_t cairo_matrix;
+
+ cairo_matrix_init (&cairo_matrix,
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0, matrix->y0);
+
+ cairo_transform (cr, &cairo_matrix);
+ }
}
static void
gdouble y,
PangoLayout *layout)
{
- const PangoMatrix *matrix;
- GdkRGBA *fg_color;
+ GdkRGBA fg_color;
+ GtkShadow *text_shadow = NULL;
GtkStateFlags flags;
gdouble progress;
gboolean running;
cairo_save (cr);
flags = gtk_theming_engine_get_state (engine);
-
- gtk_theming_engine_get (engine, flags,
- "color", &fg_color,
- NULL);
-
- matrix = pango_context_get_matrix (pango_layout_get_context (layout));
+ gtk_theming_engine_get_color (engine, flags, &fg_color);
running = gtk_theming_engine_state_is_running (engine, GTK_STATE_PRELIGHT, &progress);
if (running)
{
GtkStateFlags other_flags;
- GdkRGBA *other_fg;
+ GdkRGBA other_fg;
if (flags & GTK_STATE_FLAG_PRELIGHT)
{
else
other_flags = flags | GTK_STATE_FLAG_PRELIGHT;
- gtk_theming_engine_get (engine, other_flags,
- "color", &other_fg,
- NULL);
-
- if (fg_color && other_fg)
- {
- fg_color->red = CLAMP (fg_color->red + ((other_fg->red - fg_color->red) * progress), 0, 1);
- fg_color->green = CLAMP (fg_color->green + ((other_fg->green - fg_color->green) * progress), 0, 1);
- fg_color->blue = CLAMP (fg_color->blue + ((other_fg->blue - fg_color->blue) * progress), 0, 1);
- fg_color->alpha = CLAMP (fg_color->alpha + ((other_fg->alpha - fg_color->alpha) * progress), 0, 1);
- }
+ gtk_theming_engine_get_color (engine, other_flags, &other_fg);
- if (other_fg)
- gdk_rgba_free (other_fg);
+ fg_color.red = CLAMP (fg_color.red + ((other_fg.red - fg_color.red) * progress), 0, 1);
+ fg_color.green = CLAMP (fg_color.green + ((other_fg.green - fg_color.green) * progress), 0, 1);
+ fg_color.blue = CLAMP (fg_color.blue + ((other_fg.blue - fg_color.blue) * progress), 0, 1);
+ fg_color.alpha = CLAMP (fg_color.alpha + ((other_fg.alpha - fg_color.alpha) * progress), 0, 1);
}
- if (matrix)
- {
- cairo_matrix_t cairo_matrix;
- PangoRectangle rect;
-
- cairo_matrix_init (&cairo_matrix,
- matrix->xx, matrix->yx,
- matrix->xy, matrix->yy,
- matrix->x0, matrix->y0);
-
- pango_layout_get_extents (layout, NULL, &rect);
- pango_matrix_transform_rectangle (matrix, &rect);
- pango_extents_to_pixels (&rect, NULL);
-
- cairo_matrix.x0 += x - rect.x;
- cairo_matrix.y0 += y - rect.y;
+ gtk_theming_engine_get (engine, flags,
+ "text-shadow", &text_shadow,
+ NULL);
- cairo_set_matrix (cr, &cairo_matrix);
- }
- else
- cairo_move_to (cr, x, y);
+ prepare_context_for_layout (cr, x, y, layout);
- if (flags & GTK_STATE_FLAG_INSENSITIVE)
+ if (text_shadow != NULL)
{
- cairo_save (cr);
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_move_to (cr, x + 1, y + 1);
- _gtk_pango_fill_layout (cr, layout);
- cairo_restore (cr);
+ _gtk_text_shadow_paint_layout (text_shadow, cr, layout);
+ _gtk_shadow_unref (text_shadow);
}
- gdk_cairo_set_source_rgba (cr, fg_color);
+ gdk_cairo_set_source_rgba (cr, &fg_color);
pango_cairo_show_layout (cr, layout);
cairo_restore (cr);
-
- gdk_rgba_free (fg_color);
}
static void
{
GtkJunctionSides junction;
GtkStateFlags state;
- gint border_width, radius;
+ gint border_width;
+ GtkCssBorderCornerRadius *top_left_radius, *top_right_radius;
+ GtkCssBorderCornerRadius *bottom_left_radius, *bottom_right_radius;
+ GtkCssBorderRadius border_radius = { { 0, }, };
gdouble x0, y0, x1, y1, xc, yc, wc, hc;
- GtkBorder *border;
+ GtkBorder border;
xc = yc = wc = hc = 0;
state = gtk_theming_engine_get_state (engine);
junction = gtk_theming_engine_get_junction_sides (engine);
+
+ gtk_theming_engine_get_border (engine, state, &border);
gtk_theming_engine_get (engine, state,
- "border-width", &border,
- "border-radius", &radius,
+ /* Can't use border-radius as it's an int for
+ * backwards compat */
+ "border-top-left-radius", &top_left_radius,
+ "border-top-right-radius", &top_right_radius,
+ "border-bottom-right-radius", &bottom_right_radius,
+ "border-bottom-left-radius", &bottom_left_radius,
NULL);
- border_width = MIN (MIN (border->top, border->bottom),
- MIN (border->left, border->right));
+ if (top_left_radius)
+ border_radius.top_left = *top_left_radius;
+ g_free (top_left_radius);
+ if (top_right_radius)
+ border_radius.top_right = *top_right_radius;
+ g_free (top_right_radius);
+ if (bottom_right_radius)
+ border_radius.bottom_right = *bottom_right_radius;
+ g_free (bottom_right_radius);
+ if (bottom_left_radius)
+ border_radius.bottom_left = *bottom_left_radius;
+ g_free (bottom_left_radius);
+
+ border_width = MIN (MIN (border.top, border.bottom),
+ MIN (border.left, border.right));
cairo_save (cr);
wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
hc = border_width;
- if (xy0_gap < radius)
+ if (xy0_gap < border_radius.top_left.horizontal)
junction |= GTK_JUNCTION_CORNER_TOPLEFT;
- if (xy1_gap > width - radius)
+ if (xy1_gap > width - border_radius.top_right.horizontal)
junction |= GTK_JUNCTION_CORNER_TOPRIGHT;
break;
case GTK_POS_BOTTOM:
wc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
hc = border_width;
- if (xy0_gap < radius)
+ if (xy0_gap < border_radius.bottom_left.horizontal)
junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT;
- if (xy1_gap > width - radius)
+ if (xy1_gap > width - border_radius.bottom_right.horizontal)
junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT;
break;
wc = border_width;
hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
- if (xy0_gap < radius)
+ if (xy0_gap < border_radius.top_left.vertical)
junction |= GTK_JUNCTION_CORNER_TOPLEFT;
- if (xy1_gap > height - radius)
+ if (xy1_gap > height - border_radius.bottom_left.vertical)
junction |= GTK_JUNCTION_CORNER_BOTTOMLEFT;
break;
wc = border_width;
hc = MAX (xy1_gap - xy0_gap - 2 * border_width, 0);
- if (xy0_gap < radius)
+ if (xy0_gap < border_radius.top_right.vertical)
junction |= GTK_JUNCTION_CORNER_TOPRIGHT;
- if (xy1_gap > height - radius)
+ if (xy1_gap > height - border_radius.bottom_right.vertical)
junction |= GTK_JUNCTION_CORNER_BOTTOMRIGHT;
break;
0, junction);
cairo_restore (cr);
-
- gtk_border_free (border);
}
static void
gdouble height)
{
GtkStateFlags flags;
- GdkRGBA *bg_color;
- GdkRGBA lighter, darker;
+ GdkRGBA bg_color, lighter, darker;
+ GtkJunctionSides sides;
gint xx, yy;
cairo_save (cr);
flags = gtk_theming_engine_get_state (engine);
- cairo_set_line_width (cr, 1);
+ cairo_set_line_width (cr, 1.0);
+ sides = gtk_theming_engine_get_junction_sides (engine);
+ gtk_theming_engine_get_background_color (engine, flags, &bg_color);
- gtk_theming_engine_get (engine, flags,
- "background-color", &bg_color,
- NULL);
- color_shade (bg_color, 0.7, &darker);
- color_shade (bg_color, 1.3, &lighter);
+ color_shade (&bg_color, 0.7, &darker);
+ color_shade (&bg_color, 1.3, &lighter);
- gdk_cairo_set_source_rgba (cr, bg_color);
- cairo_rectangle (cr, x, y, width, height);
- cairo_fill (cr);
+ render_background_internal (engine, cr, x, y, width, height, sides);
if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_GRIP))
{
- GtkJunctionSides sides;
-
- cairo_save (cr);
-
- cairo_set_line_width (cr, 1.0);
- sides = gtk_theming_engine_get_junction_sides (engine);
-
/* reduce confusing values to a meaningful state */
if ((sides & (GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMRIGHT)) == (GTK_JUNCTION_CORNER_TOPLEFT | GTK_JUNCTION_CORNER_BOTTOMRIGHT))
sides &= ~GTK_JUNCTION_CORNER_TOPLEFT;
yi += 3;
}
}
-
- cairo_restore (cr);
}
else if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_PANE_SEPARATOR))
{
}
cairo_restore (cr);
-
- gdk_rgba_free (bg_color);
}
-static void
-gtk_theming_engine_render_activity (GtkThemingEngine *engine,
- cairo_t *cr,
- gdouble x,
- gdouble y,
- gdouble width,
- gdouble height)
+void
+_gtk_theming_engine_paint_spinner (cairo_t *cr,
+ gdouble radius,
+ gdouble progress,
+ GdkRGBA *color)
{
- if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_SPINNER))
- {
- GtkStateFlags state;
- guint num_steps, step;
- GdkRGBA *color;
- gdouble dx, dy;
- gdouble progress;
- gdouble radius;
- gdouble half;
- gint i;
+ guint num_steps, step;
+ gdouble half;
+ gint i;
- num_steps = 12;
+ num_steps = 12;
- state = gtk_theming_engine_get_state (engine);
- gtk_theming_engine_get (engine, state,
- "color", &color,
- NULL);
+ if (progress >= 0)
+ step = (guint) (progress * num_steps);
+ else
+ step = 0;
- if (gtk_theming_engine_state_is_running (engine, GTK_STATE_ACTIVE, &progress))
- step = (guint) (progress * num_steps);
- else
- step = 0;
+ cairo_save (cr);
- cairo_save (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_line_width (cr, 2.0);
- cairo_translate (cr, x, y);
+ half = num_steps / 2;
- /* draw clip region */
- cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ for (i = 0; i < num_steps; i++)
+ {
+ gint inset = 0.7 * radius;
+
+ /* transparency is a function of time and intial value */
+ gdouble t = 1.0 - (gdouble) ((i + step) % num_steps) / num_steps;
+ gdouble xscale = - sin (i * G_PI / half);
+ gdouble yscale = - cos (i * G_PI / half);
+
+ cairo_set_source_rgba (cr,
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha * t);
+
+ cairo_move_to (cr,
+ (radius - inset) * xscale,
+ (radius - inset) * yscale);
+ cairo_line_to (cr,
+ radius * xscale,
+ radius * yscale);
- dx = width / 2;
- dy = height / 2;
- radius = MIN (width / 2, height / 2);
- half = num_steps / 2;
+ cairo_stroke (cr);
+ }
- for (i = 0; i < num_steps; i++)
- {
- gint inset = 0.7 * radius;
+ cairo_restore (cr);
+}
- /* transparency is a function of time and intial value */
- gdouble t = (gdouble) ((i + num_steps - step)
- % num_steps) / num_steps;
+static void
+render_spinner (GtkThemingEngine *engine,
+ cairo_t *cr,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height)
+{
+ GtkStateFlags state;
+ GtkShadow *shadow;
+ GdkRGBA color;
+ gdouble progress;
+ gdouble radius;
- cairo_save (cr);
+ state = gtk_theming_engine_get_state (engine);
- cairo_set_source_rgba (cr,
- color->red,
- color->green,
- color->blue,
- color->alpha * t);
-
- cairo_set_line_width (cr, 2.0);
- cairo_move_to (cr,
- dx + (radius - inset) * cos (i * G_PI / half),
- dy + (radius - inset) * sin (i * G_PI / half));
- cairo_line_to (cr,
- dx + radius * cos (i * G_PI / half),
- dy + radius * sin (i * G_PI / half));
- cairo_stroke (cr);
+ if (!gtk_theming_engine_state_is_running (engine, GTK_STATE_ACTIVE, &progress))
+ progress = -1;
- cairo_restore (cr);
- }
+ radius = MIN (width / 2, height / 2);
- cairo_restore (cr);
+ gtk_theming_engine_get_color (engine, state, &color);
+ gtk_theming_engine_get (engine, state,
+ "icon-shadow", &shadow,
+ NULL);
- gdk_rgba_free (color);
+ cairo_save (cr);
+ cairo_translate (cr, x + width / 2, y + height / 2);
+
+ if (shadow != NULL)
+ {
+ _gtk_icon_shadow_paint_spinner (shadow, cr,
+ radius,
+ progress);
+ _gtk_shadow_unref (shadow);
+ }
+
+ _gtk_theming_engine_paint_spinner (cr,
+ radius,
+ progress,
+ &color);
+
+ cairo_restore (cr);
+}
+
+static void
+gtk_theming_engine_render_activity (GtkThemingEngine *engine,
+ cairo_t *cr,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height)
+{
+ if (gtk_theming_engine_has_class (engine, GTK_STYLE_CLASS_SPINNER))
+ {
+ render_spinner (engine, cr, x, y, width, height);
}
else
{
return gtk_icon_size_lookup_for_settings (settings, size, width, height);
}
-/* Kudos to the gnome-panel guys. */
static void
-colorshift_pixbuf (GdkPixbuf *src,
- GdkPixbuf *dest,
- gint shift)
-{
- gint i, j;
- gint width, height, has_alpha, src_rowstride, dest_rowstride;
- guchar *target_pixels;
- guchar *original_pixels;
- guchar *pix_src;
- guchar *pix_dest;
- int val;
- guchar r, g, b;
-
- has_alpha = gdk_pixbuf_get_has_alpha (src);
- width = gdk_pixbuf_get_width (src);
- height = gdk_pixbuf_get_height (src);
- src_rowstride = gdk_pixbuf_get_rowstride (src);
- dest_rowstride = gdk_pixbuf_get_rowstride (dest);
- original_pixels = gdk_pixbuf_get_pixels (src);
- target_pixels = gdk_pixbuf_get_pixels (dest);
-
- for (i = 0; i < height; i++)
- {
- pix_dest = target_pixels + i * dest_rowstride;
- pix_src = original_pixels + i * src_rowstride;
+colorshift_source (cairo_t *cr,
+ gdouble shift)
+{
+ cairo_pattern_t *source;
- for (j = 0; j < width; j++)
- {
- r = *(pix_src++);
- g = *(pix_src++);
- b = *(pix_src++);
+ cairo_save (cr);
+ cairo_paint (cr);
- val = r + shift;
- *(pix_dest++) = CLAMP (val, 0, 255);
+ source = cairo_pattern_reference (cairo_get_source (cr));
- val = g + shift;
- *(pix_dest++) = CLAMP (val, 0, 255);
+ cairo_set_source_rgb (cr, shift, shift, shift);
+ cairo_set_operator (cr, CAIRO_OPERATOR_COLOR_DODGE);
- val = b + shift;
- *(pix_dest++) = CLAMP (val, 0, 255);
+ cairo_mask (cr, source);
- if (has_alpha)
- *(pix_dest++) = *(pix_src++);
- }
- }
+ cairo_pattern_destroy (source);
+ cairo_restore (cr);
}
static GdkPixbuf *
GtkStateFlags state;
gint width = 1;
gint height = 1;
+ cairo_t *cr;
+ cairo_surface_t *surface;
base_pixbuf = gtk_icon_source_get_pixbuf (source);
state = gtk_theming_engine_get_state (engine);
{
if (state & GTK_STATE_FLAG_INSENSITIVE)
{
- stated = gdk_pixbuf_copy (scaled);
- gdk_pixbuf_saturate_and_pixelate (scaled, stated,
- 0.8, TRUE);
- g_object_unref (scaled);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ gdk_pixbuf_get_width (scaled),
+ gdk_pixbuf_get_height (scaled));
+ cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, scaled, 0, 0);
+ cairo_paint_with_alpha (cr, 0.5);
+
+ cairo_destroy (cr);
+
+ g_object_unref (scaled);
+ stated = gdk_pixbuf_get_from_surface (surface, 0, 0,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
}
else if (state & GTK_STATE_FLAG_PRELIGHT)
{
- stated = gdk_pixbuf_copy (scaled);
- colorshift_pixbuf (scaled, stated, 30);
- g_object_unref (scaled);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ gdk_pixbuf_get_width (scaled),
+ gdk_pixbuf_get_height (scaled));
+
+ cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, scaled, 0, 0);
+ colorshift_source (cr, 0.10);
+
+ cairo_destroy (cr);
+
+ g_object_unref (scaled);
+ stated = gdk_pixbuf_get_from_surface (surface, 0, 0,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
}
else
stated = scaled;
return stated;
}
+
+static void
+gtk_theming_engine_render_icon (GtkThemingEngine *engine,
+ cairo_t *cr,
+ GdkPixbuf *pixbuf,
+ gdouble x,
+ gdouble y)
+{
+ GtkStateFlags state;
+ GtkShadow *icon_shadow;
+
+ state = gtk_theming_engine_get_state (engine);
+
+ cairo_save (cr);
+
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, x, y);
+
+ gtk_theming_engine_get (engine, state,
+ "icon-shadow", &icon_shadow,
+ NULL);
+
+ if (icon_shadow != NULL)
+ {
+ _gtk_icon_shadow_paint (icon_shadow, cr);
+ _gtk_shadow_unref (icon_shadow);
+ }
+
+ cairo_paint (cr);
+
+ cairo_restore (cr);
+}
+