2 * pango-attributes.c: Attributed text
4 * Copyright (C) 2000-2002 Red Hat Software
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
25 #include "pango-attributes.h"
26 #include "pango-impl-utils.h"
32 GSList *attributes_tail;
35 struct _PangoAttrIterator
37 GSList *next_attribute;
38 GList *attribute_stack;
43 static PangoAttribute *pango_attr_color_new (const PangoAttrClass *klass,
47 static PangoAttribute *pango_attr_string_new (const PangoAttrClass *klass,
49 static PangoAttribute *pango_attr_int_new (const PangoAttrClass *klass,
51 static PangoAttribute *pango_attr_float_new (const PangoAttrClass *klass,
53 static PangoAttribute *pango_attr_size_new_internal (int size,
57 static GHashTable *name_map = NULL;
60 * pango_attr_type_register:
61 * @name: an identifier for the type
63 * Allocate a new attribute type ID. The attribute type name can be accessed
64 * later by using pango_attr_type_get_name().
66 * Return value: the new type ID.
69 pango_attr_type_register (const gchar *name)
71 static guint current_type = 0x1000000;
72 guint type = current_type++;
76 if (G_UNLIKELY (!name_map))
77 name_map = g_hash_table_new (NULL, NULL);
79 g_hash_table_insert (name_map, GUINT_TO_POINTER (type), (gpointer) g_intern_string (name));
86 * pango_attr_type_get_name:
87 * @type: an attribute type ID to fetch the name for
89 * Fetches the attribute type name passed in when registering the type using
90 * pango_attr_type_register().
92 * The returned value is an interned string (see g_intern_string() for what
93 * that means) that should not be modified or freed.
95 * Return value: the type ID name (which may be %NULL), or %NULL if @type is
96 * a built-in Pango attribute type or invalid.
100 G_CONST_RETURN char *
101 pango_attr_type_get_name (PangoAttrType type)
103 const char *result = NULL;
106 result = g_hash_table_lookup (name_map, GUINT_TO_POINTER ((guint) type));
112 * pango_attribute_init:
113 * @attr: a #PangoAttribute
114 * @klass: a #PangoAttributeClass
116 * Initializes @attr's klass to @klass,
117 * it's start_index to %PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING
118 * and end_index to %PANGO_ATTR_INDEX_TO_TEXT_END
119 * such that the attribute applies
120 * to the entire text by default.
125 pango_attribute_init (PangoAttribute *attr,
126 const PangoAttrClass *klass)
128 g_return_if_fail (attr != NULL);
129 g_return_if_fail (klass != NULL);
132 attr->start_index = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
133 attr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
137 * pango_attribute_copy:
138 * @attr: a #PangoAttribute
140 * Make a copy of an attribute.
142 * Return value: the newly allocated #PangoAttribute, which should be
143 * freed with pango_attribute_destroy().
146 pango_attribute_copy (const PangoAttribute *attr)
148 PangoAttribute *result;
150 g_return_val_if_fail (attr != NULL, NULL);
152 result = attr->klass->copy (attr);
153 result->start_index = attr->start_index;
154 result->end_index = attr->end_index;
160 * pango_attribute_destroy:
161 * @attr: a #PangoAttribute.
163 * Destroy a #PangoAttribute and free all associated memory.
166 pango_attribute_destroy (PangoAttribute *attr)
168 g_return_if_fail (attr != NULL);
170 attr->klass->destroy (attr);
174 * pango_attribute_equal:
175 * @attr1: a #PangoAttribute
176 * @attr2: another #PangoAttribute
178 * Compare two attributes for equality. This compares only the
179 * actual value of the two attributes and not the ranges that the
180 * attributes apply to.
182 * Return value: %TRUE if the two attributes have the same value.
185 pango_attribute_equal (const PangoAttribute *attr1,
186 const PangoAttribute *attr2)
188 g_return_val_if_fail (attr1 != NULL, FALSE);
189 g_return_val_if_fail (attr2 != NULL, FALSE);
191 if (attr1->klass->type != attr2->klass->type)
194 return attr1->klass->equal (attr1, attr2);
197 static PangoAttribute *
198 pango_attr_string_copy (const PangoAttribute *attr)
200 return pango_attr_string_new (attr->klass, ((PangoAttrString *)attr)->value);
204 pango_attr_string_destroy (PangoAttribute *attr)
206 PangoAttrString *sattr = (PangoAttrString *)attr;
208 g_free (sattr->value);
209 g_slice_free (PangoAttrString, sattr);
213 pango_attr_string_equal (const PangoAttribute *attr1,
214 const PangoAttribute *attr2)
216 return strcmp (((PangoAttrString *)attr1)->value, ((PangoAttrString *)attr2)->value) == 0;
219 static PangoAttribute *
220 pango_attr_string_new (const PangoAttrClass *klass,
223 PangoAttrString *result = g_slice_new (PangoAttrString);
224 pango_attribute_init (&result->attr, klass);
225 result->value = g_strdup (str);
227 return (PangoAttribute *)result;
231 * pango_attr_family_new:
232 * @family: the family or comma separated list of families
234 * Create a new font family attribute.
236 * Return value: the newly allocated #PangoAttribute, which should be
237 * freed with pango_attribute_destroy().
240 pango_attr_family_new (const char *family)
242 static const PangoAttrClass klass = {
244 pango_attr_string_copy,
245 pango_attr_string_destroy,
246 pango_attr_string_equal
249 g_return_val_if_fail (family != NULL, NULL);
251 return pango_attr_string_new (&klass, family);
254 static PangoAttribute *
255 pango_attr_language_copy (const PangoAttribute *attr)
257 return pango_attr_language_new (((PangoAttrLanguage *)attr)->value);
261 pango_attr_language_destroy (PangoAttribute *attr)
263 PangoAttrLanguage *lattr = (PangoAttrLanguage *)attr;
265 g_slice_free (PangoAttrLanguage, lattr);
269 pango_attr_language_equal (const PangoAttribute *attr1,
270 const PangoAttribute *attr2)
272 return ((PangoAttrLanguage *)attr1)->value == ((PangoAttrLanguage *)attr2)->value;
276 * pango_attr_language_new:
277 * @language: language tag
279 * Create a new language tag attribute.
281 * Return value: the newly allocated #PangoAttribute, which should be
282 * freed with pango_attribute_destroy().
285 pango_attr_language_new (PangoLanguage *language)
287 PangoAttrLanguage *result;
289 static const PangoAttrClass klass = {
291 pango_attr_language_copy,
292 pango_attr_language_destroy,
293 pango_attr_language_equal
296 result = g_slice_new (PangoAttrLanguage);
297 pango_attribute_init (&result->attr, &klass);
298 result->value = language;
300 return (PangoAttribute *)result;
303 static PangoAttribute *
304 pango_attr_color_copy (const PangoAttribute *attr)
306 const PangoAttrColor *color_attr = (PangoAttrColor *)attr;
308 return pango_attr_color_new (attr->klass,
309 color_attr->color.red,
310 color_attr->color.green,
311 color_attr->color.blue);
315 pango_attr_color_destroy (PangoAttribute *attr)
317 PangoAttrColor *cattr = (PangoAttrColor *)attr;
319 g_slice_free (PangoAttrColor, cattr);
323 pango_attr_color_equal (const PangoAttribute *attr1,
324 const PangoAttribute *attr2)
326 const PangoAttrColor *color_attr1 = (const PangoAttrColor *)attr1;
327 const PangoAttrColor *color_attr2 = (const PangoAttrColor *)attr2;
329 return (color_attr1->color.red == color_attr2->color.red &&
330 color_attr1->color.blue == color_attr2->color.blue &&
331 color_attr1->color.green == color_attr2->color.green);
334 static PangoAttribute *
335 pango_attr_color_new (const PangoAttrClass *klass,
340 PangoAttrColor *result = g_slice_new (PangoAttrColor);
341 pango_attribute_init (&result->attr, klass);
342 result->color.red = red;
343 result->color.green = green;
344 result->color.blue = blue;
346 return (PangoAttribute *)result;
350 * pango_attr_foreground_new:
351 * @red: the red value (ranging from 0 to 65535)
352 * @green: the green value
353 * @blue: the blue value
355 * Create a new foreground color attribute.
357 * Return value: the newly allocated #PangoAttribute, which should be
358 * freed with pango_attribute_destroy().
361 pango_attr_foreground_new (guint16 red,
365 static const PangoAttrClass klass = {
366 PANGO_ATTR_FOREGROUND,
367 pango_attr_color_copy,
368 pango_attr_color_destroy,
369 pango_attr_color_equal
372 return pango_attr_color_new (&klass, red, green, blue);
376 * pango_attr_background_new:
377 * @red: the red value (ranging from 0 to 65535)
378 * @green: the green value
379 * @blue: the blue value
381 * Create a new background color attribute.
383 * Return value: the newly allocated #PangoAttribute, which should be
384 * freed with pango_attribute_destroy().
387 pango_attr_background_new (guint16 red,
391 static const PangoAttrClass klass = {
392 PANGO_ATTR_BACKGROUND,
393 pango_attr_color_copy,
394 pango_attr_color_destroy,
395 pango_attr_color_equal
398 return pango_attr_color_new (&klass, red, green, blue);
401 static PangoAttribute *
402 pango_attr_int_copy (const PangoAttribute *attr)
404 const PangoAttrInt *int_attr = (PangoAttrInt *)attr;
406 return pango_attr_int_new (attr->klass, int_attr->value);
410 pango_attr_int_destroy (PangoAttribute *attr)
412 PangoAttrInt *iattr = (PangoAttrInt *)attr;
414 g_slice_free (PangoAttrInt, iattr);
418 pango_attr_int_equal (const PangoAttribute *attr1,
419 const PangoAttribute *attr2)
421 const PangoAttrInt *int_attr1 = (const PangoAttrInt *)attr1;
422 const PangoAttrInt *int_attr2 = (const PangoAttrInt *)attr2;
424 return (int_attr1->value == int_attr2->value);
427 static PangoAttribute *
428 pango_attr_int_new (const PangoAttrClass *klass,
431 PangoAttrInt *result = g_slice_new (PangoAttrInt);
432 pango_attribute_init (&result->attr, klass);
433 result->value = value;
435 return (PangoAttribute *)result;
438 static PangoAttribute *
439 pango_attr_float_copy (const PangoAttribute *attr)
441 const PangoAttrFloat *float_attr = (PangoAttrFloat *)attr;
443 return pango_attr_float_new (attr->klass, float_attr->value);
447 pango_attr_float_destroy (PangoAttribute *attr)
449 PangoAttrFloat *fattr = (PangoAttrFloat *)attr;
451 g_slice_free (PangoAttrFloat, fattr);
455 pango_attr_float_equal (const PangoAttribute *attr1,
456 const PangoAttribute *attr2)
458 const PangoAttrFloat *float_attr1 = (const PangoAttrFloat *)attr1;
459 const PangoAttrFloat *float_attr2 = (const PangoAttrFloat *)attr2;
461 return (float_attr1->value == float_attr2->value);
464 static PangoAttribute*
465 pango_attr_float_new (const PangoAttrClass *klass,
468 PangoAttrFloat *result = g_slice_new (PangoAttrFloat);
469 pango_attribute_init (&result->attr, klass);
470 result->value = value;
472 return (PangoAttribute *)result;
475 static PangoAttribute *
476 pango_attr_size_copy (const PangoAttribute *attr)
478 const PangoAttrSize *size_attr = (PangoAttrSize *)attr;
480 if (attr->klass->type == PANGO_ATTR_ABSOLUTE_SIZE)
481 return pango_attr_size_new_absolute (size_attr->size);
483 return pango_attr_size_new (size_attr->size);
487 pango_attr_size_destroy (PangoAttribute *attr)
489 PangoAttrSize *sattr = (PangoAttrSize *)attr;
491 g_slice_free (PangoAttrSize, sattr);
495 pango_attr_size_equal (const PangoAttribute *attr1,
496 const PangoAttribute *attr2)
498 const PangoAttrSize *size_attr1 = (const PangoAttrSize *)attr1;
499 const PangoAttrSize *size_attr2 = (const PangoAttrSize *)attr2;
501 return size_attr1->size == size_attr2->size;
504 static PangoAttribute *
505 pango_attr_size_new_internal (int size,
508 PangoAttrSize *result;
510 static const PangoAttrClass klass = {
512 pango_attr_size_copy,
513 pango_attr_size_destroy,
514 pango_attr_size_equal
516 static const PangoAttrClass absolute_klass = {
517 PANGO_ATTR_ABSOLUTE_SIZE,
518 pango_attr_size_copy,
519 pango_attr_size_destroy,
520 pango_attr_size_equal
523 result = g_slice_new (PangoAttrSize);
524 pango_attribute_init (&result->attr, absolute ? &absolute_klass : &klass);
526 result->absolute = absolute;
528 return (PangoAttribute *)result;
532 * pango_attr_size_new:
533 * @size: the font size, in %PANGO_SCALE<!-- -->ths of a point.
535 * Create a new font-size attribute in fractional points.
537 * Return value: the newly allocated #PangoAttribute, which should be
538 * freed with pango_attribute_destroy().
541 pango_attr_size_new (int size)
543 return pango_attr_size_new_internal (size, FALSE);
547 * pango_attr_size_new_absolute:
548 * @size: the font size, in %PANGO_SCALE<!-- -->ths of a device unit.
550 * Create a new font-size attribute in device units.
552 * Return value: the newly allocated #PangoAttribute, which should be
553 * freed with pango_attribute_destroy().
558 pango_attr_size_new_absolute (int size)
560 return pango_attr_size_new_internal (size, TRUE);
564 * pango_attr_style_new:
565 * @style: the slant style
567 * Create a new font slant style attribute.
569 * Return value: the newly allocated #PangoAttribute, which should be
570 * freed with pango_attribute_destroy().
573 pango_attr_style_new (PangoStyle style)
575 static const PangoAttrClass klass = {
578 pango_attr_int_destroy,
582 return pango_attr_int_new (&klass, (int)style);
586 * pango_attr_weight_new:
587 * @weight: the weight
589 * Create a new font weight attribute.
591 * Return value: the newly allocated #PangoAttribute, which should be
592 * freed with pango_attribute_destroy().
595 pango_attr_weight_new (PangoWeight weight)
597 static const PangoAttrClass klass = {
600 pango_attr_int_destroy,
604 return pango_attr_int_new (&klass, (int)weight);
608 * pango_attr_variant_new:
609 * @variant: the variant
611 * Create a new font variant attribute (normal or small caps)
613 * Return value: the newly allocated #PangoAttribute, which should be
614 * freed with pango_attribute_destroy().
617 pango_attr_variant_new (PangoVariant variant)
619 static const PangoAttrClass klass = {
622 pango_attr_int_destroy,
626 return pango_attr_int_new (&klass, (int)variant);
630 * pango_attr_stretch_new:
631 * @stretch: the stretch
633 * Create a new font stretch attribute
635 * Return value: the newly allocated #PangoAttribute, which should be
636 * freed with pango_attribute_destroy().
639 pango_attr_stretch_new (PangoStretch stretch)
641 static const PangoAttrClass klass = {
644 pango_attr_int_destroy,
648 return pango_attr_int_new (&klass, (int)stretch);
651 static PangoAttribute *
652 pango_attr_font_desc_copy (const PangoAttribute *attr)
654 const PangoAttrFontDesc *desc_attr = (const PangoAttrFontDesc *)attr;
656 return pango_attr_font_desc_new (desc_attr->desc);
660 pango_attr_font_desc_destroy (PangoAttribute *attr)
662 PangoAttrFontDesc *desc_attr = (PangoAttrFontDesc *)attr;
664 pango_font_description_free (desc_attr->desc);
665 g_slice_free (PangoAttrFontDesc, desc_attr);
669 pango_attr_font_desc_equal (const PangoAttribute *attr1,
670 const PangoAttribute *attr2)
672 const PangoAttrFontDesc *desc_attr1 = (const PangoAttrFontDesc *)attr1;
673 const PangoAttrFontDesc *desc_attr2 = (const PangoAttrFontDesc *)attr2;
675 return pango_font_description_get_set_fields (desc_attr1->desc) ==
676 pango_font_description_get_set_fields (desc_attr2->desc) &&
677 pango_font_description_equal (desc_attr1->desc, desc_attr2->desc);
681 * pango_attr_font_desc_new:
682 * @desc: the font description
684 * Create a new font description attribute. This attribute
685 * allows setting family, style, weight, variant, stretch,
686 * and size simultaneously.
688 * Return value: the newly allocated #PangoAttribute, which should be
689 * freed with pango_attribute_destroy().
692 pango_attr_font_desc_new (const PangoFontDescription *desc)
694 static const PangoAttrClass klass = {
695 PANGO_ATTR_FONT_DESC,
696 pango_attr_font_desc_copy,
697 pango_attr_font_desc_destroy,
698 pango_attr_font_desc_equal
701 PangoAttrFontDesc *result = g_slice_new (PangoAttrFontDesc);
702 pango_attribute_init (&result->attr, &klass);
703 result->desc = pango_font_description_copy (desc);
705 return (PangoAttribute *)result;
710 * pango_attr_underline_new:
711 * @underline: the underline style.
713 * Create a new underline-style attribute.
715 * Return value: the newly allocated #PangoAttribute, which should be
716 * freed with pango_attribute_destroy().
719 pango_attr_underline_new (PangoUnderline underline)
721 static const PangoAttrClass klass = {
722 PANGO_ATTR_UNDERLINE,
724 pango_attr_int_destroy,
728 return pango_attr_int_new (&klass, (int)underline);
732 * pango_attr_underline_color_new:
733 * @red: the red value (ranging from 0 to 65535)
734 * @green: the green value
735 * @blue: the blue value
737 * Create a new underline color attribute. This attribute
738 * modifies the color of underlines. If not set, underlines
739 * will use the foreground color.
741 * Return value: the newly allocated #PangoAttribute, which should be
742 * freed with pango_attribute_destroy().
747 pango_attr_underline_color_new (guint16 red,
751 static const PangoAttrClass klass = {
752 PANGO_ATTR_UNDERLINE_COLOR,
753 pango_attr_color_copy,
754 pango_attr_color_destroy,
755 pango_attr_color_equal
758 return pango_attr_color_new (&klass, red, green, blue);
762 * pango_attr_strikethrough_new:
763 * @strikethrough: %TRUE if the text should be struck-through.
765 * Create a new strike-through attribute.
767 * Return value: the newly allocated #PangoAttribute, which should be
768 * freed with pango_attribute_destroy().
771 pango_attr_strikethrough_new (gboolean strikethrough)
773 static const PangoAttrClass klass = {
774 PANGO_ATTR_STRIKETHROUGH,
776 pango_attr_int_destroy,
780 return pango_attr_int_new (&klass, (int)strikethrough);
784 * pango_attr_strikethrough_color_new:
785 * @red: the red value (ranging from 0 to 65535)
786 * @green: the green value
787 * @blue: the blue value
789 * Create a new strikethrough color attribute. This attribute
790 * modifies the color of strikethrough lines. If not set, strikethrough
791 * lines will use the foreground color.
793 * Return value: the newly allocated #PangoAttribute, which should be
794 * freed with pango_attribute_destroy().
799 pango_attr_strikethrough_color_new (guint16 red,
803 static const PangoAttrClass klass = {
804 PANGO_ATTR_STRIKETHROUGH_COLOR,
805 pango_attr_color_copy,
806 pango_attr_color_destroy,
807 pango_attr_color_equal
810 return pango_attr_color_new (&klass, red, green, blue);
814 * pango_attr_rise_new:
815 * @rise: the amount that the text should be displaced vertically,
816 * in Pango units. Positive values displace the text upwards.
818 * Create a new baseline displacement attribute.
820 * Return value: the newly allocated #PangoAttribute, which should be
821 * freed with pango_attribute_destroy().
824 pango_attr_rise_new (int rise)
826 static const PangoAttrClass klass = {
829 pango_attr_int_destroy,
833 return pango_attr_int_new (&klass, (int)rise);
837 * pango_attr_scale_new:
838 * @scale_factor: factor to scale the font
840 * Create a new font size scale attribute. The base font for the
841 * affected text will have its size multiplied by @scale_factor.
843 * Return value: the newly allocated #PangoAttribute, which should be
844 * freed with pango_attribute_destroy().
847 pango_attr_scale_new (double scale_factor)
849 static const PangoAttrClass klass = {
851 pango_attr_float_copy,
852 pango_attr_float_destroy,
853 pango_attr_float_equal
856 return pango_attr_float_new (&klass, scale_factor);
860 * pango_attr_fallback_new:
861 * @enable_fallback: %TRUE if we should fall back on other fonts
862 * for characters the active font is missing.
864 * Create a new font fallback attribute.
866 * If fallback is disabled, characters will only be used from the
867 * closest matching font on the system. No fallback will be done to
868 * other fonts on the system that might contain the characters in the
871 * Return value: the newly allocated #PangoAttribute, which should be
872 * freed with pango_attribute_destroy().
877 pango_attr_fallback_new (gboolean enable_fallback)
879 static const PangoAttrClass klass = {
882 pango_attr_int_destroy,
883 pango_attr_int_equal,
886 return pango_attr_int_new (&klass, (int)enable_fallback);
890 * pango_attr_letter_spacing_new:
891 * @letter_spacing: amount of extra space to add between graphemes
892 * of the text, in Pango units.
894 * Create a new letter-spacing attribute.
896 * Return value: the newly allocated #PangoAttribute, which should be
897 * freed with pango_attribute_destroy().
902 pango_attr_letter_spacing_new (int letter_spacing)
904 static const PangoAttrClass klass = {
905 PANGO_ATTR_LETTER_SPACING,
907 pango_attr_int_destroy,
911 return pango_attr_int_new (&klass, letter_spacing);
914 static PangoAttribute *
915 pango_attr_shape_copy (const PangoAttribute *attr)
917 const PangoAttrShape *shape_attr = (PangoAttrShape *)attr;
920 if (shape_attr->copy_func)
921 data = shape_attr->copy_func (shape_attr->data);
923 data = shape_attr->data;
925 return pango_attr_shape_new_with_data (&shape_attr->ink_rect, &shape_attr->logical_rect,
926 data, shape_attr->copy_func, shape_attr->destroy_func);
930 pango_attr_shape_destroy (PangoAttribute *attr)
932 PangoAttrShape *shape_attr = (PangoAttrShape *)attr;
934 if (shape_attr->destroy_func)
935 shape_attr->destroy_func (shape_attr->data);
937 g_slice_free (PangoAttrShape, shape_attr);
941 pango_attr_shape_equal (const PangoAttribute *attr1,
942 const PangoAttribute *attr2)
944 const PangoAttrShape *shape_attr1 = (const PangoAttrShape *)attr1;
945 const PangoAttrShape *shape_attr2 = (const PangoAttrShape *)attr2;
947 return (shape_attr1->logical_rect.x == shape_attr2->logical_rect.x &&
948 shape_attr1->logical_rect.y == shape_attr2->logical_rect.y &&
949 shape_attr1->logical_rect.width == shape_attr2->logical_rect.width &&
950 shape_attr1->logical_rect.height == shape_attr2->logical_rect.height &&
951 shape_attr1->ink_rect.x == shape_attr2->ink_rect.x &&
952 shape_attr1->ink_rect.y == shape_attr2->ink_rect.y &&
953 shape_attr1->ink_rect.width == shape_attr2->ink_rect.width &&
954 shape_attr1->ink_rect.height == shape_attr2->ink_rect.height &&
955 shape_attr1->data == shape_attr2->data);
959 * pango_attr_shape_new_with_data:
960 * @ink_rect: ink rectangle to assign to each character
961 * @logical_rect: logical rectangle to assign to each character
962 * @data: user data pointer
963 * @copy_func: function to copy @data when the attribute
964 * is copied. If %NULL, @data is simply copied
966 * @destroy_func: function to free @data when the attribute
969 * Like pango_attr_shape_new(), but a user data pointer is also
970 * provided; this pointer can be accessed when later
971 * rendering the glyph.
973 * Return value: the newly allocated #PangoAttribute, which should be
974 * freed with pango_attribute_destroy().
979 pango_attr_shape_new_with_data (const PangoRectangle *ink_rect,
980 const PangoRectangle *logical_rect,
982 PangoAttrDataCopyFunc copy_func,
983 GDestroyNotify destroy_func)
985 static const PangoAttrClass klass = {
987 pango_attr_shape_copy,
988 pango_attr_shape_destroy,
989 pango_attr_shape_equal
992 PangoAttrShape *result;
994 g_return_val_if_fail (ink_rect != NULL, NULL);
995 g_return_val_if_fail (logical_rect != NULL, NULL);
997 result = g_slice_new (PangoAttrShape);
998 pango_attribute_init (&result->attr, &klass);
999 result->ink_rect = *ink_rect;
1000 result->logical_rect = *logical_rect;
1001 result->data = data;
1002 result->copy_func = copy_func;
1003 result->destroy_func = destroy_func;
1005 return (PangoAttribute *)result;
1009 * pango_attr_shape_new:
1010 * @ink_rect: ink rectangle to assign to each character
1011 * @logical_rect: logical rectangle to assign to each character
1013 * Create a new shape attribute. A shape is used to impose a
1014 * particular ink and logical rectangle on the result of shaping a
1015 * particular glyph. This might be used, for instance, for
1016 * embedding a picture or a widget inside a #PangoLayout.
1018 * Return value: the newly allocated #PangoAttribute, which should be
1019 * freed with pango_attribute_destroy().
1022 pango_attr_shape_new (const PangoRectangle *ink_rect,
1023 const PangoRectangle *logical_rect)
1025 g_return_val_if_fail (ink_rect != NULL, NULL);
1026 g_return_val_if_fail (logical_rect != NULL, NULL);
1028 return pango_attr_shape_new_with_data (ink_rect, logical_rect,
1033 * pango_attr_gravity_new:
1034 * @gravity: the gravity value; should not be %PANGO_GRAVITY_AUTO.
1036 * Create a new gravity attribute.
1038 * Return value: the newly allocated #PangoAttribute, which should be
1039 * freed with pango_attribute_destroy().
1044 pango_attr_gravity_new (PangoGravity gravity)
1046 static const PangoAttrClass klass = {
1048 pango_attr_int_copy,
1049 pango_attr_int_destroy,
1050 pango_attr_int_equal
1053 g_return_val_if_fail (gravity != PANGO_GRAVITY_AUTO, NULL);
1055 return pango_attr_int_new (&klass, (int)gravity);
1059 * pango_attr_gravity_hint_new:
1060 * @hint: the gravity hint value.
1062 * Create a new gravity hint attribute.
1064 * Return value: the newly allocated #PangoAttribute, which should be
1065 * freed with pango_attribute_destroy().
1070 pango_attr_gravity_hint_new (PangoGravityHint hint)
1072 static const PangoAttrClass klass = {
1073 PANGO_ATTR_GRAVITY_HINT,
1074 pango_attr_int_copy,
1075 pango_attr_int_destroy,
1076 pango_attr_int_equal
1079 return pango_attr_int_new (&klass, (int)hint);
1088 pango_attr_list_get_type (void)
1090 static GType our_type = 0;
1092 if (G_UNLIKELY (our_type == 0))
1093 our_type = g_boxed_type_register_static (I_("PangoAttrList"),
1094 (GBoxedCopyFunc) pango_attr_list_copy,
1095 (GBoxedFreeFunc) pango_attr_list_unref);
1101 * pango_attr_list_new:
1103 * Create a new empty attribute list with a reference count of one.
1105 * Return value: the newly allocated #PangoAttrList, which should
1106 * be freed with pango_attr_list_unref().
1109 pango_attr_list_new (void)
1111 PangoAttrList *list = g_slice_new (PangoAttrList);
1113 list->ref_count = 1;
1114 list->attributes = NULL;
1115 list->attributes_tail = NULL;
1121 * pango_attr_list_ref:
1122 * @list: a #PangoAttrList, may be %NULL
1124 * Increase the reference count of the given attribute list by one.
1126 * Return value: The attribute list passed in
1131 pango_attr_list_ref (PangoAttrList *list)
1136 g_atomic_int_inc ((int *) &list->ref_count);
1142 * pango_attr_list_unref:
1143 * @list: a #PangoAttrList, may be %NULL
1145 * Decrease the reference count of the given attribute list by one.
1146 * If the result is zero, free the attribute list and the attributes
1150 pango_attr_list_unref (PangoAttrList *list)
1157 g_return_if_fail (list->ref_count > 0);
1159 if (g_atomic_int_dec_and_test ((int *) &list->ref_count))
1161 tmp_list = list->attributes;
1164 PangoAttribute *attr = tmp_list->data;
1165 tmp_list = tmp_list->next;
1167 attr->klass->destroy (attr);
1170 g_slist_free (list->attributes);
1172 g_slice_free (PangoAttrList, list);
1177 * pango_attr_list_copy:
1178 * @list: a #PangoAttrList, may be %NULL
1180 * Copy @list and return an identical new list.
1182 * Return value: the newly allocated #PangoAttrList, with a
1183 * reference count of one, which should
1184 * be freed with pango_attr_list_unref().
1185 * Returns %NULL if @list was %NULL.
1188 pango_attr_list_copy (PangoAttrList *list)
1197 new = pango_attr_list_new ();
1199 iter = list->attributes;
1201 while (iter != NULL)
1203 new_attrs = g_slist_prepend (new_attrs,
1204 pango_attribute_copy (iter->data));
1206 iter = g_slist_next (iter);
1209 /* we're going to reverse the nodes, so head becomes tail */
1210 new->attributes_tail = new_attrs;
1211 new->attributes = g_slist_reverse (new_attrs);
1217 pango_attr_list_insert_internal (PangoAttrList *list,
1218 PangoAttribute *attr,
1221 GSList *tmp_list, *prev, *link;
1222 guint start_index = attr->start_index;
1224 if (!list->attributes)
1226 list->attributes = g_slist_prepend (NULL, attr);
1227 list->attributes_tail = list->attributes;
1229 else if (((PangoAttribute *)list->attributes_tail->data)->start_index < start_index ||
1230 (!before && ((PangoAttribute *)list->attributes_tail->data)->start_index == start_index))
1232 list->attributes_tail = g_slist_append (list->attributes_tail, attr);
1233 list->attributes_tail = list->attributes_tail->next;
1234 g_assert (list->attributes_tail);
1239 tmp_list = list->attributes;
1242 PangoAttribute *tmp_attr = tmp_list->data;
1244 if (tmp_attr->start_index > start_index ||
1245 (before && tmp_attr->start_index == start_index))
1247 link = g_slist_alloc ();
1248 link->next = tmp_list;
1254 list->attributes = link;
1257 list->attributes_tail = link;
1263 tmp_list = tmp_list->next;
1269 * pango_attr_list_insert:
1270 * @list: a #PangoAttrList
1271 * @attr: the attribute to insert. Ownership of this value is
1272 * assumed by the list.
1274 * Insert the given attribute into the #PangoAttrList. It will
1275 * be inserted after all other attributes with a matching
1279 pango_attr_list_insert (PangoAttrList *list,
1280 PangoAttribute *attr)
1282 g_return_if_fail (list != NULL);
1283 g_return_if_fail (attr != NULL);
1285 pango_attr_list_insert_internal (list, attr, FALSE);
1289 * pango_attr_list_insert_before:
1290 * @list: a #PangoAttrList
1291 * @attr: the attribute to insert. Ownership of this value is
1292 * assumed by the list.
1294 * Insert the given attribute into the #PangoAttrList. It will
1295 * be inserted before all other attributes with a matching
1299 pango_attr_list_insert_before (PangoAttrList *list,
1300 PangoAttribute *attr)
1302 g_return_if_fail (list != NULL);
1303 g_return_if_fail (attr != NULL);
1305 pango_attr_list_insert_internal (list, attr, TRUE);
1309 * pango_attr_list_change:
1310 * @list: a #PangoAttrList
1311 * @attr: the attribute to insert. Ownership of this value is
1312 * assumed by the list.
1314 * Insert the given attribute into the #PangoAttrList. It will
1315 * replace any attributes of the same type on that segment
1316 * and be merged with any adjoining attributes that are identical.
1318 * This function is slower than pango_attr_list_insert() for
1319 * creating a attribute list in order (potentially much slower
1320 * for large lists). However, pango_attr_list_insert() is not
1321 * suitable for continually changing a set of attributes
1322 * since it never removes or combines existing attributes.
1325 pango_attr_list_change (PangoAttrList *list,
1326 PangoAttribute *attr)
1328 GSList *tmp_list, *prev, *link;
1329 guint start_index = attr->start_index;
1330 guint end_index = attr->end_index;
1332 g_return_if_fail (list != NULL);
1334 if (start_index == end_index) /* empty, nothing to do */
1336 pango_attribute_destroy (attr);
1340 tmp_list = list->attributes;
1344 PangoAttribute *tmp_attr;
1347 ((PangoAttribute *)tmp_list->data)->start_index > start_index)
1349 /* We need to insert a new attribute
1351 link = g_slist_alloc ();
1352 link->next = tmp_list;
1358 list->attributes = link;
1361 list->attributes_tail = link;
1364 tmp_list = prev->next;
1368 tmp_attr = tmp_list->data;
1370 if (tmp_attr->klass->type == attr->klass->type &&
1371 tmp_attr->end_index >= start_index)
1373 /* We overlap with an existing attribute */
1374 if (pango_attribute_equal (tmp_attr, attr))
1376 /* We can merge the new attribute with this attribute
1378 if (tmp_attr->end_index >= end_index)
1380 /* We are totally overlapping the previous attribute.
1381 * No action is needed.
1383 pango_attribute_destroy (attr);
1386 tmp_attr->end_index = end_index;
1387 pango_attribute_destroy (attr);
1392 tmp_list = tmp_list->next;
1398 /* Split, truncate, or remove the old attribute
1400 if (tmp_attr->end_index > attr->end_index)
1402 PangoAttribute *end_attr = pango_attribute_copy (tmp_attr);
1404 end_attr->start_index = attr->end_index;
1405 pango_attr_list_insert (list, end_attr);
1408 if (tmp_attr->start_index == attr->start_index)
1410 pango_attribute_destroy (tmp_attr);
1411 tmp_list->data = attr;
1414 tmp_list = tmp_list->next;
1419 tmp_attr->end_index = attr->start_index;
1424 tmp_list = tmp_list->next;
1426 /* At this point, prev points to the list node with attr in it,
1427 * tmp_list points to prev->next.
1430 g_assert (prev->data == attr);
1431 g_assert (prev->next == tmp_list);
1433 /* We now have the range inserted into the list one way or the
1434 * other. Fix up the remainder
1438 PangoAttribute *tmp_attr = tmp_list->data;
1440 if (tmp_attr->start_index > end_index)
1442 else if (tmp_attr->klass->type == attr->klass->type)
1444 if (tmp_attr->end_index <= attr->end_index ||
1445 pango_attribute_equal (tmp_attr, attr))
1447 /* We can merge the new attribute with this attribute.
1449 attr->end_index = MAX (end_index, tmp_attr->end_index);
1451 pango_attribute_destroy (tmp_attr);
1452 prev->next = tmp_list->next;
1455 list->attributes_tail = prev;
1457 g_slist_free_1 (tmp_list);
1458 tmp_list = prev->next;
1464 /* Trim the start of this attribute that it begins at the end
1465 * of the new attribute. This may involve moving
1466 * it in the list to maintain the required non-decreasing
1467 * order of start indices
1472 tmp_attr->start_index = attr->end_index;
1474 tmp_list2 = tmp_list->next;
1479 PangoAttribute *tmp_attr2 = tmp_list2->data;
1481 if (tmp_attr2->start_index >= tmp_attr->start_index)
1485 tmp_list2 = tmp_list2->next;
1488 /* Now remove and insert before tmp_list2. We'll
1489 * hit this attribute again later, but that's harmless.
1491 if (prev2 != tmp_list)
1493 GSList *old_next = tmp_list->next;
1495 prev->next = old_next;
1496 prev2->next = tmp_list;
1497 tmp_list->next = tmp_list2;
1499 if (!tmp_list->next)
1500 list->attributes_tail = tmp_list;
1502 tmp_list = old_next;
1510 tmp_list = tmp_list->next;
1515 * pango_attr_list_splice:
1516 * @list: a #PangoAttrList
1517 * @other: another #PangoAttrList
1518 * @pos: the position in @list at which to insert @other
1519 * @len: the length of the spliced segment. (Note that this
1520 * must be specified since the attributes in @other
1521 * may only be present at some subsection of this range)
1523 * This function opens up a hole in @list, fills it in with attributes from
1524 * the left, and then merges @other on top of the hole.
1526 * This operation is equivalent to stretching every attribute
1527 * that applies at position @pos in @list by an amount @len,
1528 * and then calling pango_attr_list_change() with a copy
1529 * of each attribute in @other in sequence (offset in position by @pos).
1531 * This operation proves useful for, for instance, inserting
1532 * a pre-edit string in the middle of an edit buffer.
1535 pango_attr_list_splice (PangoAttrList *list,
1536 PangoAttrList *other,
1543 g_return_if_fail (list != NULL);
1544 g_return_if_fail (other != NULL);
1545 g_return_if_fail (pos >= 0);
1546 g_return_if_fail (len >= 0);
1551 /* This definition only works when a and b are unsigned; overflow
1552 * isn't defined in the C standard for signed integers
1554 #define CLAMP_ADD(a,b) (((a) + (b) < (a)) ? G_MAXUINT : (a) + (b))
1556 tmp_list = list->attributes;
1559 PangoAttribute *attr = tmp_list->data;
1561 if (attr->start_index <= upos)
1563 if (attr->end_index > upos)
1564 attr->end_index = CLAMP_ADD (attr->end_index, ulen);
1568 /* This could result in a zero length attribute if it
1569 * gets squashed up against G_MAXUINT, but deleting such
1570 * an element could (in theory) suprise the caller, so
1571 * we don't delete it.
1573 attr->start_index = CLAMP_ADD (attr->start_index, ulen);
1574 attr->end_index = CLAMP_ADD (attr->end_index, ulen);
1577 tmp_list = tmp_list->next;
1580 tmp_list = other->attributes;
1583 PangoAttribute *attr = pango_attribute_copy (tmp_list->data);
1584 attr->start_index = CLAMP_ADD (attr->start_index, upos);
1585 attr->end_index = CLAMP_ADD (attr->end_index, upos);
1587 /* Same as above, the attribute could be squashed to zero-length; here
1588 * pango_attr_list_change() will take care of deleting it.
1590 pango_attr_list_change (list, attr);
1592 tmp_list = tmp_list->next;
1598 * pango_attr_list_get_iterator:
1599 * @list: a #PangoAttrList
1601 * Create a iterator initialized to the beginning of the list.
1602 * @list must not be modified until this iterator is freed.
1604 * Return value: the newly allocated #PangoAttrIterator, which should
1605 * be freed with pango_attr_iterator_destroy().
1608 pango_attr_list_get_iterator (PangoAttrList *list)
1610 PangoAttrIterator *iterator;
1612 g_return_val_if_fail (list != NULL, NULL);
1614 iterator = g_slice_new (PangoAttrIterator);
1615 iterator->next_attribute = list->attributes;
1616 iterator->attribute_stack = NULL;
1618 iterator->start_index = 0;
1619 iterator->end_index = 0;
1621 if (!pango_attr_iterator_next (iterator))
1622 iterator->end_index = G_MAXUINT;
1628 * pango_attr_iterator_range:
1629 * @iterator: a #PangoAttrIterator
1630 * @start: location to store the start of the range
1631 * @end: location to store the end of the range
1633 * Get the range of the current segment. Note that the
1634 * stored return values are signed, not unsigned like
1635 * the values in #PangoAttribute. To deal with this API
1636 * oversight, stored return values that wouldn't fit into
1637 * a signed integer are clamped to %G_MAXINT.
1640 pango_attr_iterator_range (PangoAttrIterator *iterator,
1644 g_return_if_fail (iterator != NULL);
1647 *start = MIN (iterator->start_index, G_MAXINT);
1649 *end = MIN (iterator->end_index, G_MAXINT);
1653 * pango_attr_iterator_next:
1654 * @iterator: a #PangoAttrIterator
1656 * Advance the iterator until the next change of style.
1658 * Return value: %FALSE if the iterator is at the end of the list, otherwise %TRUE
1661 pango_attr_iterator_next (PangoAttrIterator *iterator)
1665 g_return_val_if_fail (iterator != NULL, FALSE);
1667 if (!iterator->next_attribute && !iterator->attribute_stack)
1670 iterator->start_index = iterator->end_index;
1671 iterator->end_index = G_MAXUINT;
1673 tmp_list = iterator->attribute_stack;
1676 GList *next = tmp_list->next;
1677 PangoAttribute *attr = tmp_list->data;
1679 if (attr->end_index == iterator->start_index)
1681 iterator->attribute_stack = g_list_remove_link (iterator->attribute_stack, tmp_list);
1682 g_list_free_1 (tmp_list);
1686 iterator->end_index = MIN (iterator->end_index, attr->end_index);
1692 while (iterator->next_attribute &&
1693 ((PangoAttribute *)iterator->next_attribute->data)->start_index == iterator->start_index)
1695 if (((PangoAttribute *)iterator->next_attribute->data)->end_index > iterator->start_index)
1697 iterator->attribute_stack = g_list_prepend (iterator->attribute_stack, iterator->next_attribute->data);
1698 iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->end_index);
1700 iterator->next_attribute = iterator->next_attribute->next;
1703 if (iterator->next_attribute)
1704 iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->start_index);
1710 * pango_attr_iterator_copy:
1711 * @iterator: a #PangoAttrIterator.
1713 * Copy a #PangoAttrIterator
1715 * Return value: the newly allocated #PangoAttrIterator, which should
1716 * be freed with pango_attr_iterator_destroy().
1719 pango_attr_iterator_copy (PangoAttrIterator *iterator)
1721 PangoAttrIterator *copy;
1723 g_return_val_if_fail (iterator != NULL, NULL);
1725 copy = g_slice_new (PangoAttrIterator);
1729 copy->attribute_stack = g_list_copy (iterator->attribute_stack);
1735 * pango_attr_iterator_destroy:
1736 * @iterator: a #PangoAttrIterator.
1738 * Destroy a #PangoAttrIterator and free all associated memory.
1741 pango_attr_iterator_destroy (PangoAttrIterator *iterator)
1743 g_return_if_fail (iterator != NULL);
1745 g_list_free (iterator->attribute_stack);
1746 g_slice_free (PangoAttrIterator, iterator);
1750 * pango_attr_iterator_get:
1751 * @iterator: a #PangoAttrIterator
1752 * @type: the type of attribute to find.
1754 * Find the current attribute of a particular type at the iterator
1755 * location. When multiple attributes of the same type overlap,
1756 * the attribute whose range starts closest to the current location
1759 * Return value: the current attribute of the given type, or %NULL
1760 * if no attribute of that type applies to the current
1764 pango_attr_iterator_get (PangoAttrIterator *iterator,
1769 g_return_val_if_fail (iterator != NULL, NULL);
1771 tmp_list = iterator->attribute_stack;
1774 PangoAttribute *attr = tmp_list->data;
1776 if (attr->klass->type == type)
1779 tmp_list = tmp_list->next;
1786 * pango_attr_iterator_get_font:
1787 * @iterator: a #PangoAttrIterator
1788 * @desc: a #PangoFontDescription to fill in with the current values.
1789 * The family name in this structure will be set using
1790 * pango_font_description_set_family_static() using values from
1791 * an attribute in the #PangoAttrList associated with the iterator,
1792 * so if you plan to keep it around, you must call:
1793 * <literal>pango_font_description_set_family (desc, pango_font_description_get_family (desc))</literal>.
1794 * @language: if non-%NULL, location to store language tag for item, or %NULL
1796 * @extra_attrs: (element type Pango.Attribute): (transfer full): if non-%NULL,
1797 * location in which to store a list of non-font
1798 * attributes at the the current position; only the highest priority
1799 * value of each attribute will be added to this list. In order
1800 * to free this value, you must call pango_attribute_destroy() on
1803 * Get the font and other attributes at the current iterator position.
1806 pango_attr_iterator_get_font (PangoAttrIterator *iterator,
1807 PangoFontDescription *desc,
1808 PangoLanguage **language,
1809 GSList **extra_attrs)
1814 PangoFontMask mask = 0;
1815 gboolean have_language = FALSE;
1817 gboolean have_scale = FALSE;
1819 g_return_if_fail (iterator != NULL);
1820 g_return_if_fail (desc != NULL);
1826 *extra_attrs = NULL;
1828 tmp_list1 = iterator->attribute_stack;
1831 PangoAttribute *attr = tmp_list1->data;
1832 tmp_list1 = tmp_list1->next;
1834 switch ((int) attr->klass->type)
1836 case PANGO_ATTR_FONT_DESC:
1838 PangoFontMask new_mask = pango_font_description_get_set_fields (((PangoAttrFontDesc *)attr)->desc) & ~mask;
1840 pango_font_description_unset_fields (desc, new_mask);
1841 pango_font_description_merge_static (desc, ((PangoAttrFontDesc *)attr)->desc, FALSE);
1845 case PANGO_ATTR_FAMILY:
1846 if (!(mask & PANGO_FONT_MASK_FAMILY))
1848 mask |= PANGO_FONT_MASK_FAMILY;
1849 pango_font_description_set_family (desc, ((PangoAttrString *)attr)->value);
1852 case PANGO_ATTR_STYLE:
1853 if (!(mask & PANGO_FONT_MASK_STYLE))
1855 mask |= PANGO_FONT_MASK_STYLE;
1856 pango_font_description_set_style (desc, ((PangoAttrInt *)attr)->value);
1859 case PANGO_ATTR_VARIANT:
1860 if (!(mask & PANGO_FONT_MASK_VARIANT))
1862 mask |= PANGO_FONT_MASK_VARIANT;
1863 pango_font_description_set_variant (desc, ((PangoAttrInt *)attr)->value);
1866 case PANGO_ATTR_WEIGHT:
1867 if (!(mask & PANGO_FONT_MASK_WEIGHT))
1869 mask |= PANGO_FONT_MASK_WEIGHT;
1870 pango_font_description_set_weight (desc, ((PangoAttrInt *)attr)->value);
1873 case PANGO_ATTR_STRETCH:
1874 if (!(mask & PANGO_FONT_MASK_STRETCH))
1876 mask |= PANGO_FONT_MASK_STRETCH;
1877 pango_font_description_set_stretch (desc, ((PangoAttrInt *)attr)->value);
1880 case PANGO_ATTR_SIZE:
1881 if (!(mask & PANGO_FONT_MASK_SIZE))
1883 mask |= PANGO_FONT_MASK_SIZE;
1884 pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size);
1887 case PANGO_ATTR_ABSOLUTE_SIZE:
1888 if (!(mask & PANGO_FONT_MASK_SIZE))
1890 mask |= PANGO_FONT_MASK_SIZE;
1891 pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size);
1894 case PANGO_ATTR_SCALE:
1898 scale = ((PangoAttrFloat *)attr)->value;
1901 case PANGO_ATTR_LANGUAGE:
1906 have_language = TRUE;
1907 *language = ((PangoAttrLanguage *)attr)->value;
1914 gboolean found = FALSE;
1916 tmp_list2 = *extra_attrs;
1919 PangoAttribute *old_attr = tmp_list2->data;
1920 if (attr->klass->type == old_attr->klass->type)
1926 tmp_list2 = tmp_list2->next;
1930 *extra_attrs = g_slist_prepend (*extra_attrs, pango_attribute_copy (attr));
1936 pango_font_description_set_size (desc, scale * pango_font_description_get_size (desc));
1941 * pango_attr_list_filter:
1942 * @list: a #PangoAttrList
1943 * @func: callback function; returns %TRUE if an attribute
1944 * should be filtered out.
1945 * @data: Data to be passed to @func
1947 * Given a #PangoAttrList and callback function, removes any elements
1948 * of @list for which @func returns %TRUE and inserts them into
1951 * Return value: the new #PangoAttrList or %NULL if
1952 * no attributes of the given types were found.
1957 pango_attr_list_filter (PangoAttrList *list,
1958 PangoAttrFilterFunc func,
1962 PangoAttrList *new = NULL;
1966 g_return_val_if_fail (list != NULL, NULL);
1968 tmp_list = list->attributes;
1972 GSList *next = tmp_list->next;
1973 PangoAttribute *tmp_attr = tmp_list->data;
1975 if ((*func) (tmp_attr, data))
1977 if (!tmp_list->next)
1978 list->attributes_tail = prev;
1981 prev->next = tmp_list->next;
1983 list->attributes = tmp_list->next;
1985 tmp_list->next = NULL;
1989 new = pango_attr_list_new ();
1990 new->attributes = new->attributes_tail = tmp_list;
1994 new->attributes_tail->next = tmp_list;
1995 new->attributes_tail = tmp_list;
2011 * pango_attr_iterator_get_attrs:
2012 * @iterator: a #PangoAttrIterator
2014 * Gets a list of all attributes at the current position of the
2017 * Return value: (element-type Pango.Attribute): (transfer full): a list of
2018 * all attributes for the current range.
2019 * To free this value, call pango_attribute_destroy() on
2020 * each value and g_slist_free() on the list.
2025 pango_attr_iterator_get_attrs (PangoAttrIterator *iterator)
2027 GSList *attrs = NULL;
2030 for (tmp_list = iterator->attribute_stack; tmp_list; tmp_list = tmp_list->next)
2032 PangoAttribute *attr = tmp_list->data;
2034 gboolean found = FALSE;
2036 for (tmp_list2 = attrs; tmp_list2; tmp_list2 = tmp_list2->next)
2038 PangoAttribute *old_attr = tmp_list2->data;
2039 if (attr->klass->type == old_attr->klass->type)
2047 attrs = g_slist_prepend (attrs, pango_attribute_copy (attr));