Exemplo n.º 1
0
static GtkCssValue *
gtk_css_ease_value_parse_cubic_bezier (GtkCssParser *parser)
{
  double values[4];
  guint i;

  for (i = 0; i < 4; i++)
    {
      if (!_gtk_css_parser_try (parser, i ? "," : "(", TRUE))
        {
          _gtk_css_parser_error (parser, "Expected '%s'", i ? "," : "(");
          return NULL;
        }
      if (!_gtk_css_parser_try_double (parser, &values[i]))
        {
          _gtk_css_parser_error (parser, "Expected a number");
          return NULL;
        }
      if ((i == 0 || i == 2) &&
          (values[i] < 0 || values[i] > 1.0))
        {
          _gtk_css_parser_error (parser, "value %g out of range. Must be from 0.0 to 1.0", values[i]);
          return NULL;
        }
    }

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      _gtk_css_parser_error (parser, "Missing closing ')' for cubic-bezier");
      return NULL;
    }

  return _gtk_css_ease_value_new_cubic_bezier (values[0], values[1], values[2], values[3]);
}
Exemplo n.º 2
0
static gboolean 
float_value_parse (GtkCssParser *parser,
                   GValue       *value)
{
  gdouble d;

  if (!_gtk_css_parser_try_double (parser, &d))
    {
      _gtk_css_parser_error (parser, "Expected a number");
      return FALSE;
    }

  g_value_set_float (value, d);
  return TRUE;
}
Exemplo 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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
static gboolean
gtk_css_image_win32_parse (GtkCssImage  *image,
                           GtkCssParser *parser)
{
  GtkCssImageWin32 *wimage = GTK_CSS_IMAGE_WIN32 (image);

  if (!_gtk_css_parser_try (parser, "-gtk-win32-theme-part", TRUE))
    {
      _gtk_css_parser_error (parser, "'-gtk-win32-theme-part'");
      return FALSE;
    }
  
  if (!_gtk_css_parser_try (parser, "(", TRUE))
    {
      _gtk_css_parser_error (parser,
                             "Expected '(' after '-gtk-win32-theme-part'");
      return FALSE;
    }
  
  wimage->theme = gtk_win32_theme_parse (parser);
  if (wimage->theme == NULL)
    return FALSE;

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

  if (!_gtk_css_parser_try_int (parser, &wimage->part))
    {
      _gtk_css_parser_error (parser, "Expected a valid integer value");
      return FALSE;
    }

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

  if (!_gtk_css_parser_try_int (parser, &wimage->state))
    {
      _gtk_css_parser_error (parser, "Expected a valid integer value");
      return FALSE;
    }

  while ( _gtk_css_parser_try (parser, ",", TRUE))
    {
      if ( _gtk_css_parser_try (parser, "over", TRUE))
        {
          if (!_gtk_css_parser_try (parser, "(", TRUE))
            {
              _gtk_css_parser_error (parser,
                                     "Expected '(' after 'over'");
              return FALSE;
            }

          if (!_gtk_css_parser_try_int (parser, &wimage->part2))
            {
              _gtk_css_parser_error (parser, "Expected a valid integer value");
              return FALSE;
            }

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

          if (!_gtk_css_parser_try_int (parser, &wimage->state2))
            {
              _gtk_css_parser_error (parser, "Expected a valid integer value");
              return FALSE;
            }

          if ( _gtk_css_parser_try (parser, ",", TRUE))
            {
              if (!_gtk_css_parser_try_double (parser, &wimage->over_alpha))
                {
                  _gtk_css_parser_error (parser, "Expected a valid double value");
                  return FALSE;
                }
            }

          if (!_gtk_css_parser_try (parser, ")", TRUE))
            {
              _gtk_css_parser_error (parser,
                                     "Expected ')' at end of 'over'");
              return FALSE;
            }
        }
      else if ( _gtk_css_parser_try (parser, "margins", TRUE))
        {
          guint i;

          if (!_gtk_css_parser_try (parser, "(", TRUE))
            {
              _gtk_css_parser_error (parser,
                                     "Expected '(' after 'margins'");
              return FALSE;
            }

          for (i = 0; i < 4; i++)
            {
              if (!_gtk_css_parser_try_int (parser, &wimage->margins[i]))
                break;
            }
          
          if (i == 0)
            {
              _gtk_css_parser_error (parser, "Expected valid margins");
              return FALSE;
            }

          if (i == 1)
            wimage->margins[1] = wimage->margins[0];
          if (i <= 2)
            wimage->margins[2] = wimage->margins[1];
          if (i <= 3)
            wimage->margins[3] = wimage->margins[2];
          
          if (!_gtk_css_parser_try (parser, ")", TRUE))
            {
              _gtk_css_parser_error (parser,
                                     "Expected ')' at end of 'margins'");
              return FALSE;
            }
        }
      else
        {
          _gtk_css_parser_error (parser,
                                 "Expected identifier");
          return FALSE;
        }
    }

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      _gtk_css_parser_error (parser,
			     "Expected ')'");
      return FALSE;
    }
  
  return TRUE;
}
Exemplo n.º 6
0
static gboolean 
slice_value_parse (GtkCssParser *parser,
                   GFile        *base,
                   GValue       *value)
{
  gdouble distance_top, distance_bottom;
  gdouble distance_left, distance_right;
  GtkSliceSideModifier mods[2];
  GdkPixbuf *pixbuf;
  Gtk9Slice *slice;
  GFile *file;
  GError *error = NULL;
  gint i;
  char *path;

  /* Parse image url */
  file = _gtk_css_parse_url (parser, base);
  if (!file)
      return FALSE;

  if (!_gtk_css_parser_try_double (parser, &distance_top) ||
      !_gtk_css_parser_try_double (parser, &distance_right) ||
      !_gtk_css_parser_try_double (parser, &distance_bottom) ||
      !_gtk_css_parser_try_double (parser, &distance_left))
    {
      _gtk_css_parser_error (parser, "Expected a number");
      g_object_unref (file);
      return FALSE;
    }

  for (i = 0; i < 2; i++)
    {
      if (_gtk_css_parser_try (parser, "stretch", TRUE))
        mods[i] = GTK_SLICE_STRETCH;
      else if (_gtk_css_parser_try (parser, "repeat", TRUE))
        mods[i] = GTK_SLICE_REPEAT;
      else if (i == 0)
        {
          mods[1] = mods[0] = GTK_SLICE_STRETCH;
          break;
        }
      else
        mods[i] = mods[0];
    }

  path = g_file_get_path (file);
  g_object_unref (file);
  pixbuf = gdk_pixbuf_new_from_file (path, &error);
  g_free (path);
  if (!pixbuf)
    {
      _gtk_css_parser_take_error (parser, error);
      return FALSE;
    }

  slice = _gtk_9slice_new (pixbuf,
                           distance_top, distance_bottom,
                           distance_left, distance_right,
                           mods[0], mods[1]);
  g_object_unref (pixbuf);

  g_value_take_boxed (value, slice);
  return TRUE;
}