static void style_set_handler (GtkWidget *widget, GtkStyle *previous_style) { PangoLayout *layout; int width, width2; int xpad; layout = gtk_label_get_layout (GTK_LABEL(widget)); layout = pango_layout_copy (layout); pango_layout_set_text (layout, LOCATION_LABEL, -1); pango_layout_get_pixel_size (layout, &width, NULL); pango_layout_set_text (layout, GO_TO_LABEL, -1); pango_layout_get_pixel_size (layout, &width2, NULL); width = MAX (width, width2); gtk_misc_get_padding (GTK_MISC (widget), &xpad, NULL); width += 2 * xpad; gtk_widget_set_size_request (widget, width, -1); g_object_unref (layout); }
static gboolean query_unlock_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_tooltip, GtkTooltip *tooltip, gpointer user_data) { GtkWidget *label; PangoLayout *layout; PangoAttrList *attrs; IconShapeData *data; data = g_object_get_data (G_OBJECT (widget), "icon-shape-data"); label = g_object_get_data (G_OBJECT (widget), "tooltip-label"); if (label == NULL) { label = gtk_label_new (data->text); g_object_ref_sink (label); g_object_set_data_full (G_OBJECT (widget), "tooltip-label", label, g_object_unref); } layout = gtk_label_get_layout (GTK_LABEL (label)); pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout), icon_shape_renderer, data, NULL); attrs = create_shape_attr_list_for_layout (layout, data); gtk_label_set_attributes (GTK_LABEL (label), attrs); pango_attr_list_unref (attrs); gtk_tooltip_set_custom (tooltip, label); return TRUE; }
static AtkAttributeSet* gtk_label_accessible_get_run_attributes (AtkText *text, gint offset, gint *start_offset, gint *end_offset) { GtkWidget *widget; AtkAttributeSet *attributes; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) return NULL; attributes = NULL; attributes = add_attribute (attributes, ATK_TEXT_ATTR_DIRECTION, atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, gtk_widget_get_direction (widget))); attributes = _gtk_pango_get_run_attributes (attributes, gtk_label_get_layout (GTK_LABEL (widget)), offset, start_offset, end_offset); return attributes; }
static void match_label_color (GstyleColorWidget *self, GstyleColor *color) { PangoLayout *layout; PangoAttrList *attr_list; PangoAttribute *attr; GdkRGBA rgba; GdkRGBA dst_rgba; g_assert (GSTYLE_IS_COLOR_WIDGET (self)); g_assert (GSTYLE_IS_COLOR (color)); layout = gtk_label_get_layout (self->label); attr_list = pango_layout_get_attributes (layout); if (attr_list == NULL) { attr_list = pango_attr_list_new (); gtk_label_set_attributes (self->label, attr_list); pango_attr_list_unref (attr_list); } gstyle_color_fill_rgba (color, &rgba); gstyle_utils_get_contrasted_rgba (rgba, &dst_rgba); attr = pango_attr_foreground_new (dst_rgba.red * 0xffff, dst_rgba.green * 0xffff, dst_rgba.blue * 0xffff); pango_attr_list_change (attr_list, attr); attr = pango_attr_background_new (rgba.red * 0xffff, rgba.green * 0xffff, rgba.blue * 0xffff); pango_attr_list_change (attr_list, attr); }
static gchar* gail_expander_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GailExpander *expander; GtkWidget *label; widget = GTK_ACCESSIBLE (text)->widget; if (widget == NULL) /* State is defunct */ return NULL; expander = GAIL_EXPANDER (text); if (!expander->textutil) gail_expander_init_textutil (expander, GTK_EXPANDER (widget)); label = gtk_expander_get_label_widget (GTK_EXPANDER (widget)); if (!GTK_IS_LABEL(label)) return NULL; return gail_text_util_get_text (expander->textutil, gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
void get_label_text_dimensions(const char *text, int *width, int *height) { /* * Determine the dimensions of a piece of text in the standard * font used in GTK interface elements like labels. We do this by * instantiating an actual GtkLabel, and then querying its size. * * But GTK2 and GTK3 require us to query the size completely * differently. I'm sure there ought to be an easier approach than * the way I'm doing this in GTK3, too! */ GtkWidget *label = gtk_label_new(text); #if GTK_CHECK_VERSION(3,0,0) PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(label)); PangoRectangle logrect; pango_layout_get_extents(layout, NULL, &logrect); if (width) *width = logrect.width / PANGO_SCALE; if (height) *height = logrect.height / PANGO_SCALE; #else GtkRequisition req; gtk_widget_size_request(label, &req); if (width) *width = req.width; if (height) *height = req.height; #endif g_object_ref_sink(G_OBJECT(label)); #if GTK_CHECK_VERSION(2,10,0) g_object_unref(label); #endif }
static gchar* gail_label_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkLabel *label; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) { /* State is defunct */ return NULL; } /* Get label */ label = GTK_LABEL (widget); return gail_text_util_get_text (GAIL_LABEL (text)->textutil, gtk_label_get_layout (label), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
static gchar* gail_statusbar_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkWidget *label; GailStatusbar *statusbar; widget = GTK_ACCESSIBLE (text)->widget; if (widget == NULL) { /* State is defunct */ return NULL; } /* Get label */ label = get_label_from_statusbar (widget); if (!GTK_IS_LABEL(label)) return NULL; statusbar = GAIL_STATUSBAR (text); if (!statusbar->textutil) gail_statusbar_init_textutil (statusbar, label); return gail_text_util_get_text (statusbar->textutil, gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
static gchar* gail_button_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkWidget *label; GailButton *button; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) { /* State is defunct */ return NULL; } /* Get label */ label = get_label_from_button (widget, 0, FALSE); if (!GTK_IS_LABEL(label)) return NULL; button = GAIL_BUTTON (text); if (!button->textutil) gail_button_init_textutil (button, label); return gail_text_util_get_text (button->textutil, gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
static gint gail_notebook_page_get_offset_at_point (AtkText *text, gint x, gint y, AtkCoordType coords) { GtkWidget *label; GailNotebookPage *notebook_page; gint index, x_layout, y_layout; const gchar *label_text; notebook_page = GAIL_NOTEBOOK_PAGE (text); label = get_label_from_notebook_page (notebook_page); if (!GTK_IS_LABEL(label)) return -1; gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout); index = gail_misc_get_index_at_point_in_layout (label, gtk_label_get_layout (GTK_LABEL (label)), x_layout, y_layout, x, y, coords); label_text = gtk_label_get_text (GTK_LABEL (label)); if (index == -1) { if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN) return g_utf8_strlen (label_text, -1); return index; } else return g_utf8_pointer_to_offset (label_text, label_text + index); }
static void gail_expander_get_character_extents (AtkText *text, gint offset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords) { GtkWidget *widget; GtkWidget *label; PangoRectangle char_rect; gint index, x_layout, y_layout; const gchar *label_text; widget = GTK_ACCESSIBLE (text)->widget; if (widget == NULL) /* State is defunct */ return; label = gtk_expander_get_label_widget (GTK_EXPANDER (widget)); if (!GTK_IS_LABEL(label)) return; gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout); label_text = gtk_label_get_text (GTK_LABEL (label)); index = g_utf8_offset_to_pointer (label_text, offset) - label_text; pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect); gail_misc_get_extents_from_pango_rectangle (label, &char_rect, x_layout, y_layout, x, y, width, height, coords); }
static gint gail_label_get_offset_at_point (AtkText *text, gint x, gint y, AtkCoordType coords) { GtkWidget *widget; GtkLabel *label; const gchar *label_text; gint index, x_layout, y_layout; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) /* State is defunct */ return -1; label = GTK_LABEL (widget); gtk_label_get_layout_offsets (label, &x_layout, &y_layout); index = gail_misc_get_index_at_point_in_layout (widget, gtk_label_get_layout (label), x_layout, y_layout, x, y, coords); label_text = gtk_label_get_text (label); if (index == -1) { if (coords == ATK_XY_WINDOW || coords == ATK_XY_SCREEN) return g_utf8_strlen (label_text, -1); return index; } else return g_utf8_pointer_to_offset (label_text, label_text + index); }
static void gail_notebook_page_get_character_extents (AtkText *text, gint offset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords) { GtkWidget *label; GailNotebookPage *notebook_page; PangoRectangle char_rect; gint index, x_layout, y_layout; const gchar *label_text; notebook_page = GAIL_NOTEBOOK_PAGE (text); label = get_label_from_notebook_page (notebook_page); if (!GTK_IS_LABEL(label)) return; gtk_label_get_layout_offsets (GTK_LABEL (label), &x_layout, &y_layout); label_text = gtk_label_get_text (GTK_LABEL (label)); index = g_utf8_offset_to_pointer (label_text, offset) - label_text; pango_layout_index_to_pos (gtk_label_get_layout (GTK_LABEL (label)), index, &char_rect); gail_misc_get_extents_from_pango_rectangle (label, &char_rect, x_layout, y_layout, x, y, width, height, coords); }
static void gtk_label_layoutable_size_allocate (GtkLayoutable *layoutable, GtkAllocation *allocation) { GtkLabel *label = GTK_LABEL (layoutable); if (gtk_label_get_line_wrap (label)) { PangoLayout *layout; PangoRectangle rect; /* Make it span the entire line. */ layout = gtk_label_get_layout (label); pango_layout_set_width (layout, allocation->width * PANGO_SCALE); pango_layout_get_extents (layout, NULL, &rect); allocation->width = rect.width / PANGO_SCALE + label->misc.xpad * 2; allocation->height = rect.height / PANGO_SCALE + label->misc.ypad * 2; gtk_misc_set_alignment (&label->misc, 0.0, 0.0); gtk_widget_size_allocate (GTK_WIDGET (label), allocation); } else (gtk_label_parent_layoutable_iface->size_allocate) (layoutable, allocation); }
static gchar* gail_item_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkWidget *label; GailItem *item; widget = GTK_ACCESSIBLE (text)->widget; if (widget == NULL) { /* State is defunct */ return NULL; } /* Get label */ label = get_label_from_container (widget); if (!GTK_IS_LABEL(label)) return NULL; item = GAIL_ITEM (text); if (!item->textutil) gail_item_init_textutil (item, label); return gail_text_util_get_text (item->textutil, gtk_label_get_layout (GTK_LABEL (label)), GAIL_AFTER_OFFSET, boundary_type, offset, start_offset, end_offset); }
static void text_size_allocate_cb (GtkWidget * w, GtkAllocation * al, gpointer data) { PangoLayout *pl = gtk_label_get_layout (GTK_LABEL (w)); if (pango_layout_is_wrapped (pl)) gtk_widget_set_size_request (w, al->width, -1); }
GtkWidget * do_rotated_text (GtkWidget *do_widget) { static GtkWidget *window = NULL; if (!window) { GtkWidget *box; GtkWidget *drawing_area; GtkWidget *label; PangoLayout *layout; PangoAttrList *attrs; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (do_widget)); gtk_window_set_title (GTK_WINDOW (window), "Rotated Text"); gtk_window_set_default_size (GTK_WINDOW (window), 4 * RADIUS, 2 * RADIUS); g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous (GTK_BOX (box), TRUE); gtk_container_add (GTK_CONTAINER (window), box); /* Add a drawing area */ drawing_area = gtk_drawing_area_new (); gtk_container_add (GTK_CONTAINER (box), drawing_area); gtk_style_context_add_class (gtk_widget_get_style_context (drawing_area), GTK_STYLE_CLASS_VIEW); gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area), rotated_text_draw, NULL, NULL); /* And a label */ label = gtk_label_new (text); gtk_container_add (GTK_CONTAINER (box), label); gtk_label_set_angle (GTK_LABEL (label), 45); /* Set up fancy stuff on the label */ layout = gtk_label_get_layout (GTK_LABEL (label)); pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout), fancy_shape_renderer, NULL, NULL); attrs = create_fancy_attr_list_for_layout (layout); gtk_label_set_attributes (GTK_LABEL (label), attrs); pango_attr_list_unref (attrs); } if (!gtk_widget_get_visible (window)) gtk_widget_show_all (window); else gtk_widget_destroy (window); return window; }
/* Draws a rounded rectangle with text inside. */ static gboolean numbers_draw_cb (GtkWidget *widget, cairo_t *ctx, gpointer data) { double x, y, w, h; PangoLayout * layout; gint font_size = gtk_widget_get_font_size (widget); #if (INDICATOR_MESSAGES_HAS_LOZENGE == 1) gboolean is_lozenge = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "is-lozenge")); /* let the label handle the drawing if it's not a lozenge */ if (!is_lozenge) return FALSE; #endif if (!GTK_IS_WIDGET (widget)) return FALSE; /* get style + arrow position / dimensions */ double red, green, blue; GtkStyleContext *style = gtk_widget_get_style_context (widget); GdkRGBA color; gtk_style_context_get_color (style, gtk_widget_get_state(widget), &color); red = color.red; green = color.green; blue = color.blue; GtkAllocation allocation; gtk_widget_get_allocation (widget, &allocation); w = allocation.width; h = allocation.height; x = y = 0; layout = gtk_label_get_layout (GTK_LABEL(widget)); PangoRectangle layout_extents; pango_layout_get_extents (layout, NULL, &layout_extents); pango_extents_to_pixels (&layout_extents, NULL); if (layout_extents.width == 0) return TRUE; cairo_set_line_width (ctx, 1.0); cairo_set_fill_rule (ctx, CAIRO_FILL_RULE_EVEN_ODD); /* cairo drawing code */ custom_cairo_rounded_rectangle (ctx, x - font_size/2.0, y, w + font_size, h); cairo_set_source_rgba (ctx, red, green, blue, 0.5); x += (allocation.width - layout_extents.width) / 2.0; y += (allocation.height - layout_extents.height) / 2.0; cairo_move_to (ctx, floor (x), floor (y)); pango_cairo_layout_path (ctx, layout); cairo_fill (ctx); return TRUE; }
static gint gtk_label_accessible_get_offset_at_point (AtkText *atk_text, gint x, gint y, AtkCoordType coords) { GtkWidget *widget; GtkLabel *label; const gchar *text; gint index, x_layout, y_layout; gint x_window, y_window; gint x_local, y_local; GdkWindow *window; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (atk_text)); if (widget == NULL) return -1; label = GTK_LABEL (widget); gtk_label_get_layout_offsets (label, &x_layout, &y_layout); window = gtk_widget_get_window (widget); gdk_window_get_origin (window, &x_window, &y_window); x_local = x - x_layout - x_window; y_local = y - y_layout - y_window; if (coords == ATK_XY_WINDOW) { window = gdk_window_get_toplevel (window); gdk_window_get_origin (window, &x_window, &y_window); x_local += x_window; y_local += y_window; } if (!pango_layout_xy_to_index (gtk_label_get_layout (label), x_local * PANGO_SCALE, y_local * PANGO_SCALE, &index, NULL)) { if (x_local < 0 || y_local < 0) index = 0; else index = -1; } if (index != -1) { text = gtk_label_get_text (label); return g_utf8_pointer_to_offset (text, text + index); } return -1; }
static void set_item_text_gravity(GtkWidget* item) { GtkWidget* label; PangoLayout* layout; PangoContext* context; label = gtk_bin_get_child(GTK_BIN(item)); layout = gtk_label_get_layout(GTK_LABEL(label)); context = pango_layout_get_context(layout); pango_context_set_base_gravity(context, PANGO_GRAVITY_AUTO); }
static gint get_label_line_height (GtkWidget *label) { PangoLayout *layout; PangoLayoutIter *iter; PangoRectangle rect; layout = gtk_label_get_layout (GTK_LABEL (label)); iter = pango_layout_get_iter (layout); pango_layout_iter_get_line_extents (iter, NULL, &rect); pango_layout_iter_free (iter); return (rect.y + rect.height) / PANGO_SCALE; }
static int gtkButtonSetAlignmentAttrib(Ihandle* ih, const char* value) { GtkButton* button = (GtkButton*)ih->handle; PangoAlignment alignment; float xalign, yalign; char value1[30]="", value2[30]=""; if (iupAttribGet(ih, "_IUPGTK_EVENTBOX")) return 0; iupStrToStrStr(value, value1, value2, ':'); if (iupStrEqualNoCase(value1, "ARIGHT")) { xalign = 1.0f; alignment = PANGO_ALIGN_RIGHT; } else if (iupStrEqualNoCase(value1, "ACENTER")) { xalign = 0.5f; alignment = PANGO_ALIGN_CENTER; } else /* "ALEFT" */ { xalign = 0; alignment = PANGO_ALIGN_LEFT; } if (iupStrEqualNoCase(value2, "ABOTTOM")) yalign = 1.0f; else if (iupStrEqualNoCase(value2, "ATOP")) yalign = 0; else /* ACENTER (default) */ yalign = 0.5f; gtk_button_set_alignment(button, xalign, yalign); if (ih->data->type == IUP_BUTTON_TEXT) /* text only */ { GtkLabel* label = gtkButtonGetLabel(ih); if (label) { PangoLayout* layout = gtk_label_get_layout(label); if (layout) pango_layout_set_alignment(layout, alignment); } } return 1; }
static int gtkFrameSetStandardFontAttrib(Ihandle* ih, const char* value) { iupdrvSetStandardFontAttrib(ih, value); if (ih->handle) { GtkWidget* label = gtk_frame_get_label_widget((GtkFrame*)ih->handle); if (!label) return 1; gtk_widget_modify_font(label, (PangoFontDescription*)iupgtkGetPangoFontDescAttrib(ih)); iupgtkFontUpdatePangoLayout(ih, gtk_label_get_layout((GtkLabel*)label)); } return 1; }
static void gtkTabsUpdatePageFont(Ihandle* ih) { Ihandle* child; PangoFontDescription* fontdesc = (PangoFontDescription*)iupgtkGetPangoFontDescAttrib(ih); for (child = ih->firstchild; child; child = child->brother) { GtkWidget* tab_label = (GtkWidget*)iupAttribGet(child, "_IUPGTK_TABLABEL"); if (tab_label) { gtk_widget_modify_font(tab_label, fontdesc); iupgtkFontUpdatePangoLayout(ih, gtk_label_get_layout((GtkLabel*)tab_label)); } } }
static void set_label_size (NautilusZoomControl *zoom_control) { const char *text; PangoLayout *layout; int width; int height; text = gtk_label_get_text (GTK_LABEL (zoom_control->details->zoom_label)); layout = gtk_label_get_layout (GTK_LABEL (zoom_control->details->zoom_label)); pango_layout_set_text (layout, "100%", -1); pango_layout_get_pixel_size (layout, &width, &height); gtk_widget_set_size_request (zoom_control->details->zoom_label, width, height); gtk_label_set_text (GTK_LABEL (zoom_control->details->zoom_label), text); }
static int gtkToggleSetStandardFontAttrib(Ihandle* ih, const char* value) { iupdrvSetStandardFontAttrib(ih, value); if (ih->handle) { GtkWidget* label = gtk_button_get_image((GtkButton*)ih->handle); if (!label) return 1; gtk_widget_modify_font(label, (PangoFontDescription*)iupgtkGetPangoFontDescAttrib(ih)); if (ih->data->type == IUP_TOGGLE_TEXT) iupgtkFontUpdatePangoLayout(ih, gtk_label_get_layout((GtkLabel*)label)); } return 1; }
static AtkAttributeSet* gail_button_get_run_attributes (AtkText *text, gint offset, gint *start_offset, gint *end_offset) { GtkWidget *widget; GtkWidget *label; AtkAttributeSet *at_set = NULL; GtkJustification justify; GtkTextDirection dir; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) /* State is defunct */ return NULL; label = get_label_from_button (widget, 0, FALSE); if (!GTK_IS_LABEL(label)) return NULL; /* Get values set for entire label, if any */ justify = gtk_label_get_justify (GTK_LABEL (label)); if (justify != GTK_JUSTIFY_CENTER) { at_set = gail_misc_add_attribute (at_set, ATK_TEXT_ATTR_JUSTIFICATION, g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_JUSTIFICATION, justify))); } dir = gtk_widget_get_direction (label); if (dir == GTK_TEXT_DIR_RTL) { at_set = gail_misc_add_attribute (at_set, ATK_TEXT_ATTR_DIRECTION, g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir))); } at_set = gail_misc_layout_get_run_attributes (at_set, gtk_label_get_layout (GTK_LABEL (label)), (gchar *) gtk_label_get_text (GTK_LABEL (label)), offset, start_offset, end_offset); return at_set; }
static gchar* gtk_label_accessible_get_text_after_offset (AtkText *text, gint offset, AtkTextBoundary boundary_type, gint *start_offset, gint *end_offset) { GtkWidget *widget; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) return NULL; return _gtk_pango_get_text_after (gtk_label_get_layout (GTK_LABEL (widget)), boundary_type, offset, start_offset, end_offset); }
int scroll_text_label(void *data) { struct text_update_ctx *ctx = data; PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(ctx->e->widget)); if (pango_layout_is_ellipsized(layout)) ctx->curptr += 20; else ctx->curptr = ctx->orig_value; if ((ctx->curptr - ctx->orig_value) > strlen(ctx->orig_value)) ctx->curptr = ctx->orig_value; gtk_label_set_markup(GTK_LABEL(ctx->e->widget), ctx->curptr); return TRUE; }
static void gtk_label_accessible_get_character_extents (AtkText *text, gint offset, gint *x, gint *y, gint *width, gint *height, AtkCoordType coords) { GtkWidget *widget; GtkLabel *label; PangoRectangle char_rect; const gchar *label_text; gint index, x_layout, y_layout; GdkWindow *window; gint x_window, y_window; widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); if (widget == NULL) return; label = GTK_LABEL (widget); gtk_label_get_layout_offsets (label, &x_layout, &y_layout); label_text = gtk_label_get_text (label); index = g_utf8_offset_to_pointer (label_text, offset) - label_text; pango_layout_index_to_pos (gtk_label_get_layout (label), index, &char_rect); pango_extents_to_pixels (&char_rect, NULL); window = gtk_widget_get_window (widget); gdk_window_get_origin (window, &x_window, &y_window); *x = x_window + x_layout + char_rect.x; *y = x_window + y_layout + char_rect.y; *width = char_rect.width; *height = char_rect.height; if (coords == ATK_XY_WINDOW) { window = gdk_window_get_toplevel (window); gdk_window_get_origin (window, &x_window, &y_window); *x -= x_window; *y -= y_window; } }