summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-08-07 21:11:10 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-08-07 21:13:56 +0300
commita81ec4a93d8458816b29a59f81cdbea98e735234 (patch)
treee2d10a27a45bbe4b718acece8050ac36421926a5
parentc211c415d30e3bc7bc8b858396e9123a1c4e067b (diff)
downloadmetacity-a81ec4a93d8458816b29a59f81cdbea98e735234.tar.gz
libmetacity: redo image scaling
-rw-r--r--libmetacity/meta-draw-op.c113
1 files changed, 81 insertions, 32 deletions
diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c
index b9903612..3d503fa7 100644
--- a/libmetacity/meta-draw-op.c
+++ b/libmetacity/meta-draw-op.c
@@ -76,7 +76,56 @@ fill_env (MetaPositionExprEnv *env,
}
static cairo_surface_t *
-get_surface_from_pixbuf (GdkPixbuf *src,
+scale_surface (cairo_surface_t *surface,
+ gdouble old_width,
+ gdouble old_height,
+ gdouble new_width,
+ gdouble new_height,
+ gboolean vertical_stripes,
+ gboolean horizontal_stripes)
+{
+ gdouble scale_x;
+ gdouble scale_y;
+ cairo_content_t content;
+ gint width;
+ gint height;
+ cairo_surface_t *scaled;
+ cairo_t *cr;
+
+ scale_x = new_width / old_width;
+ scale_y = new_height / old_height;
+
+ if (horizontal_stripes && !vertical_stripes)
+ {
+ new_width = old_width;
+ scale_x = 1.0;
+ }
+ else if (vertical_stripes && !horizontal_stripes)
+ {
+ new_height = old_height;
+ scale_y = 1.0;
+ }
+
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+ width = ceil (new_width);
+ height = ceil (new_height);
+
+ scaled = cairo_surface_create_similar (surface, content, width, height);
+ cr = cairo_create (scaled);
+
+ cairo_scale (cr, scale_x, scale_y);
+ cairo_set_source_surface (cr, surface, 0, 0);
+
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_PAD);
+
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return scaled;
+}
+
+static cairo_surface_t *
+get_surface_from_pixbuf (GdkPixbuf *pixbuf,
MetaImageFillType fill_type,
gdouble width,
gdouble height,
@@ -85,53 +134,53 @@ get_surface_from_pixbuf (GdkPixbuf *src,
{
gdouble pixbuf_width;
gdouble pixbuf_height;
- cairo_surface_t *src_surface;
- cairo_surface_t *new_surface;
+ cairo_surface_t *surface;
+ cairo_content_t content;
+ cairo_surface_t *copy;
cairo_t *cr;
- pixbuf_width = gdk_pixbuf_get_width (src);
- pixbuf_height = gdk_pixbuf_get_height (src);
-
- src_surface = gdk_cairo_surface_create_from_pixbuf (src, 1, NULL);
- new_surface = cairo_surface_create_similar (src_surface,
- CAIRO_CONTENT_COLOR_ALPHA,
- ceil (width), ceil (height));
+ pixbuf_width = gdk_pixbuf_get_width (pixbuf);
+ pixbuf_height = gdk_pixbuf_get_height (pixbuf);
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
- cr = cairo_create (new_surface);
+ if (pixbuf_width == width && pixbuf_height == height)
+ {
+ return surface;
+ }
- if ((pixbuf_width == width && pixbuf_height == height) ||
- fill_type == META_IMAGE_FILL_TILE)
+ if (fill_type != META_IMAGE_FILL_TILE)
{
- cairo_set_source_surface (cr, src_surface, 0, 0);
+ cairo_surface_t *scaled;
+
+ scaled = scale_surface (surface, pixbuf_width, pixbuf_height,
+ width, height, vertical_stripes,
+ horizontal_stripes);
- if (fill_type == META_IMAGE_FILL_TILE)
- cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ cairo_surface_destroy (surface);
+ surface = scaled;
}
- else
- {
- gdouble scale_x;
- gdouble scale_y;
- scale_x = width / pixbuf_width;
- scale_y = height / pixbuf_height;
+ content = CAIRO_CONTENT_COLOR_ALPHA;
+ width = ceil (width);
+ height = ceil (height);
- if (vertical_stripes)
- scale_y = 1;
- else if (horizontal_stripes)
- scale_x = 1;
+ copy = cairo_surface_create_similar (surface, content, width, height);
+ cr = cairo_create (copy);
- cairo_scale (cr, scale_x, scale_y);
- cairo_set_source_surface (cr, src_surface, 0, 0);
+ cairo_set_source_surface (cr, surface, 0, 0);
- if (vertical_stripes || horizontal_stripes)
- cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ if (fill_type == META_IMAGE_FILL_TILE ||
+ vertical_stripes || horizontal_stripes)
+ {
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
}
cairo_paint (cr);
cairo_destroy (cr);
- cairo_surface_destroy (src_surface);
- return new_surface;
+ cairo_surface_destroy (surface);
+
+ return copy;
}
static GdkPixbuf *