diff options
| author | Victor Kareh <[email protected]> | 2019-05-31 07:17:47 -0400 | 
|---|---|---|
| committer | raveit65 <[email protected]> | 2019-06-01 14:49:43 +0200 | 
| commit | 06628329fc769efb2bcd83d9bd3a2dc742d94220 (patch) | |
| tree | c4529633b9e1c02246290e2621bd4fda080bbace /src | |
| parent | e01cfaee4cf5f07095be58bd33ab879377811f93 (diff) | |
| download | marco-06628329fc769efb2bcd83d9bd3a2dc742d94220.tar.bz2 marco-06628329fc769efb2bcd83d9bd3a2dc742d94220.tar.xz | |
libmetacity: use cairo to render gradient
upstream commits:
https://gitlab.gnome.org/GNOME/metacity/commit/71d5decc
https://gitlab.gnome.org/GNOME/metacity/commit/127638ca
https://gitlab.gnome.org/GNOME/metacity/commit/fc1a21ea
https://gitlab.gnome.org/GNOME/metacity/commit/431e0418
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/theme.c | 145 | ||||
| -rw-r--r-- | src/ui/theme.h | 12 | 
2 files changed, 99 insertions, 58 deletions
| diff --git a/src/ui/theme.c b/src/ui/theme.c index ec922b74..d7932e67 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -994,6 +994,70 @@ meta_gradient_spec_new (MetaGradientType type)    return spec;  } +static cairo_pattern_t * +create_cairo_pattern_from_gradient_spec (const MetaGradientSpec      *spec, +                                         const MetaAlphaGradientSpec *alpha_spec, +                                         GtkStyleContext             *context) +{ +  gint n_colors; +  cairo_pattern_t *pattern; +  GSList *tmp; +  gint i; + +  n_colors = g_slist_length (spec->color_specs); +  if (n_colors == 0) +    return NULL; + +  if (alpha_spec != NULL && alpha_spec->n_alphas != 1) +    g_assert (n_colors == alpha_spec->n_alphas); + +  if (spec->type == META_GRADIENT_HORIZONTAL) +    pattern = cairo_pattern_create_linear (0, 0, 1, 0); +  else if (spec->type == META_GRADIENT_VERTICAL) +    pattern = cairo_pattern_create_linear (0, 0, 0, 1); +  else if (spec->type == META_GRADIENT_DIAGONAL) +    pattern = cairo_pattern_create_linear (0, 0, 1, 1); +  else +    g_assert_not_reached (); + +  i = 0; +  tmp = spec->color_specs; +  while (tmp != NULL) +    { +      GdkRGBA color; + +      meta_color_spec_render (tmp->data, context, &color); + +      if (alpha_spec != NULL) +        { +          gdouble alpha; + +          if (alpha_spec->n_alphas == 1) +            alpha = alpha_spec->alphas[0] / 255.0; +          else +            alpha = alpha_spec->alphas[i] / 255.0; + +          cairo_pattern_add_color_stop_rgba (pattern, i / (gfloat) (n_colors - 1), +                                             color.red, color.green, color.blue, +                                             alpha); +        } +      else +        cairo_pattern_add_color_stop_rgb (pattern, i / (gfloat) (n_colors - 1), +                                          color.red, color.green, color.blue); + +      tmp = tmp->next; +      ++i; +    } + +  if (cairo_pattern_status (pattern) != CAIRO_STATUS_SUCCESS) +    { +      cairo_pattern_destroy (pattern); +      return NULL; +    } + +  return pattern; +} +  static void  free_color_spec (gpointer spec, gpointer user_data)  { @@ -1012,42 +1076,34 @@ meta_gradient_spec_free (MetaGradientSpec *spec)    g_free (spec);  } -GdkPixbuf* -meta_gradient_spec_render (const MetaGradientSpec *spec, -                           GtkStyleContext        *style, -                           int                     width, -                           int                     height) -{ -  int n_colors; -  GdkRGBA *colors; -  GSList *tmp; -  int i; -  GdkPixbuf *pixbuf; - -  n_colors = g_slist_length (spec->color_specs); - -  if (n_colors == 0) -    return NULL; - -  colors = g_new (GdkRGBA, n_colors); +void +meta_gradient_spec_render (const MetaGradientSpec      *spec, +                           const MetaAlphaGradientSpec *alpha_spec, +                           cairo_t                     *cr, +                           GtkStyleContext             *context, +                           gint                         x, +                           gint                         y, +                           gint                         width, +                           gint                         height) +{ +  cairo_pattern_t *pattern; + +  pattern = create_cairo_pattern_from_gradient_spec (spec, alpha_spec, context); +  if (pattern == NULL) +    return; -  i = 0; -  tmp = spec->color_specs; -  while (tmp != NULL) -    { -      meta_color_spec_render (tmp->data, style, &colors[i]); +  cairo_save (cr); -      tmp = tmp->next; -      ++i; -    } +  cairo_rectangle (cr, x, y, width, height); -  pixbuf = meta_gradient_create_multi (width, height, -                                       colors, n_colors, -                                       spec->type); +  cairo_translate (cr, x, y); +  cairo_scale (cr, width, height); -  g_free (colors); +  cairo_set_source (cr, pattern); +  cairo_fill (cr); +  cairo_pattern_destroy (pattern); -  return pixbuf; +  cairo_restore (cr);  }  gboolean @@ -3488,18 +3544,6 @@ draw_op_as_pixbuf (const MetaDrawOp    *op,        }        break; -    case META_DRAW_GRADIENT: -      { -        pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec, -                                            style, width, height); - -        pixbuf = apply_alpha (pixbuf, -                              op->data.gradient.alpha_spec, -                              FALSE); -      } -      break; - -      case META_DRAW_IMAGE:        {  	if (op->data.image.colorize_spec) @@ -3545,6 +3589,7 @@ draw_op_as_pixbuf (const MetaDrawOp    *op,          break;        } +    case META_DRAW_GRADIENT:      case META_DRAW_GTK_ARROW:      case META_DRAW_GTK_BOX:      case META_DRAW_GTK_VLINE: @@ -3838,23 +3883,15 @@ meta_draw_op_draw_with_env (const MetaDrawOp    *op,      case META_DRAW_GRADIENT:        {          int rx, ry, rwidth, rheight; -        GdkPixbuf *pixbuf;          rx = parse_x_position_unchecked (op->data.gradient.x, env);          ry = parse_y_position_unchecked (op->data.gradient.y, env);          rwidth = parse_size_unchecked (op->data.gradient.width, env);          rheight = parse_size_unchecked (op->data.gradient.height, env); -        pixbuf = draw_op_as_pixbuf (op, style_gtk, info, -                                    rwidth, rheight); - -        if (pixbuf) -          { -            gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); -            cairo_paint (cr); - -            g_object_unref (G_OBJECT (pixbuf)); -          } +        meta_gradient_spec_render (op->data.gradient.gradient_spec, +                                   op->data.gradient.alpha_spec, +                                   cr, style_gtk, rx, ry, rwidth, rheight);        }        break; diff --git a/src/ui/theme.h b/src/ui/theme.h index 0713e2ce..ef6af363 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -956,10 +956,14 @@ gboolean       meta_draw_op_list_contains (MetaDrawOpList    *op_list,  MetaGradientSpec* meta_gradient_spec_new    (MetaGradientType        type);  void              meta_gradient_spec_free   (MetaGradientSpec       *desc); -GdkPixbuf*        meta_gradient_spec_render (const MetaGradientSpec *desc, -                                             GtkStyleContext        *style_gtk, -                                             int                     width, -                                             int                     height); +void              meta_gradient_spec_render (const MetaGradientSpec      *spec, +                                             const MetaAlphaGradientSpec *alpha_spec, +                                             cairo_t                     *cr, +                                             GtkStyleContext             *context, +                                             gint                         x, +                                             gint                         y, +                                             gint                         width, +                                             gint                         height);  gboolean          meta_gradient_spec_validate (MetaGradientSpec     *spec,                                                 GError              **error); | 
