1 /* GAIL - The GNOME Accessibility Implementation Library
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.
27 /* IMPORTANT!!! This source file does NOT contain the implementation
28 * code for AtkUtil - for that code, please see gail/gail.c.
33 * @Short_description: GailMisc is a set of utility functions which may be
34 * useful to implementors of Atk interfaces for custom widgets.
37 * GailMisc is a set of utility function which are used in the implemementation
38 * of Atk interfaces for GTK+ widgets. They may be useful to implementors of
39 * Atk interfaces for custom widgets.
44 * gail_misc_get_extents_from_pango_rectangle:
45 * @widget: The widget that contains the PangoLayout, that contains
47 * @char_rect: The #PangoRectangle from which to calculate extents
48 * @x_layout: The x-offset at which the widget displays the
49 * PangoLayout that contains the PangoRectangle, relative to @widget
50 * @y_layout: The y-offset at which the widget displays the
51 * PangoLayout that contains the PangoRectangle, relative to @widget
52 * @x: The x-position of the #PangoRectangle relative to @coords
53 * @y: The y-position of the #PangoRectangle relative to @coords
54 * @width: The width of the #PangoRectangle
55 * @height: The height of the #PangoRectangle
56 * @coords: An #AtkCoordType enumeration
58 * Gets the extents of @char_rect in device coordinates,
59 * relative to either top-level window or screen coordinates as
60 * specified by @coords.
63 gail_misc_get_extents_from_pango_rectangle (GtkWidget *widget,
64 PangoRectangle *char_rect,
73 gint x_window, y_window, x_toplevel, y_toplevel;
75 gail_misc_get_origins (widget, &x_window, &y_window,
76 &x_toplevel, &y_toplevel);
78 *x = (char_rect->x / PANGO_SCALE) + x_layout + x_window;
79 *y = (char_rect->y / PANGO_SCALE) + y_layout + y_window;
80 if (coords == ATK_XY_WINDOW)
85 else if (coords != ATK_XY_SCREEN)
93 *height = char_rect->height / PANGO_SCALE;
94 *width = char_rect->width / PANGO_SCALE;
100 * gail_misc_get_index_at_point_in_layout:
101 * @widget: A #GtkWidget
102 * @layout: The #PangoLayout from which to get the index at the
104 * @x_layout: The x-offset at which the widget displays the
105 * #PangoLayout, relative to @widget
106 * @y_layout: The y-offset at which the widget displays the
107 * #PangoLayout, relative to @widget
108 * @x: The x-coordinate relative to @coords at which to
109 * calculate the index
110 * @y: The y-coordinate relative to @coords at which to
111 * calculate the index
112 * @coords: An #AtkCoordType enumeration
114 * Gets the byte offset at the specified @x and @y in a #PangoLayout.
116 * Returns: the byte offset at the specified @x and @y in a
120 gail_misc_get_index_at_point_in_layout (GtkWidget *widget,
128 gint index, x_window, y_window, x_toplevel, y_toplevel;
132 gail_misc_get_origins (widget, &x_window, &y_window,
133 &x_toplevel, &y_toplevel);
134 x_temp = x - x_layout - x_window;
135 y_temp = y - y_layout - y_window;
136 if (coords == ATK_XY_WINDOW)
138 x_temp += x_toplevel;
139 y_temp += y_toplevel;
141 else if (coords != ATK_XY_SCREEN)
144 ret = pango_layout_xy_to_index (layout,
145 x_temp * PANGO_SCALE,
146 y_temp * PANGO_SCALE,
150 if (x_temp < 0 || y_temp < 0)
159 * gail_misc_add_attribute:
160 * @attrib_set: The #AtkAttributeSet to add the attribute to
161 * @attr: The AtkTextAttrribute which identifies the attribute to be added
162 * @value: The attribute value
164 * Creates an #AtkAttribute from @attr and @value, and adds it
167 * Returns: A pointer to the new #AtkAttributeSet.
170 gail_misc_add_attribute (AtkAttributeSet *attrib_set,
171 AtkTextAttribute attr,
174 AtkAttributeSet *return_set;
175 AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
176 at->name = g_strdup (atk_text_attribute_get_name (attr));
178 return_set = g_slist_prepend(attrib_set, at);
183 * gail_misc_layout_get_run_attributes:
184 * @attrib_set: The #AtkAttributeSet to add the attribute to
185 * @layout: The PangoLayout from which the attributes will be obtained
187 * @offset: The offset at which the attributes are required
188 * @start_offset: The start offset of the current run
189 * @end_offset: The end offset of the current run
191 * Adds the attributes for the run starting at offset to the specified
194 * Returns: A pointer to the #AtkAttributeSet.
197 gail_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set,
204 PangoAttrIterator *iter;
206 PangoAttrString *pango_string;
207 PangoAttrInt *pango_int;
208 PangoAttrColor *pango_color;
209 PangoAttrLanguage *pango_lang;
210 PangoAttrFloat *pango_float;
211 gint index, start_index, end_index;
212 gboolean is_next = TRUE;
216 len = g_utf8_strlen (text, -1);
217 /* Grab the attributes of the PangoLayout, if any */
218 if ((attr = pango_layout_get_attributes (layout)) == NULL)
224 iter = pango_attr_list_get_iterator (attr);
225 /* Get invariant range offsets */
226 /* If offset out of range, set offset in range */
232 index = g_utf8_offset_to_pointer (text, offset) - text;
233 pango_attr_iterator_range (iter, &start_index, &end_index);
236 if (index >= start_index && index < end_index)
238 *start_offset = g_utf8_pointer_to_offset (text,
240 if (end_index == G_MAXINT)
244 *end_offset = g_utf8_pointer_to_offset (text,
248 is_next = pango_attr_iterator_next (iter);
249 pango_attr_iterator_range (iter, &start_index, &end_index);
252 if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter,
253 PANGO_ATTR_FAMILY)) != NULL)
255 value = g_strdup_printf("%s", pango_string->value);
256 attrib_set = gail_misc_add_attribute (attrib_set,
257 ATK_TEXT_ATTR_FAMILY_NAME,
260 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
261 PANGO_ATTR_STYLE)) != NULL)
263 attrib_set = gail_misc_add_attribute (attrib_set,
265 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value)));
267 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
268 PANGO_ATTR_WEIGHT)) != NULL)
270 value = g_strdup_printf("%i", pango_int->value);
271 attrib_set = gail_misc_add_attribute (attrib_set,
272 ATK_TEXT_ATTR_WEIGHT,
275 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
276 PANGO_ATTR_VARIANT)) != NULL)
278 attrib_set = gail_misc_add_attribute (attrib_set,
279 ATK_TEXT_ATTR_VARIANT,
280 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value)));
282 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
283 PANGO_ATTR_STRETCH)) != NULL)
285 attrib_set = gail_misc_add_attribute (attrib_set,
286 ATK_TEXT_ATTR_STRETCH,
287 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value)));
289 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
290 PANGO_ATTR_SIZE)) != NULL)
292 value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE);
293 attrib_set = gail_misc_add_attribute (attrib_set,
297 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
298 PANGO_ATTR_UNDERLINE)) != NULL)
300 attrib_set = gail_misc_add_attribute (attrib_set,
301 ATK_TEXT_ATTR_UNDERLINE,
302 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value)));
304 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
305 PANGO_ATTR_STRIKETHROUGH)) != NULL)
307 attrib_set = gail_misc_add_attribute (attrib_set,
308 ATK_TEXT_ATTR_STRIKETHROUGH,
309 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value)));
311 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
312 PANGO_ATTR_RISE)) != NULL)
314 value = g_strdup_printf("%i", pango_int->value);
315 attrib_set = gail_misc_add_attribute (attrib_set,
319 if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter,
320 PANGO_ATTR_LANGUAGE)) != NULL)
322 value = g_strdup( pango_language_to_string( pango_lang->value));
323 attrib_set = gail_misc_add_attribute (attrib_set,
324 ATK_TEXT_ATTR_LANGUAGE,
327 if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter,
328 PANGO_ATTR_SCALE)) != NULL)
330 value = g_strdup_printf("%g", pango_float->value);
331 attrib_set = gail_misc_add_attribute (attrib_set,
335 if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
336 PANGO_ATTR_FOREGROUND)) != NULL)
338 value = g_strdup_printf ("%u,%u,%u",
339 pango_color->color.red,
340 pango_color->color.green,
341 pango_color->color.blue);
342 attrib_set = gail_misc_add_attribute (attrib_set,
343 ATK_TEXT_ATTR_FG_COLOR,
346 if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
347 PANGO_ATTR_BACKGROUND)) != NULL)
349 value = g_strdup_printf ("%u,%u,%u",
350 pango_color->color.red,
351 pango_color->color.green,
352 pango_color->color.blue);
353 attrib_set = gail_misc_add_attribute (attrib_set,
354 ATK_TEXT_ATTR_BG_COLOR,
357 pango_attr_iterator_destroy (iter);
362 * gail_misc_get_default_attributes:
363 * @attrib_set: The #AtkAttributeSet to add the attribute to
364 * @layout: The PangoLayout from which the attributes will be obtained
365 * @widget: The GtkWidget for which the default attributes are required.
367 * Adds the default attributes to the specified attribute set.
369 * Returns: A pointer to the #AtkAttributeSet.
372 gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
376 PangoContext *context;
377 GtkStyleContext *style_context;
383 attrib_set = gail_misc_add_attribute (attrib_set,
384 ATK_TEXT_ATTR_DIRECTION,
385 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
386 gtk_widget_get_direction (widget))));
388 context = pango_layout_get_context (layout);
391 PangoLanguage* language;
392 PangoFontDescription* font;
394 language = pango_context_get_language (context);
397 attrib_set = gail_misc_add_attribute (attrib_set,
398 ATK_TEXT_ATTR_LANGUAGE,
399 g_strdup (pango_language_to_string (language)));
401 font = pango_context_get_font_description (context);
404 attrib_set = gail_misc_add_attribute (attrib_set,
406 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE,
407 pango_font_description_get_style (font))));
408 attrib_set = gail_misc_add_attribute (attrib_set,
409 ATK_TEXT_ATTR_VARIANT,
410 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT,
411 pango_font_description_get_variant (font))));
412 attrib_set = gail_misc_add_attribute (attrib_set,
413 ATK_TEXT_ATTR_STRETCH,
414 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH,
415 pango_font_description_get_stretch (font))));
416 attrib_set = gail_misc_add_attribute (attrib_set,
417 ATK_TEXT_ATTR_FAMILY_NAME,
418 g_strdup (pango_font_description_get_family (font)));
419 attrib_set = gail_misc_add_attribute (attrib_set,
420 ATK_TEXT_ATTR_WEIGHT,
421 g_strdup_printf ("%d",
422 pango_font_description_get_weight (font)));
423 attrib_set = gail_misc_add_attribute (attrib_set,
425 g_strdup_printf ("%i",
426 pango_font_description_get_size (font) / PANGO_SCALE));
429 if (pango_layout_get_justify (layout))
435 PangoAlignment align;
437 align = pango_layout_get_alignment (layout);
438 if (align == PANGO_ALIGN_LEFT)
440 else if (align == PANGO_ALIGN_CENTER)
442 else /* if (align == PANGO_ALIGN_RIGHT) */
445 attrib_set = gail_misc_add_attribute (attrib_set,
446 ATK_TEXT_ATTR_JUSTIFICATION,
447 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION,
449 mode = pango_layout_get_wrap (layout);
450 if (mode == PANGO_WRAP_WORD)
452 else /* if (mode == PANGO_WRAP_CHAR) */
454 attrib_set = gail_misc_add_attribute (attrib_set,
455 ATK_TEXT_ATTR_WRAP_MODE,
456 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE,
459 style_context = gtk_widget_get_style_context (widget);
461 gtk_style_context_get_background_color (style_context, 0, &color);
462 value = g_strdup_printf ("%u,%u,%u",
463 (guint) ceil (color.red * 65536 - color.red),
464 (guint) ceil (color.green * 65536 - color.green),
465 (guint) ceil (color.blue * 65536 - color.blue));
466 attrib_set = gail_misc_add_attribute (attrib_set,
467 ATK_TEXT_ATTR_BG_COLOR,
470 gtk_style_context_get_color (style_context, 0, &color);
471 value = g_strdup_printf ("%u,%u,%u",
472 (guint) ceil (color.red * 65536 - color.red),
473 (guint) ceil (color.green * 65536 - color.green),
474 (guint) ceil (color.blue * 65536 - color.blue));
475 attrib_set = gail_misc_add_attribute (attrib_set,
476 ATK_TEXT_ATTR_FG_COLOR,
479 attrib_set = gail_misc_add_attribute (attrib_set,
480 ATK_TEXT_ATTR_FG_STIPPLE,
481 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_FG_STIPPLE,
483 attrib_set = gail_misc_add_attribute (attrib_set,
484 ATK_TEXT_ATTR_BG_STIPPLE,
485 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_STIPPLE,
487 attrib_set = gail_misc_add_attribute (attrib_set,
488 ATK_TEXT_ATTR_STRIKETHROUGH,
489 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH,
491 attrib_set = gail_misc_add_attribute (attrib_set,
492 ATK_TEXT_ATTR_UNDERLINE,
493 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE,
495 attrib_set = gail_misc_add_attribute (attrib_set,
497 g_strdup_printf ("%i", 0));
498 attrib_set = gail_misc_add_attribute (attrib_set,
500 g_strdup_printf ("%g", 1.0));
501 attrib_set = gail_misc_add_attribute (attrib_set,
502 ATK_TEXT_ATTR_BG_FULL_HEIGHT,
503 g_strdup_printf ("%i", 0));
504 attrib_set = gail_misc_add_attribute (attrib_set,
505 ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP,
506 g_strdup_printf ("%i", 0));
507 attrib_set = gail_misc_add_attribute (attrib_set,
508 ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
509 g_strdup_printf ("%i", 0));
510 attrib_set = gail_misc_add_attribute (attrib_set,
511 ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
512 g_strdup_printf ("%i", 0));
513 attrib_set = gail_misc_add_attribute (attrib_set,
514 ATK_TEXT_ATTR_EDITABLE,
515 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE,
517 attrib_set = gail_misc_add_attribute (attrib_set,
518 ATK_TEXT_ATTR_INVISIBLE,
519 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE,
521 attrib_set = gail_misc_add_attribute (attrib_set,
522 ATK_TEXT_ATTR_INDENT,
523 g_strdup_printf ("%i", 0));
524 attrib_set = gail_misc_add_attribute (attrib_set,
525 ATK_TEXT_ATTR_RIGHT_MARGIN,
526 g_strdup_printf ("%i", 0));
527 attrib_set = gail_misc_add_attribute (attrib_set,
528 ATK_TEXT_ATTR_LEFT_MARGIN,
529 g_strdup_printf ("%i", 0));
534 * gail_misc_get_origins:
535 * @widget: a #GtkWidget
536 * @x_window: the x-origin of the widget->window
537 * @y_window: the y-origin of the widget->window
538 * @x_toplevel: the x-origin of the toplevel window for widget->window
539 * @y_toplevel: the y-origin of the toplevel window for widget->window
541 * Gets the origin of the widget window, and the origin of the
542 * widgets top-level window.
545 gail_misc_get_origins (GtkWidget *widget,
553 if (GTK_IS_TREE_VIEW (widget))
554 window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
556 window = gtk_widget_get_window (widget);
558 gdk_window_get_origin (window, x_window, y_window);
559 window = gdk_window_get_toplevel (gtk_widget_get_window (widget));
560 gdk_window_get_origin (window, x_toplevel, y_toplevel);
564 * gail_misc_add_to_attr_set:
565 * @attrib_set: An #AtkAttributeSet
566 * @attrs: The #GtkTextAttributes containing the attribute value
567 * @attr: The #AtkTextAttribute to be added
569 * Gets the value for the AtkTextAttribute from the GtkTextAttributes
570 * and adds it to the AttributeSet.
572 * Returns: A pointer to the updated #AtkAttributeSet.
575 gail_misc_add_to_attr_set (AtkAttributeSet *attrib_set,
576 GtkTextAttributes *attrs,
577 AtkTextAttribute attr)
583 case ATK_TEXT_ATTR_LEFT_MARGIN:
584 value = g_strdup_printf ("%i", attrs->left_margin);
586 case ATK_TEXT_ATTR_RIGHT_MARGIN:
587 value = g_strdup_printf ("%i", attrs->right_margin);
589 case ATK_TEXT_ATTR_INDENT:
590 value = g_strdup_printf ("%i", attrs->indent);
592 case ATK_TEXT_ATTR_INVISIBLE:
593 value = g_strdup (atk_text_attribute_get_value (attr, attrs->invisible));
595 case ATK_TEXT_ATTR_EDITABLE:
596 value = g_strdup (atk_text_attribute_get_value (attr, attrs->editable));
598 case ATK_TEXT_ATTR_PIXELS_ABOVE_LINES:
599 value = g_strdup_printf ("%i", attrs->pixels_above_lines);
601 case ATK_TEXT_ATTR_PIXELS_BELOW_LINES:
602 value = g_strdup_printf ("%i", attrs->pixels_below_lines);
604 case ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP:
605 value = g_strdup_printf ("%i", attrs->pixels_inside_wrap);
607 case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
608 value = g_strdup (atk_text_attribute_get_value (attr, attrs->bg_full_height));
610 case ATK_TEXT_ATTR_RISE:
611 value = g_strdup_printf ("%i", attrs->appearance.rise);
613 case ATK_TEXT_ATTR_UNDERLINE:
614 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.underline));
616 case ATK_TEXT_ATTR_STRIKETHROUGH:
617 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.strikethrough));
619 case ATK_TEXT_ATTR_SIZE:
620 value = g_strdup_printf ("%i",
621 pango_font_description_get_size (attrs->font) / PANGO_SCALE);
623 case ATK_TEXT_ATTR_SCALE:
624 value = g_strdup_printf ("%g", attrs->font_scale);
626 case ATK_TEXT_ATTR_WEIGHT:
627 value = g_strdup_printf ("%d",
628 pango_font_description_get_weight (attrs->font));
630 case ATK_TEXT_ATTR_LANGUAGE:
631 value = g_strdup ((gchar *)(attrs->language));
633 case ATK_TEXT_ATTR_FAMILY_NAME:
634 value = g_strdup (pango_font_description_get_family (attrs->font));
636 case ATK_TEXT_ATTR_BG_COLOR:
637 value = g_strdup_printf ("%u,%u,%u",
638 attrs->appearance.bg_color.red,
639 attrs->appearance.bg_color.green,
640 attrs->appearance.bg_color.blue);
642 case ATK_TEXT_ATTR_FG_COLOR:
643 value = g_strdup_printf ("%u,%u,%u",
644 attrs->appearance.fg_color.red,
645 attrs->appearance.fg_color.green,
646 attrs->appearance.fg_color.blue);
648 case ATK_TEXT_ATTR_WRAP_MODE:
649 value = g_strdup (atk_text_attribute_get_value (attr, attrs->wrap_mode));
651 case ATK_TEXT_ATTR_DIRECTION:
652 value = g_strdup (atk_text_attribute_get_value (attr, attrs->direction));
654 case ATK_TEXT_ATTR_JUSTIFICATION:
655 value = g_strdup (atk_text_attribute_get_value (attr, attrs->justification));
657 case ATK_TEXT_ATTR_STRETCH:
658 value = g_strdup (atk_text_attribute_get_value (attr,
659 pango_font_description_get_stretch (attrs->font)));
661 case ATK_TEXT_ATTR_VARIANT:
662 value = g_strdup (atk_text_attribute_get_value (attr,
663 pango_font_description_get_variant (attrs->font)));
665 case ATK_TEXT_ATTR_STYLE:
666 value = g_strdup (atk_text_attribute_get_value (attr,
667 pango_font_description_get_style (attrs->font)));
673 return gail_misc_add_attribute (attrib_set, attr, value);
677 * gail_misc_buffer_get_run_attributes:
678 * @buffer: The #GtkTextBuffer for which the attributes will be obtained
679 * @offset: The offset at which the attributes are required
680 * @start_offset: The start offset of the current run
681 * @end_offset: The end offset of the current run
683 * Creates an AtkAttributeSet which contains the attributes for the
684 * run starting at offset.
686 * Returns: A pointer to the #AtkAttributeSet.
689 gail_misc_buffer_get_run_attributes (GtkTextBuffer *buffer,
695 AtkAttributeSet *attrib_set = NULL;
697 GSList *tags, *temp_tags;
699 gboolean val_set = FALSE;
701 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
703 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
704 *end_offset = gtk_text_iter_get_offset (&iter);
706 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
707 *start_offset = gtk_text_iter_get_offset (&iter);
709 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
711 tags = gtk_text_iter_get_tags (&iter);
712 tags = g_slist_reverse (tags);
715 while (temp_tags && !val_set)
717 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
719 g_object_get (tag, "style-set", &val_set, NULL);
725 g_object_get (tag, "style", &style, NULL);
726 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, style));
727 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STYLE, value);
729 temp_tags = temp_tags->next;
734 while (temp_tags && !val_set)
736 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
738 g_object_get (tag, "variant-set", &val_set, NULL);
741 PangoVariant variant;
744 g_object_get (tag, "variant", &variant, NULL);
745 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, variant));
746 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_VARIANT, value);
748 temp_tags = temp_tags->next;
753 while (temp_tags && !val_set)
755 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
757 g_object_get (tag, "stretch-set", &val_set, NULL);
760 PangoStretch stretch;
763 g_object_get (tag, "stretch", &stretch, NULL);
764 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, stretch));
765 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRETCH, value);
767 temp_tags = temp_tags->next;
772 while (temp_tags && !val_set)
774 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
776 g_object_get (tag, "justification-set", &val_set, NULL);
779 GtkJustification justification;
782 g_object_get (tag, "justification", &justification, NULL);
783 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justification));
784 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_JUSTIFICATION, value);
786 temp_tags = temp_tags->next;
791 while (temp_tags && !val_set)
793 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
794 GtkTextDirection direction;
796 g_object_get (tag, "direction", &direction, NULL);
798 if (direction != GTK_TEXT_DIR_NONE)
802 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, direction));
803 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_DIRECTION, value);
805 temp_tags = temp_tags->next;
810 while (temp_tags && !val_set)
812 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
814 g_object_get (tag, "wrap-mode-set", &val_set, NULL);
817 GtkWrapMode wrap_mode;
820 g_object_get (tag, "wrap-mode", &wrap_mode, NULL);
821 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE, wrap_mode));
822 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WRAP_MODE, value);
824 temp_tags = temp_tags->next;
829 while (temp_tags && !val_set)
831 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
833 g_object_get (tag, "foreground-set", &val_set, NULL);
839 g_object_get (tag, "foreground-gdk", &c, NULL);
840 value = g_strdup_printf ("%u,%u,%u", c.red, c.green, c.blue);
841 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FG_COLOR, value);
843 temp_tags = temp_tags->next;
848 while (temp_tags && !val_set)
850 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
852 g_object_get (tag, "background-set", &val_set, NULL);
858 g_object_get (tag, "background-gdk", &c, NULL);
859 value = g_strdup_printf ("%u,%u,%u", c.red, c.green, c.blue);
860 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_COLOR, value);
862 temp_tags = temp_tags->next;
867 while (temp_tags && !val_set)
869 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
871 g_object_get (tag, "family-set", &val_set, NULL);
876 g_object_get (tag, "family", &value, NULL);
877 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_FAMILY_NAME, value);
879 temp_tags = temp_tags->next;
884 while (temp_tags && !val_set)
886 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
888 g_object_get (tag, "language-set", &val_set, NULL);
893 g_object_get (tag, "language", &value, NULL);
894 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LANGUAGE, value);
896 temp_tags = temp_tags->next;
901 while (temp_tags && !val_set)
903 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
905 g_object_get (tag, "weight-set", &val_set, NULL);
912 g_object_get (tag, "weight", &weight, NULL);
913 value = g_strdup_printf ("%d", weight);
914 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_WEIGHT, value);
916 temp_tags = temp_tags->next;
922 * scale is special as the scale is the product of all scale values
928 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
931 g_object_get (tag, "scale-set", &scale_set, NULL);
936 g_object_get (tag, "scale", &font_scale, NULL);
940 temp_tags = temp_tags->next;
944 at = g_malloc(sizeof(AtkAttribute));
945 at->name = g_strdup(atk_text_attribute_get_name (ATK_TEXT_ATTR_SCALE));
946 at->value = g_strdup_printf("%g", scale);
947 attrib_set = g_slist_prepend(attrib_set, at);
952 while (temp_tags && !val_set)
954 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
956 g_object_get (tag, "size-set", &val_set, NULL);
961 g_object_get (tag, "size", &size, NULL);
962 value = g_strdup_printf ("%i", size);
963 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_SIZE, value);
965 temp_tags = temp_tags->next;
970 while (temp_tags && !val_set)
972 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
974 g_object_get (tag, "strikethrough-set", &val_set, NULL);
977 gboolean strikethrough;
979 g_object_get (tag, "strikethrough", &strikethrough, NULL);
980 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, strikethrough));
981 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_STRIKETHROUGH, value);
983 temp_tags = temp_tags->next;
988 while (temp_tags && !val_set)
990 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
992 g_object_get (tag, "underline-set", &val_set, NULL);
995 PangoUnderline underline;
997 g_object_get (tag, "underline", &underline, NULL);
998 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, underline));
999 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_UNDERLINE, value);
1001 temp_tags = temp_tags->next;
1006 while (temp_tags && !val_set)
1008 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1010 g_object_get (tag, "rise-set", &val_set, NULL);
1015 g_object_get (tag, "rise", &rise, NULL);
1016 value = g_strdup_printf ("%i", rise);
1017 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RISE, value);
1019 temp_tags = temp_tags->next;
1024 while (temp_tags && !val_set)
1026 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1028 g_object_get (tag, "background-full-height-set", &val_set, NULL);
1031 gboolean bg_full_height;
1033 g_object_get (tag, "background-full-height", &bg_full_height, NULL);
1034 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_FULL_HEIGHT, bg_full_height));
1035 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_BG_FULL_HEIGHT, value);
1037 temp_tags = temp_tags->next;
1042 while (temp_tags && !val_set)
1044 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1046 g_object_get (tag, "pixels-inside-wrap-set", &val_set, NULL);
1051 g_object_get (tag, "pixels-inside-wrap", &pixels, NULL);
1052 value = g_strdup_printf ("%i", pixels);
1053 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP, value);
1055 temp_tags = temp_tags->next;
1060 while (temp_tags && !val_set)
1062 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1064 g_object_get (tag, "pixels-below-lines-set", &val_set, NULL);
1069 g_object_get (tag, "pixels-below-lines", &pixels, NULL);
1070 value = g_strdup_printf ("%i", pixels);
1071 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_BELOW_LINES, value);
1073 temp_tags = temp_tags->next;
1078 while (temp_tags && !val_set)
1080 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1082 g_object_get (tag, "pixels-above-lines-set", &val_set, NULL);
1087 g_object_get (tag, "pixels-above-lines", &pixels, NULL);
1088 value = g_strdup_printf ("%i", pixels);
1089 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_PIXELS_ABOVE_LINES, value);
1091 temp_tags = temp_tags->next;
1096 while (temp_tags && !val_set)
1098 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1100 g_object_get (tag, "editable-set", &val_set, NULL);
1105 g_object_get (tag, "editable", &editable, NULL);
1106 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE, editable));
1107 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_EDITABLE, value);
1109 temp_tags = temp_tags->next;
1114 while (temp_tags && !val_set)
1116 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1118 g_object_get (tag, "invisible-set", &val_set, NULL);
1123 g_object_get (tag, "invisible", &invisible, NULL);
1124 value = g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE, invisible));
1125 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INVISIBLE, value);
1127 temp_tags = temp_tags->next;
1132 while (temp_tags && !val_set)
1134 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1136 g_object_get (tag, "indent-set", &val_set, NULL);
1141 g_object_get (tag, "indent", &indent, NULL);
1142 value = g_strdup_printf ("%i", indent);
1143 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_INDENT, value);
1145 temp_tags = temp_tags->next;
1150 while (temp_tags && !val_set)
1152 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1154 g_object_get (tag, "right-margin-set", &val_set, NULL);
1159 g_object_get (tag, "right-margin", &margin, NULL);
1160 value = g_strdup_printf ("%i", margin);
1161 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_RIGHT_MARGIN, value);
1163 temp_tags = temp_tags->next;
1168 while (temp_tags && !val_set)
1170 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1172 g_object_get (tag, "left-margin-set", &val_set, NULL);
1177 g_object_get (tag, "left-margin", &margin, NULL);
1178 value = g_strdup_printf ("%i", margin);
1179 gail_misc_add_attribute (attrib_set, ATK_TEXT_ATTR_LEFT_MARGIN, value);
1181 temp_tags = temp_tags->next;
1185 g_slist_free (tags);