Пример #1
0
static gboolean 
parse_border_radius (GtkCssShorthandProperty  *shorthand,
                     GtkCssValue             **values,
                     GtkCssParser             *parser)
{
  GtkCssValue *x[4] = { NULL, }, *y[4] = { NULL, };
  guint i;

  for (i = 0; i < 4; i++)
    {
      if (!_gtk_css_parser_has_number (parser))
        break;
      x[i] = _gtk_css_number_value_parse (parser,
                                          GTK_CSS_POSITIVE_ONLY
                                          | GTK_CSS_PARSE_PERCENT
                                          | GTK_CSS_NUMBER_AS_PIXELS
                                          | GTK_CSS_PARSE_LENGTH);
      if (x[i] == NULL)
        goto fail;
    }

  if (i == 0)
    {
      _gtk_css_parser_error (parser, "Expected a number");
      goto fail;
    }

  /* The magic (i - 1) >> 1 below makes it take the correct value
   * according to spec. Feel free to check the 4 cases
   */
  for (; i < 4; i++)
    x[i] = _gtk_css_value_ref (x[(i - 1) >> 1]);

  if (_gtk_css_parser_try (parser, "/", TRUE))
    {
      for (i = 0; i < 4; i++)
        {
          if (!_gtk_css_parser_has_number (parser))
            break;
          y[i] = _gtk_css_number_value_parse (parser,
                                              GTK_CSS_POSITIVE_ONLY
                                              | GTK_CSS_PARSE_PERCENT
                                              | GTK_CSS_NUMBER_AS_PIXELS
                                              | GTK_CSS_PARSE_LENGTH);
          if (y[i] == NULL)
            goto fail;
        }

      if (i == 0)
        {
          _gtk_css_parser_error (parser, "Expected a number");
          goto fail;
        }

      for (; i < 4; i++)
        y[i] = _gtk_css_value_ref (y[(i - 1) >> 1]);
    }
  else
    {
      for (i = 0; i < 4; i++)
Пример #2
0
static gboolean
parse_four_numbers (GtkCssShorthandProperty  *shorthand,
                    GtkCssValue             **values,
                    GtkCssParser             *parser,
                    GtkCssNumberParseFlags    flags)
{
  guint i;

  for (i = 0; i < 4; i++)
    {
      if (!_gtk_css_parser_has_number (parser))
        break;

      values[i] = _gtk_css_number_value_parse (parser, flags);
      if (values[i] == NULL)
        return FALSE;
    }

  if (i == 0)
    {
      _gtk_css_parser_error (parser, "Expected a length");
      return FALSE;
    }

  for (; i < 4; i++)
    {
      values[i] = _gtk_css_value_ref (values[(i - 1) >> 1]);
    }

  return TRUE;
}
Пример #3
0
static gboolean
gtk_css_image_cross_fade_parse (GtkCssImage  *image,
                                GtkCssParser *parser)
{
  GtkCssImageCrossFade *cross_fade = GTK_CSS_IMAGE_CROSS_FADE (image);
  if (!_gtk_css_parser_try (parser, "cross-fade(", TRUE))
    {
      _gtk_css_parser_error (parser, "Expected 'cross-fade('");
      return FALSE;
    }

  if (_gtk_css_parser_has_number (parser))
    {
      GtkCssValue *number;
      
      number = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_PERCENT | GTK_CSS_POSITIVE_ONLY);
      if (number == NULL)
        return FALSE;
      cross_fade->progress = _gtk_css_number_value_get (number, 1);
      _gtk_css_value_unref (number);

      if (cross_fade->progress > 1.0)
        {
          _gtk_css_parser_error (parser, "Percentages over 100%% are not allowed");
          return FALSE;
        }
    }
  else
    cross_fade->progress = 0.5;

  cross_fade->start = _gtk_css_image_new_parse (parser);
  if (cross_fade->start == NULL)
    return FALSE;

  if (_gtk_css_parser_try (parser, ",", TRUE))
    {
      /* XXX: allow parsing colors here */
      cross_fade->end = _gtk_css_image_new_parse (parser);
      if (cross_fade->end == NULL)
        return FALSE;
    }

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      _gtk_css_parser_error (parser, "Missing closing bracket");
      return FALSE;
    }

  return TRUE;
}
Пример #4
0
GtkCssValue *
_gtk_css_bg_size_value_parse (GtkCssParser *parser)
{
  GtkCssValue *x, *y;

  if (_gtk_css_parser_try (parser, "cover", TRUE))
    return _gtk_css_value_ref (&cover_singleton);
  else if (_gtk_css_parser_try (parser, "contain", TRUE))
    return _gtk_css_value_ref (&contain_singleton);

  if (_gtk_css_parser_try (parser, "auto", TRUE))
    x = NULL;
  else
    {
      x = _gtk_css_number_value_parse (parser,
                                       GTK_CSS_POSITIVE_ONLY
                                       | GTK_CSS_PARSE_PERCENT
                                       | GTK_CSS_PARSE_LENGTH);
      if (x == NULL)
        return NULL;
    }

  if (_gtk_css_parser_try (parser, "auto", TRUE))
    y = NULL;
  else if (!_gtk_css_parser_has_number (parser))
    y = NULL;
  else
    {
      y = _gtk_css_number_value_parse (parser,
                                       GTK_CSS_POSITIVE_ONLY
                                       | GTK_CSS_PARSE_PERCENT
                                       | GTK_CSS_PARSE_LENGTH);
      if (y == NULL)
        {
          _gtk_css_value_unref (x);
          return NULL;
        }
    }

  return _gtk_css_bg_size_value_new (x, y);
}
static gboolean
parse_four_numbers (GtkCssShorthandProperty *shorthand,
                    GValue                  *values,
                    GtkCssParser            *parser,
                    GtkCssNumberParseFlags   flags)
{
  GtkCssNumber numbers[4];
  guint i;

  for (i = 0; i < 4; i++)
    {
      if (!_gtk_css_parser_has_number (parser))
        break;

      if (!_gtk_css_parser_read_number (parser,
                                        &numbers[i], 
                                        flags))
        return FALSE;
    }

  if (i == 0)
    {
      _gtk_css_parser_error (parser, "Expected a length");
      return FALSE;
    }

  for (; i < 4; i++)
    {
      numbers[i] = numbers[(i - 1) >> 1];
    }

  for (i = 0; i < 4; i++)
    {
      g_value_init (&values[i], GTK_TYPE_CSS_NUMBER);
      g_value_set_boxed (&values[i], &numbers[i]);
    }

  return TRUE;
}
Пример #6
0
static gboolean
gtk_css_image_radial_parse (GtkCssImage  *image,
                            GtkCssParser *parser)
{
    GtkCssImageRadial *radial = GTK_CSS_IMAGE_RADIAL (image);
    gboolean has_shape = FALSE;
    gboolean has_size = FALSE;
    gboolean found_one = FALSE;
    guint i;
    static struct {
        const char *name;
        guint       value;
    } names[] = {
        { "closest-side", GTK_CSS_CLOSEST_SIDE },
        { "farthest-side", GTK_CSS_FARTHEST_SIDE },
        { "closest-corner", GTK_CSS_CLOSEST_CORNER },
        { "farthest-corner", GTK_CSS_FARTHEST_CORNER }
    };

    if (_gtk_css_parser_try (parser, "repeating-radial-gradient(", TRUE))
        radial->repeating = TRUE;
    else if (_gtk_css_parser_try (parser, "radial-gradient(", TRUE))
        radial->repeating = FALSE;
    else
    {
        _gtk_css_parser_error (parser, "Not a radial gradient");
        return FALSE;
    }

    do {
        found_one = FALSE;
        if (!has_shape && _gtk_css_parser_try (parser, "circle", TRUE))
        {
            radial->circle = TRUE;
            found_one = has_shape = TRUE;
        }
        else if (!has_shape && _gtk_css_parser_try (parser, "ellipse", TRUE))
        {
            radial->circle = FALSE;
            found_one = has_shape = TRUE;
        }
        else if (!has_size)
        {
            for (i = 0; i < G_N_ELEMENTS (names); i++)
            {
                if (_gtk_css_parser_try (parser, names[i].name, TRUE))
                {
                    found_one = has_size = TRUE;
                    radial->size = names[i].value;
                    break;
                }
            }

            if (!has_size)
            {
                if (_gtk_css_parser_has_number (parser))
                    radial->sizes[0] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
                if (_gtk_css_parser_has_number (parser))
                    radial->sizes[1] = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_LENGTH | GTK_CSS_PARSE_PERCENT);
                found_one = has_size = radial->sizes[0] != NULL;
            }
        }

    } while (found_one && !(has_shape && has_size));

    if (_gtk_css_parser_try (parser, "at", TRUE))
    {
        radial->position = _gtk_css_position_value_parse (parser);
        if (!radial->position)
            return FALSE;
        if (!_gtk_css_parser_try (parser, ",", TRUE))
        {
            _gtk_css_parser_error (parser, "Expected a comma here");
            return FALSE;
        }
    }
    else
    {
        radial->position = _gtk_css_position_value_new (_gtk_css_number_value_new (50, GTK_CSS_PERCENT),
                           _gtk_css_number_value_new (50, GTK_CSS_PERCENT));

        if ((has_shape || has_size) &&
                !_gtk_css_parser_try (parser, ",", TRUE))
        {
            _gtk_css_parser_error (parser, "Expected a comma here");
            return FALSE;
        }
    }

    if (!has_size)
    {
        radial->size = GTK_CSS_FARTHEST_CORNER;
    }

    if (!has_shape)
    {
        if (radial->sizes[0] && radial->sizes[1])
            radial->circle = FALSE;
        else
            radial->circle = TRUE;
    }

    if (has_shape && radial->circle)
    {
        if (radial->sizes[0] && radial->sizes[1])
        {
            _gtk_css_parser_error (parser, "Circular gradient can only have one size");
            return FALSE;
        }

        if (radial->sizes[0] && _gtk_css_number_value_get_unit (radial->sizes[0]) == GTK_CSS_PERCENT)
        {
            _gtk_css_parser_error (parser, "Circular gradient cannot have percentage as size");
            return FALSE;
        }
    }

    if (has_size && !radial->circle)
    {
        if (!radial->sizes[1])
            radial->sizes[1] = _gtk_css_value_ref (radial->sizes[0]);
    }

    do {
        GtkCssImageRadialColorStop stop;

        stop.color = _gtk_css_color_value_parse (parser);
        if (stop.color == NULL)
            return FALSE;

        if (_gtk_css_parser_has_number (parser))
        {
            stop.offset = _gtk_css_number_value_parse (parser,
                          GTK_CSS_PARSE_PERCENT
                          | GTK_CSS_PARSE_LENGTH);
            if (stop.offset == NULL)
            {
                _gtk_css_value_unref (stop.color);
                return FALSE;
            }
        }
        else
        {
            stop.offset = NULL;
        }

        g_array_append_val (radial->stops, stop);

    } while (_gtk_css_parser_try (parser, ",", TRUE));

    if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
        _gtk_css_parser_error (parser, "Missing closing bracket at end of radial gradient");
        return FALSE;
    }

    return TRUE;
}
static gboolean 
parse_border_radius (GtkCssShorthandProperty *shorthand,
                     GValue                  *values,
                     GtkCssParser            *parser,
                     GFile                   *base)
{
  GtkCssBorderCornerRadius borders[4];
  guint i;

  for (i = 0; i < G_N_ELEMENTS (borders); i++)
    {
      if (!_gtk_css_parser_has_number (parser))
        break;
      if (!_gtk_css_parser_read_number (parser,
                                        &borders[i].horizontal,
                                        GTK_CSS_POSITIVE_ONLY
                                        | GTK_CSS_PARSE_PERCENT
                                        | GTK_CSS_NUMBER_AS_PIXELS
                                        | GTK_CSS_PARSE_LENGTH))
        return FALSE;
    }

  if (i == 0)
    {
      _gtk_css_parser_error (parser, "Expected a number");
      return FALSE;
    }

  /* The magic (i - 1) >> 1 below makes it take the correct value
   * according to spec. Feel free to check the 4 cases */
  for (; i < G_N_ELEMENTS (borders); i++)
    borders[i].horizontal = borders[(i - 1) >> 1].horizontal;

  if (_gtk_css_parser_try (parser, "/", TRUE))
    {
      for (i = 0; i < G_N_ELEMENTS (borders); i++)
        {
          if (!_gtk_css_parser_has_number (parser))
            break;
          if (!_gtk_css_parser_read_number (parser,
                                            &borders[i].vertical,
                                            GTK_CSS_POSITIVE_ONLY
                                            | GTK_CSS_PARSE_PERCENT
                                            | GTK_CSS_NUMBER_AS_PIXELS
                                            | GTK_CSS_PARSE_LENGTH))
            return FALSE;
        }

      if (i == 0)
        {
          _gtk_css_parser_error (parser, "Expected a number");
          return FALSE;
        }

      for (; i < G_N_ELEMENTS (borders); i++)
        borders[i].vertical = borders[(i - 1) >> 1].vertical;

    }
  else
    {
      for (i = 0; i < G_N_ELEMENTS (borders); i++)
Пример #8
0
static gboolean
gtk_css_image_linear_parse (GtkCssImage  *image,
                            GtkCssParser *parser)
{
  GtkCssImageLinear *linear = GTK_CSS_IMAGE_LINEAR (image);
  guint i;

  if (_gtk_css_parser_try (parser, "repeating-linear-gradient(", TRUE))
    linear->repeating = TRUE;
  else if (_gtk_css_parser_try (parser, "linear-gradient(", TRUE))
    linear->repeating = FALSE;
  else
    {
      _gtk_css_parser_error (parser, "Not a linear gradient");
      return FALSE;
    }

  if (_gtk_css_parser_try (parser, "to", TRUE))
    {
      guint side = 0;

      for (i = 0; i < 2; i++)
        {
          if (_gtk_css_parser_try (parser, "left", TRUE))
            {
              if (side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT)))
                {
                  _gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma");
                  return FALSE;
                }
              side |= (1 << GTK_CSS_LEFT);
            }
          else if (_gtk_css_parser_try (parser, "right", TRUE))
            {
              if (side & ((1 << GTK_CSS_LEFT) | (1 << GTK_CSS_RIGHT)))
                {
                  _gtk_css_parser_error (parser, "Expected 'top', 'bottom' or comma");
                  return FALSE;
                }
              side |= (1 << GTK_CSS_RIGHT);
            }
          else if (_gtk_css_parser_try (parser, "top", TRUE))
            {
              if (side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM)))
                {
                  _gtk_css_parser_error (parser, "Expected 'left', 'right' or comma");
                  return FALSE;
                }
              side |= (1 << GTK_CSS_TOP);
            }
          else if (_gtk_css_parser_try (parser, "bottom", TRUE))
            {
              if (side & ((1 << GTK_CSS_TOP) | (1 << GTK_CSS_BOTTOM)))
                {
                  _gtk_css_parser_error (parser, "Expected 'left', 'right' or comma");
                  return FALSE;
                }
              side |= (1 << GTK_CSS_BOTTOM);
            }
          else
            break;
        }

      if (side == 0)
        {
          _gtk_css_parser_error (parser, "Expected side that gradient should go to");
          return FALSE;
        }

      linear->angle = _gtk_css_number_value_new (side, GTK_CSS_NUMBER);

      if (!_gtk_css_parser_try (parser, ",", TRUE))
        {
          _gtk_css_parser_error (parser, "Expected a comma");
          return FALSE;
        }
    }
  else if (_gtk_css_parser_has_number (parser))
    {
      linear->angle = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_ANGLE);
      if (linear->angle == NULL)
        return FALSE;

      if (!_gtk_css_parser_try (parser, ",", TRUE))
        {
          _gtk_css_parser_error (parser, "Expected a comma");
          return FALSE;
        }
    }
  else
    linear->angle = _gtk_css_number_value_new (1 << GTK_CSS_BOTTOM, GTK_CSS_NUMBER);

  do {
    GtkCssImageLinearColorStop stop;

    stop.color = _gtk_css_color_value_parse (parser);
    if (stop.color == NULL)
      return FALSE;

    if (_gtk_css_parser_has_number (parser))
      {
        stop.offset = _gtk_css_number_value_parse (parser,
                                                   GTK_CSS_PARSE_PERCENT
                                                   | GTK_CSS_PARSE_LENGTH);
        if (stop.offset == NULL)
          {
            _gtk_css_value_unref (stop.color);
            return FALSE;
          }
      }
    else
      {
        stop.offset = NULL;
      }

    g_array_append_val (linear->stops, stop);

  } while (_gtk_css_parser_try (parser, ",", TRUE));

  if (!_gtk_css_parser_try (parser, ")", TRUE))
    {
      _gtk_css_parser_error (parser, "Missing closing bracket at end of linear gradient");
      return FALSE;
    }

  return TRUE;
}