mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-14 12:41:07 +00:00
css: Make font property a shorthand
... and implement the CSS font properties: - font-size - font-style - font-family - font-weight - font-variant This is the second try at this. The first was backed out previously due to bugginess. Let's hope this one survives a bit longer. Also makes the font-family CSS test work again.
This commit is contained in:
parent
0c162851ed
commit
0d253b67f4
@ -386,7 +386,10 @@ _gtk_css_parser_read_string (GtkCssParser *parser)
|
|||||||
quote = *parser->data;
|
quote = *parser->data;
|
||||||
|
|
||||||
if (quote != '"' && quote != '\'')
|
if (quote != '"' && quote != '\'')
|
||||||
return NULL;
|
{
|
||||||
|
_gtk_css_parser_error (parser, "Expected a string.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
parser->data++;
|
parser->data++;
|
||||||
str = g_string_new (NULL);
|
str = g_string_new (NULL);
|
||||||
|
@ -725,6 +725,36 @@
|
|||||||
* <entry>[transparent|color]{1,4}</entry>
|
* <entry>[transparent|color]{1,4}</entry>
|
||||||
* </row>
|
* </row>
|
||||||
* <row>
|
* <row>
|
||||||
|
* <entry>font-family</entry>
|
||||||
|
* <entry>@family [, @family]*</entry>
|
||||||
|
* <entry>#gchararray</entry>
|
||||||
|
* <entry>font-family: Sans, Arial;</entry>
|
||||||
|
* </row>
|
||||||
|
* <row>
|
||||||
|
* <entry>font-style</entry>
|
||||||
|
* <entry>[normal|oblique|italic]</entry>
|
||||||
|
* <entry>#PANGO_TYPE_STYLE</entry>
|
||||||
|
* <entry>font-style: italic;</entry>
|
||||||
|
* </row>
|
||||||
|
* <row>
|
||||||
|
* <entry>font-variant</entry>
|
||||||
|
* <entry>[normal|small-caps]</entry>
|
||||||
|
* <entry>#PANGO_TYPE_VARIANT</entry>
|
||||||
|
* <entry>font-variant: normal;</entry>
|
||||||
|
* </row>
|
||||||
|
* <row>
|
||||||
|
* <entry>font-weight</entry>
|
||||||
|
* <entry>[normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900]</entry>
|
||||||
|
* <entry>#PANGO_TYPE_WEIGHT</entry>
|
||||||
|
* <entry>font-weight: bold;</entry>
|
||||||
|
* </row>
|
||||||
|
* <row>
|
||||||
|
* <entry>font-size</entry>
|
||||||
|
* <entry>Font size in point</entry>
|
||||||
|
* <entry>#gint</entry>
|
||||||
|
* <entry>font-size: 13;</entry>
|
||||||
|
* </row>
|
||||||
|
* <row>
|
||||||
* <entry>font</entry>
|
* <entry>font</entry>
|
||||||
* <entry>@family [@style] [@size]</entry>
|
* <entry>@family [@style] [@size]</entry>
|
||||||
* <entry>#PangoFontDescription</entry>
|
* <entry>#PangoFontDescription</entry>
|
||||||
|
@ -3562,7 +3562,8 @@ gtk_style_context_get_font (GtkStyleContext *context,
|
|||||||
{
|
{
|
||||||
GtkStyleContextPrivate *priv;
|
GtkStyleContextPrivate *priv;
|
||||||
StyleData *data;
|
StyleData *data;
|
||||||
const GValue *value;
|
GHashTable *font_cache;
|
||||||
|
PangoFontDescription *description;
|
||||||
|
|
||||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
|
||||||
|
|
||||||
@ -3570,12 +3571,31 @@ gtk_style_context_get_font (GtkStyleContext *context,
|
|||||||
g_return_val_if_fail (priv->widget_path != NULL, NULL);
|
g_return_val_if_fail (priv->widget_path != NULL, NULL);
|
||||||
|
|
||||||
data = style_data_lookup (context);
|
data = style_data_lookup (context);
|
||||||
value = _gtk_style_properties_peek_property (data->store, "font", state, NULL);
|
|
||||||
|
|
||||||
if (value)
|
/* Yuck, fonts are created on-demand but we don't return a ref.
|
||||||
return g_value_get_boxed (value);
|
* Do bad things to achieve this requirement */
|
||||||
|
font_cache = g_object_get_data (G_OBJECT (data->store), "font-cache-for-get_font");
|
||||||
|
if (font_cache)
|
||||||
|
{
|
||||||
|
description = g_hash_table_lookup (font_cache, GUINT_TO_POINTER (state));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
font_cache = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) pango_font_description_free);
|
||||||
|
g_object_set_data_full (G_OBJECT (data->store),
|
||||||
|
"font-cache-for-get_font",
|
||||||
|
font_cache,
|
||||||
|
(GDestroyNotify) g_hash_table_unref);
|
||||||
|
description = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
if (description == NULL)
|
||||||
|
{
|
||||||
|
gtk_style_properties_get (data->store, state, "font", &description, NULL);
|
||||||
|
g_hash_table_insert (font_cache, GUINT_TO_POINTER (state), description);
|
||||||
|
}
|
||||||
|
|
||||||
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "gtkstylepropertyprivate.h"
|
#include "gtkstylepropertyprivate.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -227,6 +228,74 @@ symbolic_color_value_print (const GValue *value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
font_family_parse (GtkCssParser *parser,
|
||||||
|
GFile *base,
|
||||||
|
GValue *value)
|
||||||
|
{
|
||||||
|
GPtrArray *names;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* We don't special case generic families. Pango should do
|
||||||
|
* that for us */
|
||||||
|
|
||||||
|
names = g_ptr_array_new ();
|
||||||
|
|
||||||
|
do {
|
||||||
|
name = _gtk_css_parser_try_ident (parser, TRUE);
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
GString *string = g_string_new (name);
|
||||||
|
g_free (name);
|
||||||
|
while ((name = _gtk_css_parser_try_ident (parser, TRUE)))
|
||||||
|
{
|
||||||
|
g_string_append_c (string, ' ');
|
||||||
|
g_string_append (string, name);
|
||||||
|
g_free (name);
|
||||||
|
}
|
||||||
|
name = g_string_free (string, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name = _gtk_css_parser_read_string (parser);
|
||||||
|
if (name == NULL)
|
||||||
|
{
|
||||||
|
g_ptr_array_free (names, TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add (names, name);
|
||||||
|
} while (_gtk_css_parser_try (parser, ",", TRUE));
|
||||||
|
|
||||||
|
/* NULL-terminate array */
|
||||||
|
g_ptr_array_add (names, NULL);
|
||||||
|
g_value_set_boxed (value, g_ptr_array_free (names, FALSE));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
font_family_value_print (const GValue *value,
|
||||||
|
GString *string)
|
||||||
|
{
|
||||||
|
const char **names = g_value_get_boxed (value);
|
||||||
|
|
||||||
|
if (names == NULL || *names == NULL)
|
||||||
|
{
|
||||||
|
g_string_append (string, "none");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_append_string (string, *names);
|
||||||
|
names++;
|
||||||
|
while (*names)
|
||||||
|
{
|
||||||
|
g_string_append (string, ", ");
|
||||||
|
string_append_string (string, *names);
|
||||||
|
names++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
font_description_value_parse (GtkCssParser *parser,
|
font_description_value_parse (GtkCssParser *parser,
|
||||||
GFile *base,
|
GFile *base,
|
||||||
@ -1754,6 +1823,119 @@ pack_border_radius (GValue *value,
|
|||||||
g_free (top_left);
|
g_free (top_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GParameter *
|
||||||
|
unpack_font_description (const GValue *value,
|
||||||
|
guint *n_params)
|
||||||
|
{
|
||||||
|
GParameter *parameter = g_new0 (GParameter, 5);
|
||||||
|
PangoFontDescription *description;
|
||||||
|
PangoFontMask mask;
|
||||||
|
guint n;
|
||||||
|
|
||||||
|
/* For backwards compat, we only unpack values that are indeed set.
|
||||||
|
* For strict CSS conformance we need to unpack all of them.
|
||||||
|
* Note that we do set all of them in the parse function, so it
|
||||||
|
* will not have effects when parsing CSS files. It will though
|
||||||
|
* for custom style providers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
description = g_value_get_boxed (value);
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
if (description)
|
||||||
|
mask = pango_font_description_get_set_fields (description);
|
||||||
|
else
|
||||||
|
mask = 0;
|
||||||
|
|
||||||
|
if (mask & PANGO_FONT_MASK_FAMILY)
|
||||||
|
{
|
||||||
|
GPtrArray *strv = g_ptr_array_new ();
|
||||||
|
|
||||||
|
g_ptr_array_add (strv, g_strdup (pango_font_description_get_family (description)));
|
||||||
|
g_ptr_array_add (strv, NULL);
|
||||||
|
parameter[n].name = "font-family";
|
||||||
|
g_value_init (¶meter[n].value, G_TYPE_STRV);
|
||||||
|
g_value_take_boxed (¶meter[n].value,
|
||||||
|
g_ptr_array_free (strv, FALSE));
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & PANGO_FONT_MASK_STYLE)
|
||||||
|
{
|
||||||
|
parameter[n].name = "font-style";
|
||||||
|
g_value_init (¶meter[n].value, PANGO_TYPE_STYLE);
|
||||||
|
g_value_set_enum (¶meter[n].value,
|
||||||
|
pango_font_description_get_style (description));
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & PANGO_FONT_MASK_VARIANT)
|
||||||
|
{
|
||||||
|
parameter[n].name = "font-variant";
|
||||||
|
g_value_init (¶meter[n].value, PANGO_TYPE_VARIANT);
|
||||||
|
g_value_set_enum (¶meter[n].value,
|
||||||
|
pango_font_description_get_variant (description));
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & PANGO_FONT_MASK_WEIGHT)
|
||||||
|
{
|
||||||
|
parameter[n].name = "font-weight";
|
||||||
|
g_value_init (¶meter[n].value, PANGO_TYPE_WEIGHT);
|
||||||
|
g_value_set_enum (¶meter[n].value,
|
||||||
|
pango_font_description_get_weight (description));
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & PANGO_FONT_MASK_SIZE)
|
||||||
|
{
|
||||||
|
parameter[n].name = "font-size";
|
||||||
|
g_value_init (¶meter[n].value, G_TYPE_DOUBLE);
|
||||||
|
g_value_set_double (¶meter[n].value,
|
||||||
|
(double) pango_font_description_get_size (description) / PANGO_SCALE);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*n_params = n;
|
||||||
|
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
pack_font_description (GValue *value,
|
||||||
|
GtkStyleProperties *props,
|
||||||
|
GtkStateFlags state)
|
||||||
|
{
|
||||||
|
PangoFontDescription *description;
|
||||||
|
char **families;
|
||||||
|
PangoStyle style;
|
||||||
|
PangoVariant variant;
|
||||||
|
PangoWeight weight;
|
||||||
|
double size;
|
||||||
|
|
||||||
|
gtk_style_properties_get (props,
|
||||||
|
state,
|
||||||
|
"font-family", &families,
|
||||||
|
"font-style", &style,
|
||||||
|
"font-variant", &variant,
|
||||||
|
"font-weight", &weight,
|
||||||
|
"font-size", &size,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
description = pango_font_description_new ();
|
||||||
|
/* xxx: Can we set all the families here somehow? */
|
||||||
|
if (families)
|
||||||
|
pango_font_description_set_family (description, families[0]);
|
||||||
|
pango_font_description_set_size (description, round (size * PANGO_SCALE));
|
||||||
|
pango_font_description_set_style (description, style);
|
||||||
|
pango_font_description_set_variant (description, variant);
|
||||||
|
pango_font_description_set_weight (description, weight);
|
||||||
|
|
||||||
|
g_free (families);
|
||||||
|
|
||||||
|
g_value_take_boxed (value, description);
|
||||||
|
}
|
||||||
|
|
||||||
static GParameter *
|
static GParameter *
|
||||||
unpack_border_color (const GValue *value,
|
unpack_border_color (const GValue *value,
|
||||||
guint *n_params)
|
guint *n_params)
|
||||||
@ -2220,14 +2402,73 @@ gtk_style_property_init (void)
|
|||||||
"Background color",
|
"Background color",
|
||||||
GDK_TYPE_RGBA, 0));
|
GDK_TYPE_RGBA, 0));
|
||||||
|
|
||||||
|
_gtk_style_property_register (g_param_spec_boxed ("font-family",
|
||||||
|
"Font family",
|
||||||
|
"Font family",
|
||||||
|
G_TYPE_STRV, 0),
|
||||||
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
font_family_parse,
|
||||||
|
font_family_value_print,
|
||||||
|
NULL);
|
||||||
|
_gtk_style_property_register (g_param_spec_enum ("font-style",
|
||||||
|
"Font style",
|
||||||
|
"Font style",
|
||||||
|
PANGO_TYPE_STYLE,
|
||||||
|
PANGO_STYLE_NORMAL, 0),
|
||||||
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
_gtk_style_property_register (g_param_spec_enum ("font-variant",
|
||||||
|
"Font variant",
|
||||||
|
"Font variant",
|
||||||
|
PANGO_TYPE_VARIANT,
|
||||||
|
PANGO_VARIANT_NORMAL, 0),
|
||||||
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
/* xxx: need to parse this properly, ie parse the numbers */
|
||||||
|
_gtk_style_property_register (g_param_spec_enum ("font-weight",
|
||||||
|
"Font weight",
|
||||||
|
"Font weight",
|
||||||
|
PANGO_TYPE_WEIGHT,
|
||||||
|
PANGO_WEIGHT_NORMAL, 0),
|
||||||
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
_gtk_style_property_register (g_param_spec_double ("font-size",
|
||||||
|
"Font size",
|
||||||
|
"Font size",
|
||||||
|
0, G_MAXDOUBLE, 0, 0),
|
||||||
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
_gtk_style_property_register (g_param_spec_boxed ("font",
|
_gtk_style_property_register (g_param_spec_boxed ("font",
|
||||||
"Font Description",
|
"Font Description",
|
||||||
"Font Description",
|
"Font Description",
|
||||||
PANGO_TYPE_FONT_DESCRIPTION, 0),
|
PANGO_TYPE_FONT_DESCRIPTION, 0),
|
||||||
GTK_STYLE_PROPERTY_INHERIT,
|
GTK_STYLE_PROPERTY_INHERIT,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
unpack_font_description,
|
||||||
NULL,
|
pack_font_description,
|
||||||
font_description_value_parse,
|
font_description_value_parse,
|
||||||
font_description_value_print,
|
font_description_value_print,
|
||||||
NULL);
|
NULL);
|
||||||
|
Loading…
Reference in New Issue
Block a user