Esempio n. 1
0
static GtkGradient *
gtk_gradient_fade (GtkGradient *gradient,
                   double       opacity)
{
  GtkGradient *faded;
  guint i;

  faded = g_slice_new (GtkGradient);
  faded->stops = g_array_new (FALSE, FALSE, sizeof (ColorStop));

  faded->x0 = gradient->x0;
  faded->y0 = gradient->y0;
  faded->x1 = gradient->x1;
  faded->y1 = gradient->y1;
  faded->radius0 = gradient->radius0;
  faded->radius1 = gradient->radius1;

  faded->ref_count = 1;

  for (i = 0; i < gradient->stops->len; i++)
    {
      GtkSymbolicColor *color;
      ColorStop *stop;

      stop = &g_array_index (gradient->stops, ColorStop, i);
      color = gtk_symbolic_color_new_alpha (stop->color, opacity);
      gtk_gradient_add_color_stop (faded, stop->offset, color);
      gtk_symbolic_color_unref (color);
    }

  return faded;
}
Esempio n. 2
0
GtkGradient *
_gtk_gradient_transition (GtkGradient *start,
                          GtkGradient *end,
                          guint        property_id,
                          double       progress)
{
  GtkGradient *gradient;
  guint i;

  g_return_val_if_fail (start != NULL, NULL);

  if (end == NULL)
    return gtk_gradient_fade (start, 1.0 - CLAMP (progress, 0.0, 1.0));

  if (start->stops->len != end->stops->len)
    return NULL;

  /* check both are radial/linear */
  if ((start->radius0 == 0 && start->radius1 == 0) != (end->radius0 == 0 && end->radius1 == 0))
    return NULL;

  gradient = g_slice_new (GtkGradient);
  gradient->stops = g_array_new (FALSE, FALSE, sizeof (ColorStop));

  gradient->x0 = (1 - progress) * start->x0 + progress * end->x0;
  gradient->y0 = (1 - progress) * start->y0 + progress * end->y0;
  gradient->x1 = (1 - progress) * start->x1 + progress * end->x1;
  gradient->y1 = (1 - progress) * start->y1 + progress * end->y1;
  gradient->radius0 = (1 - progress) * start->radius0 + progress * end->radius0;
  gradient->radius1 = (1 - progress) * start->radius1 + progress * end->radius1;

  gradient->ref_count = 1;

  for (i = 0; i < start->stops->len; i++)
    {
      ColorStop *start_stop, *end_stop;
      GtkSymbolicColor *color;
      double offset;

      start_stop = &g_array_index (start->stops, ColorStop, i);
      end_stop = &g_array_index (end->stops, ColorStop, i);

      offset = (1 - progress) * start_stop->offset + progress * end_stop->offset;
      color = gtk_symbolic_color_new_mix (start_stop->color,
                                          end_stop->color,
                                          progress);
      gtk_gradient_add_color_stop (gradient, offset, color);
      gtk_symbolic_color_unref (color);
    }

  return gradient;
}
Esempio n. 3
0
GtkGradient *
_gtk_gradient_parse (GtkCssParser *parser)
{
  GtkGradient *gradient;
  cairo_pattern_type_t type;
  gdouble coords[6];
  guint i;

  g_return_val_if_fail (parser != NULL, NULL);

  if (!_gtk_css_parser_try (parser, "-gtk-gradient", TRUE))
    {
      _gtk_css_parser_error (parser,
                             "Expected '-gtk-gradient'");
      return NULL;
    }

  if (!_gtk_css_parser_try (parser, "(", TRUE))
    {
      _gtk_css_parser_error (parser,
                             "Expected '(' after '-gtk-gradient'");
      return NULL;
    }

  /* Parse gradient type */
  if (_gtk_css_parser_try (parser, "linear", TRUE))
    type = CAIRO_PATTERN_TYPE_LINEAR;
  else if (_gtk_css_parser_try (parser, "radial", TRUE))
    type = CAIRO_PATTERN_TYPE_RADIAL;
  else
    {
      _gtk_css_parser_error (parser,
                             "Gradient type must be 'radial' or 'linear'");
      return NULL;
    }

  /* Parse start/stop position parameters */
  for (i = 0; i < 2; i++)
    {
      if (! _gtk_css_parser_try (parser, ",", TRUE))
        {
          _gtk_css_parser_error (parser,
                                 "Expected ','");
          return NULL;
        }

      if (_gtk_css_parser_try (parser, "left", TRUE))
        coords[i * 3] = 0;
      else if (_gtk_css_parser_try (parser, "right", TRUE))
        coords[i * 3] = 1;
      else if (_gtk_css_parser_try (parser, "center", TRUE))
        coords[i * 3] = 0.5;
      else if (!_gtk_css_parser_try_double (parser, &coords[i * 3]))
        {
          _gtk_css_parser_error (parser,
                                 "Expected a valid X coordinate");
          return NULL;
        }

      if (_gtk_css_parser_try (parser, "top", TRUE))
        coords[i * 3 + 1] = 0;
      else if (_gtk_css_parser_try (parser, "bottom", TRUE))
        coords[i * 3 + 1] = 1;
      else if (_gtk_css_parser_try (parser, "center", TRUE))
        coords[i * 3 + 1] = 0.5;
      else if (!_gtk_css_parser_try_double (parser, &coords[i * 3 + 1]))
        {
          _gtk_css_parser_error (parser,
                                 "Expected a valid Y coordinate");
          return NULL;
        }

      if (type == CAIRO_PATTERN_TYPE_RADIAL)
        {
          /* Parse radius */
          if (! _gtk_css_parser_try (parser, ",", TRUE))
            {
              _gtk_css_parser_error (parser,
                                     "Expected ','");
              return NULL;
            }

          if (! _gtk_css_parser_try_double (parser, &coords[(i * 3) + 2]))
            {
              _gtk_css_parser_error (parser,
                                     "Expected a numer for the radius");
              return NULL;
            }
        }
    }

  if (type == CAIRO_PATTERN_TYPE_LINEAR)
    gradient = gtk_gradient_new_linear (coords[0], coords[1], coords[3], coords[4]);
  else
    gradient = gtk_gradient_new_radial (coords[0], coords[1], coords[2],
                                        coords[3], coords[4], coords[5]);

  while (_gtk_css_parser_try (parser, ",", TRUE))
    {
      GtkSymbolicColor *color;
      gdouble position;

      if (_gtk_css_parser_try (parser, "from", TRUE))
        {
          position = 0;

          if (!_gtk_css_parser_try (parser, "(", TRUE))
            {
              gtk_gradient_unref (gradient);
              _gtk_css_parser_error (parser,
                                     "Expected '('");
              return NULL;
            }

        }
      else if (_gtk_css_parser_try (parser, "to", TRUE))
        {
          position = 1;

          if (!_gtk_css_parser_try (parser, "(", TRUE))
            {
              gtk_gradient_unref (gradient);
              _gtk_css_parser_error (parser,
                                     "Expected '('");
              return NULL;
            }

        }
      else if (_gtk_css_parser_try (parser, "color-stop", TRUE))
        {
          if (!_gtk_css_parser_try (parser, "(", TRUE))
            {
              gtk_gradient_unref (gradient);
              _gtk_css_parser_error (parser,
                                     "Expected '('");
              return NULL;
            }

          if (!_gtk_css_parser_try_double (parser, &position))
            {
              gtk_gradient_unref (gradient);
              _gtk_css_parser_error (parser,
                                     "Expected a valid number");
              return NULL;
            }

          if (!_gtk_css_parser_try (parser, ",", TRUE))
            {
              gtk_gradient_unref (gradient);
              _gtk_css_parser_error (parser,
                                     "Expected a comma");
              return NULL;
            }
        }
      else
        {
          gtk_gradient_unref (gradient);
          _gtk_css_parser_error (parser,
                                 "Not a valid color-stop definition");
          return NULL;
        }

      color = _gtk_css_parser_read_symbolic_color (parser);
      if (color == NULL)
        {
          gtk_gradient_unref (gradient);
          return NULL;
        }

      gtk_gradient_add_color_stop (gradient, position, color);
      gtk_symbolic_color_unref (color);

      if (!_gtk_css_parser_try (parser, ")", TRUE))
        {
          gtk_gradient_unref (gradient);
          _gtk_css_parser_error (parser,
                                 "Expected ')'");
          return NULL;
        }
    }

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      gtk_gradient_unref (gradient);
      _gtk_css_parser_error (parser,
                             "Expected ')'");
      return NULL;
    }

  return gradient;
}