void _gtk_icon_helper_draw (GtkIconHelper *self, GtkStyleContext *context, cairo_t *cr, gdouble x, gdouble y) { cairo_surface_t *surface; surface = _gtk_icon_helper_ensure_surface (self, context); if (surface != NULL) { gtk_render_icon_surface (context, cr, surface, x, y); cairo_surface_destroy (surface); } }
static gboolean gtk_color_swatch_render_overlay (GtkCssGadget *gadget, cairo_t *cr, int x, int y, int width, int height, gpointer data) { GtkWidget *widget; GtkColorSwatch *swatch; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkIconInfo *icon_info = NULL; gint scale; widget = gtk_css_gadget_get_owner (gadget); swatch = GTK_COLOR_SWATCH (widget); theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_style_context_get_state (context); scale = gtk_widget_get_scale_factor (widget); if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GIcon *gicon; gicon = g_themed_icon_new ("object-select-symbolic"); /* fallback for themes that don't have object-select-symbolic */ g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply"); icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } /* now draw the overlay image */ if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { cairo_surface_t *surface; surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget)); gtk_render_icon_surface (context, cr, surface, x, y); cairo_surface_destroy (surface); g_object_unref (pixbuf); } g_object_unref (icon_info); } return FALSE; }
static gboolean swatch_draw (GtkWidget *widget, cairo_t *cr) { GtkColorSwatch *swatch = (GtkColorSwatch*)widget; gdouble width, height; GtkStyleContext *context; GtkStateFlags state; GtkIconTheme *theme; GtkBorder border, padding; GdkRectangle rect; GtkIconInfo *icon_info = NULL; gint scale; theme = gtk_icon_theme_get_default (); context = gtk_widget_get_style_context (widget); state = gtk_style_context_get_state (context); width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); gtk_render_background (context, cr, 0, 0, width, height); if (swatch->priv->has_color) { cairo_pattern_t *pattern; cairo_matrix_t matrix; gtk_render_content_path (context, cr, 0, 0, width, height); if (swatch->priv->use_alpha) { cairo_save (cr); cairo_clip_preserve (cr); cairo_set_source_rgb (cr, 0.33, 0.33, 0.33); cairo_fill_preserve (cr); pattern = _gtk_color_chooser_get_checkered_pattern (); cairo_matrix_init_scale (&matrix, 0.125, 0.125); cairo_pattern_set_matrix (pattern, &matrix); cairo_set_source_rgb (cr, 0.66, 0.66, 0.66); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); cairo_restore (cr); gdk_cairo_set_source_rgba (cr, &swatch->priv->color); } else { cairo_set_source_rgb (cr, swatch->priv->color.red, swatch->priv->color.green, swatch->priv->color.blue); } cairo_fill (cr); } gtk_render_frame (context, cr, 0, 0, width, height); scale = gtk_widget_get_scale_factor (widget); if (swatch->priv->icon) { icon_info = gtk_icon_theme_lookup_icon_for_scale (theme, swatch->priv->icon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); } else if ((state & GTK_STATE_FLAG_SELECTED) != 0) { GIcon *gicon; gicon = g_themed_icon_new ("object-select-symbolic"); /* fallback for themes that don't have object-select-symbolic */ g_themed_icon_append_name (G_THEMED_ICON (gicon), "gtk-apply"); icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, gicon, PIXBUF_SIZE, scale, GTK_ICON_LOOKUP_GENERIC_FALLBACK | GTK_ICON_LOOKUP_USE_BUILTIN); g_object_unref (gicon); } /* now draw the overlay image */ gtk_style_context_get_border (context, state, &border); gtk_style_context_get_padding (context, state, &padding); rect.width = width - (border.left + border.right + padding.left + padding.right); rect.height = height - (border.top + border.bottom + padding.top + padding.bottom); rect.x = border.left + padding.left; rect.y = border.top + padding.top; gtk_style_context_save_to_node (context, swatch->priv->overlay_node); gtk_render_background (context, cr, rect.x, rect.y, rect.width, rect.height); gtk_render_frame (context, cr, rect.x, rect.y, rect.width, rect.height); if (icon_info != NULL) { GdkPixbuf *pixbuf; pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, context, NULL, NULL); if (pixbuf != NULL) { cairo_surface_t *surface; surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, gtk_widget_get_window (widget)); gtk_render_icon_surface (context, cr, surface, rect.x + (rect.width - (gdk_pixbuf_get_width (pixbuf) / scale)) / 2, rect.y + (rect.height - (gdk_pixbuf_get_height (pixbuf) / scale)) / 2); cairo_surface_destroy (surface); g_object_unref (pixbuf); } g_object_unref (icon_info); } if (gtk_widget_has_visible_focus (widget)) gtk_render_focus (context, cr, 0, 0, width, height); gtk_style_context_restore (context); return FALSE; }
GIcon * photos_utils_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale) { g_autoptr (GIcon) icon = NULL; GIcon *ret_val = NULL; g_autoptr (GdkPixbuf) pixbuf = NULL; g_autoptr (GtkIconInfo) info = NULL; GtkIconTheme *theme; g_autoptr (GtkStyleContext) style = NULL; g_autoptr (GtkWidgetPath) path = NULL; cairo_surface_t *icon_surface = NULL; /* TODO: use g_autoptr */ cairo_surface_t *surface; /* TODO: use g_autoptr */ cairo_t *cr; /* TODO: use g_autoptr */ g_autofree gchar *symbolic_name = NULL; const gint bg_size = 24; const gint emblem_margin = 4; gint emblem_pos; gint emblem_size; gint total_size; gint total_size_scaled; total_size = base_size / 2; total_size_scaled = total_size * scale; emblem_size = bg_size - emblem_margin * 2; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled); cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale); cr = cairo_create (surface); style = gtk_style_context_new (); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (style, path); gtk_style_context_add_class (style, "photos-icon-bg"); gtk_render_background (style, cr, total_size - bg_size, total_size - bg_size, bg_size, bg_size); symbolic_name = g_strconcat (name, "-symbolic", NULL); icon = g_themed_icon_new_with_default_fallbacks (symbolic_name); theme = gtk_icon_theme_get_default(); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); if (info == NULL) goto out; pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); if (pixbuf == NULL) goto out; icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL); emblem_pos = total_size - emblem_size - emblem_margin; gtk_render_icon_surface (style, cr, icon_surface, emblem_pos, emblem_pos); ret_val = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled)); out: cairo_surface_destroy (icon_surface); cairo_surface_destroy (surface); cairo_destroy (cr); return ret_val; }
static void gd_tagged_entry_tag_draw (GdTaggedEntryTag *tag, cairo_t *cr, GdTaggedEntry *entry) { GtkStyleContext *context; GtkStateFlags state; GtkAllocation background_allocation, layout_allocation, button_allocation; context = gd_tagged_entry_tag_get_context (tag, entry); gd_tagged_entry_tag_get_relative_allocations (tag, entry, context, &background_allocation, &layout_allocation, &button_allocation); cairo_save (cr); gtk_cairo_transform_to_window (cr, GTK_WIDGET (entry), tag->window); gtk_style_context_save (context); state = gd_tagged_entry_tag_get_state (tag, entry); gtk_style_context_set_state (context, state); gtk_render_background (context, cr, background_allocation.x, background_allocation.y, background_allocation.width, background_allocation.height); gtk_render_frame (context, cr, background_allocation.x, background_allocation.y, background_allocation.width, background_allocation.height); gtk_render_layout (context, cr, layout_allocation.x, layout_allocation.y, tag->layout); gtk_style_context_restore (context); if (!entry->button_visible || !tag->has_close_button) goto done; gtk_style_context_add_class (context, GTK_STYLE_CLASS_BUTTON); state = gd_tagged_entry_tag_get_button_state (tag, entry); gtk_style_context_set_state (context, state); /* if the state changed since last time we draw the pixbuf, * clear and redraw it. */ if (state != tag->last_button_state) { g_clear_pointer (&tag->close_surface, cairo_surface_destroy); gd_tagged_entry_tag_ensure_close_surface (tag, context); tag->last_button_state = state; } gtk_render_background (context, cr, button_allocation.x, button_allocation.y, button_allocation.width, button_allocation.height); gtk_render_frame (context, cr, button_allocation.x, button_allocation.y, button_allocation.width, button_allocation.height); gtk_render_icon_surface (context, cr, tag->close_surface, button_allocation.x, button_allocation.y); done: cairo_restore (cr); g_object_unref (context); }
/** * gd_create_symbolic_icon_for_scale: * @name: * @base_size: * @scale: * * Returns: (transfer full): */ GIcon * gd_create_symbolic_icon_for_scale (const gchar *name, gint base_size, gint scale) { gchar *symbolic_name; GIcon *icon, *retval = NULL; cairo_surface_t *icon_surface; cairo_surface_t *surface; cairo_t *cr; GtkStyleContext *style; GtkWidgetPath *path; GdkPixbuf *pixbuf; GtkIconTheme *theme; GtkIconInfo *info; gint bg_size; gint emblem_size; gint total_size; gint total_size_scaled; total_size = base_size / 2; total_size_scaled = total_size * scale; bg_size = MAX (total_size / 2, _BG_MIN_SIZE); emblem_size = MAX (bg_size - 8, _EMBLEM_MIN_SIZE); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, total_size_scaled, total_size_scaled); cairo_surface_set_device_scale (surface, (gdouble) scale, (gdouble) scale); cr = cairo_create (surface); style = gtk_style_context_new (); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (style, path); gtk_widget_path_unref (path); gtk_style_context_add_class (style, "documents-icon-bg"); gtk_render_background (style, cr, (total_size - bg_size) / 2, (total_size - bg_size) / 2, bg_size, bg_size); symbolic_name = g_strconcat (name, "-symbolic", NULL); icon = g_themed_icon_new_with_default_fallbacks (symbolic_name); g_free (symbolic_name); theme = gtk_icon_theme_get_default(); info = gtk_icon_theme_lookup_by_gicon_for_scale (theme, icon, emblem_size, scale, GTK_ICON_LOOKUP_FORCE_SIZE); g_object_unref (icon); if (info == NULL) goto out; pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); g_object_unref (info); if (pixbuf == NULL) goto out; icon_surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL); g_object_unref (pixbuf); gtk_render_icon_surface (style, cr, icon_surface, (total_size - emblem_size) / 2, (total_size - emblem_size) / 2); cairo_surface_destroy (icon_surface); retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, total_size_scaled, total_size_scaled)); out: g_object_unref (style); cairo_surface_destroy (surface); cairo_destroy (cr); return retval; }
/** * gd_embed_surface_in_frame: * @source_image: * @frame_image_url: * @slice_width: * @border_width: * * Returns: (transfer full): */ cairo_surface_t * gd_embed_surface_in_frame (cairo_surface_t *source_image, const gchar *frame_image_url, GtkBorder *slice_width, GtkBorder *border_width) { cairo_surface_t *surface; cairo_t *cr; int source_width, source_height; gchar *css_str; GtkCssProvider *provider; GtkStyleContext *context; GError *error = NULL; GdkPixbuf *retval; GtkWidgetPath *path; gdouble scale_x, scale_y; cairo_surface_get_device_scale (source_image, &scale_x, &scale_y); source_width = cairo_image_surface_get_width (source_image) / (gint) floor (scale_x), source_height = cairo_image_surface_get_height (source_image) / (gint) floor (scale_y); css_str = g_strdup_printf (".embedded-image { border-image: url(\"%s\") %d %d %d %d / %dpx %dpx %dpx %dpx }", frame_image_url, slice_width->top, slice_width->right, slice_width->bottom, slice_width->left, border_width->top, border_width->right, border_width->bottom, border_width->left); provider = gtk_css_provider_new (); gtk_css_provider_load_from_data (provider, css_str, -1, &error); if (error != NULL) { g_warning ("Unable to create the thumbnail frame image: %s", error->message); g_error_free (error); g_free (css_str); return g_object_ref (source_image); } surface = cairo_surface_create_similar (source_image, CAIRO_CONTENT_COLOR_ALPHA, source_width, source_height); cr = cairo_create (surface); context = gtk_style_context_new (); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (context, path); gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), 600); cairo_save (cr); cairo_rectangle (cr, border_width->left, border_width->top, source_width - border_width->left - border_width->right, source_height - border_width->top - border_width->bottom); cairo_clip (cr); gtk_render_icon_surface (context, cr, source_image, 0, 0); cairo_restore (cr); gtk_style_context_save (context); gtk_style_context_add_class (context, "embedded-image"); gtk_render_frame (context, cr, 0, 0, source_width, source_height); gtk_style_context_restore (context); cairo_destroy (cr); gtk_widget_path_unref (path); g_object_unref (provider); g_object_unref (context); g_free (css_str); return surface; }