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.
26 /* IMPORTANT!!! This source file does NOT contain the implementation
27 * code for AtkUtil - for that code, please see gail/gail.c.
32 * @Short_description: GailMisc is a set of utility functions which may be
33 * useful to implementors of Atk interfaces for custom widgets.
36 * GailMisc is a set of utility function which are used in the implemementation
37 * of Atk interfaces for GTK+ widgets. They may be useful to implementors of
38 * Atk interfaces for custom widgets.
43 * gail_misc_get_extents_from_pango_rectangle:
44 * @widget: The widget that contains the PangoLayout, that contains
46 * @char_rect: The #PangoRectangle from which to calculate extents
47 * @x_layout: The x-offset at which the widget displays the
48 * PangoLayout that contains the PangoRectangle, relative to @widget
49 * @y_layout: The y-offset at which the widget displays the
50 * PangoLayout that contains the PangoRectangle, relative to @widget
51 * @x: The x-position of the #PangoRectangle relative to @coords
52 * @y: The y-position of the #PangoRectangle relative to @coords
53 * @width: The width of the #PangoRectangle
54 * @height: The height of the #PangoRectangle
55 * @coords: An #AtkCoordType enumeration
57 * Gets the extents of @char_rect in device coordinates,
58 * relative to either top-level window or screen coordinates as
59 * specified by @coords.
62 gail_misc_get_extents_from_pango_rectangle (GtkWidget *widget,
63 PangoRectangle *char_rect,
72 gint x_window, y_window, x_toplevel, y_toplevel;
74 gail_misc_get_origins (widget, &x_window, &y_window,
75 &x_toplevel, &y_toplevel);
77 *x = (char_rect->x / PANGO_SCALE) + x_layout + x_window;
78 *y = (char_rect->y / PANGO_SCALE) + y_layout + y_window;
79 if (coords == ATK_XY_WINDOW)
84 else if (coords != ATK_XY_SCREEN)
92 *height = char_rect->height / PANGO_SCALE;
93 *width = char_rect->width / PANGO_SCALE;
99 * gail_misc_get_index_at_point_in_layout:
100 * @widget: A #GtkWidget
101 * @layout: The #PangoLayout from which to get the index at the
103 * @x_layout: The x-offset at which the widget displays the
104 * #PangoLayout, relative to @widget
105 * @y_layout: The y-offset at which the widget displays the
106 * #PangoLayout, relative to @widget
107 * @x: The x-coordinate relative to @coords at which to
108 * calculate the index
109 * @y: The y-coordinate relative to @coords at which to
110 * calculate the index
111 * @coords: An #AtkCoordType enumeration
113 * Gets the byte offset at the specified @x and @y in a #PangoLayout.
115 * Returns: the byte offset at the specified @x and @y in a
119 gail_misc_get_index_at_point_in_layout (GtkWidget *widget,
127 gint index, x_window, y_window, x_toplevel, y_toplevel;
131 gail_misc_get_origins (widget, &x_window, &y_window,
132 &x_toplevel, &y_toplevel);
133 x_temp = x - x_layout - x_window;
134 y_temp = y - y_layout - y_window;
135 if (coords == ATK_XY_WINDOW)
137 x_temp += x_toplevel;
138 y_temp += y_toplevel;
140 else if (coords != ATK_XY_SCREEN)
143 ret = pango_layout_xy_to_index (layout,
144 x_temp * PANGO_SCALE,
145 y_temp * PANGO_SCALE,
149 if (x_temp < 0 || y_temp < 0)
158 * gail_misc_add_attribute:
159 * @attrib_set: The #AtkAttributeSet to add the attribute to
160 * @attr: The AtkTextAttrribute which identifies the attribute to be added
161 * @value: The attribute value
163 * Creates an #AtkAttribute from @attr and @value, and adds it
166 * Returns: A pointer to the new #AtkAttributeSet.
169 gail_misc_add_attribute (AtkAttributeSet *attrib_set,
170 AtkTextAttribute attr,
173 AtkAttributeSet *return_set;
174 AtkAttribute *at = g_malloc (sizeof (AtkAttribute));
175 at->name = g_strdup (atk_text_attribute_get_name (attr));
177 return_set = g_slist_prepend(attrib_set, at);
182 * gail_misc_layout_get_run_attributes:
183 * @attrib_set: The #AtkAttributeSet to add the attribute to
184 * @layout: The PangoLayout from which the attributes will be obtained
186 * @offset: The offset at which the attributes are required
187 * @start_offset: The start offset of the current run
188 * @end_offset: The end offset of the current run
190 * Adds the attributes for the run starting at offset to the specified
193 * Returns: A pointer to the #AtkAttributeSet.
196 gail_misc_layout_get_run_attributes (AtkAttributeSet *attrib_set,
203 PangoAttrIterator *iter;
205 PangoAttrString *pango_string;
206 PangoAttrInt *pango_int;
207 PangoAttrColor *pango_color;
208 PangoAttrLanguage *pango_lang;
209 PangoAttrFloat *pango_float;
210 gint index, start_index, end_index;
211 gboolean is_next = TRUE;
215 len = g_utf8_strlen (text, -1);
216 /* Grab the attributes of the PangoLayout, if any */
217 if ((attr = pango_layout_get_attributes (layout)) == NULL)
223 iter = pango_attr_list_get_iterator (attr);
224 /* Get invariant range offsets */
225 /* If offset out of range, set offset in range */
231 index = g_utf8_offset_to_pointer (text, offset) - text;
232 pango_attr_iterator_range (iter, &start_index, &end_index);
235 if (index >= start_index && index < end_index)
237 *start_offset = g_utf8_pointer_to_offset (text,
239 if (end_index == G_MAXINT)
243 *end_offset = g_utf8_pointer_to_offset (text,
247 is_next = pango_attr_iterator_next (iter);
248 pango_attr_iterator_range (iter, &start_index, &end_index);
251 if ((pango_string = (PangoAttrString*) pango_attr_iterator_get (iter,
252 PANGO_ATTR_FAMILY)) != NULL)
254 value = g_strdup_printf("%s", pango_string->value);
255 attrib_set = gail_misc_add_attribute (attrib_set,
256 ATK_TEXT_ATTR_FAMILY_NAME,
259 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
260 PANGO_ATTR_STYLE)) != NULL)
262 attrib_set = gail_misc_add_attribute (attrib_set,
264 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE, pango_int->value)));
266 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
267 PANGO_ATTR_WEIGHT)) != NULL)
269 value = g_strdup_printf("%i", pango_int->value);
270 attrib_set = gail_misc_add_attribute (attrib_set,
271 ATK_TEXT_ATTR_WEIGHT,
274 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
275 PANGO_ATTR_VARIANT)) != NULL)
277 attrib_set = gail_misc_add_attribute (attrib_set,
278 ATK_TEXT_ATTR_VARIANT,
279 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT, pango_int->value)));
281 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
282 PANGO_ATTR_STRETCH)) != NULL)
284 attrib_set = gail_misc_add_attribute (attrib_set,
285 ATK_TEXT_ATTR_STRETCH,
286 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH, pango_int->value)));
288 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
289 PANGO_ATTR_SIZE)) != NULL)
291 value = g_strdup_printf("%i", pango_int->value / PANGO_SCALE);
292 attrib_set = gail_misc_add_attribute (attrib_set,
296 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
297 PANGO_ATTR_UNDERLINE)) != NULL)
299 attrib_set = gail_misc_add_attribute (attrib_set,
300 ATK_TEXT_ATTR_UNDERLINE,
301 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE, pango_int->value)));
303 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
304 PANGO_ATTR_STRIKETHROUGH)) != NULL)
306 attrib_set = gail_misc_add_attribute (attrib_set,
307 ATK_TEXT_ATTR_STRIKETHROUGH,
308 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH, pango_int->value)));
310 if ((pango_int = (PangoAttrInt*) pango_attr_iterator_get (iter,
311 PANGO_ATTR_RISE)) != NULL)
313 value = g_strdup_printf("%i", pango_int->value);
314 attrib_set = gail_misc_add_attribute (attrib_set,
318 if ((pango_lang = (PangoAttrLanguage*) pango_attr_iterator_get (iter,
319 PANGO_ATTR_LANGUAGE)) != NULL)
321 value = g_strdup( pango_language_to_string( pango_lang->value));
322 attrib_set = gail_misc_add_attribute (attrib_set,
323 ATK_TEXT_ATTR_LANGUAGE,
326 if ((pango_float = (PangoAttrFloat*) pango_attr_iterator_get (iter,
327 PANGO_ATTR_SCALE)) != NULL)
329 value = g_strdup_printf("%g", pango_float->value);
330 attrib_set = gail_misc_add_attribute (attrib_set,
334 if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
335 PANGO_ATTR_FOREGROUND)) != NULL)
337 value = g_strdup_printf ("%u,%u,%u",
338 pango_color->color.red,
339 pango_color->color.green,
340 pango_color->color.blue);
341 attrib_set = gail_misc_add_attribute (attrib_set,
342 ATK_TEXT_ATTR_FG_COLOR,
345 if ((pango_color = (PangoAttrColor*) pango_attr_iterator_get (iter,
346 PANGO_ATTR_BACKGROUND)) != NULL)
348 value = g_strdup_printf ("%u,%u,%u",
349 pango_color->color.red,
350 pango_color->color.green,
351 pango_color->color.blue);
352 attrib_set = gail_misc_add_attribute (attrib_set,
353 ATK_TEXT_ATTR_BG_COLOR,
356 pango_attr_iterator_destroy (iter);
361 * gail_misc_get_default_attributes:
362 * @attrib_set: The #AtkAttributeSet to add the attribute to
363 * @layout: The PangoLayout from which the attributes will be obtained
364 * @widget: The GtkWidget for which the default attributes are required.
366 * Adds the default attributes to the specified attribute set.
368 * Returns: A pointer to the #AtkAttributeSet.
371 gail_misc_get_default_attributes (AtkAttributeSet *attrib_set,
375 PangoContext *context;
376 GtkStyle *style_value;
380 attrib_set = gail_misc_add_attribute (attrib_set,
381 ATK_TEXT_ATTR_DIRECTION,
382 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION,
383 gtk_widget_get_direction (widget))));
385 context = pango_layout_get_context (layout);
388 PangoLanguage* language;
389 PangoFontDescription* font;
391 language = pango_context_get_language (context);
394 attrib_set = gail_misc_add_attribute (attrib_set,
395 ATK_TEXT_ATTR_LANGUAGE,
396 g_strdup (pango_language_to_string (language)));
398 font = pango_context_get_font_description (context);
401 attrib_set = gail_misc_add_attribute (attrib_set,
403 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STYLE,
404 pango_font_description_get_style (font))));
405 attrib_set = gail_misc_add_attribute (attrib_set,
406 ATK_TEXT_ATTR_VARIANT,
407 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_VARIANT,
408 pango_font_description_get_variant (font))));
409 attrib_set = gail_misc_add_attribute (attrib_set,
410 ATK_TEXT_ATTR_STRETCH,
411 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRETCH,
412 pango_font_description_get_stretch (font))));
413 attrib_set = gail_misc_add_attribute (attrib_set,
414 ATK_TEXT_ATTR_FAMILY_NAME,
415 g_strdup (pango_font_description_get_family (font)));
416 attrib_set = gail_misc_add_attribute (attrib_set,
417 ATK_TEXT_ATTR_WEIGHT,
418 g_strdup_printf ("%d",
419 pango_font_description_get_weight (font)));
420 attrib_set = gail_misc_add_attribute (attrib_set,
422 g_strdup_printf ("%i",
423 pango_font_description_get_size (font) / PANGO_SCALE));
426 if (pango_layout_get_justify (layout))
432 PangoAlignment align;
434 align = pango_layout_get_alignment (layout);
435 if (align == PANGO_ALIGN_LEFT)
437 else if (align == PANGO_ALIGN_CENTER)
439 else /* if (align == PANGO_ALIGN_RIGHT) */
442 attrib_set = gail_misc_add_attribute (attrib_set,
443 ATK_TEXT_ATTR_JUSTIFICATION,
444 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION,
446 mode = pango_layout_get_wrap (layout);
447 if (mode == PANGO_WRAP_WORD)
449 else /* if (mode == PANGO_WRAP_CHAR) */
451 attrib_set = gail_misc_add_attribute (attrib_set,
452 ATK_TEXT_ATTR_WRAP_MODE,
453 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_WRAP_MODE,
456 style_value = gtk_widget_get_style (widget);
462 color = style_value->base[GTK_STATE_NORMAL];
463 value = g_strdup_printf ("%u,%u,%u",
464 color.red, color.green, color.blue);
465 attrib_set = gail_misc_add_attribute (attrib_set,
466 ATK_TEXT_ATTR_BG_COLOR,
468 color = style_value->text[GTK_STATE_NORMAL];
469 value = g_strdup_printf ("%u,%u,%u",
470 color.red, color.green, color.blue);
471 attrib_set = gail_misc_add_attribute (attrib_set,
472 ATK_TEXT_ATTR_FG_COLOR,
475 attrib_set = gail_misc_add_attribute (attrib_set,
476 ATK_TEXT_ATTR_FG_STIPPLE,
477 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_FG_STIPPLE,
479 attrib_set = gail_misc_add_attribute (attrib_set,
480 ATK_TEXT_ATTR_BG_STIPPLE,
481 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_BG_STIPPLE,
483 attrib_set = gail_misc_add_attribute (attrib_set,
484 ATK_TEXT_ATTR_STRIKETHROUGH,
485 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_STRIKETHROUGH,
487 attrib_set = gail_misc_add_attribute (attrib_set,
488 ATK_TEXT_ATTR_UNDERLINE,
489 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_UNDERLINE,
491 attrib_set = gail_misc_add_attribute (attrib_set,
493 g_strdup_printf ("%i", 0));
494 attrib_set = gail_misc_add_attribute (attrib_set,
496 g_strdup_printf ("%g", 1.0));
497 attrib_set = gail_misc_add_attribute (attrib_set,
498 ATK_TEXT_ATTR_BG_FULL_HEIGHT,
499 g_strdup_printf ("%i", 0));
500 attrib_set = gail_misc_add_attribute (attrib_set,
501 ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP,
502 g_strdup_printf ("%i", 0));
503 attrib_set = gail_misc_add_attribute (attrib_set,
504 ATK_TEXT_ATTR_PIXELS_BELOW_LINES,
505 g_strdup_printf ("%i", 0));
506 attrib_set = gail_misc_add_attribute (attrib_set,
507 ATK_TEXT_ATTR_PIXELS_ABOVE_LINES,
508 g_strdup_printf ("%i", 0));
509 attrib_set = gail_misc_add_attribute (attrib_set,
510 ATK_TEXT_ATTR_EDITABLE,
511 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_EDITABLE,
513 attrib_set = gail_misc_add_attribute (attrib_set,
514 ATK_TEXT_ATTR_INVISIBLE,
515 g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_INVISIBLE,
517 attrib_set = gail_misc_add_attribute (attrib_set,
518 ATK_TEXT_ATTR_INDENT,
519 g_strdup_printf ("%i", 0));
520 attrib_set = gail_misc_add_attribute (attrib_set,
521 ATK_TEXT_ATTR_RIGHT_MARGIN,
522 g_strdup_printf ("%i", 0));
523 attrib_set = gail_misc_add_attribute (attrib_set,
524 ATK_TEXT_ATTR_LEFT_MARGIN,
525 g_strdup_printf ("%i", 0));
530 * gail_misc_get_origins:
531 * @widget: a #GtkWidget
532 * @x_window: the x-origin of the widget->window
533 * @y_window: the y-origin of the widget->window
534 * @x_toplevel: the x-origin of the toplevel window for widget->window
535 * @y_toplevel: the y-origin of the toplevel window for widget->window
537 * Gets the origin of the widget window, and the origin of the
538 * widgets top-level window.
541 gail_misc_get_origins (GtkWidget *widget,
549 if (GTK_IS_TREE_VIEW (widget))
550 window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
552 window = widget->window;
553 gdk_window_get_origin (window, x_window, y_window);
554 window = gdk_window_get_toplevel (widget->window);
555 gdk_window_get_origin (window, x_toplevel, y_toplevel);
559 * gail_misc_add_to_attr_set:
560 * @attrib_set: An #AtkAttributeSet
561 * @attrs: The #GtkTextAttributes containing the attribute value
562 * @attr: The #AtkTextAttribute to be added
564 * Gets the value for the AtkTextAttribute from the GtkTextAttributes
565 * and adds it to the AttributeSet.
567 * Returns: A pointer to the updated #AtkAttributeSet.
570 gail_misc_add_to_attr_set (AtkAttributeSet *attrib_set,
571 GtkTextAttributes *attrs,
572 AtkTextAttribute attr)
578 case ATK_TEXT_ATTR_LEFT_MARGIN:
579 value = g_strdup_printf ("%i", attrs->left_margin);
581 case ATK_TEXT_ATTR_RIGHT_MARGIN:
582 value = g_strdup_printf ("%i", attrs->right_margin);
584 case ATK_TEXT_ATTR_INDENT:
585 value = g_strdup_printf ("%i", attrs->indent);
587 case ATK_TEXT_ATTR_INVISIBLE:
588 value = g_strdup (atk_text_attribute_get_value (attr, attrs->invisible));
590 case ATK_TEXT_ATTR_EDITABLE:
591 value = g_strdup (atk_text_attribute_get_value (attr, attrs->editable));
593 case ATK_TEXT_ATTR_PIXELS_ABOVE_LINES:
594 value = g_strdup_printf ("%i", attrs->pixels_above_lines);
596 case ATK_TEXT_ATTR_PIXELS_BELOW_LINES:
597 value = g_strdup_printf ("%i", attrs->pixels_below_lines);
599 case ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP:
600 value = g_strdup_printf ("%i", attrs->pixels_inside_wrap);
602 case ATK_TEXT_ATTR_BG_FULL_HEIGHT:
603 value = g_strdup (atk_text_attribute_get_value (attr, attrs->bg_full_height));
605 case ATK_TEXT_ATTR_RISE:
606 value = g_strdup_printf ("%i", attrs->appearance.rise);
608 case ATK_TEXT_ATTR_UNDERLINE:
609 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.underline));
611 case ATK_TEXT_ATTR_STRIKETHROUGH:
612 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.strikethrough));
614 case ATK_TEXT_ATTR_SIZE:
615 value = g_strdup_printf ("%i",
616 pango_font_description_get_size (attrs->font) / PANGO_SCALE);
618 case ATK_TEXT_ATTR_SCALE:
619 value = g_strdup_printf ("%g", attrs->font_scale);
621 case ATK_TEXT_ATTR_WEIGHT:
622 value = g_strdup_printf ("%d",
623 pango_font_description_get_weight (attrs->font));
625 case ATK_TEXT_ATTR_LANGUAGE:
626 value = g_strdup ((gchar *)(attrs->language));
628 case ATK_TEXT_ATTR_FAMILY_NAME:
629 value = g_strdup (pango_font_description_get_family (attrs->font));
631 case ATK_TEXT_ATTR_BG_COLOR:
632 value = g_strdup_printf ("%u,%u,%u",
633 attrs->appearance.bg_color.red,
634 attrs->appearance.bg_color.green,
635 attrs->appearance.bg_color.blue);
637 case ATK_TEXT_ATTR_FG_COLOR:
638 value = g_strdup_printf ("%u,%u,%u",
639 attrs->appearance.fg_color.red,
640 attrs->appearance.fg_color.green,
641 attrs->appearance.fg_color.blue);
643 case ATK_TEXT_ATTR_BG_STIPPLE:
644 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.bg_stipple ? 1 : 0));
646 case ATK_TEXT_ATTR_FG_STIPPLE:
647 value = g_strdup (atk_text_attribute_get_value (attr, attrs->appearance.fg_stipple ? 1 : 0));
649 case ATK_TEXT_ATTR_WRAP_MODE:
650 value = g_strdup (atk_text_attribute_get_value (attr, attrs->wrap_mode));
652 case ATK_TEXT_ATTR_DIRECTION:
653 value = g_strdup (atk_text_attribute_get_value (attr, attrs->direction));
655 case ATK_TEXT_ATTR_JUSTIFICATION:
656 value = g_strdup (atk_text_attribute_get_value (attr, attrs->justification));
658 case ATK_TEXT_ATTR_STRETCH:
659 value = g_strdup (atk_text_attribute_get_value (attr,
660 pango_font_description_get_stretch (attrs->font)));
662 case ATK_TEXT_ATTR_VARIANT:
663 value = g_strdup (atk_text_attribute_get_value (attr,
664 pango_font_description_get_variant (attrs->font)));
666 case ATK_TEXT_ATTR_STYLE:
667 value = g_strdup (atk_text_attribute_get_value (attr,
668 pango_font_description_get_style (attrs->font)));
674 return gail_misc_add_attribute (attrib_set, attr, value);
678 * gail_misc_buffer_get_run_attributes:
679 * @buffer: The #GtkTextBuffer for which the attributes will be obtained
680 * @offset: The offset at which the attributes are required
681 * @start_offset: The start offset of the current run
682 * @end_offset: The end offset of the current run
684 * Creates an AtkAttributeSet which contains the attributes for the
685 * run starting at offset.
687 * Returns: A pointer to the #AtkAttributeSet.
690 gail_misc_buffer_get_run_attributes (GtkTextBuffer *buffer,
696 AtkAttributeSet *attrib_set = NULL;
698 GSList *tags, *temp_tags;
700 gboolean val_set = FALSE;
703 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
705 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
706 *end_offset = gtk_text_iter_get_offset (&iter);
708 gtk_text_iter_backward_to_tag_toggle (&iter, NULL);
709 *start_offset = gtk_text_iter_get_offset (&iter);
711 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
713 tags = gtk_text_iter_get_tags (&iter);
714 tags = g_slist_reverse (tags);
717 while (temp_tags && !val_set)
719 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
720 PangoFontDescription *font;
722 font = tag->values->font;
726 mask = pango_font_description_get_set_fields (font);
727 val_set = mask & PANGO_FONT_MASK_STYLE;
729 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
730 ATK_TEXT_ATTR_STYLE);
732 temp_tags = temp_tags->next;
737 while (temp_tags && !val_set)
739 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
740 PangoFontDescription *font;
742 font = tag->values->font;
746 mask = pango_font_description_get_set_fields (font);
747 val_set = mask & PANGO_FONT_MASK_VARIANT;
749 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
750 ATK_TEXT_ATTR_VARIANT);
752 temp_tags = temp_tags->next;
757 while (temp_tags && !val_set)
759 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
760 PangoFontDescription *font;
762 font = tag->values->font;
766 mask = pango_font_description_get_set_fields (font);
767 val_set = mask & PANGO_FONT_MASK_STRETCH;
769 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
770 ATK_TEXT_ATTR_STRETCH);
772 temp_tags = temp_tags->next;
777 while (temp_tags && !val_set)
779 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
781 val_set = tag->justification_set;
783 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
784 ATK_TEXT_ATTR_JUSTIFICATION);
785 temp_tags = temp_tags->next;
790 while (temp_tags && !val_set)
792 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
794 if (tag->values->direction != GTK_TEXT_DIR_NONE)
797 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
798 ATK_TEXT_ATTR_DIRECTION);
800 temp_tags = temp_tags->next;
805 while (temp_tags && !val_set)
807 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
809 val_set = tag->wrap_mode_set;
811 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
812 ATK_TEXT_ATTR_WRAP_MODE);
813 temp_tags = temp_tags->next;
818 while (temp_tags && !val_set)
820 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
822 val_set = tag->fg_stipple_set;
824 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
825 ATK_TEXT_ATTR_FG_STIPPLE);
826 temp_tags = temp_tags->next;
831 while (temp_tags && !val_set)
833 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
835 val_set = tag->bg_stipple_set;
837 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
838 ATK_TEXT_ATTR_BG_STIPPLE);
839 temp_tags = temp_tags->next;
844 while (temp_tags && !val_set)
846 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
848 val_set = tag->fg_color_set;
850 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
851 ATK_TEXT_ATTR_FG_COLOR);
852 temp_tags = temp_tags->next;
857 while (temp_tags && !val_set)
859 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
861 val_set = tag->bg_color_set;
863 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
864 ATK_TEXT_ATTR_BG_COLOR);
865 temp_tags = temp_tags->next;
870 while (temp_tags && !val_set)
872 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
873 PangoFontDescription *font;
875 font = tag->values->font;
879 mask = pango_font_description_get_set_fields (font);
880 val_set = mask & PANGO_FONT_MASK_FAMILY;
882 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
883 ATK_TEXT_ATTR_FAMILY_NAME);
885 temp_tags = temp_tags->next;
890 while (temp_tags && !val_set)
892 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
894 val_set = tag->language_set;
896 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
897 ATK_TEXT_ATTR_LANGUAGE);
898 temp_tags = temp_tags->next;
903 while (temp_tags && !val_set)
905 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
906 PangoFontDescription *font;
908 font = tag->values->font;
912 mask = pango_font_description_get_set_fields (font);
913 val_set = mask & PANGO_FONT_MASK_WEIGHT;
915 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
916 ATK_TEXT_ATTR_WEIGHT);
918 temp_tags = temp_tags->next;
924 * scale is special as the scale is the product of all scale values
930 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
935 scale *= tag->values->font_scale;
937 temp_tags = temp_tags->next;
941 at = g_malloc(sizeof(AtkAttribute));
942 at->name = g_strdup(atk_text_attribute_get_name (ATK_TEXT_ATTR_SCALE));
943 at->value = g_strdup_printf("%g", scale);
944 attrib_set = g_slist_prepend(attrib_set, at);
949 while (temp_tags && !val_set)
951 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
952 PangoFontDescription *font;
954 font = tag->values->font;
958 mask = pango_font_description_get_set_fields (font);
959 val_set = mask & PANGO_FONT_MASK_SIZE;
961 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
964 temp_tags = temp_tags->next;
969 while (temp_tags && !val_set)
971 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
973 val_set = tag->strikethrough_set;
975 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
976 ATK_TEXT_ATTR_STRIKETHROUGH);
977 temp_tags = temp_tags->next;
982 while (temp_tags && !val_set)
984 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
986 val_set = tag->underline_set;
988 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
989 ATK_TEXT_ATTR_UNDERLINE);
990 temp_tags = temp_tags->next;
995 while (temp_tags && !val_set)
997 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
999 val_set = tag->rise_set;
1001 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1002 ATK_TEXT_ATTR_RISE);
1003 temp_tags = temp_tags->next;
1008 while (temp_tags && !val_set)
1010 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1012 val_set = tag->bg_full_height_set;
1014 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1015 ATK_TEXT_ATTR_BG_FULL_HEIGHT);
1016 temp_tags = temp_tags->next;
1021 while (temp_tags && !val_set)
1023 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1025 val_set = tag->pixels_inside_wrap_set;
1027 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1028 ATK_TEXT_ATTR_PIXELS_INSIDE_WRAP);
1029 temp_tags = temp_tags->next;
1034 while (temp_tags && !val_set)
1036 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1038 val_set = tag->pixels_below_lines_set;
1040 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1041 ATK_TEXT_ATTR_PIXELS_BELOW_LINES);
1042 temp_tags = temp_tags->next;
1047 while (temp_tags && !val_set)
1049 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1051 val_set = tag->pixels_above_lines_set;
1053 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1054 ATK_TEXT_ATTR_PIXELS_ABOVE_LINES);
1055 temp_tags = temp_tags->next;
1060 while (temp_tags && !val_set)
1062 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1064 val_set = tag->editable_set;
1066 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1067 ATK_TEXT_ATTR_EDITABLE);
1068 temp_tags = temp_tags->next;
1073 while (temp_tags && !val_set)
1075 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1077 val_set = tag->invisible_set;
1079 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1080 ATK_TEXT_ATTR_INVISIBLE);
1081 temp_tags = temp_tags->next;
1086 while (temp_tags && !val_set)
1088 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1090 val_set = tag->indent_set;
1092 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1093 ATK_TEXT_ATTR_INDENT);
1094 temp_tags = temp_tags->next;
1099 while (temp_tags && !val_set)
1101 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1103 val_set = tag->right_margin_set;
1105 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1106 ATK_TEXT_ATTR_RIGHT_MARGIN);
1107 temp_tags = temp_tags->next;
1112 while (temp_tags && !val_set)
1114 GtkTextTag *tag = GTK_TEXT_TAG (temp_tags->data);
1116 val_set = tag->left_margin_set;
1118 attrib_set = gail_misc_add_to_attr_set (attrib_set, tag->values,
1119 ATK_TEXT_ATTR_LEFT_MARGIN);
1120 temp_tags = temp_tags->next;
1124 g_slist_free (tags);