static gboolean sup_parse_func (MarkupData *md, OpenTag *tag, const gchar **names, const gchar **values, GMarkupParseContext *context, GError **error) { CHECK_NO_ATTRS("sup"); /* Shrink font, and set a positive rise */ if (tag) { tag->scale_level_delta -= 1; tag->scale_level -= 1; } add_attribute (tag, pango_attr_rise_new (SUPERSUB_RISE)); return TRUE; }
/* This function is used by gtk_text_cell_accessible_get_offset_at_point() * and gtk_text_cell_accessible_get_character_extents(). There is no * cached PangoLayout so we must create a temporary one using this function. */ static PangoLayout * create_pango_layout (GtkTextCellAccessible *text) { GdkRGBA *foreground_rgba; PangoAttrList *attr_list, *attributes; PangoLayout *layout; PangoUnderline uline, underline; PangoFontMask mask; PangoFontDescription *font_desc; gboolean foreground_set, strikethrough_set, strikethrough; gboolean scale_set, underline_set, rise_set; gchar *renderer_text; gdouble scale; gint rise; GtkRendererCellAccessible *gail_renderer; GtkCellRendererText *gtk_renderer; gail_renderer = GTK_RENDERER_CELL_ACCESSIBLE (text); gtk_renderer = GTK_CELL_RENDERER_TEXT (gail_renderer->renderer); g_object_get (gtk_renderer, "text", &renderer_text, "attributes", &attributes, "foreground-set", &foreground_set, "foreground-rgba", &foreground_rgba, "strikethrough-set", &strikethrough_set, "strikethrough", &strikethrough, "font-desc", &font_desc, "scale-set", &scale_set, "scale", &scale, "underline-set", &underline_set, "underline", &underline, "rise-set", &rise_set, "rise", &rise, NULL); layout = gtk_widget_create_pango_layout (get_widget (text), renderer_text); if (attributes) attr_list = pango_attr_list_copy (attributes); else attr_list = pango_attr_list_new (); if (foreground_set) { add_attr (attr_list, pango_attr_foreground_new (foreground_rgba->red * 65535, foreground_rgba->green * 65535, foreground_rgba->blue * 65535)); } if (strikethrough_set) add_attr (attr_list, pango_attr_strikethrough_new (strikethrough)); mask = pango_font_description_get_set_fields (font_desc); if (mask & PANGO_FONT_MASK_FAMILY) add_attr (attr_list, pango_attr_family_new (pango_font_description_get_family (font_desc))); if (mask & PANGO_FONT_MASK_STYLE) add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (font_desc))); if (mask & PANGO_FONT_MASK_VARIANT) add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (font_desc))); if (mask & PANGO_FONT_MASK_WEIGHT) add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (font_desc))); if (mask & PANGO_FONT_MASK_STRETCH) add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (font_desc))); if (mask & PANGO_FONT_MASK_SIZE) add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (font_desc))); if (scale_set && scale != 1.0) add_attr (attr_list, pango_attr_scale_new (scale)); if (underline_set) uline = underline; else uline = PANGO_UNDERLINE_NONE; if (uline != PANGO_UNDERLINE_NONE) add_attr (attr_list, pango_attr_underline_new (underline)); if (rise_set) add_attr (attr_list, pango_attr_rise_new (rise)); pango_layout_set_attributes (layout, attr_list); pango_layout_set_width (layout, -1); pango_attr_list_unref (attr_list); pango_font_description_free (font_desc); pango_attr_list_unref (attributes); g_free (renderer_text); gdk_rgba_free (foreground_rgba); return layout; }
/** * gimp_label_set_attributes: * @label: a #GtkLabel * @...: a list of PangoAttrType and value pairs terminated by -1. * * Sets Pango attributes on a #GtkLabel in a more convenient way than * gtk_label_set_attributes(). * * This function is useful if you want to change the font attributes * of a #GtkLabel. This is an alternative to using PangoMarkup which * is slow to parse and akward to handle in an i18n-friendly way. * * The attributes are set on the complete label, from start to end. If * you need to set attributes on part of the label, you will have to * use the PangoAttributes API directly. * * Since: 2.2 **/ void gimp_label_set_attributes (GtkLabel *label, ...) { PangoAttribute *attr = NULL; PangoAttrList *attrs; va_list args; g_return_if_fail (GTK_IS_LABEL (label)); attrs = pango_attr_list_new (); va_start (args, label); do { PangoAttrType attr_type = va_arg (args, PangoAttrType); if (attr_type == -1) attr_type = PANGO_ATTR_INVALID; switch (attr_type) { case PANGO_ATTR_LANGUAGE: attr = pango_attr_language_new (va_arg (args, PangoLanguage *)); break; case PANGO_ATTR_FAMILY: attr = pango_attr_family_new (va_arg (args, const gchar *)); break; case PANGO_ATTR_STYLE: attr = pango_attr_style_new (va_arg (args, PangoStyle)); break; case PANGO_ATTR_WEIGHT: attr = pango_attr_weight_new (va_arg (args, PangoWeight)); break; case PANGO_ATTR_VARIANT: attr = pango_attr_variant_new (va_arg (args, PangoVariant)); break; case PANGO_ATTR_STRETCH: attr = pango_attr_stretch_new (va_arg (args, PangoStretch)); break; case PANGO_ATTR_SIZE: attr = pango_attr_size_new (va_arg (args, gint)); break; case PANGO_ATTR_FONT_DESC: attr = pango_attr_font_desc_new (va_arg (args, const PangoFontDescription *)); break; case PANGO_ATTR_FOREGROUND: { const PangoColor *color = va_arg (args, const PangoColor *); attr = pango_attr_foreground_new (color->red, color->green, color->blue); } break; case PANGO_ATTR_BACKGROUND: { const PangoColor *color = va_arg (args, const PangoColor *); attr = pango_attr_background_new (color->red, color->green, color->blue); } break; case PANGO_ATTR_UNDERLINE: attr = pango_attr_underline_new (va_arg (args, PangoUnderline)); break; case PANGO_ATTR_STRIKETHROUGH: attr = pango_attr_strikethrough_new (va_arg (args, gboolean)); break; case PANGO_ATTR_RISE: attr = pango_attr_rise_new (va_arg (args, gint)); break; case PANGO_ATTR_SCALE: attr = pango_attr_scale_new (va_arg (args, gdouble)); break; default: g_warning ("%s: invalid PangoAttribute type %d", G_STRFUNC, attr_type); case PANGO_ATTR_INVALID: attr = NULL; break; } if (attr) { attr->start_index = 0; attr->end_index = -1; pango_attr_list_insert (attrs, attr); } } while (attr); va_end (args); gtk_label_set_attributes (label, attrs); pango_attr_list_unref (attrs); }
static void go_pango_translate_here (PangoAttrIterator *state_iter, PangoAttrIterator *attr_iter, PangoAttrList *attrs) { double font_scale = 1.; double scale = 1.; int rise = 0; PangoAttribute *pa; PangoFontDescription *desc = pango_font_description_new (); GSList *the_attrs, *l; gint range_start, range_end; pango_attr_iterator_range (attr_iter, &range_start, &range_end); if (range_start == range_end) return; desc = pango_font_description_new (); pango_attr_iterator_get_font (state_iter, desc, NULL, NULL); font_scale = pango_font_description_get_size (desc)/ (double)PANGO_SCALE/10.; pango_font_description_free (desc); pa = pango_attr_iterator_get (state_iter, PANGO_ATTR_SCALE); if (pa) scale = ((PangoAttrFloat *)pa)->value; pa = pango_attr_iterator_get (state_iter, PANGO_ATTR_RISE); if (pa) rise = ((PangoAttrInt *)pa)->value; /* We should probably figured out the default font size used */ /* rather than assuming it is 10 pts * scale */ if (font_scale == 0) font_scale = scale; the_attrs = pango_attr_iterator_get_attrs (attr_iter); for (l = the_attrs; l != NULL; l = l->next) { PangoAttribute *attribute = l->data; PangoAttrType type = attribute->klass->type; if (type == go_pango_attr_superscript_get_attr_type ()) { GOPangoAttrSuperscript *attr = (GOPangoAttrSuperscript *)attribute; if (attr->val) { scale *= GO_SUPERSCRIPT_SCALE; rise += GO_SUPERSCRIPT_RISE * font_scale; font_scale *= GO_SUPERSCRIPT_SCALE; } } else { /* go_pango_attr_subscript_type */ GOPangoAttrSubscript *attr = (GOPangoAttrSubscript *)attribute; if (attr->val) { scale *= GO_SUBSCRIPT_SCALE; rise += GO_SUBSCRIPT_RISE * font_scale; font_scale *= GO_SUBSCRIPT_SCALE; } } } if (the_attrs != NULL) { PangoAttribute *attr = pango_attr_scale_new (scale); attr->start_index = range_start; attr->end_index = range_end; pango_attr_list_insert (attrs, attr); attr = pango_attr_rise_new (rise); attr->start_index = range_start; attr->end_index = range_end; pango_attr_list_insert (attrs, attr); } g_slist_free_full (the_attrs, (GDestroyNotify)pango_attribute_destroy); }
/* * This function is used by gail_text_cell_get_offset_at_point() * and gail_text_cell_get_character_extents(). There is no * cached PangoLayout for gailtextcell so we must create a temporary * one using this function. */ static PangoLayout* create_pango_layout(GtkCellRendererText *gtk_renderer, GtkWidget *widget) { PangoAttrList *attr_list; PangoLayout *layout; PangoUnderline uline; PangoFontMask mask; layout = gtk_widget_create_pango_layout (widget, gtk_renderer->text); if (gtk_renderer->extra_attrs) attr_list = pango_attr_list_copy (gtk_renderer->extra_attrs); else attr_list = pango_attr_list_new (); if (gtk_renderer->foreground_set) { PangoColor color; color = gtk_renderer->foreground; add_attr (attr_list, pango_attr_foreground_new (color.red, color.green, color.blue)); } if (gtk_renderer->strikethrough_set) add_attr (attr_list, pango_attr_strikethrough_new (gtk_renderer->strikethrough)); mask = pango_font_description_get_set_fields (gtk_renderer->font); if (mask & PANGO_FONT_MASK_FAMILY) add_attr (attr_list, pango_attr_family_new (pango_font_description_get_family (gtk_renderer->font))); if (mask & PANGO_FONT_MASK_STYLE) add_attr (attr_list, pango_attr_style_new (pango_font_description_get_style (gtk_renderer->font))); if (mask & PANGO_FONT_MASK_VARIANT) add_attr (attr_list, pango_attr_variant_new (pango_font_description_get_variant (gtk_renderer->font))); if (mask & PANGO_FONT_MASK_WEIGHT) add_attr (attr_list, pango_attr_weight_new (pango_font_description_get_weight (gtk_renderer->font))); if (mask & PANGO_FONT_MASK_STRETCH) add_attr (attr_list, pango_attr_stretch_new (pango_font_description_get_stretch (gtk_renderer->font))); if (mask & PANGO_FONT_MASK_SIZE) add_attr (attr_list, pango_attr_size_new (pango_font_description_get_size (gtk_renderer->font))); if (gtk_renderer->scale_set && gtk_renderer->font_scale != 1.0) add_attr (attr_list, pango_attr_scale_new (gtk_renderer->font_scale)); if (gtk_renderer->underline_set) uline = gtk_renderer->underline_style; else uline = PANGO_UNDERLINE_NONE; if (uline != PANGO_UNDERLINE_NONE) add_attr (attr_list, pango_attr_underline_new (gtk_renderer->underline_style)); if (gtk_renderer->rise_set) add_attr (attr_list, pango_attr_rise_new (gtk_renderer->rise)); pango_layout_set_attributes (layout, attr_list); pango_layout_set_width (layout, -1); pango_attr_list_unref (attr_list); return layout; }
static void decorate_text (GimpAboutDialog *dialog, gint anim_type, gdouble time) { GtkStyle *style = gtk_widget_get_style (dialog->anim_area); const gchar *text; const gchar *ptr; gint letter_count = 0; gint text_length = 0; gint text_bytelen = 0; gint cluster_start, cluster_end; gunichar unichr; PangoAttrList *attrlist = NULL; PangoAttribute *attr; PangoRectangle irect = {0, 0, 0, 0}; PangoRectangle lrect = {0, 0, 0, 0}; GdkColor mix; mix_colors (style->bg + GTK_STATE_NORMAL, style->fg + GTK_STATE_NORMAL, &mix, time); text = pango_layout_get_text (dialog->layout); g_return_if_fail (text != NULL); text_length = g_utf8_strlen (text, -1); text_bytelen = strlen (text); attrlist = pango_attr_list_new (); dialog->textrange[0] = 0; dialog->textrange[1] = text_bytelen; switch (anim_type) { case 0: /* Fade in */ attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue); attr->start_index = 0; attr->end_index = text_bytelen; pango_attr_list_insert (attrlist, attr); break; case 1: /* Fade in, spread */ attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue); attr->start_index = 0; attr->end_index = text_bytelen; pango_attr_list_change (attrlist, attr); ptr = text; cluster_start = 0; while ((unichr = g_utf8_get_char (ptr))) { ptr = g_utf8_next_char (ptr); cluster_end = (ptr - text); if (unichr == 0x200b) { lrect.width = (1.0 - time) * 15.0 * PANGO_SCALE + 0.5; attr = pango_attr_shape_new (&irect, &lrect); attr->start_index = cluster_start; attr->end_index = cluster_end; pango_attr_list_change (attrlist, attr); } cluster_start = cluster_end; } break; case 2: /* Fade in, sinewave */ attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue); attr->start_index = 0; attr->end_index = text_bytelen; pango_attr_list_change (attrlist, attr); ptr = text; cluster_start = 0; while ((unichr = g_utf8_get_char (ptr))) { if (unichr == 0x200b) { cluster_end = ptr - text; attr = pango_attr_rise_new ((1.0 -time) * 18000 * sin (4.0 * time + (float) letter_count * 0.7)); attr->start_index = cluster_start; attr->end_index = cluster_end; pango_attr_list_change (attrlist, attr); letter_count++; cluster_start = cluster_end; } ptr = g_utf8_next_char (ptr); } break; case 3: /* letterwise Fade in */ ptr = text; letter_count = 0; cluster_start = 0; while ((unichr = g_utf8_get_char (ptr))) { gint border = (text_length + 15) * time - 15; gdouble pos; if (letter_count < border) pos = 0; else if (letter_count > border + 15) pos = 1; else pos = ((gdouble) (letter_count - border)) / 15; mix_colors (style->fg + GTK_STATE_NORMAL, style->bg + GTK_STATE_NORMAL, &mix, pos); ptr = g_utf8_next_char (ptr); cluster_end = ptr - text; attr = pango_attr_foreground_new (mix.red, mix.green, mix.blue); attr->start_index = cluster_start; attr->end_index = cluster_end; pango_attr_list_change (attrlist, attr); if (pos < 1.0) dialog->textrange[1] = cluster_end; letter_count++; cluster_start = cluster_end; } break; default: g_printerr ("Unknown animation type %d\n", anim_type); } pango_layout_set_attributes (dialog->layout, attrlist); pango_attr_list_unref (attrlist); }
static PangoAttrList* hildon_font_selection_dialog_create_attrlist (HildonFontSelectionDialog *fontsel, guint start_index, guint len) { PangoAttrList *list; PangoAttribute *attr; gint size, position; gboolean family_set, size_set, color_set, bold, bold_set, italic, italic_set, underline, underline_set, strikethrough, strikethrough_set, position_set; GdkColor *color = NULL; gchar *family = NULL; gdouble font_scaling = 1.0; list = pango_attr_list_new (); g_object_get (G_OBJECT (fontsel), "family", &family, "family-set", &family_set, "size", &size, "size-set", &size_set, "color", &color, "color-set", &color_set, "bold", &bold, "bold-set", &bold_set, "italic", &italic, "italic-set", &italic_set, "underline", &underline, "underline-set", &underline_set, "strikethrough", &strikethrough, "strikethrough-set", &strikethrough_set, "position", &position, "position-set", &position_set, "font-scaling", &font_scaling, NULL); /* family */ if (family_set) { attr = pango_attr_family_new (family); add_preview_text_attr (list, attr, start_index, len); } g_free (family); /* size */ if (size_set) { attr = pango_attr_size_new (size * PANGO_SCALE); add_preview_text_attr (list, attr, start_index, len); } /*color*/ if (color_set) { attr = pango_attr_foreground_new (color->red, color->green, color->blue); add_preview_text_attr (list, attr, start_index, len); } if (color != NULL) gdk_color_free (color); /*weight*/ if (bold_set) { if (bold) attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD); else attr = pango_attr_weight_new (PANGO_WEIGHT_NORMAL); add_preview_text_attr(list, attr, start_index, len); } /* style */ if (italic_set) { if (italic) attr = pango_attr_style_new (PANGO_STYLE_ITALIC); else attr = pango_attr_style_new (PANGO_STYLE_NORMAL); add_preview_text_attr(list, attr, start_index, len); } /* underline */ if (underline_set) { if (underline) attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); else attr = pango_attr_underline_new (PANGO_UNDERLINE_NONE); add_preview_text_attr(list, attr, start_index, len); } /* strikethrough */ if (strikethrough_set) { if (strikethrough) attr = pango_attr_strikethrough_new (TRUE); else attr = pango_attr_strikethrough_new (FALSE); add_preview_text_attr(list, attr, start_index, len); } /* position */ if (position_set) { switch (position) { case 1: /*super*/ attr = pango_attr_rise_new (SUPERSCRIPT_RISE); break; case -1: /*sub*/ attr = pango_attr_rise_new (SUBSCRIPT_LOW); break; default: /*normal*/ attr = pango_attr_rise_new (0); break; } add_preview_text_attr (list, attr, start_index, len); } /* font scaling for preview */ if (font_scaling) { attr = pango_attr_scale_new(font_scaling); add_preview_text_attr(list, attr, 0, len + start_index); } return list; }
static gboolean span_parse_func (MarkupData *md, OpenTag *tag, const gchar **names, const gchar **values, GMarkupParseContext *context, GError **error) { int line_number, char_number; int i; const char *family = NULL; const char *size = NULL; const char *style = NULL; const char *weight = NULL; const char *variant = NULL; const char *stretch = NULL; const char *desc = NULL; const char *foreground = NULL; const char *background = NULL; const char *underline = NULL; const char *underline_color = NULL; const char *strikethrough = NULL; const char *strikethrough_color = NULL; const char *rise = NULL; const char *letter_spacing = NULL; const char *lang = NULL; const char *fallback = NULL; const char *gravity = NULL; const char *gravity_hint = NULL; g_markup_parse_context_get_position (context, &line_number, &char_number); #define CHECK_DUPLICATE(var) G_STMT_START{ \ if ((var) != NULL) { \ g_set_error (error, G_MARKUP_ERROR, \ G_MARKUP_ERROR_INVALID_CONTENT, \ _("Attribute '%s' occurs twice on <span> tag " \ "on line %d char %d, may only occur once"), \ names[i], line_number, char_number); \ return FALSE; \ }}G_STMT_END #define CHECK_ATTRIBUTE2(var, name) \ if (attr_strcmp (names[i], (name)) == 0) { \ CHECK_DUPLICATE (var); \ (var) = values[i]; \ found = TRUE; \ break; \ } #define CHECK_ATTRIBUTE(var) CHECK_ATTRIBUTE2 (var, G_STRINGIFY (var)) i = 0; while (names[i]) { gboolean found = FALSE; switch (names[i][0]) { case 'f': CHECK_ATTRIBUTE (fallback); CHECK_ATTRIBUTE2(desc, "font"); CHECK_ATTRIBUTE2(desc, "font_desc"); CHECK_ATTRIBUTE2(family, "face"); CHECK_ATTRIBUTE2(family, "font_family"); CHECK_ATTRIBUTE2(size, "font_size"); CHECK_ATTRIBUTE2(stretch, "font_stretch"); CHECK_ATTRIBUTE2(style, "font_style"); CHECK_ATTRIBUTE2(variant, "font_variant"); CHECK_ATTRIBUTE2(weight, "font_weight"); CHECK_ATTRIBUTE (foreground); CHECK_ATTRIBUTE2 (foreground, "fgcolor"); break; case 's': CHECK_ATTRIBUTE (size); CHECK_ATTRIBUTE (stretch); CHECK_ATTRIBUTE (strikethrough); CHECK_ATTRIBUTE (strikethrough_color); CHECK_ATTRIBUTE (style); break; case 'g': CHECK_ATTRIBUTE (gravity); CHECK_ATTRIBUTE (gravity_hint); break; case 'l': CHECK_ATTRIBUTE (lang); CHECK_ATTRIBUTE (letter_spacing); break; case 'u': CHECK_ATTRIBUTE (underline); CHECK_ATTRIBUTE (underline_color); break; default: CHECK_ATTRIBUTE (background); CHECK_ATTRIBUTE2 (background, "bgcolor"); CHECK_ATTRIBUTE2(foreground, "color"); CHECK_ATTRIBUTE (rise); CHECK_ATTRIBUTE (variant); CHECK_ATTRIBUTE (weight); break; } if (!found) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, _("Attribute '%s' is not allowed on the <span> tag " "on line %d char %d"), names[i], line_number, char_number); return FALSE; } ++i; } /* Parse desc first, then modify it with other font-related attributes. */ if (G_UNLIKELY (desc)) { PangoFontDescription *parsed; parsed = pango_font_description_from_string (desc); if (parsed) { add_attribute (tag, pango_attr_font_desc_new (parsed)); if (tag) open_tag_set_absolute_font_size (tag, pango_font_description_get_size (parsed)); pango_font_description_free (parsed); } } if (G_UNLIKELY (family)) { add_attribute (tag, pango_attr_family_new (family)); } if (G_UNLIKELY (size)) { if (g_ascii_isdigit (*size)) { const char *end; gint n; /* cap size from the top at an arbitrary 2048 */ #define MAX_SIZE (2048 * PANGO_SCALE) if ((end = size, !pango_scan_int (&end, &n)) || *end != '\0' || n < 0 || n > MAX_SIZE) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("Value of 'size' attribute on <span> tag on line %d " "could not be parsed; should be an integer less than %d, or a " "string such as 'small', not '%s'"), line_number, MAX_SIZE+1, size); goto error; } add_attribute (tag, pango_attr_size_new (n)); if (tag) open_tag_set_absolute_font_size (tag, n); } else if (strcmp (size, "smaller") == 0) { if (tag) { tag->scale_level_delta -= 1; tag->scale_level -= 1; } } else if (strcmp (size, "larger") == 0) { if (tag) { tag->scale_level_delta += 1; tag->scale_level += 1; } } else if (parse_absolute_size (tag, size)) ; /* nothing */ else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("Value of 'size' attribute on <span> tag on line %d " "could not be parsed; should be an integer, or a " "string such as 'small', not '%s'"), line_number, size); goto error; } } if (G_UNLIKELY (style)) { PangoStyle pango_style; if (pango_parse_style (style, &pango_style, FALSE)) add_attribute (tag, pango_attr_style_new (pango_style)); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("'%s' is not a valid value for the 'style' attribute " "on <span> tag, line %d; valid values are " "'normal', 'oblique', 'italic'"), style, line_number); goto error; } } if (G_UNLIKELY (weight)) { PangoWeight pango_weight; if (pango_parse_weight (weight, &pango_weight, FALSE)) add_attribute (tag, pango_attr_weight_new (pango_weight)); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("'%s' is not a valid value for the 'weight' " "attribute on <span> tag, line %d; valid " "values are for example 'light', 'ultrabold' or a number"), weight, line_number); goto error; } } if (G_UNLIKELY (variant)) { PangoVariant pango_variant; if (pango_parse_variant (variant, &pango_variant, FALSE)) add_attribute (tag, pango_attr_variant_new (pango_variant)); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("'%s' is not a valid value for the 'variant' " "attribute on <span> tag, line %d; valid values are " "'normal', 'smallcaps'"), variant, line_number); goto error; } } if (G_UNLIKELY (stretch)) { PangoStretch pango_stretch; if (pango_parse_stretch (stretch, &pango_stretch, FALSE)) add_attribute (tag, pango_attr_stretch_new (pango_stretch)); else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, _("'%s' is not a valid value for the 'stretch' " "attribute on <span> tag, line %d; valid " "values are for example 'condensed', " "'ultraexpanded', 'normal'"), stretch, line_number); goto error; } } if (G_UNLIKELY (foreground)) { PangoColor color; if (!span_parse_color ("foreground", foreground, &color, line_number, error)) goto error; add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue)); } if (G_UNLIKELY (background)) { PangoColor color; if (!span_parse_color ("background", background, &color, line_number, error)) goto error; add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue)); } if (G_UNLIKELY (underline)) { PangoUnderline ul = PANGO_UNDERLINE_NONE; if (!span_parse_enum ("underline", underline, PANGO_TYPE_UNDERLINE, &ul, line_number, error)) goto error; add_attribute (tag, pango_attr_underline_new (ul)); } if (G_UNLIKELY (underline_color)) { PangoColor color; if (!span_parse_color ("underline_color", underline_color, &color, line_number, error)) goto error; add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue)); } if (G_UNLIKELY (gravity)) { PangoGravity gr = PANGO_GRAVITY_SOUTH; if (!span_parse_enum ("gravity", gravity, PANGO_TYPE_GRAVITY, &gr, line_number, error)) goto error; add_attribute (tag, pango_attr_gravity_new (gr)); } if (G_UNLIKELY (gravity_hint)) { PangoGravityHint hint = PANGO_GRAVITY_HINT_NATURAL; if (!span_parse_enum ("gravity_hint", gravity_hint, PANGO_TYPE_GRAVITY_HINT, &hint, line_number, error)) goto error; add_attribute (tag, pango_attr_gravity_hint_new (hint)); } if (G_UNLIKELY (strikethrough)) { gboolean b = FALSE; if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error)) goto error; add_attribute (tag, pango_attr_strikethrough_new (b)); } if (G_UNLIKELY (strikethrough_color)) { PangoColor color; if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, line_number, error)) goto error; add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue)); } if (G_UNLIKELY (fallback)) { gboolean b = FALSE; if (!span_parse_boolean ("fallback", fallback, &b, line_number, error)) goto error; add_attribute (tag, pango_attr_fallback_new (b)); } if (G_UNLIKELY (rise)) { gint n = 0; if (!span_parse_int ("rise", rise, &n, line_number, error)) goto error; add_attribute (tag, pango_attr_rise_new (n)); } if (G_UNLIKELY (letter_spacing)) { gint n = 0; if (!span_parse_int ("letter_spacing", letter_spacing, &n, line_number, error)) goto error; add_attribute (tag, pango_attr_letter_spacing_new (n)); } if (G_UNLIKELY (lang)) { add_attribute (tag, pango_attr_language_new (pango_language_from_string (lang))); } return TRUE; error: return FALSE; }