Compare commits

...

4 Commits

Author SHA1 Message Date
Matthias Clasen
3a82ea2051 Change the way we handle hint-metrics
Be a bit more systematic about sanitizing the font options
to values we know we can work with.
2024-02-01 03:20:56 +01:00
Matthias Clasen
d70b59d680 Add a testcase for dpi changes 2024-02-01 03:20:56 +01:00
Matthias Clasen
15d15bc68f Accept font options in node files
The goal is to fix all the context that influences the rendering
of text nodes in the node file. This includes the relevant parts
of cairo_font_options_t (via pango_cairo_context_set_font_options)
as well as the dpi (via pango_cairo_font_map_set_resolution).

The default values we use match the default of the gsettings backing
our GtkSettings:

hint-metrics: off;
hint-style: slight;
antialias: on;
dpi: 96;

This will help with better font testing.

Parser test included.
2024-01-30 16:47:50 -05:00
Matthias Clasen
2306f65cac node-editor: Drop a duplicated menu item 2024-01-30 13:54:27 -05:00
12 changed files with 439 additions and 95 deletions

View File

@@ -10,10 +10,6 @@
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">app.help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Help</attribute>
<attribute name="action">app.help</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Inspector</attribute>
<attribute name="action">app.inspector</attribute>

View File

@@ -322,12 +322,16 @@ stroke bounds of the path.
### text
| property | syntax | default | printed |
| -------- | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| property | syntax | default | printed |
| ------------ | ------------------- | ------------------- | ----------- |
| color | `<color>` | black | non-default |
| font | `<string>` `<url>`? | "Cantarell 11" | always |
| glyphs | `<glyphs>` | "Hello" | always |
| offset | `<point>` | 0 0 | non-default |
| hint-metrics | `<hint metrics>` | off | non-default |
| hint-style | `<hint style>` | slight | non-default |
| antialias | `<antialias>` | on | non-default |
| dpi | `<number>` | 96 | non-default |
Creates a node like `gsk_text_node_new()` with the given properties.

View File

@@ -46,7 +46,9 @@
#include <cairo-script-interpreter.h>
#endif
#include <cairo-gobject.h>
#include <pango/pangocairo.h>
#ifdef HAVE_PANGOFT
#include <pango/pangofc-fontmap.h>
#endif
@@ -86,6 +88,39 @@ context_finish (Context *context)
g_clear_object (&context->fontmap);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_rect (GtkCssParser *parser,
Context *context,
@@ -887,6 +922,82 @@ font_from_string (PangoFontMap *fontmap,
return font;
}
static double
font_get_dpi (PangoFont *font)
{
#ifdef HAVE_PANGOFT
if (PANGO_IS_FC_FONT (font))
{
FcPattern *pattern;
double dpi;
pattern = pango_fc_font_get_pattern (PANGO_FC_FONT (font));
if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) == FcResultMatch)
return dpi;
}
#endif
/* FIXME, needs pango api */
return 96.0;
}
static PangoFont *
recreate_font_with_options (PangoFont *font,
cairo_hint_metrics_t hint_metrics,
cairo_hint_style_t hint_style,
cairo_antialias_t antialias,
double dpi)
{
PangoFontMap *fontmap;
PangoFontDescription *desc;
PangoContext *ctx;
cairo_scaled_font_t *sf;
cairo_font_options_t *options;
PangoFont *new_font;
double old_dpi;
options = cairo_font_options_create ();
sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_scaled_font_get_font_options (sf, options);
if (cairo_font_options_get_hint_metrics (options) == hint_metrics &&
cairo_font_options_get_hint_style (options) == hint_style &&
cairo_font_options_get_antialias (options) == antialias &&
font_get_dpi (font) == dpi)
{
cairo_font_options_destroy (options);
return font;
}
cairo_font_options_set_hint_metrics (options, hint_metrics);
cairo_font_options_set_hint_style (options, hint_style);
cairo_font_options_set_antialias (options, antialias);
desc = pango_font_describe (font);
fontmap = pango_font_get_font_map (font);
ctx = pango_font_map_create_context (fontmap);
pango_cairo_context_set_font_options (ctx, options);
old_dpi = pango_cairo_font_map_get_resolution (PANGO_CAIRO_FONT_MAP (fontmap));
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), dpi);
new_font = pango_font_map_load_font (fontmap, ctx, desc);
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), old_dpi);
g_object_unref (ctx);
pango_font_description_free (desc);
cairo_font_options_destroy (options);
g_object_unref (font);
return new_font;
}
#define MIN_ASCII_GLYPH 32
#define MAX_ASCII_GLYPH 127 /* exclusive */
#define N_ASCII_GLYPHS (MAX_ASCII_GLYPH - MIN_ASCII_GLYPH)
@@ -2217,6 +2328,61 @@ unpack_glyphs (PangoFont *font,
return TRUE;
}
static gboolean
parse_hint_metrics (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_HINT_METRICS, out))
return FALSE;
if (*(cairo_hint_metrics_t *) out == CAIRO_HINT_METRICS_DEFAULT)
{
gtk_css_parser_error_value (parser, "Unsupported value for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_HINT_METRICS));
return FALSE;
}
return TRUE;
}
static gboolean
parse_hint_style (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_HINT_STYLE, out))
return FALSE;
if (*(cairo_hint_style_t *) out == CAIRO_HINT_STYLE_DEFAULT)
{
gtk_css_parser_error_value (parser, "Unsupported value for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_HINT_STYLE));
return FALSE;
}
return TRUE;
}
static gboolean
parse_antialias (GtkCssParser *parser,
Context *context,
gpointer out)
{
if (!parse_enum (parser, CAIRO_GOBJECT_TYPE_ANTIALIAS, out))
return FALSE;
if (*(cairo_antialias_t *) out != CAIRO_ANTIALIAS_NONE &&
*(cairo_antialias_t *) out != CAIRO_ANTIALIAS_GRAY)
{
gtk_css_parser_error_value (parser, "Unsupported value for enum \"%s\"",
g_type_name (CAIRO_GOBJECT_TYPE_ANTIALIAS));
return FALSE;
}
return TRUE;
}
static GskRenderNode *
parse_text_node (GtkCssParser *parser,
Context *context)
@@ -2225,11 +2391,19 @@ parse_text_node (GtkCssParser *parser,
graphene_point_t offset = GRAPHENE_POINT_INIT (0, 0);
GdkRGBA color = GDK_RGBA("000000");
PangoGlyphString *glyphs = NULL;
cairo_hint_metrics_t hint_metrics = CAIRO_HINT_METRICS_OFF;
cairo_hint_style_t hint_style = CAIRO_HINT_STYLE_SLIGHT;
cairo_antialias_t antialias = CAIRO_ANTIALIAS_GRAY;
double dpi = 96.0;
const Declaration declarations[] = {
{ "font", parse_font, clear_font, &font },
{ "offset", parse_point, NULL, &offset },
{ "color", parse_color, NULL, &color },
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs }
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs },
{ "hint-metrics", parse_hint_metrics, NULL, &hint_metrics },
{ "hint-style", parse_hint_style, NULL, &hint_style },
{ "antialias", parse_antialias, NULL, &antialias },
{ "dpi", parse_positive_double, NULL, &dpi },
};
GskRenderNode *result;
@@ -2241,6 +2415,8 @@ parse_text_node (GtkCssParser *parser,
g_assert (font);
}
font = recreate_font_with_options (font, hint_metrics, hint_style, antialias, dpi);
if (!glyphs)
{
const char *text = "Hello";
@@ -2429,39 +2605,6 @@ clear_dash (gpointer inout_array)
g_clear_pointer ((GArray **) inout_array, g_array_unref);
}
static gboolean
parse_enum (GtkCssParser *parser,
GType type,
gpointer out_value)
{
GEnumClass *class;
GEnumValue *v;
char *enum_name;
enum_name = gtk_css_parser_consume_ident (parser);
if (enum_name == NULL)
return FALSE;
class = g_type_class_ref (type);
v = g_enum_get_value_by_nick (class, enum_name);
if (v == NULL)
{
gtk_css_parser_error_value (parser, "Unknown value \"%s\" for enum \"%s\"",
enum_name, g_type_name (type));
g_free (enum_name);
g_type_class_unref (class);
return FALSE;
}
*(int*)out_value = v->value;
g_free (enum_name);
g_type_class_unref (class);
return TRUE;
}
static gboolean
parse_fill_rule (GtkCssParser *parser,
Context *context,
@@ -3248,6 +3391,33 @@ append_string_param (Printer *p,
g_string_append_c (p->str, '\n');
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_vec4_param (Printer *p,
const char *param_name,
@@ -3515,6 +3685,43 @@ gsk_text_node_serialize_font (GskRenderNode *node,
#endif
}
static void
gsk_text_node_serialize_font_options (GskRenderNode *node,
Printer *p)
{
PangoFont *font = gsk_text_node_get_font (node);
cairo_scaled_font_t *sf = pango_cairo_font_get_scaled_font (PANGO_CAIRO_FONT (font));
cairo_font_options_t *options;
cairo_hint_metrics_t hint_metrics;
cairo_hint_style_t hint_style;
cairo_antialias_t antialias;
options = cairo_font_options_create ();
cairo_scaled_font_get_font_options (sf, options);
hint_metrics = cairo_font_options_get_hint_metrics (options);
hint_style = cairo_font_options_get_hint_style (options);
antialias = cairo_font_options_get_antialias (options);
cairo_font_options_destroy (options);
if (hint_metrics != CAIRO_HINT_METRICS_OFF && hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
append_enum_param (p, "hint-metrics", CAIRO_GOBJECT_TYPE_HINT_METRICS, hint_metrics);
if (hint_style != CAIRO_HINT_STYLE_SLIGHT && hint_style != CAIRO_HINT_STYLE_DEFAULT)
append_enum_param (p, "hint-style", CAIRO_GOBJECT_TYPE_HINT_STYLE, hint_style);
if (antialias != CAIRO_ANTIALIAS_GRAY && antialias != CAIRO_ANTIALIAS_DEFAULT)
append_enum_param (p, "antialias", CAIRO_GOBJECT_TYPE_ANTIALIAS, antialias);
}
static void
gsk_text_node_serialize_font_dpi (GskRenderNode *node,
Printer *p)
{
PangoFont *font = gsk_text_node_get_font (node);
append_float_param (p, "dpi", font_get_dpi (font), 96.f);
}
void
gsk_text_node_serialize_glyphs (GskRenderNode *node,
GString *p)
@@ -3596,33 +3803,6 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
pango_glyph_string_free (ascii);
}
static const char *
enum_to_nick (GType type,
int value)
{
GEnumClass *class;
GEnumValue *v;
class = g_type_class_ref (type);
v = g_enum_get_value (class, value);
g_type_class_unref (class);
return v->value_nick;
}
static void
append_enum_param (Printer *p,
const char *param_name,
GType type,
int value)
{
_indent (p);
g_string_append_printf (p->str, "%s: ", param_name);
g_string_append (p->str, enum_to_nick (type, value));
g_string_append_c (p->str, ';');
g_string_append_c (p->str, '\n');
}
static void
append_path_param (Printer *p,
const char *param_name,
@@ -4087,6 +4267,9 @@ render_node_print (Printer *p,
if (!graphene_point_equal (offset, graphene_point_zero ()))
append_point_param (p, "offset", offset);
gsk_text_node_serialize_font_options (node, p);
gsk_text_node_serialize_font_dpi (node, p);
end_node (p);
}
break;

View File

@@ -6454,6 +6454,30 @@ gtk_widget_get_effective_font_map (GtkWidget *widget)
return pango_cairo_font_map_get_default ();
}
static void
sanitize_font_options (cairo_font_options_t *options,
gboolean hint_font_metrics)
{
cairo_hint_metrics_t hint_metrics;
cairo_hint_style_t hint_style;
cairo_antialias_t antialias;
hint_metrics = hint_font_metrics ? CAIRO_HINT_METRICS_ON : CAIRO_HINT_METRICS_OFF;
hint_style = cairo_font_options_get_hint_style (options);
antialias = cairo_font_options_get_antialias (options);
if (hint_metrics == CAIRO_HINT_METRICS_ON)
hint_style = CAIRO_HINT_STYLE_NONE;
if (antialias != CAIRO_ANTIALIAS_NONE)
antialias = CAIRO_ANTIALIAS_GRAY;
cairo_font_options_set_hint_metrics (options, hint_metrics);
cairo_font_options_set_hint_style (options, hint_style);
cairo_font_options_set_antialias (options, antialias);
}
gboolean
gtk_widget_update_pango_context (GtkWidget *widget,
PangoContext *context,
@@ -6463,10 +6487,12 @@ gtk_widget_update_pango_context (GtkWidget *widget,
GtkCssStyle *style = gtk_css_node_get_style (priv->cssnode);
PangoFontDescription *font_desc;
GtkSettings *settings;
cairo_font_options_t *font_options;
const cairo_font_options_t *font_options;
guint old_serial;
gboolean hint_font_metrics = FALSE;
int scale;
cairo_font_options_t *options;
gboolean got_font_options;
old_serial = pango_context_get_serial (context);
@@ -6485,10 +6511,10 @@ gtk_widget_update_pango_context (GtkWidget *widget,
/* Override the user setting on non-HiDPI */
if (scale == 1)
hint_font_metrics = TRUE;
pango_context_set_round_glyph_positions (context, hint_font_metrics);
}
pango_context_set_round_glyph_positions (context, hint_font_metrics);
if (direction != GTK_TEXT_DIR_NONE)
pango_context_set_base_dir (context, direction == GTK_TEXT_DIR_LTR
? PANGO_DIRECTION_LTR
@@ -6496,34 +6522,34 @@ gtk_widget_update_pango_context (GtkWidget *widget,
pango_cairo_context_set_resolution (context, _gtk_css_number_value_get (style->core->dpi, 100));
font_options = (cairo_font_options_t*)g_object_get_qdata (G_OBJECT (widget), quark_font_options);
if (settings && font_options)
{
cairo_font_options_t *options;
options = cairo_font_options_create ();
got_font_options = FALSE;
options = cairo_font_options_copy (gtk_settings_get_font_options (settings));
if (settings)
{
font_options = gtk_settings_get_font_options (settings);
if (font_options)
{
cairo_font_options_merge (options, font_options);
got_font_options = TRUE;
}
}
font_options = (cairo_font_options_t *) g_object_get_qdata (G_OBJECT (widget), quark_font_options);
if (font_options)
{
cairo_font_options_merge (options, font_options);
cairo_font_options_set_hint_metrics (options,
hint_font_metrics == 1 ? CAIRO_HINT_METRICS_ON
: CAIRO_HINT_METRICS_OFF);
pango_cairo_context_set_font_options (context, options);
cairo_font_options_destroy (options);
got_font_options = TRUE;
}
else if (settings)
if (got_font_options)
{
cairo_font_options_t *options;
options = cairo_font_options_copy (gtk_settings_get_font_options (settings));
cairo_font_options_set_hint_metrics (options,
hint_font_metrics == 1 ? CAIRO_HINT_METRICS_ON
: CAIRO_HINT_METRICS_OFF);
sanitize_font_options (options, hint_font_metrics != 0);
pango_cairo_context_set_font_options (context, options);
cairo_font_options_destroy (options);
}
cairo_font_options_destroy (options);
pango_context_set_font_map (context, gtk_widget_get_effective_font_map (widget));
return old_serial != pango_context_get_serial (context);

View File

@@ -0,0 +1,29 @@
color {
bounds: -20 -70 100 100;
color: rgb(0,0,0);
}
text {
color: rgb(100,100,100);
font: "text-mixed-color-colrv1 15" url("data:font/ttf;base64,AAEAAAAKAIAAAwAgQ09MUhc9T40AAAI4AAAAe0NQQUwB/wATAAACtAAAABpjbWFwAHUAPQAAATgA\
AAA0Z2x5Zn7NhtgAAAF8AAAAkGhlYWQmof0NAAAArAAAADZoaGVhDAEEAgAAAOQAAAAkaG10eAQA\
AAAAAAEoAAAAEGxvY2EAbACQAAABbAAAABBtYXhwAAkABQAAAQgAAAAgbmFtZR9CFpQAAAIMAAAA\
KQABAAAAARmaAQnTZV8PPPUAAggAAAAAAOHCPQAAAAAA4cpZfQAAAAAEAAgAAAAAAQACAAAAAAAA\
AAEAAAgAAAAAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAABAAEAAAAHAAQAAQAAAAAAAQAAAAAA\
AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAMAAQAKAAAAAYABAABAAIAIABG\
//8AAAAgAEH////g/8AAAQAAAAAAAAAAAAAADAAYACQAMAA8AEgAAQAAAAAEAAgAAAMAADEhESEE\
APwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAA\
AAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMAADEhESEEAPwACAAAAQAAAAAEAAgAAAMA\
ADEhESEEAPwACAAAAAABABIAAQAAAAAAAQAXAAB0ZXh0LW1peGVkLWNvbG9yLWNvbHJ2MQAAAAAB\
AAAAAAAAAAAAAAAAAAAAIgAAAEoAAAAAAAAAAAAAAAAAAAADAAQAAAAWAAUAAAAcAAYAAAAiAQEA\
AAAAAQEAAAABAQEAAAACAAAAAwAAABAAAAAbAAAAJgoAAAYAAQIAAEAACgAABgACAgABQAAKAAAG\
AAMCAAJAAAAAAAADAAEAAwAAAA4AAAAA//8A/wD//wAA/wAA\
");
glyphs: 1 20;
}
text {
color: rgb(100,100,100);
font: "text-mixed-color-colrv1 15";
glyphs: 1 40;
offset: 20 0;
dpi: 192;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

View File

@@ -146,6 +146,7 @@ compare_render_tests = [
'subpixel-positioning',
'subpixel-positioning-hidpi-nogl-nocairo',
'text-color-mix',
'text-dpi-changes',
'text-glyph-lsb',
'text-mixed-color-nocairo',
'text-mixed-color-colrv1',
@@ -400,6 +401,11 @@ node_parser_tests = [
'text-font-errors.node',
'text-font-errors.ref.node',
'text-font-errors.errors',
'text-font-options.node',
'text-font-options.ref.node',
'text-font-options-error.node',
'text-font-options-error.ref.node',
'text-font-options-error.ref.errors',
'text-no-color.node',
'texture-fail.node',
'texture-fail.ref.node',

View File

@@ -0,0 +1,5 @@
<data>:7:17-24: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:8:15-22: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:9:14-21: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE
<data>:10:8-10: error: GTK_CSS_PARSER_ERROR_SYNTAX
<data>:17:14-22: error: GTK_CSS_PARSER_ERROR_UNKNOWN_VALUE

View File

@@ -0,0 +1,18 @@
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-metrics: default;
hint-style: default;
antialias: default;
dpi: -1;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
antialias: subpixel;
}

View File

@@ -0,0 +1,13 @@
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
antialias: subpixel;
}

View File

@@ -0,0 +1,34 @@
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-metrics: off;
hint-style: slight;
antialias: gray;
dpi: 96;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-metrics: on;
hint-style: full;
antialias: none;
dpi: 111;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-style: medium;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-style: none;
}

View File

@@ -0,0 +1,30 @@
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
}
text {
color: rgb(50,50,50);
font: "Cantarell 10.9990234375";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-metrics: on;
hint-style: full;
antialias: none;
dpi: 111;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-style: medium;
}
text {
color: rgb(50,50,50);
font: "Cantarell 11";
glyphs: "N", 430 5, 406 8, 417 7, 772 4, 783 5, 783 5, 793 6 0 0 same-cluster;
offset: 0 32.0186;
hint-style: none;
}