diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 53b163f7fb..5c2875cf7c 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -391,6 +391,7 @@ gtk_private_h_sources = \ gtkcsscornervalueprivate.h \ gtkcsscustomgadgetprivate.h \ gtkcsscustompropertyprivate.h \ + gtkcssdimensionvalueprivate.h \ gtkcsseasevalueprivate.h \ gtkcssenginevalueprivate.h \ gtkcssenumvalueprivate.h \ @@ -655,6 +656,7 @@ gtk_base_c_sources = \ gtkcsscornervalue.c \ gtkcsscustomgadget.c \ gtkcsscustomproperty.c \ + gtkcssdimensionvalue.c \ gtkcsseasevalue.c \ gtkcssenumvalue.c \ gtkcssenginevalue.c \ diff --git a/gtk/gtkcssdimensionvalue.c b/gtk/gtkcssdimensionvalue.c new file mode 100644 index 0000000000..edf8a6fc75 --- /dev/null +++ b/gtk/gtkcssdimensionvalue.c @@ -0,0 +1,293 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gtkcssdimensionvalueprivate.h" + +#include "gtkcssenumvalueprivate.h" +#include "gtkstylepropertyprivate.h" + +#include "fallback-c89.c" + +struct _GtkCssValue { + GTK_CSS_VALUE_BASE + GtkCssUnit unit; + double value; +}; + +static void +gtk_css_value_dimension_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_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); + } +} + +static gboolean +gtk_css_value_dimension_equal (const GtkCssValue *number1, + const GtkCssValue *number2) +{ + return number1->unit == number2->unit && + number1->value == number2->value; +} + +static GtkCssValue * +gtk_css_value_dimension_transition (GtkCssValue *start, + GtkCssValue *end, + guint property_id, + double progress) +{ + /* 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; + + return gtk_css_dimension_value_new (start->value + (end->value - start->value) * progress, + start->unit); +} + +static void +gtk_css_value_dimension_print (const GtkCssValue *number, + GString *string) +{ + 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", + }; + + 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]); + } +} + +static double +gtk_css_value_dimension_get (const GtkCssValue *value, + double one_hundred_percent) +{ + if (value->unit == GTK_CSS_PERCENT) + return value->value * one_hundred_percent / 100; + else + return value->value; +} + +static GtkCssDimension +gtk_css_value_dimension_get_dimension (const GtkCssValue *value) +{ + return gtk_css_unit_get_dimension (value->unit); +} + +static gboolean +gtk_css_value_dimension_has_percent (const GtkCssValue *value) +{ + return gtk_css_unit_get_dimension (value->unit) == GTK_CSS_DIMENSION_PERCENTAGE; +} + +static const GtkCssNumberValueClass GTK_CSS_VALUE_DIMENSION = { + { + gtk_css_value_dimension_free, + gtk_css_value_dimension_compute, + gtk_css_value_dimension_equal, + gtk_css_value_dimension_transition, + gtk_css_value_dimension_print + }, + gtk_css_value_dimension_get, + gtk_css_value_dimension_get_dimension, + gtk_css_value_dimension_has_percent +}; + +GtkCssValue * +gtk_css_dimension_value_new (double value, + GtkCssUnit unit) +{ + static GtkCssValue number_singletons[] = { + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 0 }, + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_NUMBER, 1 }, + }; + static GtkCssValue px_singletons[] = { + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 0 }, + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 1 }, + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 2 }, + { >K_CSS_VALUE_DIMENSION.value_class, 1, GTK_CSS_PX, 3 }, + { >K_CSS_VALUE_DIMENSION.value_class, 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_DIMENSION.value_class); + result->unit = unit; + result->value = value; + + return result; +} + diff --git a/gtk/gtkcssdimensionvalueprivate.h b/gtk/gtkcssdimensionvalueprivate.h new file mode 100644 index 0000000000..2e08eba785 --- /dev/null +++ b/gtk/gtkcssdimensionvalueprivate.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2012 Red Hat Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: Alexander Larsson + */ + +#ifndef __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ +#define __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ + +#include "gtkcssnumbervalueprivate.h" + +G_BEGIN_DECLS + +GtkCssValue * gtk_css_dimension_value_new (double value, + GtkCssUnit unit); +/* This function implemented in gtkcssparser.c */ +GtkCssValue * gtk_css_dimension_value_parse (GtkCssParser *parser, + GtkCssNumberParseFlags flags); + +G_END_DECLS + +#endif /* __GTK_CSS_DIMENSION_VALUE_PRIVATE_H__ */ 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 * * 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) -{ - /* 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; - - return _gtk_css_number_value_new (start->value + (end->value - start->value) * progress, - start->unit); -} - -static void -gtk_css_value_number_print (const GtkCssValue *number, - GString *string) -{ - 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", - }; - - 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]); - } -} - -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; -} - 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); + GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; - return gtk_css_unit_get_dimension (value->unit); + return number_value_class->get_dimension (value); } gboolean gtk_css_number_value_has_percent (const GtkCssValue *value) { - g_return_val_if_fail (value->class == >K_CSS_VALUE_NUMBER, FALSE); + GtkCssNumberValueClass *number_value_class = (GtkCssNumberValueClass *) value->class; - return gtk_css_unit_get_dimension (value->unit) == GTK_CSS_DIMENSION_PERCENTAGE; + return number_value_class->has_percent (value); +} + +GtkCssValue * +_gtk_css_number_value_new (double value, + GtkCssUnit unit) +{ + return gtk_css_dimension_value_new (value, unit); +} + +GtkCssValue * +_gtk_css_number_value_parse (GtkCssParser *parser, + GtkCssNumberParseFlags flags) +{ + return gtk_css_dimension_value_parse (parser, flags); } double _gtk_css_number_value_get (const GtkCssValue *number, double one_hundred_percent) { - g_return_val_if_fail (number != NULL, 0.0); - g_return_val_if_fail (number->class == >K_CSS_VALUE_NUMBER, 0.0); + GtkCssNumberValueClass *number_value_class; - if (number->unit == GTK_CSS_PERCENT) - return number->value * one_hundred_percent / 100; - else - return number->value; + g_return_val_if_fail (number != NULL, 0.0); + + number_value_class = (GtkCssNumberValueClass *) number->class; + + return number_value_class->get (number, one_hundred_percent); } diff --git a/gtk/gtkcssnumbervalueprivate.h b/gtk/gtkcssnumbervalueprivate.h index 454374bffe..dec0f080ad 100644 --- a/gtk/gtkcssnumbervalueprivate.h +++ b/gtk/gtkcssnumbervalueprivate.h @@ -36,9 +36,19 @@ typedef enum /*< skip >*/ { GTK_CSS_PARSE_TIME = (1 << 6) } GtkCssNumberParseFlags; +typedef struct _GtkCssNumberValueClass GtkCssNumberValueClass; + +struct _GtkCssNumberValueClass { + GtkCssValueClass value_class; + + double (* get) (const GtkCssValue *value, + double one_hundred_percent); + GtkCssDimension (* get_dimension) (const GtkCssValue *value); + gboolean (* has_percent) (const GtkCssValue *value); +}; + GtkCssValue * _gtk_css_number_value_new (double value, GtkCssUnit unit); -/* This function implemented in gtkcssparser.c */ GtkCssValue * _gtk_css_number_value_parse (GtkCssParser *parser, GtkCssNumberParseFlags flags); diff --git a/gtk/gtkcssparser.c b/gtk/gtkcssparser.c index 2c52fb2144..86320f3a72 100644 --- a/gtk/gtkcssparser.c +++ b/gtk/gtkcssparser.c @@ -19,8 +19,7 @@ #include "gtkcssparserprivate.h" -#include "gtkcssnumbervalueprivate.h" -#include "gtkwin32themeprivate.h" +#include "gtkcssdimensionvalueprivate.h" #include #include @@ -605,8 +604,8 @@ _gtk_css_parser_has_number (GtkCssParser *parser) } GtkCssValue * -_gtk_css_number_value_parse (GtkCssParser *parser, - GtkCssNumberParseFlags flags) +gtk_css_dimension_value_parse (GtkCssParser *parser, + GtkCssNumberParseFlags flags) { static const struct { const char *name; @@ -721,7 +720,7 @@ _gtk_css_number_value_parse (GtkCssParser *parser, _gtk_css_parser_skip_whitespace (parser); - return _gtk_css_number_value_new (value, unit); + return gtk_css_dimension_value_new (value, unit); } /* XXX: we should introduce GtkCssLenght that deals with