forked from AuroraMiddleware/gtk
iconhelper: Add support for GskTexture
... and use that in GtkImage.
This commit is contained in:
parent
09359197a7
commit
1259a489f2
@ -43,6 +43,7 @@ struct _GtkIconHelperPrivate {
|
||||
guint rendered_surface_is_symbolic : 1;
|
||||
|
||||
cairo_surface_t *rendered_surface;
|
||||
GskTexture *texture;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET)
|
||||
@ -50,6 +51,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (GtkIconHelper, gtk_icon_helper, GTK_TYPE_CSS_GADGET)
|
||||
static void
|
||||
gtk_icon_helper_invalidate (GtkIconHelper *self)
|
||||
{
|
||||
g_clear_pointer (&self->priv->texture, gsk_texture_unref);
|
||||
|
||||
if (self->priv->rendered_surface != NULL)
|
||||
{
|
||||
cairo_surface_destroy (self->priv->rendered_surface);
|
||||
@ -95,6 +98,7 @@ gtk_icon_helper_take_definition (GtkIconHelper *self,
|
||||
void
|
||||
_gtk_icon_helper_clear (GtkIconHelper *self)
|
||||
{
|
||||
g_clear_pointer (&self->priv->texture, gsk_texture_unref);
|
||||
g_clear_pointer (&self->priv->rendered_surface, cairo_surface_destroy);
|
||||
|
||||
gtk_image_definition_unref (self->priv->def);
|
||||
@ -554,6 +558,34 @@ gtk_icon_helper_ensure_surface (GtkIconHelper *self)
|
||||
self->priv->rendered_surface = gtk_icon_helper_load_surface (self, scale);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_helper_ensure_texture (GtkIconHelper *self,
|
||||
GskRenderer *renderer)
|
||||
{
|
||||
cairo_surface_t *map;
|
||||
int width, height, scale;
|
||||
|
||||
if (self->priv->texture)
|
||||
return;
|
||||
|
||||
gtk_icon_helper_ensure_surface (self);
|
||||
if (self->priv->rendered_surface == NULL)
|
||||
return;
|
||||
|
||||
scale = gtk_widget_get_scale_factor (gtk_css_gadget_get_owner (GTK_CSS_GADGET (self))),
|
||||
_gtk_icon_helper_get_size (self, &width, &height);
|
||||
map = cairo_surface_map_to_image (self->priv->rendered_surface,
|
||||
&(GdkRectangle) { 0, 0, width * scale, height * scale});
|
||||
|
||||
self->priv->texture = gsk_texture_new_for_data (renderer,
|
||||
cairo_image_surface_get_data (map),
|
||||
width * scale,
|
||||
height * scale,
|
||||
cairo_image_surface_get_stride (map));
|
||||
|
||||
cairo_surface_unmap_image (self->priv->rendered_surface, map);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_icon_helper_get_size (GtkIconHelper *self,
|
||||
gint *width_out,
|
||||
@ -825,6 +857,29 @@ _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
}
|
||||
}
|
||||
|
||||
GskRenderNode *
|
||||
gtk_icon_helper_get_render_node (GtkIconHelper *self,
|
||||
GskRenderer *renderer)
|
||||
{
|
||||
GskTexture *texture;
|
||||
GskRenderNode *node;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
gtk_icon_helper_ensure_texture (self, renderer);
|
||||
texture = self->priv->texture;
|
||||
if (texture == NULL)
|
||||
return NULL;
|
||||
|
||||
graphene_rect_init (&bounds, 0, 0, gsk_texture_get_width (texture), gsk_texture_get_height (texture));
|
||||
|
||||
node = gsk_renderer_create_render_node (renderer);
|
||||
gsk_render_node_set_name (node, "Icon Helper");
|
||||
gsk_render_node_set_bounds (node, &bounds);
|
||||
gsk_render_node_set_texture (node, texture);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_icon_helper_get_is_empty (GtkIconHelper *self)
|
||||
{
|
||||
|
@ -125,6 +125,8 @@ void _gtk_icon_helper_draw (GtkIconHelper *self,
|
||||
cairo_t *cr,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
GskRenderNode * gtk_icon_helper_get_render_node (GtkIconHelper *self,
|
||||
GskRenderer *renderer);
|
||||
|
||||
gboolean _gtk_icon_helper_get_force_scale_pixbuf (GtkIconHelper *self);
|
||||
void _gtk_icon_helper_set_force_scale_pixbuf (GtkIconHelper *self,
|
||||
|
@ -1420,44 +1420,44 @@ gtk_image_get_render_node (GtkWidget *widget,
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
|
||||
node = gtk_widget_create_render_node (widget, renderer, "Image Content");
|
||||
|
||||
gtk_widget_get_clip (widget, &clip);
|
||||
_gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
cr = gsk_render_node_get_draw_context (node, renderer);
|
||||
cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
|
||||
x = 0;
|
||||
y = 0;
|
||||
width = alloc.width;
|
||||
height = alloc.height;
|
||||
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (baseline == -1)
|
||||
y += floor(height - h) / 2;
|
||||
else
|
||||
y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
|
||||
|
||||
x += (width - w) / 2;
|
||||
|
||||
if (gtk_image_get_storage_type (image) == GTK_IMAGE_ANIMATION)
|
||||
{
|
||||
node = gtk_widget_create_render_node (widget, renderer, "Image Content");
|
||||
|
||||
gtk_widget_get_clip (widget, &clip);
|
||||
_gtk_widget_get_allocation (widget, &alloc);
|
||||
|
||||
cr = gsk_render_node_get_draw_context (node, renderer);
|
||||
cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
|
||||
x = 0;
|
||||
y = 0;
|
||||
width = alloc.width;
|
||||
height = alloc.height;
|
||||
|
||||
_gtk_icon_helper_get_size (priv->icon_helper, &w, &h);
|
||||
|
||||
baseline = gtk_widget_get_allocated_baseline (widget);
|
||||
|
||||
if (baseline == -1)
|
||||
y += floor(height - h) / 2;
|
||||
else
|
||||
y += CLAMP (baseline - h * gtk_image_get_baseline_align (image), 0, height - h);
|
||||
|
||||
x += (width - w) / 2;
|
||||
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
GdkPixbuf *pixbuf = get_animation_frame (image);
|
||||
|
||||
gtk_render_icon (context, cr, pixbuf, x, y);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_icon_helper_draw (priv->icon_helper, cr, x, y);
|
||||
node = gtk_icon_helper_get_render_node (priv->icon_helper, renderer);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
gsk_render_node_append_child (res, node);
|
||||
gsk_render_node_unref (node);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user