예제 #1
0
static GtkBitmask *
gtk_css_transition_set_values (GtkStyleAnimation    *animation,
                               GtkBitmask           *changed,
                               gint64                for_time_us,
                               GtkCssComputedValues *values)
{
  GtkCssTransition *transition = GTK_CSS_TRANSITION (animation);
  GtkCssValue *value;
  double progress;

  if (transition->start_time >= for_time_us)
    value = _gtk_css_value_ref (transition->start);
  else if (transition->end_time <= for_time_us)
    value = _gtk_css_value_ref (transition->end);
  else
    {
      progress = (double) (for_time_us - transition->start_time) / (transition->end_time - transition->start_time);
      progress = _gtk_css_ease_value_transform (transition->ease, progress);

      value = _gtk_css_value_transition (transition->start,
                                         transition->end,
                                         progress);
      if (value == NULL)
        value = _gtk_css_value_ref (transition->end);
    }

  _gtk_css_computed_values_set_value (values, transition->property, value, NULL);
  _gtk_css_value_unref (value);

  return _gtk_bitmask_set (changed, transition->property, TRUE);
}
예제 #2
0
static GtkCssValue *
gtk_css_value_image_compute (GtkCssValue             *value,
                             guint                    property_id,
                             GtkStyleProviderPrivate *provider,
                             GtkCssComputedValues    *values,
                             GtkCssComputedValues    *parent_values,
                             GtkCssDependencies      *dependencies)
{
  GtkCssImage *image, *computed;
  
  image = _gtk_css_image_value_get_image (value);

  if (image == NULL)
    return _gtk_css_value_ref (value);

  computed = _gtk_css_image_compute (image, property_id, provider, values, parent_values, dependencies);

  if (computed == image)
    {
      g_object_unref (computed);
      return _gtk_css_value_ref (value);
    }

  return _gtk_css_image_value_new (computed);
}
예제 #3
0
GtkStyleAnimation *
_gtk_css_transition_new (guint        property,
                         GtkCssValue *start,
                         GtkCssValue *end,
                         GtkCssValue *ease,
                         gint64       start_time_us,
                         gint64       end_time_us)
{
  GtkCssTransition *transition;

  g_return_val_if_fail (start != NULL, NULL);
  g_return_val_if_fail (end != NULL, NULL);
  g_return_val_if_fail (ease != NULL, NULL);
  g_return_val_if_fail (start_time_us <= end_time_us, NULL);

  transition = g_object_new (GTK_TYPE_CSS_TRANSITION, NULL);

  transition->property = property;
  transition->start = _gtk_css_value_ref (start);
  transition->end = _gtk_css_value_ref (end);
  transition->ease = _gtk_css_value_ref (ease);
  transition->start_time = start_time_us;
  transition->end_time = end_time_us;

  return GTK_STYLE_ANIMATION (transition);
}
예제 #4
0
static GtkCssValue *
gtk_css_value_bg_size_compute (GtkCssValue             *value,
                               guint                    property_id,
                               GtkStyleProviderPrivate *provider,
			       int                      scale,
                               GtkCssComputedValues    *values,
                               GtkCssComputedValues    *parent_values,
                               GtkCssDependencies      *dependencies)
{
  GtkCssValue *x, *y;
  GtkCssDependencies x_deps, y_deps;

  if (value->x == NULL && value->y == NULL)
    return _gtk_css_value_ref (value);

  x_deps = y_deps = 0;
  x = y = NULL;

  if (value->x)
    x = _gtk_css_value_compute (value->x, property_id, provider, scale, values, parent_values, &x_deps);

  if (value->y)
    y = _gtk_css_value_compute (value->y, property_id, provider, scale, values, parent_values, &y_deps);

  *dependencies = _gtk_css_dependencies_union (x_deps, y_deps);

  return _gtk_css_bg_size_value_new (value->x ? x : NULL,
                                     value->y ? y : NULL);
}
예제 #5
0
GtkCssValue *
_gtk_css_border_style_value_new (GtkBorderStyle border_style)
{
  g_return_val_if_fail (border_style < G_N_ELEMENTS (border_style_values), NULL);

  return _gtk_css_value_ref (&border_style_values[border_style]);
}
예제 #6
0
static GtkCssValue *
gtk_css_value_shadows_compute (GtkCssValue             *value,
                               guint                    property_id,
                               GtkStyleProviderPrivate *provider,
			       int                      scale,
                               GtkCssComputedValues    *values,
                               GtkCssComputedValues    *parent_values,
                               GtkCssDependencies      *dependencies)
{
  GtkCssValue *result;
  GtkCssDependencies child_deps;
  guint i;

  if (value->len == 0)
    return _gtk_css_value_ref (value);

  result = gtk_css_shadows_value_new (value->values, value->len);
  for (i = 0; i < value->len; i++)
    {
      result->values[i] = _gtk_css_value_compute (value->values[i], property_id, provider, scale, values, parent_values, &child_deps);
      *dependencies = _gtk_css_dependencies_union (*dependencies, child_deps);
    }

  return result;
}
예제 #7
0
static GtkCssValue *
gtk_css_value_rgba_compute (GtkCssValue             *value,
                            guint                    property_id,
                            GtkStyleProviderPrivate *provider,
                            GtkCssStyle             *style,
                            GtkCssStyle             *parent_style)
{
  return _gtk_css_value_ref (value);
}
예제 #8
0
GtkCssValue *
gtk_css_icon_theme_value_new (GtkIconTheme *icontheme)
{
  GtkCssValue *result;

  if (icontheme == NULL)
    return _gtk_css_value_ref (&default_icon_theme_value);

  result = g_object_get_data (G_OBJECT (icontheme), "-gtk-css-value");
  if (result)
    return _gtk_css_value_ref (result);

  result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_ICON_THEME);
  result->icontheme = g_object_ref (icontheme);

  g_object_set_data (G_OBJECT (icontheme), I_("-gtk-css-value"), result);
  result->changed_id = g_signal_connect (icontheme, "changed", G_CALLBACK (gtk_css_value_icon_theme_changed_cb), result);

  return result;
}
예제 #9
0
파일: gtkcssenumvalue.c 프로젝트: 3v1n0/gtk
static GtkCssValue *
gtk_css_value_enum_compute (GtkCssValue             *value,
                            guint                    property_id,
                            GtkStyleProviderPrivate *provider,
			    int                      scale,
                            GtkCssComputedValues    *values,
                            GtkCssComputedValues    *parent_values,
                            GtkCssDependencies      *dependencies)
{
  return _gtk_css_value_ref (value);
}
예제 #10
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_number_value_can_parse (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);
}
예제 #11
0
static GtkCssValue *
gtk_css_value_bg_size_transition (GtkCssValue *start,
                                  GtkCssValue *end,
                                  guint        property_id,
                                  double       progress)
{
  GtkCssValue *x, *y;

  if (start->cover)
    return end->cover ? _gtk_css_value_ref (end) : NULL;
  if (start->contain)
    return end->contain ? _gtk_css_value_ref (end) : NULL;

  if ((start->x != NULL) ^ (end->x != NULL) ||
      (start->y != NULL) ^ (end->y != NULL))
    return NULL;

  if (start->x)
    {
      x = _gtk_css_value_transition (start->x, end->x, property_id, progress);
      if (x == NULL)
        return NULL;
    }
  else
    x = NULL;

  if (start->y)
    {
      y = _gtk_css_value_transition (start->y, end->y, property_id, progress);
      if (y == NULL)
        {
          _gtk_css_value_unref (x);
          return NULL;
        }
    }
  else
    y = NULL;

  return _gtk_css_bg_size_value_new (x, y);
}
예제 #12
0
GtkCssValue *
_gtk_css_image_value_new (GtkCssImage *image)
{
  static GtkCssValue none_singleton = { &GTK_CSS_VALUE_IMAGE, 1, NULL };
  GtkCssValue *value;

  if (image == NULL)
    return _gtk_css_value_ref (&none_singleton);

  value = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_IMAGE);
  value->image = image;

  return value;
}
예제 #13
0
GtkCssValue *
_gtk_css_bg_size_value_new (GtkCssValue *x,
                            GtkCssValue *y)
{
  GtkCssValue *result;

  if (x == NULL && y == NULL)
    return _gtk_css_value_ref (&auto_singleton);

  result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_BG_SIZE);
  result->x = x;
  result->y = y;

  return result;
}
예제 #14
0
GtkCssValue *
_gtk_css_border_style_value_try_parse (GtkCssParser *parser)
{
  guint i;

  g_return_val_if_fail (parser != NULL, NULL);

  for (i = 0; i < G_N_ELEMENTS (border_style_values); i++)
    {
      if (_gtk_css_parser_try (parser, border_style_values[i].name, TRUE))
        return _gtk_css_value_ref (&border_style_values[i]);
    }

  return NULL;
}
예제 #15
0
static GtkCssValue *
gtk_css_value_image_compute (GtkCssValue      *value,
                             guint             property_id,
                             GtkStyleProvider *provider,
                             GtkCssStyle      *style,
                             GtkCssStyle      *parent_style)
{
  GtkCssImage *image, *computed;
  
  image = _gtk_css_image_value_get_image (value);

  if (image == NULL)
    return _gtk_css_value_ref (value);

  computed = _gtk_css_image_compute (image, property_id, provider, style, parent_style);

  if (computed == image)
    {
      g_object_unref (computed);
      return _gtk_css_value_ref (value);
    }

  return _gtk_css_image_value_new (computed);
}
예제 #16
0
GtkCssValue *
_gtk_css_number_value_new (double     value,
                           GtkCssUnit unit)
{
  static GtkCssValue number_singletons[] = {
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_NUMBER, 0 },
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_NUMBER, 1 },
  };
  static GtkCssValue px_singletons[] = {
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 0 },
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 1 },
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 2 },
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 3 },
    { &GTK_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 4 },
  };
  GtkCssValue *result;

  if (unit == GTK_CSS_NUMBER && (value == 0 || value == 1))
    return _gtk_css_value_ref (&number_singletons[(int) value]);

  if (unit == GTK_CSS_PX &&
      (value == 0 ||
       value == 1 ||
       value == 2 ||
       value == 3 ||
       value == 4))
    {
      return _gtk_css_value_ref (&px_singletons[(int) value]);
    }

  result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_NUMBER);
  result->unit = unit;
  result->value = value;

  return result;
}
예제 #17
0
void
_gtk_css_computed_values_set_animated_value (GtkCssComputedValues *values,
        guint                 id,
        GtkCssValue          *value)
{
    gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
    gtk_internal_return_if_fail (value != NULL);

    if (values->animated_values == NULL)
        values->animated_values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
    if (id >= values->animated_values->len)
        g_ptr_array_set_size (values->animated_values, id + 1);

    if (g_ptr_array_index (values->animated_values, id))
        _gtk_css_value_unref (g_ptr_array_index (values->animated_values, id));
    g_ptr_array_index (values->animated_values, id) = _gtk_css_value_ref (value);

}
예제 #18
0
void
gtk_css_animated_style_set_animated_value (GtkCssAnimatedStyle *style,
                                           guint                id,
                                           GtkCssValue         *value)
{
  gtk_internal_return_if_fail (GTK_IS_CSS_ANIMATED_STYLE (style));
  gtk_internal_return_if_fail (value != NULL);

  if (style->animated_values == NULL)
    style->animated_values = g_ptr_array_new_with_free_func ((GDestroyNotify)_gtk_css_value_unref);
  if (id >= style->animated_values->len)
   g_ptr_array_set_size (style->animated_values, id + 1);

  if (g_ptr_array_index (style->animated_values, id))
    _gtk_css_value_unref (g_ptr_array_index (style->animated_values, id));
  g_ptr_array_index (style->animated_values, id) = _gtk_css_value_ref (value);

}
예제 #19
0
void
_gtk_css_computed_values_set_value (GtkCssComputedValues *values,
                                    guint                 id,
                                    GtkCssValue          *value,
                                    GtkCssDependencies    dependencies,
                                    GtkCssSection        *section)
{
    gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));

    if (values->values == NULL)
        values->values = g_ptr_array_new_full (_gtk_css_style_property_get_n_properties (),
                                               (GDestroyNotify)_gtk_css_value_unref);
    if (id >= values->values->len)
        g_ptr_array_set_size (values->values, id + 1);

    if (g_ptr_array_index (values->values, id))
        _gtk_css_value_unref (g_ptr_array_index (values->values, id));
    g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value);

    if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT))
        values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE);
    if (dependencies & (GTK_CSS_EQUALS_PARENT))
        values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE);
    if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR))
        values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE);
    if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE))
        values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE);

    if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id))
    {
        gtk_css_section_unref (g_ptr_array_index (values->sections, id));
        g_ptr_array_index (values->sections, id) = NULL;
    }

    if (section)
    {
        if (values->sections == NULL)
            values->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
        if (values->sections->len <= id)
            g_ptr_array_set_size (values->sections, id + 1);

        g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section);
    }
}
예제 #20
0
static GtkCssValue *
gtk_css_value_inherit_compute (GtkCssValue             *value,
                               guint                    property_id,
                               GtkStyleProviderPrivate *provider,
                               GtkCssStyle             *style,
                               GtkCssStyle             *parent_style)
{
  if (parent_style)
    {
      return _gtk_css_value_ref (gtk_css_style_get_value (parent_style, property_id));
    }
  else
    {
      return _gtk_css_value_compute (_gtk_css_initial_value_get (),
                                     property_id,
                                     provider,
                                     style,
                                     parent_style);
    }
}
예제 #21
0
void
_gtk_css_computed_values_compute_value (GtkCssComputedValues    *values,
                                        GtkStyleProviderPrivate *provider,
                                        GtkCssComputedValues    *parent_values,
                                        guint                    id,
                                        GtkCssValue             *specified,
                                        GtkCssSection           *section)
{
    GtkCssDependencies dependencies;
    GtkCssValue *value;

    gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
    gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER_PRIVATE (provider));
    gtk_internal_return_if_fail (parent_values == NULL || GTK_IS_CSS_COMPUTED_VALUES (parent_values));

    /* http://www.w3.org/TR/css3-cascade/#cascade
     * Then, for every element, the value for each property can be found
     * by following this pseudo-algorithm:
     * 1) Identify all declarations that apply to the element
     */
    if (specified == NULL)
    {
        GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (id);

        if (_gtk_css_style_property_is_inherit (prop))
            specified = _gtk_css_inherit_value_new ();
        else
            specified = _gtk_css_initial_value_new ();
    }
    else
        _gtk_css_value_ref (specified);

    value = _gtk_css_value_compute (specified, id, provider, values, parent_values, &dependencies);

    _gtk_css_computed_values_set_value (values, id, value, dependencies, section);

    _gtk_css_value_unref (value);
    _gtk_css_value_unref (specified);
}
예제 #22
0
static GtkCssValue *
gtk_css_value_bg_size_compute (GtkCssValue             *value,
                               guint                    property_id,
                               GtkStyleProviderPrivate *provider,
                               GtkCssStyle             *style,
                               GtkCssStyle             *parent_style)
{
  GtkCssValue *x, *y;

  if (value->x == NULL && value->y == NULL)
    return _gtk_css_value_ref (value);

  x = y = NULL;

  if (value->x)
    x = _gtk_css_value_compute (value->x, property_id, provider, style, parent_style);

  if (value->y)
    y = _gtk_css_value_compute (value->y, property_id, provider, style, parent_style);

  return _gtk_css_bg_size_value_new (value->x ? x : NULL,
                                     value->y ? y : NULL);
}
예제 #23
0
static GtkCssValue *
gtk_css_value_inherit_compute (GtkCssValue             *value,
                               guint                    property_id,
                               GtkStyleProviderPrivate *provider,
                               GtkCssComputedValues    *values,
                               GtkCssComputedValues    *parent_values,
                               GtkCssDependencies      *dependencies)
{
  if (parent_values)
    {
      *dependencies = GTK_CSS_EQUALS_PARENT;
      return _gtk_css_value_ref (_gtk_css_computed_values_get_value (parent_values, property_id));
    }
  else
    {
      return _gtk_css_value_compute (_gtk_css_initial_value_get (),
                                     property_id,
                                     provider,
                                     values,
                                     parent_values,
                                     dependencies);
    }
}
예제 #24
0
파일: gtkcssanimation.c 프로젝트: 3v1n0/gtk
GtkStyleAnimation *
_gtk_css_animation_new (const char      *name,
                        GtkCssKeyframes *keyframes,
                        gint64           timestamp,
                        gint64           delay_us,
                        gint64           duration_us,
                        GtkCssValue     *ease,
                        GtkCssDirection  direction,
                        GtkCssPlayState  play_state,
                        GtkCssFillMode   fill_mode,
                        double           iteration_count)
{
  GtkCssAnimation *animation;

  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (keyframes != NULL, NULL);
  g_return_val_if_fail (ease != NULL, NULL);
  g_return_val_if_fail (iteration_count >= 0, NULL);

  animation = g_object_new (GTK_TYPE_CSS_ANIMATION, NULL);

  animation->name = g_strdup (name);
  animation->keyframes = _gtk_css_keyframes_ref (keyframes);
  if (play_state == GTK_CSS_PLAY_STATE_PAUSED)
    animation->timestamp = - delay_us;
  else
    animation->timestamp = timestamp + delay_us;

  animation->duration = duration_us;
  animation->ease = _gtk_css_value_ref (ease);
  animation->direction = direction;
  animation->play_state = play_state;
  animation->fill_mode = fill_mode;
  animation->iteration_count = iteration_count;

  return GTK_STYLE_ANIMATION (animation);
}
예제 #25
0
static GtkCssValue *
gtk_css_value_number_compute (GtkCssValue             *number,
                              guint                    property_id,
                              GtkStyleProviderPrivate *provider,
			      int                      scale,
                              GtkCssComputedValues    *values,
                              GtkCssComputedValues    *parent_values,
                              GtkCssDependencies      *dependencies)
{
  switch (number->unit)
    {
    default:
      g_assert_not_reached();
      /* fall through */
    case GTK_CSS_PERCENT:
      /* percentages for font sizes are computed, other percentages aren't */
      if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
        return _gtk_css_number_value_new (number->value / 100.0 * 
                                          get_base_font_size (property_id, provider, values, parent_values, dependencies),
                                          GTK_CSS_PX);
    case GTK_CSS_NUMBER:
    case GTK_CSS_PX:
    case GTK_CSS_DEG:
    case GTK_CSS_S:
      return _gtk_css_value_ref (number);
    case GTK_CSS_PT:
      return _gtk_css_number_value_new (number->value * 96.0 / 72.0,
                                        GTK_CSS_PX);
    case GTK_CSS_PC:
      return _gtk_css_number_value_new (number->value * 96.0 / 72.0 * 12.0,
                                        GTK_CSS_PX);
      break;
    case GTK_CSS_IN:
      return _gtk_css_number_value_new (number->value * 96.0,
                                        GTK_CSS_PX);
      break;
    case GTK_CSS_CM:
      return _gtk_css_number_value_new (number->value * 96.0 * 0.39370078740157477,
                                        GTK_CSS_PX);
      break;
    case GTK_CSS_MM:
      return _gtk_css_number_value_new (number->value * 96.0 * 0.039370078740157477,
                                        GTK_CSS_PX);
      break;
    case GTK_CSS_EM:
      return _gtk_css_number_value_new (number->value *
                                        get_base_font_size (property_id, provider, values, parent_values, dependencies),
                                        GTK_CSS_PX);
      break;
    case GTK_CSS_EX:
      /* for now we pretend ex is half of em */
      return _gtk_css_number_value_new (number->value * 0.5 * 
                                        get_base_font_size (property_id, provider, values, parent_values, dependencies),
                                        GTK_CSS_PX);
    case GTK_CSS_RAD:
      return _gtk_css_number_value_new (number->value * 360.0 / (2 * G_PI),
                                        GTK_CSS_DEG);
    case GTK_CSS_GRAD:
      return _gtk_css_number_value_new (number->value * 360.0 / 400.0,
                                        GTK_CSS_DEG);
    case GTK_CSS_TURN:
      return _gtk_css_number_value_new (number->value * 360.0,
                                        GTK_CSS_DEG);
    case GTK_CSS_MS:
      return _gtk_css_number_value_new (number->value / 1000.0,
                                        GTK_CSS_S);
    }
}
예제 #26
0
static GtkCssValue *
gtk_css_value_dimension_compute (GtkCssValue             *number,
                              guint                    property_id,
                              GtkStyleProviderPrivate *provider,
                              GtkCssStyle             *style,
                              GtkCssStyle             *parent_style)
{
  GtkBorderStyle border_style;

  /* special case according to http://dev.w3.org/csswg/css-backgrounds/#the-border-width */
  switch (property_id)
    {
      case GTK_CSS_PROPERTY_BORDER_TOP_WIDTH:
        border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_TOP_STYLE));
        if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
          return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
        break;
      case GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH:
        border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE));
        if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
          return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
        break;
      case GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH:
        border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE));
        if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
          return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
        break;
      case GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH:
        border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_BORDER_LEFT_STYLE));
        if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
          return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
        break;
      case GTK_CSS_PROPERTY_OUTLINE_WIDTH:
        border_style = _gtk_css_border_style_value_get(gtk_css_style_get_value (style, GTK_CSS_PROPERTY_OUTLINE_STYLE));
        if (border_style == GTK_BORDER_STYLE_NONE || border_style == GTK_BORDER_STYLE_HIDDEN)
          return gtk_css_dimension_value_new (0, GTK_CSS_NUMBER);
        break;
      default:
        break;
    }

  switch (number->unit)
    {
    default:
      g_assert_not_reached();
      /* fall through */
    case GTK_CSS_PERCENT:
      /* percentages for font sizes are computed, other percentages aren't */
      if (property_id == GTK_CSS_PROPERTY_FONT_SIZE)
        return gtk_css_dimension_value_new (number->value / 100.0 * 
                                            get_base_font_size (property_id, provider, style, parent_style),
                                            GTK_CSS_PX);
    case GTK_CSS_NUMBER:
    case GTK_CSS_PX:
    case GTK_CSS_DEG:
    case GTK_CSS_S:
      return _gtk_css_value_ref (number);
    case GTK_CSS_PT:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0,
                                          GTK_CSS_PX);
    case GTK_CSS_PC:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 * 12.0,
                                          GTK_CSS_PX);
    case GTK_CSS_IN:
      return gtk_css_dimension_value_new (number->value * get_dpi (style),
                                          GTK_CSS_PX);
    case GTK_CSS_CM:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.39370078740157477,
                                          GTK_CSS_PX);
    case GTK_CSS_MM:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) * 0.039370078740157477,
                                          GTK_CSS_PX);
    case GTK_CSS_EM:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 *
                                          get_base_font_size (property_id, provider, style, parent_style),
                                          GTK_CSS_PX);
    case GTK_CSS_EX:
      /* for now we pretend ex is half of em */
      return gtk_css_dimension_value_new (number->value * 0.5 * get_dpi (style) / 72.0 *
                                          get_base_font_size (property_id, provider, style, parent_style),
                                          GTK_CSS_PX);
    case GTK_CSS_REM:
      return gtk_css_dimension_value_new (number->value * get_dpi (style) / 72.0 *
                                          _gtk_css_font_size_get_default (provider),
                                          GTK_CSS_PX);
    case GTK_CSS_RAD:
      return gtk_css_dimension_value_new (number->value * 360.0 / (2 * G_PI),
                                          GTK_CSS_DEG);
    case GTK_CSS_GRAD:
      return gtk_css_dimension_value_new (number->value * 360.0 / 400.0,
                                          GTK_CSS_DEG);
    case GTK_CSS_TURN:
      return gtk_css_dimension_value_new (number->value * 360.0,
                                          GTK_CSS_DEG);
    case GTK_CSS_MS:
      return gtk_css_dimension_value_new (number->value / 1000.0,
                                          GTK_CSS_S);
    }
}
예제 #27
0
void
_gtk_css_computed_values_compute_value (GtkCssComputedValues    *values,
                                        GtkStyleProviderPrivate *provider,
					int                      scale,
                                        GtkCssComputedValues    *parent_values,
                                        guint                    id,
                                        GtkCssValue             *specified,
                                        GtkCssSection           *section)
{
  GtkCssDependencies dependencies;
  GtkCssValue *value;

  gtk_internal_return_if_fail (GTK_IS_CSS_COMPUTED_VALUES (values));
  gtk_internal_return_if_fail (GTK_IS_STYLE_PROVIDER_PRIVATE (provider));
  gtk_internal_return_if_fail (parent_values == NULL || GTK_IS_CSS_COMPUTED_VALUES (parent_values));

  /* http://www.w3.org/TR/css3-cascade/#cascade
   * Then, for every element, the value for each property can be found
   * by following this pseudo-algorithm:
   * 1) Identify all declarations that apply to the element
   */
  if (specified == NULL)
    {
      GtkCssStyleProperty *prop = _gtk_css_style_property_lookup_by_id (id);

      if (_gtk_css_style_property_is_inherit (prop))
        specified = _gtk_css_inherit_value_new ();
      else
        specified = _gtk_css_initial_value_new ();
    }
  else
    _gtk_css_value_ref (specified);

  value = _gtk_css_value_compute (specified, id, provider, scale, values, parent_values, &dependencies);

  if (values->values == NULL)
    values->values = g_ptr_array_new_full (_gtk_css_style_property_get_n_properties (),
					   (GDestroyNotify)_gtk_css_value_unref);
  if (id >= values->values->len)
   g_ptr_array_set_size (values->values, id + 1);

  if (g_ptr_array_index (values->values, id))
    _gtk_css_value_unref (g_ptr_array_index (values->values, id));
  g_ptr_array_index (values->values, id) = _gtk_css_value_ref (value);

  if (dependencies & (GTK_CSS_DEPENDS_ON_PARENT | GTK_CSS_EQUALS_PARENT))
    values->depends_on_parent = _gtk_bitmask_set (values->depends_on_parent, id, TRUE);
  if (dependencies & (GTK_CSS_EQUALS_PARENT))
    values->equals_parent = _gtk_bitmask_set (values->equals_parent, id, TRUE);
  if (dependencies & (GTK_CSS_DEPENDS_ON_COLOR))
    values->depends_on_color = _gtk_bitmask_set (values->depends_on_color, id, TRUE);
  if (dependencies & (GTK_CSS_DEPENDS_ON_FONT_SIZE))
    values->depends_on_font_size = _gtk_bitmask_set (values->depends_on_font_size, id, TRUE);

  if (values->sections && values->sections->len > id && g_ptr_array_index (values->sections, id))
    {
      gtk_css_section_unref (g_ptr_array_index (values->sections, id));
      g_ptr_array_index (values->sections, id) = NULL;
    }

  if (section)
    {
      if (values->sections == NULL)
        values->sections = g_ptr_array_new_with_free_func (maybe_unref_section);
      if (values->sections->len <= id)
        g_ptr_array_set_size (values->sections, id + 1);

      g_ptr_array_index (values->sections, id) = gtk_css_section_ref (section);
    }

  _gtk_css_value_unref (value);
  _gtk_css_value_unref (specified);
}
예제 #28
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;
}
예제 #29
0
GtkCssValue *
_gtk_css_unset_value_new (void)
{
    return _gtk_css_value_ref (&unset);
}
예제 #30
0
            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++)
        y[i] = _gtk_css_value_ref (x[i]);
    }

  for (i = 0; i < 4; i++)
    {
      values[i] = _gtk_css_corner_value_new (x[i], y[i]);
    }

  return TRUE;

fail:
  for (i = 0; i < 4; i++)
    {
      if (x[i])
        _gtk_css_value_unref (x[i]);
      if (y[i])