summaryrefslogtreecommitdiff
path: root/libcaja-private/caja-icon-canvas-item.c
diff options
context:
space:
mode:
authorCosimo Cecchi <[email protected]>2013-08-02 14:37:13 +0200
committerlukefromdc <[email protected]>2018-04-04 21:53:21 -0400
commitbc1405c9f54e19e74f973581130229ef1053ff9c (patch)
tree8ae544cad7a3b815ff6c48304ced204f37dd4947 /libcaja-private/caja-icon-canvas-item.c
parent779e0af4042b6572d729190067cfee6a876d73e5 (diff)
downloadcaja-bc1405c9f54e19e74f973581130229ef1053ff9c.tar.bz2
caja-bc1405c9f54e19e74f973581130229ef1053ff9c.tar.xz
Support HiDpi icons
Port the rendering of icons to cairo surfaces, so that we can apply the GDK scale factor when rendering icons. origin commit: https://gitlab.gnome.org/GNOME/nautilus/commit/0d4555d7
Diffstat (limited to 'libcaja-private/caja-icon-canvas-item.c')
-rw-r--r--libcaja-private/caja-icon-canvas-item.c150
1 files changed, 83 insertions, 67 deletions
diff --git a/libcaja-private/caja-icon-canvas-item.c b/libcaja-private/caja-icon-canvas-item.c
index 88908196..98551be4 100644
--- a/libcaja-private/caja-icon-canvas-item.c
+++ b/libcaja-private/caja-icon-canvas-item.c
@@ -83,7 +83,7 @@ struct CajaIconCanvasItemDetails
/* The image, text, font. */
double x, y;
GdkPixbuf *pixbuf;
- GdkPixbuf *rendered_pixbuf;
+ cairo_surface_t *rendered_surface;
GList *emblem_pixbufs;
char *editable_text; /* Text that can be modified by a renaming function */
char *additional_text; /* Text that cannot be modifed, such as file size, etc. */
@@ -278,9 +278,9 @@ caja_icon_canvas_item_finalize (GObject *object)
g_free (details->additional_text);
g_free (details->attach_points);
- if (details->rendered_pixbuf != NULL)
+ if (details->rendered_surface != NULL)
{
- g_object_unref (details->rendered_pixbuf);
+ g_object_unref (details->rendered_surface);
}
if (details->editable_text_layout != NULL)
@@ -498,6 +498,27 @@ caja_icon_canvas_item_get_property (GObject *object,
}
}
+static void
+get_scaled_icon_size (CajaIconCanvasItem *item,
+ gint *width,
+ gint *height)
+{
+ EelCanvas *canvas;
+ GdkPixbuf *pixbuf = NULL;
+ gint scale;
+
+ if (item != NULL) {
+ canvas = EEL_CANVAS_ITEM (item)->canvas;
+ scale = gtk_widget_get_scale_factor (GTK_WIDGET (canvas));
+ pixbuf = item->details->pixbuf;
+ }
+
+ if (width)
+ *width = (pixbuf == NULL) ? 0 : (gdk_pixbuf_get_width (pixbuf) / scale);
+ if (height)
+ *height = (pixbuf == NULL) ? 0 : (gdk_pixbuf_get_height (pixbuf) / scale);
+}
+
cairo_surface_t *
caja_icon_canvas_item_get_drag_surface (CajaIconCanvasItem *item)
{
@@ -506,6 +527,7 @@ caja_icon_canvas_item_get_drag_surface (CajaIconCanvasItem *item)
EelCanvas *canvas;
GdkScreen *screen;
int width, height;
+ int pix_width, pix_height;
int item_offset_x, item_offset_y;
EelIRect icon_rect;
EelIRect emblem_rect;
@@ -554,11 +576,12 @@ caja_icon_canvas_item_get_drag_surface (CajaIconCanvasItem *item)
item_offset_x, item_offset_y);
cairo_surface_destroy (drag_surface);
+ get_scaled_icon_size (item, &pix_width, &pix_height);
icon_rect.x0 = item_offset_x;
icon_rect.y0 = item_offset_y;
- icon_rect.x1 = item_offset_x + gdk_pixbuf_get_width (item->details->pixbuf);
- icon_rect.y1 = item_offset_y + gdk_pixbuf_get_height (item->details->pixbuf);
+ icon_rect.x1 = item_offset_x + pix_width;
+ icon_rect.y1 = item_offset_y + pix_height;
is_rtl = caja_icon_container_is_layout_rtl (CAJA_ICON_CONTAINER (canvas));
@@ -607,10 +630,10 @@ caja_icon_canvas_item_set_image (CajaIconCanvasItem *item,
{
g_object_unref (details->pixbuf);
}
- if (details->rendered_pixbuf != NULL)
+ if (details->rendered_surface != NULL)
{
- g_object_unref (details->rendered_pixbuf);
- details->rendered_pixbuf = NULL;
+ cairo_surface_destroy (details->rendered_surface);
+ details->rendered_surface = NULL;
}
details->pixbuf = image;
@@ -1671,8 +1694,8 @@ draw_pixbuf (GdkPixbuf *pixbuf,
}
/* shared code to highlight or dim the passed-in pixbuf */
-static GdkPixbuf *
-real_map_pixbuf (CajaIconCanvasItem *icon_item)
+static cairo_surface_t *
+real_map_surface (CajaIconCanvasItem *icon_item)
{
EelCanvas *canvas;
char *audio_filename;
@@ -1681,6 +1704,7 @@ real_map_pixbuf (CajaIconCanvasItem *icon_item)
int emblem_size;
GtkStyleContext *style;
GdkRGBA color;
+ cairo_surface_t *surface;
temp_pixbuf = icon_item->details->pixbuf;
canvas = EEL_CANVAS_ITEM(icon_item)->canvas;
@@ -1758,13 +1782,18 @@ real_map_pixbuf (CajaIconCanvasItem *icon_item)
g_object_unref (old_pixbuf);
}
- return temp_pixbuf;
+ surface = gdk_cairo_surface_create_from_pixbuf (temp_pixbuf,
+ gtk_widget_get_scale_factor (GTK_WIDGET (canvas)),
+ gtk_widget_get_window (GTK_WIDGET (canvas)));
+ g_object_unref (temp_pixbuf);
+
+ return surface;
}
-static GdkPixbuf *
-map_pixbuf (CajaIconCanvasItem *icon_item)
+static cairo_surface_t *
+map_surface (CajaIconCanvasItem *icon_item)
{
- if (!(icon_item->details->rendered_pixbuf != NULL
+ if (!(icon_item->details->rendered_surface != NULL
&& icon_item->details->rendered_is_active == icon_item->details->is_active
&& icon_item->details->rendered_is_prelit == icon_item->details->is_prelit
&& icon_item->details->rendered_is_highlighted_for_selection == icon_item->details->is_highlighted_for_selection
@@ -1772,11 +1801,11 @@ map_pixbuf (CajaIconCanvasItem *icon_item)
&& icon_item->details->rendered_is_highlighted_for_clipboard == icon_item->details->is_highlighted_for_clipboard
&& (icon_item->details->is_highlighted_for_selection && icon_item->details->rendered_is_focused == gtk_widget_has_focus (GTK_WIDGET (EEL_CANVAS_ITEM (icon_item)->canvas)))))
{
- if (icon_item->details->rendered_pixbuf != NULL)
+ if (icon_item->details->rendered_surface != NULL)
{
- g_object_unref (icon_item->details->rendered_pixbuf);
+ cairo_surface_destroy (icon_item->details->rendered_surface);
}
- icon_item->details->rendered_pixbuf = real_map_pixbuf (icon_item);
+ icon_item->details->rendered_surface = real_map_surface (icon_item);
icon_item->details->rendered_is_active = icon_item->details->is_active;
icon_item->details->rendered_is_prelit = icon_item->details->is_prelit;
icon_item->details->rendered_is_highlighted_for_selection = icon_item->details->is_highlighted_for_selection;
@@ -1785,9 +1814,9 @@ map_pixbuf (CajaIconCanvasItem *icon_item)
icon_item->details->rendered_is_focused = gtk_widget_has_focus (GTK_WIDGET (EEL_CANVAS_ITEM (icon_item)->canvas));
}
- g_object_ref (icon_item->details->rendered_pixbuf);
+ cairo_surface_reference (icon_item->details->rendered_surface);
- return icon_item->details->rendered_pixbuf;
+ return icon_item->details->rendered_surface;
}
static void
@@ -1863,7 +1892,8 @@ caja_icon_canvas_item_draw (EelCanvasItem *item,
CajaIconCanvasItemDetails *details;
EelIRect icon_rect, emblem_rect;
EmblemLayout emblem_layout;
- GdkPixbuf *emblem_pixbuf, *temp_pixbuf;
+ GdkPixbuf *emblem_pixbuf;
+ cairo_surface_t *temp_surface;
GtkStyleContext *context;
container = CAJA_ICON_CONTAINER (item->canvas);
@@ -1884,12 +1914,12 @@ caja_icon_canvas_item_draw (EelCanvasItem *item,
icon_rect = icon_item->details->canvas_rect;
- temp_pixbuf = map_pixbuf (icon_item);
+ temp_surface = map_surface (icon_item);
- gtk_render_icon (context, cr,
- temp_pixbuf,
- icon_rect.x0, icon_rect.y0);
- g_object_unref (temp_pixbuf);
+ gtk_render_icon_surface (context, cr,
+ temp_surface,
+ icon_rect.x0, icon_rect.y0);
+ cairo_surface_destroy (temp_surface);
draw_embedded_text (icon_item, cr, icon_rect.x0, icon_rect.y0);
@@ -2360,6 +2390,7 @@ caja_icon_canvas_item_ensure_bounds_up_to_date (CajaIconCanvasItem *icon_item)
EelIRect total_rect, total_rect_for_layout, total_rect_for_entire_text;
EelCanvasItem *item;
double pixels_per_unit;
+ gint width, height;
EmblemLayout emblem_layout;
GdkPixbuf *emblem_pixbuf;
gboolean is_rtl;
@@ -2378,20 +2409,13 @@ caja_icon_canvas_item_ensure_bounds_up_to_date (CajaIconCanvasItem *icon_item)
icon_rect.y0 = 0;
icon_rect_raw.x0 = 0;
icon_rect_raw.y0 = 0;
- if (details->pixbuf == NULL)
- {
- icon_rect.x1 = icon_rect.x0;
- icon_rect.y1 = icon_rect.y0;
- icon_rect_raw.x1 = icon_rect_raw.x0;
- icon_rect_raw.y1 = icon_rect_raw.y0;
- }
- else
- {
- icon_rect_raw.x1 = icon_rect_raw.x0 + gdk_pixbuf_get_width (details->pixbuf);
- icon_rect_raw.y1 = icon_rect_raw.y0 + gdk_pixbuf_get_height (details->pixbuf);
- icon_rect.x1 = icon_rect_raw.x1 / pixels_per_unit;
- icon_rect.y1 = icon_rect_raw.y1 / pixels_per_unit;
- }
+
+ get_scaled_icon_size (icon_item, &width, &height);
+
+ icon_rect_raw.x1 = icon_rect_raw.x0 + width;
+ icon_rect_raw.y1 = icon_rect_raw.y0 + height;
+ icon_rect.x1 = icon_rect_raw.x1 / pixels_per_unit;
+ icon_rect.y1 = icon_rect_raw.y1 / pixels_per_unit;
/* Compute text rectangle. */
text_rect = compute_text_rectangle (icon_item, icon_rect, FALSE, BOUNDS_USAGE_FOR_DISPLAY);
@@ -2430,18 +2454,17 @@ caja_icon_canvas_item_get_icon_rectangle (const CajaIconCanvasItem *item)
{
EelDRect rectangle;
double pixels_per_unit;
- GdkPixbuf *pixbuf;
+ gint width, height;
g_return_val_if_fail (CAJA_IS_ICON_CANVAS_ITEM (item), eel_drect_empty);
rectangle.x0 = item->details->x;
rectangle.y0 = item->details->y;
- pixbuf = item->details->pixbuf;
-
pixels_per_unit = EEL_CANVAS_ITEM (item)->canvas->pixels_per_unit;
- rectangle.x1 = rectangle.x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit;
- rectangle.y1 = rectangle.y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit;
+ get_scaled_icon_size (EEL_CANVAS_ITEM (item), &width, &height);
+ rectangle.x1 = rectangle.x0 + width / pixels_per_unit;
+ rectangle.y1 = rectangle.y0 + height / pixels_per_unit;
eel_canvas_item_i2w (EEL_CANVAS_ITEM (item),
&rectangle.x0,
@@ -2462,18 +2485,17 @@ caja_icon_canvas_item_get_text_rectangle (CajaIconCanvasItem *item,
EelIRect text_rectangle;
EelDRect ret;
double pixels_per_unit;
- GdkPixbuf *pixbuf;
+ gint width, height;
g_return_val_if_fail (CAJA_IS_ICON_CANVAS_ITEM (item), eel_drect_empty);
icon_rectangle.x0 = item->details->x;
icon_rectangle.y0 = item->details->y;
- pixbuf = item->details->pixbuf;
-
pixels_per_unit = EEL_CANVAS_ITEM (item)->canvas->pixels_per_unit;
- icon_rectangle.x1 = icon_rectangle.x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf)) / pixels_per_unit;
- icon_rectangle.y1 = icon_rectangle.y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf)) / pixels_per_unit;
+ get_scaled_icon_size (item, &width, &height);
+ icon_rectangle.x1 = icon_rectangle.x0 + width / pixels_per_unit;
+ icon_rectangle.y1 = icon_rectangle.y0 + height / pixels_per_unit;
measure_label_text (item);
@@ -2495,27 +2517,27 @@ caja_icon_canvas_item_get_text_rectangle (CajaIconCanvasItem *item,
return ret;
}
-
/* Get the rectangle of the icon only, in canvas coordinates. */
static void
get_icon_canvas_rectangle (CajaIconCanvasItem *item,
EelIRect *rect)
{
- GdkPixbuf *pixbuf;
+ gint width, height;
g_assert (CAJA_IS_ICON_CANVAS_ITEM (item));
g_assert (rect != NULL);
+
eel_canvas_w2c (EEL_CANVAS_ITEM (item)->canvas,
item->details->x,
item->details->y,
&rect->x0,
&rect->y0);
- pixbuf = item->details->pixbuf;
+ get_scaled_icon_size (item, &width, &height);
- rect->x1 = rect->x0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_width (pixbuf));
- rect->y1 = rect->y0 + (pixbuf == NULL ? 0 : gdk_pixbuf_get_height (pixbuf));
+ rect->x1 = rect->x0 + width;
+ rect->y1 = rect->y0 + height;
}
void
@@ -3114,15 +3136,7 @@ caja_icon_canvas_item_accessible_get_image_size
item = CAJA_ICON_CANVAS_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (image)));
- if (!item || !item->details->pixbuf)
- {
- *width = *height = 0;
- }
- else
- {
- *width = gdk_pixbuf_get_width (item->details->pixbuf);
- *height = gdk_pixbuf_get_height (item->details->pixbuf);
- }
+ get_scaled_icon_size (item, width, height);
}
static void
@@ -3224,7 +3238,7 @@ caja_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
char *icon_text;
gboolean have_editable;
gboolean have_additional;
- gint text_offset;
+ gint text_offset, height;
atk_component_get_extents (ATK_COMPONENT (text), &real_x, &real_y,
&real_width, &real_height, coords);
@@ -3236,7 +3250,8 @@ caja_icon_canvas_item_accessible_get_offset_at_point (AtkText *text,
if (item->details->pixbuf)
{
- y -= gdk_pixbuf_get_height (item->details->pixbuf);
+ get_scaled_icon_size (item, NULL, &height);
+ y -= height;
}
have_editable = item->details->editable_text != NULL &&
item->details->editable_text[0] != '\0';
@@ -3353,14 +3368,15 @@ caja_icon_canvas_item_accessible_get_character_extents (AtkText *text,
PangoRectangle rect;
PangoRectangle rect0;
gboolean have_editable;
- gint text_offset;
+ gint text_offset, pix_height;
atk_component_get_extents (ATK_COMPONENT (text), &pos_x, &pos_y, NULL, NULL, coords);
item = CAJA_ICON_CANVAS_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
if (item->details->pixbuf)
{
- pos_y += gdk_pixbuf_get_height (item->details->pixbuf);
+ get_scaled_icon_size (item, NULL, &pix_height);
+ pos_y += pix_height;
}
have_editable = item->details->editable_text != NULL &&