Пример #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;
}
Пример #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;
}
Пример #3
0
/**
 * gtk_gradient_unref:
 * @gradient: a #GtkGradient
 *
 * Decreases the reference count of @gradient, freeing its memory
 * if the reference count reaches 0.
 *
 * Since: 3.0
 *
 * Deprecated: 3.8: #GtkGradient is deprecated.
 **/
void
gtk_gradient_unref (GtkGradient *gradient)
{
  g_return_if_fail (gradient != NULL);

  gradient->ref_count--;

  if (gradient->ref_count == 0)
    {
      guint i;

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

          stop = &g_array_index (gradient->stops, ColorStop, i);
          gtk_symbolic_color_unref (stop->color);
        }

      g_array_free (gradient->stops, TRUE);
      g_slice_free (GtkGradient, gradient);
    }
}
Пример #4
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;
}
Пример #5
0
static GtkSymbolicColor *
gtk_css_parser_read_symbolic_color_function (GtkCssParser *parser,
                                             ColorType     color)
{
  GtkSymbolicColor *symbolic;
  GtkSymbolicColor *child1, *child2;
  double value;

  if (!_gtk_css_parser_try (parser, "(", TRUE))
    {
      _gtk_css_parser_error (parser, "Missing opening bracket in color definition");
      return NULL;
    }

  if (color == COLOR_RGB || color == COLOR_RGBA)
    {
      GdkRGBA rgba;
      double tmp;
      guint i;

      for (i = 0; i < 3; i++)
        {
          if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
            {
              _gtk_css_parser_error (parser, "Expected ',' in color definition");
              return NULL;
            }

          if (!_gtk_css_parser_try_double (parser, &tmp))
            {
              _gtk_css_parser_error (parser, "Invalid number for color value");
              return NULL;
            }
          if (_gtk_css_parser_try (parser, "%", TRUE))
            tmp /= 100.0;
          else
            tmp /= 255.0;
          if (i == 0)
            rgba.red = tmp;
          else if (i == 1)
            rgba.green = tmp;
          else if (i == 2)
            rgba.blue = tmp;
          else
            g_assert_not_reached ();
        }

      if (color == COLOR_RGBA)
        {
          if (i > 0 && !_gtk_css_parser_try (parser, ",", TRUE))
            {
              _gtk_css_parser_error (parser, "Expected ',' in color definition");
              return NULL;
            }

          if (!_gtk_css_parser_try_double (parser, &rgba.alpha))
            {
              _gtk_css_parser_error (parser, "Invalid number for alpha value");
              return NULL;
            }
        }
      else
        rgba.alpha = 1.0;
      
      symbolic = gtk_symbolic_color_new_literal (&rgba);
    }
  else if (color == COLOR_WIN32)
    {
      symbolic = _gtk_win32_theme_color_parse (parser);
      if (symbolic == NULL)
	return NULL;
    }
  else
    {
      child1 = _gtk_css_parser_read_symbolic_color (parser);
      if (child1 == NULL)
        return NULL;

      if (color == COLOR_MIX)
        {
          if (!_gtk_css_parser_try (parser, ",", TRUE))
            {
              _gtk_css_parser_error (parser, "Expected ',' in color definition");
              gtk_symbolic_color_unref (child1);
              return NULL;
            }

          child2 = _gtk_css_parser_read_symbolic_color (parser);
          if (child2 == NULL)
            {
              gtk_symbolic_color_unref (child1);
              return NULL;
            }
        }
      else
        child2 = NULL;

      if (color == COLOR_LIGHTER)
        value = 1.3;
      else if (color == COLOR_DARKER)
        value = 0.7;
      else
        {
          if (!_gtk_css_parser_try (parser, ",", TRUE))
            {
              _gtk_css_parser_error (parser, "Expected ',' in color definition");
              gtk_symbolic_color_unref (child1);
              if (child2)
                gtk_symbolic_color_unref (child2);
              return NULL;
            }

          if (!_gtk_css_parser_try_double (parser, &value))
            {
              _gtk_css_parser_error (parser, "Expected number in color definition");
              gtk_symbolic_color_unref (child1);
              if (child2)
                gtk_symbolic_color_unref (child2);
              return NULL;
            }
        }
      
      switch (color)
        {
        case COLOR_LIGHTER:
        case COLOR_DARKER:
        case COLOR_SHADE:
          symbolic = gtk_symbolic_color_new_shade (child1, value);
          break;
        case COLOR_ALPHA:
          symbolic = gtk_symbolic_color_new_alpha (child1, value);
          break;
        case COLOR_MIX:
          symbolic = gtk_symbolic_color_new_mix (child1, child2, value);
          break;
        default:
          g_assert_not_reached ();
          symbolic = NULL;
        }

      gtk_symbolic_color_unref (child1);
      if (child2)
        gtk_symbolic_color_unref (child2);
    }

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      _gtk_css_parser_error (parser, "Expected ')' in color definition");
      gtk_symbolic_color_unref (symbolic);
      return NULL;
    }

  return symbolic;
}