1 /* ATK - The Accessibility Toolkit for GTK+
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 #include "atkmarshal.h"
22 #include "atk-enum-types.h"
26 GPtrArray *extra_attributes = NULL;
31 TEXT_SELECTION_CHANGED,
32 TEXT_ATTRIBUTES_CHANGED,
36 static const gchar *bool[] = {"false",
38 static const gchar *style[] = {"normal",
41 static const gchar *variant[] = {"normal",
43 static const gchar *stretch[] = {"ultra_condensed",
52 static const gchar *justification[] = {"left",
56 static const gchar *direction[] = {"none",
59 static const gchar *wrap_mode[] = {"none",
62 static const gchar *underline[] = {"none",
67 static void atk_text_base_init (gpointer *g_class);
69 static guint atk_text_signals[LAST_SIGNAL] = { 0 };
74 static GType type = 0;
78 static const GTypeInfo tinfo =
80 sizeof (AtkTextIface),
81 (GBaseInitFunc) atk_text_base_init,
82 (GBaseFinalizeFunc) NULL,
83 (GClassInitFunc) NULL /* atk_text_interface_init */ ,
84 (GClassFinalizeFunc) NULL,
88 type = g_type_register_static (G_TYPE_INTERFACE, "AtkText", &tinfo, 0);
95 atk_text_base_init (gpointer *g_class)
97 static gboolean initialized = FALSE;
102 * Note that text_changed signal supports details "insert", "delete",
103 * possibly "replace".
106 atk_text_signals[TEXT_CHANGED] =
107 g_signal_new ("text_changed",
109 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
110 G_STRUCT_OFFSET (AtkTextIface, text_changed),
111 (GSignalAccumulator) NULL, NULL,
112 atk_marshal_VOID__INT_INT,
114 2, G_TYPE_INT, G_TYPE_INT);
116 atk_text_signals[TEXT_CARET_MOVED] =
117 g_signal_new ("text_caret_moved",
120 G_STRUCT_OFFSET (AtkTextIface, text_caret_moved),
121 (GSignalAccumulator) NULL, NULL,
122 g_cclosure_marshal_VOID__INT,
125 atk_text_signals[TEXT_SELECTION_CHANGED] =
126 g_signal_new ("text_selection_changed",
129 G_STRUCT_OFFSET (AtkTextIface, text_selection_changed),
130 (GSignalAccumulator) NULL, NULL,
131 g_cclosure_marshal_VOID__VOID,
133 atk_text_signals[TEXT_ATTRIBUTES_CHANGED] =
134 g_signal_new ("text_attributes_changed",
137 G_STRUCT_OFFSET (AtkTextIface, text_attributes_changed),
138 (GSignalAccumulator) NULL, NULL,
139 g_cclosure_marshal_VOID__VOID,
150 * @start_offset: start position
151 * @end_offset: end position
153 * Gets the specified text.
155 * Returns: the text from @start_offset up to, but not including @end_offset.
158 atk_text_get_text (AtkText *text,
164 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
166 iface = ATK_TEXT_GET_IFACE (text);
168 if (start_offset < 0 || end_offset < -1)
172 return (*(iface->get_text)) (text, start_offset, end_offset);
178 * atk_text_get_character_at_offset:
182 * Gets the specified text.
184 * Returns: the character at @offset.
187 atk_text_get_character_at_offset (AtkText *text,
192 g_return_val_if_fail (ATK_IS_TEXT (text), (gunichar) 0);
197 iface = ATK_TEXT_GET_IFACE (text);
199 if (iface->get_character_at_offset)
200 return (*(iface->get_character_at_offset)) (text, offset);
206 * atk_text_get_text_after_offset:
209 * @boundary_type: An #AtkTextBoundary
210 * @start_offset: the start offset of the returned string.
211 * @end_offset: the end offset of the returned string.
213 * Gets the specified text.
215 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character after the
216 * offset is returned.
218 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
219 * is from the word start after the offset to the next word start.
221 * The returned string will contain the word after the offset if the offset
222 * is inside a word or if the offset is not inside a word.
224 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
225 * is from the word end at or after the offset to the next work end.
227 * The returned string will contain the word after the offset if the offset
228 * is inside a word and will contain the word after the word after the offset
229 * if the offset is not inside a word.
231 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
232 * string is from the sentence start after the offset to the next sentence
235 * The returned string will contain the sentence after the offset if the offset
236 * is inside a sentence or if the offset is not inside a sentence.
238 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
239 * is from the sentence end at or after the offset to the next sentence end.
241 * The returned string will contain the sentence after the offset if the offset
242 * is inside a sentence and will contain the sentence after the sentence
243 * after the offset if the offset is not inside a sentence.
245 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
246 * string is from the line start after the offset to the next line start.
248 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
249 * is from the line end at or after the offset to the next line start.
251 * Returns: the text after @offset bounded by the specified @boundary_type.
254 atk_text_get_text_after_offset (AtkText *text,
256 AtkTextBoundary boundary_type,
261 gint local_start_offset, local_end_offset;
262 gint *real_start_offset, *real_end_offset;
264 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
267 real_start_offset = start_offset;
269 real_start_offset = &local_start_offset;
271 real_end_offset = end_offset;
273 real_end_offset = &local_end_offset;
278 iface = ATK_TEXT_GET_IFACE (text);
280 if (iface->get_text_after_offset)
281 return (*(iface->get_text_after_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
287 * atk_text_get_text_at_offset:
290 * @boundary_type: An #AtkTextBoundary
291 * @start_offset: the start offset of the returned string.
292 * @end_offset: the end offset of the returned string.
294 * Gets the specified text.
296 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character at the
297 * offset is returned.
299 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
300 * is from the word start at or before the offset to the word start after
303 * The returned string will contain the word at the offset if the offset
304 * is inside a word and will contain the word before the offset if the
305 * offset is not inside a word.
307 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
308 * is from the word end before the offset to the word end at or after the
311 * The returned string will contain the word at the offset if the offset
312 * is inside a word and will contain the word after to the offset if the
313 * offset is not inside a word.
315 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
316 * string is from the sentence start at or before the offset to the sentence
317 * start after the offset.
319 * The returned string will contain the sentence at the offset if the offset
320 * is inside a sentence and will contain the sentence before the offset
321 * if the offset is not inside a sentence.
323 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
324 * is from the sentence end before the offset to the sentence end at or
327 * The returned string will contain the sentence at the offset if the offset
328 * is inside a sentence and will contain the sentence after the offset
329 * if the offset is not inside a sentence.
331 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
332 * string is from the line start at or before the offset to the line
333 * start after the offset.
335 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
336 * is from the line end before the offset to the line end at or after
339 * Returns: the text at @offset bounded by the specified @boundary_type.
342 atk_text_get_text_at_offset (AtkText *text,
344 AtkTextBoundary boundary_type,
349 gint local_start_offset, local_end_offset;
350 gint *real_start_offset, *real_end_offset;
352 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
355 real_start_offset = start_offset;
357 real_start_offset = &local_start_offset;
359 real_end_offset = end_offset;
361 real_end_offset = &local_end_offset;
366 iface = ATK_TEXT_GET_IFACE (text);
368 if (iface->get_text_at_offset)
369 return (*(iface->get_text_at_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
375 * atk_text_get_text_before_offset:
378 * @boundary_type: An #AtkTextBoundary
379 * @start_offset: the start offset of the returned string.
380 * @end_offset: the end offset of the returned string.
382 * Gets the specified text.
384 * If the boundary_type if ATK_TEXT_BOUNDARY_CHAR the character before the
385 * offset is returned.
387 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_START the returned string
388 * is from the word start before the word start before the offset to
389 * the word start before the offset.
391 * The returned string will contain the word before the offset if the offset
392 * is inside a word and will contain the word before the word before the
393 * offset if the offset is not inside a word.
395 * If the boundary_type is ATK_TEXT_BOUNDARY_WORD_END the returned string
396 * is from the word end before the word end at or before the offset to the
397 * word end at or before the offset.
399 * The returned string will contain the word before the offset if the offset
400 * is inside a word or if the offset is not inside a word.
402 * If the boundary type is ATK_TEXT_BOUNDARY_SENTENCE_START the returned
403 * string is from the sentence start before the sentence start before
404 * the offset to the sentence start before the offset.
406 * The returned string will contain the sentence before the offset if the
407 * offset is inside a sentence and will contain the sentence before the
408 * sentence before the offset if the offset is not inside a sentence.
410 * If the boundary_type is ATK_TEXT_BOUNDARY_SENTENCE_END the returned string
411 * is from the sentence end before the sentence end at or before the offset to
412 * the sentence end at or before the offset.
414 * The returned string will contain the sentence before the offset if the
415 * offset is inside a sentence or if the offset is not inside a sentence.
417 * If the boundary type is ATK_TEXT_BOUNDARY_LINE_START the returned
418 * string is from the line start before the line start ar or before the offset
419 * to the line start ar or before the offset.
421 * If the boundary_type is ATK_TEXT_BOUNDARY_LINE_END the returned string
422 * is from the line end before the line end before the offset to the
423 * line end before the offset.
425 * Returns: the text before @offset bounded by the specified @boundary_type.
428 atk_text_get_text_before_offset (AtkText *text,
430 AtkTextBoundary boundary_type,
435 gint local_start_offset, local_end_offset;
436 gint *real_start_offset, *real_end_offset;
438 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
441 real_start_offset = start_offset;
443 real_start_offset = &local_start_offset;
445 real_end_offset = end_offset;
447 real_end_offset = &local_end_offset;
452 iface = ATK_TEXT_GET_IFACE (text);
454 if (iface->get_text_before_offset)
455 return (*(iface->get_text_before_offset)) (text, offset, boundary_type, real_start_offset, real_end_offset);
461 * atk_text_get_caret_offset:
464 * Gets the offset position of the caret (cursor).
466 * Returns: the offset position of the caret (cursor).
469 atk_text_get_caret_offset (AtkText *text)
473 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
475 iface = ATK_TEXT_GET_IFACE (text);
477 if (iface->get_caret_offset)
478 return (*(iface->get_caret_offset)) (text);
484 * atk_text_get_character_extents:
487 * @x: x-position of character
488 * @y: y-position of character
489 * @width: width of character
490 * @height: height of character
491 * @coords: specify whether coordinates are relative to the screen or widget window
493 * Given an @offset, the @x, @y, @width, and @height values are filled
497 atk_text_get_character_extents (AtkText *text,
506 gint local_x, local_y, local_width, local_height;
507 gint *real_x, *real_y, *real_width, *real_height;
509 g_return_if_fail (ATK_IS_TEXT (text));
522 real_width = &local_width;
524 real_height = height;
526 real_height = &local_height;
536 iface = ATK_TEXT_GET_IFACE (text);
538 if (iface->get_character_extents)
539 (*(iface->get_character_extents)) (text, offset, real_x, real_y, real_width, real_height, coords);
543 *atk_text_get_run_attributes:
545 *@offset: the offset at which to get the attributes
546 *@start_offset: the address to put the start offset of the range
547 *@end_offset: the address to put the end offset of the range
549 *Creates an #AtkAttributeSet which consists of the attributes explicitly
550 *set at the position @offset in the text. @start_offset and @end_offset are
551 *set to the start and end of the range around @offset where the attributes are
552 *invariant. See the enum AtkTextAttribute for types of text attributes that
553 *can be returned. Note that other attributes may also be returned.
555 *Returns: an #AtkAttributeSet which contains the attributes explicitly set
556 *at @offset. This #AtkAttributeSet should be freed by a call to
557 *atk_attribute_set_free().
560 atk_text_get_run_attributes (AtkText *text,
566 gint local_start_offset, local_end_offset;
567 gint *real_start_offset, *real_end_offset;
569 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
572 real_start_offset = start_offset;
574 real_start_offset = &local_start_offset;
576 real_end_offset = end_offset;
578 real_end_offset = &local_end_offset;
583 iface = ATK_TEXT_GET_IFACE (text);
585 if (iface->get_run_attributes)
586 return (*(iface->get_run_attributes)) (text, offset, real_start_offset, real_end_offset);
592 *atk_text_get_default_attributes:
595 *Creates an #AtkAttributeSet which consists of the default values of
596 *attributes for the text. See the enum AtkTextAttribute for types of text
597 *attributes that can be returned. Note that other attributes may also be
600 *Returns: an #AtkAttributeSet which contains the default values of attributes.
601 *at @offset. This #AtkAttributeSet should be freed by a call to
602 *atk_attribute_set_free().
605 atk_text_get_default_attributes (AtkText *text)
609 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
611 iface = ATK_TEXT_GET_IFACE (text);
613 if (iface->get_default_attributes)
614 return (*(iface->get_default_attributes)) (text);
620 * atk_text_get_character_count:
623 * Gets the character count.
625 * Returns: the number of characters.
628 atk_text_get_character_count (AtkText *text)
632 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
634 iface = ATK_TEXT_GET_IFACE (text);
636 if (iface->get_character_count)
637 return (*(iface->get_character_count)) (text);
643 * atk_text_get_offset_at_point:
645 * @x: screen x-position of character
646 * @y: screen y-position of character
647 * @coords: specify whether coordinates are relative to the screen or
650 * Gets the offset of the character located at coordinates @x and @y. @x and @y
651 * are interpreted as being relative to the screen or this widget's window
652 * depending on @coords.
654 * Returns: the offset to the character which is located at
655 * the specified @x and @y coordinates.
658 atk_text_get_offset_at_point (AtkText *text,
665 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
667 iface = ATK_TEXT_GET_IFACE (text);
669 if (iface->get_offset_at_point)
670 return (*(iface->get_offset_at_point)) (text, x, y, coords);
676 * atk_text_get_n_selections:
679 * Gets the number of selected regions.
681 * Returns: The number of selected regions, or -1 if a failure
685 atk_text_get_n_selections (AtkText *text)
689 g_return_val_if_fail (ATK_IS_TEXT (text), -1);
691 iface = ATK_TEXT_GET_IFACE (text);
693 if (iface->get_n_selections)
694 return (*(iface->get_n_selections)) (text);
700 * atk_text_get_selection:
702 * @selection_num: The selection number. The selected regions are
703 * assigned numbers that correspond to how far the region is from the
704 * start of the text. The selected region closest to the beginning
705 * of the text region is assigned the number 0, etc. Note that adding,
706 * moving or deleting a selected region can change the numbering.
707 * @start_offset: passes back the start position of the selected region
708 * @end_offset: passes back the end position of the selected region
710 * Gets the text from the specified selection.
712 * Returns: the selected text.
715 atk_text_get_selection (AtkText *text,
721 gint local_start_offset, local_end_offset;
722 gint *real_start_offset, *real_end_offset;
724 g_return_val_if_fail (ATK_IS_TEXT (text), NULL);
727 real_start_offset = start_offset;
729 real_start_offset = &local_start_offset;
731 real_end_offset = end_offset;
733 real_end_offset = &local_end_offset;
735 iface = ATK_TEXT_GET_IFACE (text);
737 if (iface->get_selection)
739 return (*(iface->get_selection)) (text, selection_num,
740 real_start_offset, real_end_offset);
747 * atk_text_add_selection:
749 * @start_offset: the start position of the selected region
750 * @end_offset: the end position of the selected region
752 * Adds a selection bounded by the specified offsets.
754 * Returns: %TRUE if success, %FALSE otherwise
757 atk_text_add_selection (AtkText *text,
763 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
765 iface = ATK_TEXT_GET_IFACE (text);
767 if (iface->add_selection)
768 return (*(iface->add_selection)) (text, start_offset, end_offset);
774 * atk_text_remove_selection:
776 * @selection_num: The selection number. The selected regions are
777 * assigned numbers that correspond to how far the region is from the
778 * start of the text. The selected region closest to the beginning
779 * of the text region is assigned the number 0, etc. Note that adding,
780 * moving or deleting a selected region can change the numbering.
782 * Removes the specified selection.
784 * Returns: %TRUE if success, %FALSE otherwise
787 atk_text_remove_selection (AtkText *text,
792 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
794 iface = ATK_TEXT_GET_IFACE (text);
796 if (iface->remove_selection)
797 return (*(iface->remove_selection)) (text, selection_num);
803 * atk_text_set_selection:
805 * @selection_num: The selection number. The selected regions are
806 * assigned numbers that correspond to how far the region is from the
807 * start of the text. The selected region closest to the beginning
808 * of the text region is assigned the number 0, etc. Note that adding,
809 * moving or deleting a selected region can change the numbering.
810 * @start_offset: the new start position of the selection
811 * @end_offset: the new end position of the selection
813 * Changes the start and end offset of the specified selection.
815 * Returns: %TRUE if success, %FALSE otherwise
818 atk_text_set_selection (AtkText *text,
825 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
827 iface = ATK_TEXT_GET_IFACE (text);
829 if (iface->set_selection)
831 return (*(iface->set_selection)) (text, selection_num,
832 start_offset, end_offset);
839 * atk_text_set_caret_offset:
843 * Sets the caret (cursor) position to the specified @offset.
845 * Returns: %TRUE if success, %FALSE otherwise.
848 atk_text_set_caret_offset (AtkText *text,
853 g_return_val_if_fail (ATK_IS_TEXT (text), FALSE);
855 iface = ATK_TEXT_GET_IFACE (text);
857 if (iface->set_caret_offset)
859 return (*(iface->set_caret_offset)) (text, offset);
868 * atk_attribute_set_free:
869 * @attrib_set: The #AtkAttributeSet to free
871 * Frees the memory used by an #AtkAttributeSet, including all its
875 atk_attribute_set_free (AtkAttributeSet *attrib_set)
892 g_slist_free (attrib_set);
896 * atk_text_attribute_register:
897 * @name: a name string
899 * Associate @name with a new #AtkTextAttribute
901 * Returns: an #AtkTextAttribute associated with @name
904 atk_text_attribute_register (const gchar *name)
906 g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID);
908 if (!extra_attributes)
909 extra_attributes = g_ptr_array_new ();
911 g_ptr_array_add (extra_attributes, g_strdup (name));
912 return extra_attributes->len + ATK_TEXT_ATTR_LAST_DEFINED;
916 * atk_text_attribute_get_name:
917 * @attr: The #AtkTextAttribute whose name is required
919 * Gets the name corresponding to the #AtkTextAttribute
921 * Returns: a string containing the name; this string should not be freed
923 G_CONST_RETURN gchar*
924 atk_text_attribute_get_name (AtkTextAttribute attr)
926 GTypeClass *type_class;
930 type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE);
931 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
933 value = g_enum_get_value (G_ENUM_CLASS (type_class), attr);
937 name = value->value_nick;
941 if (extra_attributes)
945 n -= ATK_TEXT_ATTR_LAST_DEFINED + 1;
947 if (n < extra_attributes->len)
949 name = g_ptr_array_index (extra_attributes, n);
952 g_type_class_unref (type_class);
957 * atk_text_attribute_for_name:
958 * @name: a string which is the (non-localized) name of an ATK text attribute.
960 * Get the #AtkTextAttribute type corresponding to a text attribute name.
962 * Returns: the #AtkTextAttribute enumerated type corresponding to the specified
964 * or #ATK_TEXT_ATTRIBUTE_INVALID if no matching text attribute is found.
967 atk_text_attribute_for_name (const gchar *name)
969 GTypeClass *type_class;
971 AtkTextAttribute type = ATK_TEXT_ATTR_INVALID;
973 g_return_val_if_fail (name, ATK_TEXT_ATTR_INVALID);
975 type_class = g_type_class_ref (ATK_TYPE_TEXT_ATTRIBUTE);
976 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_TEXT_ATTR_INVALID);
978 value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
988 if (extra_attributes)
990 for (i = 0; i < extra_attributes->len; i++)
992 gchar *extra_attribute = (gchar *)g_ptr_array_index (extra_attributes, i);
994 g_return_val_if_fail (extra_attribute, ATK_TEXT_ATTR_INVALID);
996 if (strcmp (name, extra_attribute) == 0)
998 type = i + 1 + ATK_TEXT_ATTR_LAST_DEFINED;
1004 g_type_class_unref (type_class);
1011 * atk_text_attribute_get_value:
1012 * @attr: The #AtkTextAttribute for which a value is required
1013 * @index_: The index of the required value
1015 * Gets the value for the index of the #AtkTextAttribute
1017 * Returns: a string containing the value; this string should not be freed;
1018 * NULL is returned if there are no values maintained for the attr value.
1020 G_CONST_RETURN gchar*
1021 atk_text_attribute_get_value (AtkTextAttribute attr,
1026 case ATK_TEXT_ATTR_INVISIBLE:
1027 case ATK_TEXT_ATTR_EDITABLE:
1028 case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
1029 case ATK_TEXT_ATTR_STRIKETHROUGH:
1030 case ATK_TEXT_ATTR_BG_STIPPLE:
1031 case ATK_TEXT_ATTR_FG_STIPPLE:
1032 g_assert (index >= 0 && index < 2);
1034 case ATK_TEXT_ATTR_UNDERLINE:
1035 g_assert (index >= 0 && index < 4);
1036 return underline[index];
1037 case ATK_TEXT_ATTR_WRAP_MODE:
1038 g_assert (index >= 0 && index < 3);
1039 return wrap_mode[index];
1040 case ATK_TEXT_ATTR_DIRECTION:
1041 g_assert (index >= 0 && index < 3);
1042 return direction[index];
1043 case ATK_TEXT_ATTR_JUSTIFICATION:
1044 g_assert (index >= 0 && index < 3);
1045 return justification[index];
1046 case ATK_TEXT_ATTR_STRETCH:
1047 g_assert (index >= 0 && index < 9);
1048 return stretch[index];
1049 case ATK_TEXT_ATTR_VARIANT:
1050 g_assert (index >= 0 && index < 2);
1051 return variant[index];
1052 case ATK_TEXT_ATTR_STYLE:
1053 g_assert (index >= 0 && index < 3);
1054 return style[index];