void gtk_css_style_print (GtkCssStyle *style, GString *string) { guint i; g_return_if_fail (GTK_IS_CSS_STYLE (style)); g_return_if_fail (string != NULL); for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++) { GtkCssSection *section = gtk_css_style_get_section (style, i); g_string_append (string, _gtk_style_property_get_name (GTK_STYLE_PROPERTY (_gtk_css_style_property_lookup_by_id (i)))); g_string_append (string, ": "); _gtk_css_value_print (gtk_css_style_get_value (style, i), string); g_string_append (string, ";"); if (section) { g_string_append (string, " /* "); _gtk_css_section_print (section, string); g_string_append (string, " */"); } g_string_append (string, "\n"); } }
/** * _gtk_css_lookup_resolve: * @lookup: the lookup * @context: the context the values are resolved for * @values: a new #GtkCssStyle to be filled with the new properties * * Resolves the current lookup into a styleproperties object. This is done * by converting from the “winning declaration” to the “computed value”. * * XXX: This bypasses the notion of “specified value”. If this ever becomes * an issue, go fix it. **/ void _gtk_css_lookup_resolve (GtkCssLookup *lookup, GtkStyleProviderPrivate *provider, GtkCssStaticStyle *style, GtkCssStyle *parent_style) { guint i, n; gtk_internal_return_if_fail (lookup != NULL); gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER_PRIVATE (provider)); gtk_internal_return_if_fail (GTK_IS_CSS_STATIC_STYLE (style)); gtk_internal_return_if_fail (parent_style == NULL || GTK_IS_CSS_STYLE (parent_style)); n = _gtk_css_style_property_get_n_properties (); for (i = 0; i < n; i++) { if (lookup->values[i].value || _gtk_bitmask_get (lookup->missing, i)) gtk_css_static_style_compute_value (GTK_CSS_STATIC_STYLE (style), provider, parent_style, i, lookup->values[i].value, lookup->values[i].section); /* else not a relevant property */ } }
gboolean gtk_css_style_is_static (GtkCssStyle *style) { gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (style), TRUE); return GTK_CSS_STYLE_GET_CLASS (style)->is_static (style); }
GtkCssSection * gtk_css_style_get_section (GtkCssStyle *style, guint id) { gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (style), NULL); return GTK_CSS_STYLE_GET_CLASS (style)->get_section (style, id); }
GtkCssImage * _gtk_css_image_compute (GtkCssImage *image, guint property_id, GtkStyleProviderPrivate *provider, GtkCssStyle *style, GtkCssStyle *parent_style) { GtkCssImageClass *klass; g_return_val_if_fail (GTK_IS_CSS_IMAGE (image), NULL); g_return_val_if_fail (GTK_IS_CSS_STYLE (style), NULL); g_return_val_if_fail (parent_style == NULL || GTK_IS_CSS_STYLE (parent_style), NULL); klass = GTK_CSS_IMAGE_GET_CLASS (image); return klass->compute (image, property_id, provider, style, parent_style); }
void gtk_css_style_render_icon_surface (GtkCssStyle *style, cairo_t *cr, cairo_surface_t *surface, double x, double y) { const GtkCssValue *shadows; cairo_matrix_t matrix, transform_matrix, saved_matrix; GdkRectangle extents; g_return_if_fail (GTK_IS_CSS_STYLE (style)); g_return_if_fail (cr != NULL); g_return_if_fail (surface != NULL); shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW); if (!get_surface_extents (surface, &extents)) { /* weird infinite surface, no special magic for you */ cairo_set_source_surface (cr, surface, x, y); _gtk_css_shadows_value_paint_icon (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW), cr); cairo_paint (cr); return; } cairo_get_matrix (cr, &saved_matrix); cairo_translate (cr, x + extents.x, y + extents.y); if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix)) { cairo_pattern_t *pattern; /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */ cairo_matrix_init_translate (&matrix, extents.width / 2, extents.height / 2); cairo_matrix_multiply (&matrix, &transform_matrix, &matrix); cairo_matrix_translate (&matrix, - extents.width / 2, - extents.height / 2); if (cairo_matrix_invert (&matrix) != CAIRO_STATUS_SUCCESS) { g_assert_not_reached (); } cairo_matrix_translate (&matrix, extents.x, extents.y); pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_matrix (pattern, &matrix); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); _gtk_css_shadows_value_paint_icon (shadows, cr); cairo_paint (cr); } cairo_set_matrix (cr, &saved_matrix); }
char * gtk_css_style_to_string (GtkCssStyle *style) { GString *string; g_return_val_if_fail (GTK_IS_CSS_STYLE (style), NULL); string = g_string_new (""); gtk_css_style_print (style, string); return g_string_free (string, FALSE); }
void gtk_css_style_render_icon (GtkCssStyle *style, cairo_t *cr, double x, double y, double width, double height, GtkCssImageBuiltinType builtin_type) { const GtkCssValue *shadows; cairo_matrix_t matrix, transform_matrix, saved_matrix; GtkCssImage *image; g_return_if_fail (GTK_IS_CSS_STYLE (style)); g_return_if_fail (cr != NULL); image = _gtk_css_image_value_get_image (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SOURCE)); if (image == NULL) return; cairo_get_matrix (cr, &saved_matrix); shadows = gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_SHADOW); cairo_translate (cr, x, y); if (_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_ICON_TRANSFORM), &transform_matrix)) { /* XXX: Implement -gtk-icon-transform-origin instead of hardcoding "50% 50%" here */ cairo_matrix_init_translate (&matrix, width / 2, height / 2); cairo_matrix_multiply (&matrix, &transform_matrix, &matrix); cairo_matrix_translate (&matrix, - width / 2, - height / 2); if (_gtk_css_shadows_value_is_none (shadows)) { cairo_transform (cr, &matrix); gtk_css_image_builtin_draw (image, cr, width, height, builtin_type); } else { cairo_push_group (cr); cairo_transform (cr, &matrix); gtk_css_image_builtin_draw (image, cr, width, height, builtin_type); cairo_pop_group_to_source (cr); _gtk_css_shadows_value_paint_icon (shadows, cr); cairo_paint (cr); } } cairo_set_matrix (cr, &saved_matrix); }
GtkCssStyle * gtk_css_animated_style_new (GtkCssStyle *base_style, GtkCssStyle *parent_style, gint64 timestamp, GtkStyleProviderPrivate *provider, GtkCssStyle *previous_style) { GtkCssAnimatedStyle *result; GSList *animations; gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (base_style), NULL); gtk_internal_return_val_if_fail (parent_style == NULL || GTK_IS_CSS_STYLE (parent_style), NULL); gtk_internal_return_val_if_fail (GTK_IS_STYLE_PROVIDER (provider), NULL); gtk_internal_return_val_if_fail (previous_style == NULL || GTK_IS_CSS_STYLE (previous_style), NULL); if (timestamp == 0) return g_object_ref (base_style); animations = NULL; if (previous_style != NULL) animations = gtk_css_animated_style_create_css_transitions (animations, base_style, timestamp, previous_style); animations = gtk_css_animated_style_create_css_animations (animations, base_style, parent_style, timestamp, provider, previous_style); if (animations == NULL) return g_object_ref (base_style); result = g_object_new (GTK_TYPE_CSS_ANIMATED_STYLE, NULL); result->style = g_object_ref (base_style); result->current_time = timestamp; result->animations = animations; gtk_css_animated_style_apply_animations (result); return GTK_CSS_STYLE (result); }
/* * gtk_css_style_print: * @style: a #GtkCssStyle * @string: the #GString to print to * @indent: level of indentation to use * @skip_initial: %TRUE to skip properties that have their initial value * * Print the @style to @string, in CSS format. Every property is printed * on a line by itself, indented by @indent spaces. If @skip_initial is * %TRUE, properties are only printed if their value in @style is different * from the initial value of the property. * * Returns: %TRUE is any properties have been printed */ gboolean gtk_css_style_print (GtkCssStyle *style, GString *string, guint indent, gboolean skip_initial) { guint i; gboolean retval = FALSE; g_return_val_if_fail (GTK_IS_CSS_STYLE (style), FALSE); g_return_val_if_fail (string != NULL, FALSE); for (i = 0; i < _gtk_css_style_property_get_n_properties (); i++) { GtkCssSection *section; GtkCssStyleProperty *prop; GtkCssValue *value; const char *name; section = gtk_css_style_get_section (style, i); if (!section && skip_initial) continue; prop = _gtk_css_style_property_lookup_by_id (i); name = _gtk_style_property_get_name (GTK_STYLE_PROPERTY (prop)); value = gtk_css_style_get_value (style, i); g_string_append_printf (string, "%*s%s: ", indent, "", name); _gtk_css_value_print (value, string); g_string_append_c (string, ';'); if (section) { g_string_append (string, " /* "); _gtk_css_section_print (section, string); g_string_append (string, " */"); } g_string_append_c (string, '\n'); retval = TRUE; } return retval; }
GtkCssStyle * gtk_css_animated_style_new_advance (GtkCssAnimatedStyle *source, GtkCssStyle *base, gint64 timestamp) { GtkCssAnimatedStyle *result; GSList *l, *animations; gtk_internal_return_val_if_fail (GTK_IS_CSS_ANIMATED_STYLE (source), NULL); gtk_internal_return_val_if_fail (GTK_IS_CSS_STYLE (base), NULL); if (timestamp == 0 || timestamp == source->current_time) return g_object_ref (source->style); gtk_internal_return_val_if_fail (timestamp > source->current_time, NULL); animations = NULL; for (l = source->animations; l; l = l->next) { GtkStyleAnimation *animation = l->data; if (_gtk_style_animation_is_finished (animation)) continue; animation = _gtk_style_animation_advance (animation, timestamp); animations = g_slist_prepend (animations, animation); } animations = g_slist_reverse (animations); if (animations == NULL) return g_object_ref (source->style); result = g_object_new (GTK_TYPE_CSS_ANIMATED_STYLE, NULL); result->style = g_object_ref (base); result->current_time = timestamp; result->animations = animations; gtk_css_animated_style_apply_animations (result); return GTK_CSS_STYLE (result); }
void gtk_css_style_render_icon_get_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_if_fail (GTK_IS_CSS_STYLE (style)); g_return_if_fail (extents != NULL); extents->x = x; extents->y = y; extents->width = width; extents->height = height; if (!_gtk_css_transform_value_get_matrix (gtk_css_style_get_value (style, 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_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; }