mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-26 21:51:08 +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)
|
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)
|
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)
|
else if (g_strcmp0 (method_name, "GetBoundedRanges") == 0)
|
||||||
{
|
{
|
||||||
|
@ -426,6 +426,35 @@ gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
|
|||||||
return TRUE;
|
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:
|
* gtk_accessible_text_update_caret_position:
|
||||||
* @self: the accessible object
|
* @self: the accessible object
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gtk/gtkaccessible.h>
|
#include <gtk/gtkaccessible.h>
|
||||||
|
#include <graphene.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@ -255,6 +256,24 @@ struct _GtkAccessibleTextInterface
|
|||||||
void (* get_default_attributes) (GtkAccessibleText *self,
|
void (* get_default_attributes) (GtkAccessibleText *self,
|
||||||
char ***attribute_names,
|
char ***attribute_names,
|
||||||
char ***attribute_values);
|
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
|
GDK_AVAILABLE_IN_4_14
|
||||||
|
@ -52,4 +52,10 @@ gtk_accessible_text_get_attributes_run (GtkAccessibleText *self,
|
|||||||
char ***attribute_names,
|
char ***attribute_names,
|
||||||
char ***attribute_values);
|
char ***attribute_values);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gtk_accessible_text_get_extents (GtkAccessibleText *self,
|
||||||
|
unsigned int start,
|
||||||
|
unsigned int end,
|
||||||
|
graphene_rect_t *extents);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -1435,6 +1435,39 @@ gtk_inscription_accessible_text_get_default_attributes (GtkAccessibleText *sel
|
|||||||
*attribute_values = values;
|
*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
|
static void
|
||||||
gtk_inscription_accessible_text_init (GtkAccessibleTextInterface *iface)
|
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_selection = gtk_inscription_accessible_text_get_selection;
|
||||||
iface->get_attributes = gtk_inscription_accessible_text_get_attributes;
|
iface->get_attributes = gtk_inscription_accessible_text_get_attributes;
|
||||||
iface->get_default_attributes = gtk_inscription_accessible_text_get_default_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;
|
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
|
static void
|
||||||
gtk_label_accessible_text_init (GtkAccessibleTextInterface *iface)
|
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_selection = gtk_label_accessible_text_get_selection;
|
||||||
iface->get_attributes = gtk_label_accessible_text_get_attributes;
|
iface->get_attributes = gtk_label_accessible_text_get_attributes;
|
||||||
iface->get_default_attributes = gtk_label_accessible_text_get_default_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;
|
*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
|
static void
|
||||||
gtk_text_accessible_text_init (GtkAccessibleTextInterface *iface)
|
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_selection = gtk_text_accessible_text_get_selection;
|
||||||
iface->get_attributes = gtk_text_accessible_text_get_attributes;
|
iface->get_attributes = gtk_text_accessible_text_get_attributes;
|
||||||
iface->get_default_attributes = gtk_text_accessible_text_get_default_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: */
|
/* vim:set foldmethod=marker expandtab: */
|
||||||
|
@ -10685,6 +10685,54 @@ gtk_text_view_accessible_text_get_default_attributes (GtkAccessibleText *self,
|
|||||||
g_hash_table_unref (attrs);
|
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
|
static void
|
||||||
gtk_text_view_accessible_text_init (GtkAccessibleTextInterface *iface)
|
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_selection = gtk_text_view_accessible_text_get_selection;
|
||||||
iface->get_attributes = gtk_text_view_accessible_text_get_attributes;
|
iface->get_attributes = gtk_text_view_accessible_text_get_attributes;
|
||||||
iface->get_default_attributes = gtk_text_view_accessible_text_get_default_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