This scales the icon cairo surface for the titlebar if it isn't the
target size.

shared/cairo-util: Add surface resizing function to be used for this
case and other potential cases.
---

Changed in v2:

- Rebase to [PATCH 1/1 v3] xwm: Choose icon closest to target size

Changed in v3:

- No changes

Changed in v4:

- Fixed whitespace problems
- Renamed cairo_resize_surface() to resize_cairo_surface()

 shared/cairo-util.c       | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 shared/cairo-util.h       |  4 +++
 xwayland/window-manager.c |  4 +++
 3 files changed, 71 insertions(+)

diff --git a/shared/cairo-util.c b/shared/cairo-util.c
index d71e0ed..442182b 100644
--- a/shared/cairo-util.c
+++ b/shared/cairo-util.c
@@ -365,6 +365,69 @@ load_cairo_surface(const char *filename)
                                                   width, height, stride);
 }
 
+static cairo_surface_t *
+scale_surface(cairo_surface_t *source, cairo_filter_t filter,
+                                       double width, double height)
+{
+       cairo_surface_t *dest;
+       cairo_t *cr;
+       int old_width, old_height;
+
+       old_width = cairo_image_surface_get_width(source);
+       old_height = cairo_image_surface_get_height(source);
+
+       dest = cairo_surface_create_similar(source,
+                                       CAIRO_CONTENT_COLOR_ALPHA,
+                                       width, height);
+       cr = cairo_create (dest);
+
+       cairo_scale (cr, width / old_width, height / old_height);
+       cairo_set_source_surface (cr, source, 0, 0);
+
+       cairo_pattern_set_extend (cairo_get_source(cr),
+                                       CAIRO_EXTEND_REFLECT);
+
+       cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+
+       cairo_paint (cr);
+
+       cairo_destroy (cr);
+
+       cairo_surface_destroy(source);
+
+       return dest;
+}
+
+cairo_surface_t *
+resize_cairo_surface(cairo_surface_t *source, cairo_filter_t filter,
+                                               int width, int height)
+{
+       if (!filter)
+               filter = CAIRO_FILTER_BEST;
+
+       while((cairo_image_surface_get_width(source) / 2.0f) > width)
+               source = scale_surface(source, filter,
+                       cairo_image_surface_get_width(source) / 2.0f,
+                       cairo_image_surface_get_height(source));
+
+       while((cairo_image_surface_get_height(source) / 2.0f) > height)
+               source = scale_surface(source, filter,
+                       cairo_image_surface_get_width(source),
+                       cairo_image_surface_get_height(source) / 2.0f);
+
+       while((cairo_image_surface_get_width(source) * 2.0f) < width)
+               source = scale_surface(source, filter,
+                       cairo_image_surface_get_width(source) * 2.0f,
+                       cairo_image_surface_get_height(source));
+
+       while((cairo_image_surface_get_height(source) * 2.0f) < height)
+               source = scale_surface(source, filter,
+                       cairo_image_surface_get_width(source),
+                       cairo_image_surface_get_height(source) * 2.0f);
+
+       return scale_surface(source, filter, width, height);
+}
+
 void
 theme_set_background_source(struct theme *t, cairo_t *cr, uint32_t flags)
 {
diff --git a/shared/cairo-util.h b/shared/cairo-util.h
index 6fd11f6..1c58f3b 100644
--- a/shared/cairo-util.h
+++ b/shared/cairo-util.h
@@ -49,6 +49,10 @@ rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, 
int radius);
 cairo_surface_t *
 load_cairo_surface(const char *filename);
 
+cairo_surface_t *
+resize_cairo_surface(cairo_surface_t *source, cairo_filter_t filter,
+                                               int width, int height);
+
 struct theme {
        cairo_surface_t *active_frame;
        cairo_surface_t *inactive_frame;
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 5fb41bf..50c5855 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -1463,6 +1463,10 @@ weston_wm_handle_icon(struct weston_wm *wm, struct 
weston_wm_window *window)
                return;
        }
 
+       if (width != XWM_ICON_SIZE || height != XWM_ICON_SIZE)
+               new_surface = resize_cairo_surface(new_surface, 0,
+                                       XWM_ICON_SIZE, XWM_ICON_SIZE);
+
        if (window->frame)
                frame_set_icon(window->frame, new_surface);
        else /* We don’t have a frame yet */
-- 
2.7.4

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to