summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-07-10 11:08:10 +0300
committerAlberts Muktupāvels <alberts.muktupavels@gmail.com>2016-07-10 11:08:10 +0300
commit580cc874c2a6c92d05b6a55b06ea01fccb80e570 (patch)
treef5d69cc5dd5f3a4c2194ca601bbfb8c37228d6a0
parentce6c42674901ded2a8e1d2fcd4d8f27274ef1a4f (diff)
downloadmetacity-580cc874c2a6c92d05b6a55b06ea01fccb80e570.tar.gz
libmetacity: use cairo to apply alpha
-rw-r--r--libmetacity/meta-draw-op.c103
-rw-r--r--libmetacity/meta-gradient-spec-private.h8
-rw-r--r--libmetacity/meta-gradient-spec.c67
3 files changed, 95 insertions, 83 deletions
diff --git a/libmetacity/meta-draw-op.c b/libmetacity/meta-draw-op.c
index 0e3e6ae4..e88d11c4 100644
--- a/libmetacity/meta-draw-op.c
+++ b/libmetacity/meta-draw-op.c
@@ -24,12 +24,6 @@
#include "meta-draw-op-private.h"
#include "meta-theme-impl-private.h"
-#define GDK_COLOR_RGBA(color) \
- ((guint32) (0xff | \
- ((int)((color).red * 255) << 24) | \
- ((int)((color).green * 255) << 16) | \
- ((int)((color).blue * 255) << 8)))
-
#define GDK_COLOR_RGB(color) \
((guint32) (((int)((color).red * 255) << 16) | \
((int)((color).green * 255) << 8) | \
@@ -210,18 +204,15 @@ replicate_cols (GdkPixbuf *src,
}
static GdkPixbuf*
-scale_and_alpha_pixbuf (GdkPixbuf *src,
- MetaAlphaGradientSpec *alpha_spec,
- MetaImageFillType fill_type,
- int width,
- int height,
- gboolean vertical_stripes,
- gboolean horizontal_stripes)
+scale_pixbuf (GdkPixbuf *src,
+ MetaAlphaGradientSpec *alpha_spec,
+ MetaImageFillType fill_type,
+ gint width,
+ gint height,
+ gboolean vertical_stripes,
+ gboolean horizontal_stripes)
{
GdkPixbuf *pixbuf;
- GdkPixbuf *temp_pixbuf;
-
- pixbuf = NULL;
pixbuf = src;
@@ -238,6 +229,7 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
}
else
{
+ GdkPixbuf *temp_pixbuf;
int src_h, src_w, dest_h, dest_w;
src_h = gdk_pixbuf_get_height (src);
src_w = gdk_pixbuf_get_width (src);
@@ -294,9 +286,6 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
}
}
- if (pixbuf)
- pixbuf = meta_alpha_gradient_spec_apply_alpha (alpha_spec, pixbuf, pixbuf == src);
-
return pixbuf;
}
@@ -438,22 +427,22 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
if (op->data.image.colorize_cache_pixbuf)
{
- pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf,
- op->data.image.alpha_spec,
- op->data.image.fill_type,
- width, height,
- op->data.image.vertical_stripes,
- op->data.image.horizontal_stripes);
+ pixbuf = scale_pixbuf (op->data.image.colorize_cache_pixbuf,
+ op->data.image.alpha_spec,
+ op->data.image.fill_type,
+ width, height,
+ op->data.image.vertical_stripes,
+ op->data.image.horizontal_stripes);
}
}
else
{
- pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
- op->data.image.alpha_spec,
- op->data.image.fill_type,
- width, height,
- op->data.image.vertical_stripes,
- op->data.image.horizontal_stripes);
+ pixbuf = scale_pixbuf (op->data.image.pixbuf,
+ op->data.image.alpha_spec,
+ op->data.image.fill_type,
+ width, height,
+ op->data.image.vertical_stripes,
+ op->data.image.horizontal_stripes);
}
break;
}
@@ -467,17 +456,13 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
if (info->mini_icon &&
width <= gdk_pixbuf_get_width (info->mini_icon) &&
height <= gdk_pixbuf_get_height (info->mini_icon))
- pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
- op->data.icon.alpha_spec,
- op->data.icon.fill_type,
- width, height,
- FALSE, FALSE);
+ pixbuf = scale_pixbuf (info->mini_icon, op->data.icon.alpha_spec,
+ op->data.icon.fill_type, width, height,
+ FALSE, FALSE);
else if (info->icon)
- pixbuf = scale_and_alpha_pixbuf (info->icon,
- op->data.icon.alpha_spec,
- op->data.icon.fill_type,
- width, height,
- FALSE, FALSE);
+ pixbuf = scale_pixbuf (info->icon, op->data.icon.alpha_spec,
+ op->data.icon.fill_type, width, height,
+ FALSE, FALSE);
break;
case META_DRAW_TITLE:
@@ -723,7 +708,23 @@ draw_op_draw_with_env (const MetaDrawOp *op,
ry = meta_draw_spec_parse_y_position (op->data.image.y, env);
gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
- cairo_paint (cr);
+
+ if (op->data.image.alpha_spec)
+ {
+ cairo_pattern_t *pattern;
+
+ cairo_translate (cr, rx, ry);
+ cairo_scale (cr, rwidth, rheight);
+
+ pattern = meta_alpha_gradient_spec_get_mask (op->data.image.alpha_spec);
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+ }
+ else
+ {
+ cairo_paint (cr);
+ }
g_object_unref (G_OBJECT (pixbuf));
}
@@ -811,7 +812,23 @@ draw_op_draw_with_env (const MetaDrawOp *op,
ry = meta_draw_spec_parse_y_position (op->data.icon.y, env);
gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
- cairo_paint (cr);
+
+ if (op->data.icon.alpha_spec)
+ {
+ cairo_pattern_t *pattern;
+
+ cairo_translate (cr, rx, ry);
+ cairo_scale (cr, rwidth, rheight);
+
+ pattern = meta_alpha_gradient_spec_get_mask (op->data.icon.alpha_spec);
+ cairo_mask (cr, pattern);
+
+ cairo_pattern_destroy (pattern);
+ }
+ else
+ {
+ cairo_paint (cr);
+ }
g_object_unref (G_OBJECT (pixbuf));
}
diff --git a/libmetacity/meta-gradient-spec-private.h b/libmetacity/meta-gradient-spec-private.h
index a07240f1..aaa883b9 100644
--- a/libmetacity/meta-gradient-spec-private.h
+++ b/libmetacity/meta-gradient-spec-private.h
@@ -69,11 +69,6 @@ guchar meta_alpha_gradient_spec_get_alpha (MetaAlphaGradientSp
gint n_alpha);
G_GNUC_INTERNAL
-GdkPixbuf *meta_alpha_gradient_spec_apply_alpha (MetaAlphaGradientSpec *spec,
- GdkPixbuf *pixbuf,
- gboolean force_copy);
-
-G_GNUC_INTERNAL
void meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
GdkRGBA color,
cairo_t *cr,
@@ -82,6 +77,9 @@ void meta_alpha_gradient_spec_render (MetaAlphaGradientSp
gint width,
gint height);
+G_GNUC_INTERNAL
+cairo_pattern_t *meta_alpha_gradient_spec_get_mask (const MetaAlphaGradientSpec *spec);
+
G_END_DECLS
#endif
diff --git a/libmetacity/meta-gradient-spec.c b/libmetacity/meta-gradient-spec.c
index dd4b48e5..cb99a692 100644
--- a/libmetacity/meta-gradient-spec.c
+++ b/libmetacity/meta-gradient-spec.c
@@ -220,41 +220,6 @@ meta_alpha_gradient_spec_get_alpha (MetaAlphaGradientSpec *spec,
return spec->alphas[n_alpha];
}
-GdkPixbuf *
-meta_alpha_gradient_spec_apply_alpha (MetaAlphaGradientSpec *spec,
- GdkPixbuf *pixbuf,
- gboolean force_copy)
-{
- GdkPixbuf *new_pixbuf;
- gboolean needs_alpha;
-
- g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
-
- needs_alpha = spec && (spec->n_alphas > 1 || spec->alphas[0] != 0xff);
-
- if (!needs_alpha)
- return pixbuf;
-
- if (!gdk_pixbuf_get_has_alpha (pixbuf))
- {
- new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
- g_object_unref (G_OBJECT (pixbuf));
- pixbuf = new_pixbuf;
- }
- else if (force_copy)
- {
- new_pixbuf = gdk_pixbuf_copy (pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- pixbuf = new_pixbuf;
- }
-
- g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
-
- meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type);
-
- return pixbuf;
-}
-
void
meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
GdkRGBA color,
@@ -309,3 +274,35 @@ meta_alpha_gradient_spec_render (MetaAlphaGradientSpec *spec,
cairo_restore (cr);
}
}
+
+cairo_pattern_t *
+meta_alpha_gradient_spec_get_mask (const MetaAlphaGradientSpec *spec)
+{
+ gint n_alphas;
+ cairo_pattern_t *pattern;
+ gint i;
+
+ /* Hardcoded in meta-theme-metacity.c */
+ g_assert (spec->type == META_GRADIENT_HORIZONTAL);
+
+ n_alphas = spec->n_alphas;
+ if (n_alphas == 0)
+ return NULL;
+
+ if (n_alphas == 1)
+ return cairo_pattern_create_rgba (0, 0, 0, spec->alphas[0] / 255.0);
+
+ pattern = cairo_pattern_create_linear (0, 0, 1, 0);
+
+ for (i = 0; i < n_alphas; i++)
+ cairo_pattern_add_color_stop_rgba (pattern, i / (gfloat) (n_alphas - 1),
+ 0, 0, 0, spec->alphas[i] / 255.0);
+
+ if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS)
+ {
+ cairo_pattern_destroy (pattern);
+ return NULL;
+ }
+
+ return pattern;
+}