From eb28d16300d5f86f64a2c595f59d7de3469d7704 Mon Sep 17 00:00:00 2001 From: Philippe Normand Date: Wed, 2 Feb 2011 12:58:47 +0100 Subject: [PATCH] a11y: cally-text get_offset_at_point implementation See http://bugzilla.clutter-project.org/show_bug.cgi?id=1733 --- clutter/cally/cally-text.c | 83 ++++++++++++++++++++- tests/accessibility/cally-atktext-example.c | 6 ++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/clutter/cally/cally-text.c b/clutter/cally/cally-text.c index 8e861d6a6..1c7c68622 100644 --- a/clutter/cally/cally-text.c +++ b/clutter/cally/cally-text.c @@ -141,6 +141,11 @@ static void cally_text_get_character_extents (AtkText *text, gint *width, gint *height, AtkCoordType coords); +static gint cally_text_get_offset_at_point (AtkText *text, + gint x, + gint y, + AtkCoordType coords); + static void _cally_text_get_selection_bounds (ClutterText *clutter_text, gint *start_offset, gint *end_offset); @@ -190,6 +195,11 @@ static AtkAttributeSet* _cally_misc_layout_get_run_attributes (AtkAttributeS static AtkAttributeSet* _cally_misc_layout_get_default_attributes (AtkAttributeSet *attrib_set, ClutterText *text); +static int _cally_misc_get_index_at_point (ClutterText *clutter_text, + gint x, + gint y, + AtkCoordType coords); + G_DEFINE_TYPE_WITH_CODE (CallyText, cally_text, CALLY_TYPE_ACTOR, @@ -406,7 +416,7 @@ cally_text_text_interface_init (AtkTextIface *iface) iface->get_run_attributes = cally_text_get_run_attributes; iface->get_default_attributes = cally_text_get_default_attributes; iface->get_character_extents = cally_text_get_character_extents; -/* iface->get_offset_at_point = */ + iface->get_offset_at_point = cally_text_get_offset_at_point; } @@ -855,6 +865,31 @@ done: *yp = y; } +static gint +cally_text_get_offset_at_point (AtkText *text, + gint x, + gint y, + AtkCoordType coords) +{ + ClutterActor *actor = NULL; + ClutterText *clutter_text = NULL; + const gchar *text_value; + gint index; + + actor = CALLY_GET_CLUTTER_ACTOR (text); + if (actor == NULL) /* State is defunct */ + return -1; + + clutter_text = CLUTTER_TEXT (actor); + + index = _cally_misc_get_index_at_point (clutter_text, x, y, coords); + text_value = clutter_text_get_text (clutter_text); + if (index == -1) + return g_utf8_strlen (text_value, -1); + else + return g_utf8_pointer_to_offset (text_value, text_value + index); +} + /******** Auxiliar private methods ******/ @@ -1617,3 +1652,49 @@ _cally_misc_layout_get_default_attributes (AtkAttributeSet *attrib_set, return attrib_set; } + +static int +_cally_misc_get_index_at_point (ClutterText *clutter_text, + gint x, + gint y, + AtkCoordType coords) +{ + gint index, x_window, y_window, x_toplevel, y_toplevel; + gint x_temp, y_temp; + gboolean ret; + ClutterVertex verts[4]; + PangoLayout *layout; + gint x_layout, y_layout; + + clutter_text_get_layout_offsets (clutter_text, &x_layout, &y_layout); + + clutter_actor_get_abs_allocation_vertices (CLUTTER_ACTOR (clutter_text), verts); + x_window = verts[0].x; + y_window = verts[0].y; + + x_temp = x - x_layout - x_window; + y_temp = y - y_layout - y_window; + + if (coords == ATK_XY_SCREEN) + { + _cally_actor_get_top_level_origin (CLUTTER_ACTOR (clutter_text), &x_toplevel, + &y_toplevel); + x_temp -= x_toplevel; + y_temp -= y_toplevel; + } + + layout = clutter_text_get_layout (clutter_text); + ret = pango_layout_xy_to_index (layout, + x_temp * PANGO_SCALE, + y_temp * PANGO_SCALE, + &index, NULL); + + if (!ret) + { + if (x_temp < 0 || y_temp < 0) + index = 0; + else + index = -1; + } + return index; +} diff --git a/tests/accessibility/cally-atktext-example.c b/tests/accessibility/cally-atktext-example.c index 6181b71f5..4d6099dc4 100644 --- a/tests/accessibility/cally-atktext-example.c +++ b/tests/accessibility/cally-atktext-example.c @@ -135,6 +135,12 @@ test_atk_text (ClutterActor *actor) g_print ("atk_text_get_character_extents (0, screen): x=%i y=%i width=%i height=%i\n", x, y, width, height); + pos = atk_text_get_offset_at_point (cally_text, 200, 10, ATK_XY_WINDOW); + g_print ("atk_text_get_offset_at_point (200, 10, window): %i\n", pos); + + pos = atk_text_get_offset_at_point (cally_text, 200, 100, ATK_XY_SCREEN); + g_print ("atk_text_get_offset_at_point (200, 100, screen): %i\n", pos); + } static void