diff options
Diffstat (limited to 'gtk/gtkcssnumbervalue.c')
-rw-r--r-- | gtk/gtkcssnumbervalue.c | 266 |
1 files changed, 20 insertions, 246 deletions
diff --git a/gtk/gtkcssnumbervalue.c b/gtk/gtkcssnumbervalue.c index 86b4c40dc8..a766a631b5 100644 --- a/gtk/gtkcssnumbervalue.c +++ b/gtk/gtkcssnumbervalue.c @@ -1,5 +1,5 @@ /* GTK - The GIMP Toolkit - * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2016 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,278 +19,52 @@ #include "gtkcssnumbervalueprivate.h" -#include "gtkcssenumvalueprivate.h" -#include "gtkcssinitialvalueprivate.h" -#include "gtkstylepropertyprivate.h" - -#include "fallback-c89.c" +#include "gtkcssdimensionvalueprivate.h" struct _GtkCssValue { GTK_CSS_VALUE_BASE - GtkCssUnit unit; - double value; }; -static void -gtk_css_value_number_free (GtkCssValue *value) -{ - g_slice_free (GtkCssValue, value); -} - -static double -get_base_font_size (guint property_id, - GtkStyleProviderPrivate *provider, - GtkCssStyle *style, - GtkCssStyle *parent_style) -{ - if (property_id == GTK_CSS_PROPERTY_FONT_SIZE) - { - if (parent_style) - return _gtk_css_number_value_get (gtk_css_style_get_value (parent_style, GTK_CSS_PROPERTY_FONT_SIZE), 100); - else - return _gtk_css_font_size_get_default (provider); - } - - return _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_FONT_SIZE), 100); -} - -static double -get_dpi (GtkCssStyle *style) -{ - return _gtk_css_number_value_get (gtk_css_style_get_value (style, GTK_CSS_PROPERTY_DPI), 96); -} - -static GtkCssValue * -gtk_css_value_number_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_number_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_number_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_number_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_number_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_number_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_number_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_number_value_new (number->value * get_dpi (style) / 72.0, - GTK_CSS_PX); - case GTK_CSS_PC: - return _gtk_css_number_value_new (number->value * get_dpi (style) / 72.0 * 12.0, - GTK_CSS_PX); - case GTK_CSS_IN: - return _gtk_css_number_value_new (number->value * get_dpi (style), - GTK_CSS_PX); - case GTK_CSS_CM: - return _gtk_css_number_value_new (number->value * get_dpi (style) * 0.39370078740157477, - GTK_CSS_PX); - case GTK_CSS_MM: - return _gtk_css_number_value_new (number->value * get_dpi (style) * 0.039370078740157477, - GTK_CSS_PX); - case GTK_CSS_EM: - return _gtk_css_number_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_number_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_number_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_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); - } -} - -static gboolean -gtk_css_value_number_equal (const GtkCssValue *number1, - const GtkCssValue *number2) -{ - return number1->unit == number2->unit && - number1->value == number2->value; -} - -static GtkCssValue * -gtk_css_value_number_transition (GtkCssValue *start, - GtkCssValue *end, - guint property_id, - double progress) +GtkCssDimension +gtk_css_number_value_get_dimension (const GtkCssValue *value) { - /* FIXME: This needs to be supported at least for percentages, - * but for that we kinda need to support calc(5px + 50%) */ - if (start->unit != end->unit) - return NULL; + GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; - return _gtk_css_number_value_new (start->value + (end->value - start->value) * progress, - start->unit); + return number_value_class->get_dimension (value); } -static void -gtk_css_value_number_print (const GtkCssValue *number, - GString *string) +gboolean +gtk_css_number_value_has_percent (const GtkCssValue *value) { - char buf[G_ASCII_DTOSTR_BUF_SIZE]; - - const char *names[] = { - /* [GTK_CSS_NUMBER] = */ "", - /* [GTK_CSS_PERCENT] = */ "%", - /* [GTK_CSS_PX] = */ "px", - /* [GTK_CSS_PT] = */ "pt", - /* [GTK_CSS_EM] = */ "em", - /* [GTK_CSS_EX] = */ "ex", - /* [GTK_CSS_REM] = */ "rem", - /* [GTK_CSS_PC] = */ "pc", - /* [GTK_CSS_IN] = */ "in", - /* [GTK_CSS_CM] = */ "cm", - /* [GTK_CSS_MM] = */ "mm", - /* [GTK_CSS_RAD] = */ "rad", - /* [GTK_CSS_DEG] = */ "deg", - /* [GTK_CSS_GRAD] = */ "grad", - /* [GTK_CSS_TURN] = */ "turn", - /* [GTK_CSS_S] = */ "s", - /* [GTK_CSS_MS] = */ "ms", - }; + GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; - if (isinf (number->value)) - g_string_append (string, "infinite"); - else - { - g_ascii_dtostr (buf, sizeof (buf), number->value); - g_string_append (string, buf); - if (number->value != 0.0) - g_string_append (string, names[number->unit]); - } + return number_value_class->has_percent (value); } -static const GtkCssValueClass GTK_CSS_VALUE_NUMBER = { - gtk_css_value_number_free, - gtk_css_value_number_compute, - gtk_css_value_number_equal, - gtk_css_value_number_transition, - gtk_css_value_number_print -}; - GtkCssValue * _gtk_css_number_value_new (double value, GtkCssUnit unit) { - static GtkCssValue number_singletons[] = { - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_NUMBER, 0 }, - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_NUMBER, 1 }, - }; - static GtkCssValue px_singletons[] = { - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 0 }, - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 1 }, - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 2 }, - { >K_CSS_VALUE_NUMBER, 1, GTK_CSS_PX, 3 }, - { >K_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, >K_CSS_VALUE_NUMBER); - result->unit = unit; - result->value = value; - - return result; + return gtk_css_dimension_value_new (value, unit); } -GtkCssDimension -gtk_css_number_value_get_dimension (const GtkCssValue *value) -{ - g_return_val_if_fail (value->class == >K_CSS_VALUE_NUMBER, GTK_CSS_DIMENSION_PERCENTAGE); - - return gtk_css_unit_get_dimension (value->unit); -} - -gboolean -gtk_css_number_value_has_percent (const GtkCssValue *value) +GtkCssValue * +_gtk_css_number_value_parse (GtkCssParser *parser, + GtkCssNumberParseFlags flags) { - g_return_val_if_fail (value->class == >K_CSS_VALUE_NUMBER, FALSE); - - return gtk_css_unit_get_dimension (value->unit) == GTK_CSS_DIMENSION_PERCENTAGE; + return gtk_css_dimension_value_parse (parser, flags); } double _gtk_css_number_value_get (const GtkCssValue *number, double one_hundred_percent) { + GtkCssNumberValueClass *number_value_class; + g_return_val_if_fail (number != NULL, 0.0); - g_return_val_if_fail (number->class == >K_CSS_VALUE_NUMBER, 0.0); - if (number->unit == GTK_CSS_PERCENT) - return number->value * one_hundred_percent / 100; - else - return number->value; + number_value_class = (GtkCssNumberValueClass *) number->class; + + return number_value_class->get (number, one_hundred_percent); } |