mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-25 21:21:21 +00:00
Merge branch 'a11y-text-work2' into 'main'
a11y: Add gtk_accessible_text_get_extents See merge request GNOME/gtk!7006
This commit is contained in:
commit
bacdc735a4
@ -330,11 +330,85 @@ accessible_text_handle_method (GDBusConnection *connection,
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetCharacterExtents") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
int offset;
|
||||
unsigned int coords_type;
|
||||
graphene_rect_t extents;
|
||||
graphene_point_t point;
|
||||
int x, y, w, h;
|
||||
GtkNative *native;
|
||||
double nx, ny;
|
||||
|
||||
g_variant_get (parameters, "(iu)", &offset, &coords_type);
|
||||
|
||||
if (coords_type != ATSPI_COORD_TYPE_WINDOW)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
"Unsupported coordinate space");
|
||||
return;
|
||||
}
|
||||
|
||||
native = gtk_widget_get_native (GTK_WIDGET (accessible));
|
||||
gtk_native_get_surface_transform (native, &nx, &ny);
|
||||
|
||||
if (!gtk_accessible_text_get_extents (accessible_text, offset, offset + 1, &extents) ||
|
||||
!gtk_widget_compute_point (GTK_WIDGET (accessible), GTK_WIDGET (native), &extents.origin, &point))
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Failed to get extents");
|
||||
return;
|
||||
}
|
||||
|
||||
x = floor (point.x + nx);
|
||||
y = floor (point.y + ny);
|
||||
w = ceilf (extents.size.width) - x;
|
||||
h = ceilf (extents.size.height) - y;
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(iiii)", x, y, w, h));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetRangeExtents") == 0)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "");
|
||||
int start, end;
|
||||
guint coords_type;
|
||||
graphene_rect_t extents;
|
||||
graphene_point_t point;
|
||||
int x, y, w, h;
|
||||
GtkNative *native;
|
||||
double nx, ny;
|
||||
|
||||
g_variant_get (parameters, "(iiu)", &start, &end, &coords_type);
|
||||
|
||||
if (coords_type != ATSPI_COORD_TYPE_WINDOW)
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_NOT_SUPPORTED,
|
||||
"Unsupported coordinate space");
|
||||
return;
|
||||
}
|
||||
|
||||
native = gtk_widget_get_native (GTK_WIDGET (accessible));
|
||||
gtk_native_get_surface_transform (native, &nx, &ny);
|
||||
|
||||
if (!gtk_accessible_text_get_extents (accessible_text, start, end, &extents) ||
|
||||
!gtk_widget_compute_point (GTK_WIDGET (accessible), GTK_WIDGET (native), &extents.origin, &point))
|
||||
{
|
||||
g_dbus_method_invocation_return_error_literal (invocation,
|
||||
G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_FAILED,
|
||||
"Failed to get extents");
|
||||
return;
|
||||
}
|
||||
|
||||
x = floor (point.x + nx);
|
||||
y = floor (point.y + ny);
|
||||
w = ceilf (extents.size.width) - x;
|
||||
h = ceilf (extents.size.height) - y;
|
||||
|
||||
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(iiii)", x, y, w, h));
|
||||
}
|
||||
else if (g_strcmp0 (method_name, "GetBoundedRanges") == 0)
|
||||
{
|
||||
|
@ -426,6 +426,35 @@ gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_accessible_text_get_extents:
|
||||
* @self: a `GtkAccessibleText`
|
||||
* @start: start offset, in characters
|
||||
* @end: end offset, in characters
|
||||
* @extents: (out caller-allocates): return location for the extents
|
||||
*
|
||||
* Obtains the extents of a range of text, in widget coordinates.
|
||||
*
|
||||
* Returns: true if the extents were filled in, false otherwise
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
gboolean
|
||||
gtk_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ACCESSIBLE_TEXT (self), FALSE);
|
||||
g_return_val_if_fail (start <= end, FALSE);
|
||||
g_return_val_if_fail (extents != NULL, FALSE);
|
||||
|
||||
if (GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_extents != NULL)
|
||||
return GTK_ACCESSIBLE_TEXT_GET_IFACE (self)->get_extents (self, start, end, extents);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_accessible_text_update_caret_position:
|
||||
* @self: the accessible object
|
||||
|
@ -11,6 +11,7 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkaccessible.h>
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -255,6 +256,24 @@ struct _GtkAccessibleTextInterface
|
||||
void (* get_default_attributes) (GtkAccessibleText *self,
|
||||
char ***attribute_names,
|
||||
char ***attribute_values);
|
||||
|
||||
/**
|
||||
* GtkAccessibleTextInterface::get_extents:
|
||||
* @self: the accessible object
|
||||
* @start: the start offset, in characters
|
||||
* @end: the end offset, in characters,
|
||||
* @extents (out caller-allocates): return location for the extents
|
||||
*
|
||||
* Obtains the extents of a range of text, in widget coordinates.
|
||||
*
|
||||
* Returns: true if the extents were filled in, false otherwise
|
||||
*
|
||||
* Since: 4.16
|
||||
*/
|
||||
gboolean (* get_extents) (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
|
@ -52,4 +52,10 @@ gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
|
||||
char ***attribute_names,
|
||||
char ***attribute_values);
|
||||
|
||||
gboolean
|
||||
gtk_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -1435,6 +1435,39 @@ gtk_inscription_accessible_text_get_default_attributes (GtkAccessibleText *sel
|
||||
*attribute_values = values;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_inscription_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents)
|
||||
{
|
||||
GtkInscription *inscription = GTK_INSCRIPTION (self);
|
||||
PangoLayout *layout;
|
||||
const char *text;
|
||||
float lx, ly;
|
||||
cairo_region_t *range_clip;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
int range[2];
|
||||
|
||||
layout = inscription->layout;
|
||||
text = inscription->text;
|
||||
gtk_inscription_get_layout_location (inscription, &lx, &ly);
|
||||
|
||||
range[0] = g_utf8_pointer_to_offset (text, text + start);
|
||||
range[1] = g_utf8_pointer_to_offset (text, text + end);
|
||||
|
||||
range_clip = gdk_pango_layout_get_clip_region (layout, lx, ly, range, 1);
|
||||
cairo_region_get_extents (range_clip, &clip_rect);
|
||||
cairo_region_destroy (range_clip);
|
||||
|
||||
extents->origin.x = clip_rect.x;
|
||||
extents->origin.y = clip_rect.y;
|
||||
extents->size.width = clip_rect.width;
|
||||
extents->size.height = clip_rect.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inscription_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
{
|
||||
@ -1444,6 +1477,7 @@ gtk_inscription_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
iface->get_selection = gtk_inscription_accessible_text_get_selection;
|
||||
iface->get_attributes = gtk_inscription_accessible_text_get_attributes;
|
||||
iface->get_default_attributes = gtk_inscription_accessible_text_get_default_attributes;
|
||||
iface->get_extents = gtk_inscription_accessible_text_get_extents;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
@ -6179,6 +6179,39 @@ gtk_label_accessible_text_get_attributes (GtkAccessibleText *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_label_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (self);
|
||||
PangoLayout *layout;
|
||||
const char *text;
|
||||
float lx, ly;
|
||||
cairo_region_t *range_clip;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
int range[2];
|
||||
|
||||
layout = label->layout;
|
||||
text = label->text;
|
||||
get_layout_location (label, &lx, &ly);
|
||||
|
||||
range[0] = g_utf8_pointer_to_offset (text, text + start);
|
||||
range[1] = g_utf8_pointer_to_offset (text, text + end);
|
||||
|
||||
range_clip = gdk_pango_layout_get_clip_region (layout, lx, ly, range, 1);
|
||||
cairo_region_get_extents (range_clip, &clip_rect);
|
||||
cairo_region_destroy (range_clip);
|
||||
|
||||
extents->origin.x = clip_rect.x;
|
||||
extents->origin.y = clip_rect.y;
|
||||
extents->size.width = clip_rect.width;
|
||||
extents->size.height = clip_rect.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
{
|
||||
@ -6188,6 +6221,7 @@ gtk_label_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
iface->get_selection = gtk_label_accessible_text_get_selection;
|
||||
iface->get_attributes = gtk_label_accessible_text_get_attributes;
|
||||
iface->get_default_attributes = gtk_label_accessible_text_get_default_attributes;
|
||||
iface->get_extents = gtk_label_accessible_text_get_extents;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
@ -7555,6 +7555,38 @@ gtk_text_accessible_text_get_default_attributes (GtkAccessibleText *self,
|
||||
*attribute_values = values;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents)
|
||||
{
|
||||
PangoLayout *layout = gtk_text_get_layout (GTK_TEXT (self));
|
||||
const char *text;
|
||||
int lx, ly;
|
||||
int range[2];
|
||||
cairo_region_t *range_clip;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
layout = gtk_text_get_layout (GTK_TEXT (self));
|
||||
text = gtk_entry_buffer_get_text (get_buffer (GTK_TEXT (self)));
|
||||
get_layout_position (GTK_TEXT (self), &lx, &ly);
|
||||
|
||||
range[0] = g_utf8_pointer_to_offset (text, text + start);
|
||||
range[1] = g_utf8_pointer_to_offset (text, text + end);
|
||||
|
||||
range_clip = gdk_pango_layout_get_clip_region (layout, lx, ly, range, 1);
|
||||
cairo_region_get_extents (range_clip, &clip_rect);
|
||||
cairo_region_destroy (range_clip);
|
||||
|
||||
extents->origin.x = clip_rect.x;
|
||||
extents->origin.y = clip_rect.y;
|
||||
extents->size.width = clip_rect.width;
|
||||
extents->size.height = clip_rect.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
{
|
||||
@ -7564,6 +7596,7 @@ gtk_text_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
iface->get_selection = gtk_text_accessible_text_get_selection;
|
||||
iface->get_attributes = gtk_text_accessible_text_get_attributes;
|
||||
iface->get_default_attributes = gtk_text_accessible_text_get_default_attributes;
|
||||
iface->get_extents = gtk_text_accessible_text_get_extents;
|
||||
}
|
||||
|
||||
/* vim:set foldmethod=marker expandtab: */
|
||||
|
@ -10685,6 +10685,54 @@ gtk_text_view_accessible_text_get_default_attributes (GtkAccessibleText *self,
|
||||
g_hash_table_unref (attrs);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_view_accessible_text_get_extents (GtkAccessibleText *self,
|
||||
unsigned int start,
|
||||
unsigned int end,
|
||||
graphene_rect_t *extents)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start_iter, end_iter;
|
||||
cairo_region_t *region;
|
||||
GdkRectangle rect;
|
||||
|
||||
buffer = get_buffer (GTK_TEXT_VIEW (self));
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end);
|
||||
|
||||
region = cairo_region_create ();
|
||||
do
|
||||
{
|
||||
gtk_text_view_get_iter_location (GTK_TEXT_VIEW (self), &start_iter, &rect);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
|
||||
gtk_text_iter_forward_to_line_end (&start_iter);
|
||||
gtk_text_iter_order (&start_iter, &end_iter);
|
||||
|
||||
gtk_text_view_get_iter_location (GTK_TEXT_VIEW (self), &end_iter, &rect);
|
||||
cairo_region_union_rectangle (region, &rect);
|
||||
|
||||
gtk_text_iter_forward_line (&start_iter);
|
||||
}
|
||||
while (gtk_text_iter_compare (&start_iter, &end_iter) < 0);
|
||||
|
||||
cairo_region_get_extents (region, &rect);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
gtk_text_view_buffer_to_window_coords (GTK_TEXT_VIEW (self),
|
||||
GTK_TEXT_WINDOW_TEXT,
|
||||
rect.x, rect.y,
|
||||
&rect.x, &rect.y);
|
||||
_text_window_to_widget_coords (GTK_TEXT_VIEW (self), &rect.x, &rect.y);
|
||||
|
||||
extents->origin.x = rect.x;
|
||||
extents->origin.y = rect.y;
|
||||
extents->size.width = rect.width;
|
||||
extents->size.height = rect.height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
{
|
||||
@ -10694,6 +10742,7 @@ gtk_text_view_accessible_text_init (GtkAccessibleTextInterface *iface)
|
||||
iface->get_selection = gtk_text_view_accessible_text_get_selection;
|
||||
iface->get_attributes = gtk_text_view_accessible_text_get_attributes;
|
||||
iface->get_default_attributes = gtk_text_view_accessible_text_get_default_attributes;
|
||||
iface->get_extents = gtk_text_view_accessible_text_get_extents;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
Loading…
Reference in New Issue
Block a user