2009-06-10 Xan Lopez <xlopez@igalia.com>
authorxan@webkit.org <xan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Jun 2009 13:10:16 +0000 (13:10 +0000)
committerxan@webkit.org <xan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Jun 2009 13:10:16 +0000 (13:10 +0000)
        Reviewed by Jan Alonzo.

        https://bugs.webkit.org/show_bug.cgi?id=25415
        [GTK][ATK] Please implement support for get_text_at_offset

        Add new dependency on the Gail utils library, needed for our a11y
        implementation.

        * GNUmakefile.am:
        * configure.ac:

WebCore:

2009-06-10  Xan Lopez  <xlopez@igalia.com>

        Reviewed by Jan Alonzo.

        https://bugs.webkit.org/show_bug.cgi?id=25415
        [GTK][ATK] Please implement support for get_text_at_offset

        Use GailUtilText instead of my crappy partial reimplementation of
        it. This should add support for LINE boundaries too, although it's
        mostly untested for now.

        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
        (getGailTextUtilForAtk):
        (webkit_accessible_text_get_text_after_offset):
        (webkit_accessible_text_get_text_at_offset):

WebKit/gtk:

2009-06-10  Xan Lopez  <xlopez@igalia.com>

        Reviewed by Jan Alonzo.

        https://bugs.webkit.org/show_bug.cgi?id=25415
        [GTK][ATK] Please implement support for get_text_at_offset

        Update test for new implementation (it fixes two bugs and adds
        actual implementations for LINE boundaries).

        * tests/testatk.c:
        (test_webkit_atk_get_text_at_offset):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@44557 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
GNUmakefile.am
WebCore/ChangeLog
WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
WebKit/gtk/ChangeLog
WebKit/gtk/tests/testatk.c
configure.ac

index 1946d56..71bc2e4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-10  Xan Lopez  <xlopez@igalia.com>
+
+        Reviewed by Jan Alonzo.
+
+        https://bugs.webkit.org/show_bug.cgi?id=25415
+        [GTK][ATK] Please implement support for get_text_at_offset
+
+        Add new dependency on the Gail utils library, needed for our a11y
+        implementation.
+
+        * GNUmakefile.am:
+        * configure.ac:
+
 2009-05-29  Gustavo Noronha Silva  <gns@gnome.org>
 
         Reviewed by Jan Alonzo.
index c87ee49..722e467 100644 (file)
@@ -84,6 +84,7 @@ corekit_cflags += \
        -fno-strict-aliasing \
        $(COVERAGE_CFLAGS) \
        $(ENCHANT_CFLAGS) \
+       $(GAIL_CFLAGS) \
        $(GEOCLUE_CFLAGS) \
        $(GLIB_CFLAGS) \
        $(GNOMEKEYRING_CFLAGS) \
@@ -243,6 +244,7 @@ libwebkit_1_0_la_LIBADD = \
        $(COVERAGE_LDFLAGS) \
        $(ENCHANT_LIBS) \
        $(FREETYPE_LIBS) \
+       $(GAIL_LIBS) \
        $(GEOCLUE_LIBS) \
        $(GLIB_LIBS) \
        $(GNOMEKEYRING_LIBS) \
index 0fbfa17..e70e186 100644 (file)
@@ -1,3 +1,19 @@
+2009-06-10  Xan Lopez  <xlopez@igalia.com>
+
+        Reviewed by Jan Alonzo.
+
+        https://bugs.webkit.org/show_bug.cgi?id=25415
+        [GTK][ATK] Please implement support for get_text_at_offset
+
+        Use GailUtilText instead of my crappy partial reimplementation of
+        it. This should add support for LINE boundaries too, although it's
+        mostly untested for now.
+
+        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
+        (getGailTextUtilForAtk):
+        (webkit_accessible_text_get_text_after_offset):
+        (webkit_accessible_text_get_text_at_offset):
+
 2009-06-10  Jan Michael Alonzo  <jmalonzo@webkit.org>
 
         Gtk build fix: include <stdio.h> as it is required in jpeglib.h
index 141d561..e70aaa0 100644 (file)
@@ -48,6 +48,7 @@
 #include <atk/atk.h>
 #include <glib.h>
 #include <glib/gprintf.h>
+#include <libgail-util/gail-util.h>
 #include <pango/pango.h>
 
 using namespace WebCore;
@@ -482,225 +483,39 @@ static gchar* webkit_accessible_text_get_text(AtkText* text, gint startOffset, g
     return g_strdup(ret.utf8().data());
 }
 
-enum GetTextFunctionType {
-    AfterOffset,
-    AtOffset,
-    BeforeOffset
-};
-
-typedef bool (*isCharacterAttribute) (PangoLogAttr* attr);
-
-static inline bool isWordStart(PangoLogAttr* attr)
-{
-    return attr->is_word_start;
-}
-
-static inline bool isWordEnd(PangoLogAttr* attr)
-{
-    return attr->is_word_end;
-}
-
-static inline bool isSentenceStart(PangoLogAttr* attr)
-{
-    return attr->is_sentence_start;
-}
-
-static inline bool isSentenceEnd(PangoLogAttr* attr)
-{
-    return attr->is_sentence_end;
-}
-
-enum Direction {
-    DirectionForward,
-    DirectionBackwards
-};
-
-static bool findCharacterAttribute(isCharacterAttribute predicateFunction, PangoLogAttr* attributes, Direction direction, int startOffset, int attrsLength, int* resultOffset)
-{
-    int advanceBy = direction == DirectionForward ? 1 : -1;
-
-    *resultOffset = -1;
-
-    for (int i = startOffset; i >= 0 && i < attrsLength; i += advanceBy) {
-        if (predicateFunction(attributes + i)) {
-            *resultOffset = i;
-            return true;
-        }
-    }
-
-    return false;
-}
-
-static bool findCharacterAttributeSkip(isCharacterAttribute predicateFunction, unsigned skip, PangoLogAttr* attributes, Direction direction, int startOffset, int attrsLength, int* resultOffset)
+static GailTextUtil* getGailTextUtilForAtk(AtkText* textObject)
 {
-    int tmpOffset;
+    gpointer data = g_object_get_data(G_OBJECT(textObject), "webkit-accessible-gail-text-util");
+    if (data)
+        return static_cast<GailTextUtil*>(data);
 
-    bool retValue = findCharacterAttribute(predicateFunction, attributes, direction, startOffset, attrsLength, &tmpOffset);
-    if (skip == 0) {
-        *resultOffset = tmpOffset;
-        return retValue;
-    }
-
-    if (direction == DirectionForward)
-        tmpOffset++;
-    else
-        tmpOffset--;
-
-    return findCharacterAttributeSkip(predicateFunction, skip - 1, attributes, direction, tmpOffset, attrsLength, resultOffset);
-}
-
-static isCharacterAttribute oppositePredicate(isCharacterAttribute predicate)
-{
-    if (predicate == isWordStart)
-        return isWordEnd;
-    if (predicate == isWordEnd)
-        return isWordStart;
-    if (predicate == isSentenceStart)
-        return isSentenceEnd;
-    if (predicate == isSentenceEnd)
-        return isSentenceStart;
-
-    g_assert_not_reached();
-}
-
-static gchar* getTextHelper(GetTextFunctionType getTextFunctionType, AtkText* textObject, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
-{
-    AccessibilityObject* coreObject = core(textObject);
     String text;
-
-    *startOffset = *endOffset = -1;
+    AccessibilityObject* coreObject = core(textObject);
 
     if (coreObject->isTextControl())
         text = coreObject->text();
     else
         text = coreObject->textUnderElement();
 
-    char* cText = g_strdup(text.utf8().data());
-    glong textLength = g_utf8_strlen(cText, -1);
-
-    if (boundaryType == ATK_TEXT_BOUNDARY_CHAR) {
-        int effectiveOffset;
-
-        switch (getTextFunctionType) {
-        case AfterOffset:
-            effectiveOffset = offset + 1;
-            break;
-        case BeforeOffset:
-            effectiveOffset = offset - 1;
-            break;
-        case AtOffset:
-            effectiveOffset = offset;
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        *startOffset = effectiveOffset;
-        *endOffset = effectiveOffset + 1;
-    } else {
-        PangoLogAttr* attrs = g_new(PangoLogAttr, textLength + 1);
-        PangoLanguage* language = pango_language_get_default();
-        pango_get_log_attrs(cText, -1, -1, language, attrs, textLength + 1);
-      
-        isCharacterAttribute predicate;
-
-        if (boundaryType == ATK_TEXT_BOUNDARY_WORD_START)
-            predicate = isWordStart;
-        else if (boundaryType == ATK_TEXT_BOUNDARY_WORD_END)
-            predicate = isWordEnd;
-        else if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_START)
-            predicate = isSentenceStart;
-        else if (boundaryType == ATK_TEXT_BOUNDARY_SENTENCE_END)
-            predicate = isSentenceEnd;
-        else
-            // FIXME: bail out for now, since we are missing the LINE
-            // boundary implementations
-            goto out;
-
-        switch (boundaryType) {
-        case ATK_TEXT_BOUNDARY_WORD_START:
-        case ATK_TEXT_BOUNDARY_SENTENCE_START:
-            if (getTextFunctionType == AfterOffset) {
-                // Take the item after the current one in any case
-                findCharacterAttribute(predicate, attrs, DirectionForward, offset + 1, textLength + 1, startOffset);
-                findCharacterAttributeSkip(predicate, 1, attrs, DirectionForward, offset + 1, textLength + 1, endOffset);
-            } else if (getTextFunctionType == AtOffset) {
-                // Take the item at point if the offset is in an item or
-                // the item before otherwise
-                findCharacterAttribute(predicate, attrs, DirectionBackwards, offset, textLength + 1, startOffset);
-                if (!findCharacterAttribute(predicate, attrs, DirectionForward, offset + 1, textLength + 1, endOffset)) {
-                    findCharacterAttribute(oppositePredicate(predicate), attrs, DirectionForward, offset + 1, textLength + 1, endOffset);
-                    // We want to include the actual end boundary
-                    // here, since *_START would have done so. Advance
-                    // until the end of the string if possible
-                    if (*endOffset != -1 && *endOffset < textLength)
-                        *endOffset = textLength;
-                }
-            } else {
-                // Take the item before the point if the offset is in an
-                // item, or the the item before that one otherwise
-                findCharacterAttributeSkip(predicate, 1, attrs, DirectionBackwards, offset, textLength + 1, startOffset);
-                findCharacterAttribute(predicate, attrs, DirectionBackwards, offset, textLength + 1, endOffset);
-            }
-            break;
-        case ATK_TEXT_BOUNDARY_WORD_END:
-        case ATK_TEXT_BOUNDARY_SENTENCE_END:
-            if (getTextFunctionType == AfterOffset) {
-                // Take the item after the current item if the offset is
-                // in a item, or the item after that otherwise
-                findCharacterAttribute(predicate, attrs, DirectionForward, offset, textLength + 1, startOffset);
-                findCharacterAttributeSkip(predicate, 1, attrs, DirectionForward, offset, textLength + 1, endOffset);
-            } else if (getTextFunctionType == AtOffset) {
-                // Take the item at point if the offset is in a item or
-                // the item after otherwise
-                if (!findCharacterAttribute(predicate, attrs, DirectionBackwards, offset, textLength + 1, startOffset))
-                    // No match before offset, take the first opposite match at or before the offset
-                    findCharacterAttribute(oppositePredicate(predicate), attrs, DirectionBackwards, offset, textLength + 1, startOffset);
-                findCharacterAttribute(predicate, attrs, DirectionForward, offset + 1, textLength + 1, endOffset);
-            } else {
-                // Take the item before the point in any case
-                if (!findCharacterAttributeSkip(predicate, 1, attrs, DirectionBackwards, offset, textLength + 1, startOffset)) {
-                    int tmpOffset;
-                    // No match before offset, take the first opposite match at or before the offset
-                    findCharacterAttribute(predicate, attrs, DirectionBackwards, offset, textLength + 1, &tmpOffset);
-                    findCharacterAttribute(oppositePredicate(predicate), attrs, DirectionBackwards, tmpOffset - 1, textLength + 1, startOffset);
-                }
-                findCharacterAttribute(predicate, attrs, DirectionBackwards, offset, textLength + 1, endOffset);
-            }
-            break;
-        default:
-            g_assert_not_reached();
-        }
-
-        g_free(attrs);
-    }
-
- out:
-    if (*startOffset < 0 || *endOffset < 0) {
-        *startOffset = *endOffset = 0;
-        return g_strdup("");
-    }
-
-    char* start = g_utf8_offset_to_pointer(cText, (glong)*startOffset);
-    char* end = g_utf8_offset_to_pointer(cText, (glong)*endOffset);
-    char* resultText = g_strndup(start, end - start);
-    g_free(cText);
-    return resultText;
+    GailTextUtil* gailTextUtil = gail_text_util_new();
+    gail_text_util_text_setup(gailTextUtil, text.utf8().data());
+    g_object_set_data_full(G_OBJECT(textObject), "webkit-accessible-gail-text-util", gailTextUtil, g_object_unref);
+    return gailTextUtil;
 }
 
 static gchar* webkit_accessible_text_get_text_after_offset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
-    return getTextHelper(AfterOffset, text, offset, boundaryType, startOffset, endOffset);
+    return gail_text_util_get_text(getGailTextUtilForAtk(text), NULL, GAIL_AFTER_OFFSET, boundaryType, offset, startOffset, endOffset);
 }
 
 static gchar* webkit_accessible_text_get_text_at_offset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
-    return getTextHelper(AtOffset, text, offset, boundaryType, startOffset, endOffset);
+    return gail_text_util_get_text(getGailTextUtilForAtk(text), NULL, GAIL_AT_OFFSET, boundaryType, offset, startOffset, endOffset);
 }
 
 static gchar* webkit_accessible_text_get_text_before_offset(AtkText* text, gint offset, AtkTextBoundary boundaryType, gint* startOffset, gint* endOffset)
 {
-    return getTextHelper(BeforeOffset, text, offset, boundaryType, startOffset, endOffset);
+    return gail_text_util_get_text(getGailTextUtilForAtk(text), NULL, GAIL_BEFORE_OFFSET, boundaryType, offset, startOffset, endOffset);
 }
 
 static gunichar webkit_accessible_text_get_character_at_offset(AtkText* text, gint offset)
index 8df66e0..66e0d17 100644 (file)
@@ -1,3 +1,16 @@
+2009-06-10  Xan Lopez  <xlopez@igalia.com>
+
+        Reviewed by Jan Alonzo.
+
+        https://bugs.webkit.org/show_bug.cgi?id=25415
+        [GTK][ATK] Please implement support for get_text_at_offset
+
+        Update test for new implementation (it fixes two bugs and adds
+        actual implementations for LINE boundaries).
+
+        * tests/testatk.c:
+        (test_webkit_atk_get_text_at_offset):
+
 2009-06-09  Gustavo Noronha Silva  <gustavo.noronha@collabora.co.uk>
 
         Reviewed by Xan Lopez.
index 166a8e2..61eae60 100644 (file)
@@ -148,7 +148,7 @@ static void test_webkit_atk_get_text_at_offset(void)
                            5, " a", 7, 9);
 
     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_WORD_END,
-                           4, " is", 4, 7);
+                           4, " a", 7, 9);
 
     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_WORD_END,
                            58, " third", 57, 63);
@@ -192,7 +192,7 @@ static void test_webkit_atk_get_text_at_offset(void)
                            0, " This is the second sentence.", 15, 44);
 
     test_get_text_function(text_obj, atk_text_get_text_after_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
-                           15, " This is the second sentence.", 15, 44);
+                           15, " And this the third.", 44, 64);
 
     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
                            16, "This is a test.", 0, 15);
@@ -206,15 +206,16 @@ static void test_webkit_atk_get_text_at_offset(void)
     test_get_text_function(text_obj, atk_text_get_text_before_offset, ATK_TEXT_BOUNDARY_SENTENCE_END,
                            44, " This is the second sentence.", 15, 44);
 
+    /* It's trick to test these properly right now, since our a11y
+       implementation splits different lines in different a11y
+       items */
     /* ATK_TEXT_BOUNDARY_LINE_START */
-    /* TODO */
     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_START,
-                           0, "", 0, 0);
+                           0, "This is a test. This is the second sentence. And this the third.", 0, 64);
 
     /* ATK_TEXT_BOUNDARY_LINE_END */
-    /* TODO */
     test_get_text_function(text_obj, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END,
-                           0, "", 0, 0);
+                           0, "This is a test. This is the second sentence. And this the third.", 0, 64);
 
     g_object_unref(webView);
 }
index 2ee8210..c0ee676 100644 (file)
@@ -192,6 +192,7 @@ SQLITE_REQUIRED_VERSION=3.0
 GSTREAMER_REQUIRED_VERSION=0.10
 GNOME_KEYRING_REQUIRED_VERSION=2.26.0
 ENCHANT_REQUIRED_VERSION=0.22
+GAIL_REQUIRED_VERSION=1.8
 
 # Available modules
 #
@@ -220,6 +221,10 @@ PKG_CHECK_MODULES(ENCHANT, enchant >= $ENCHANT_REQUIRED_VERSION)
 AC_SUBST(ENCHANT_CFLAGS)
 AC_SUBST(ENCHANT_LIBS)
 
+PKG_CHECK_MODULES(GAIL, gail >= $GAIL_REQUIRED_VERSION)
+AC_SUBST(GAIL_CFLAGS)
+AC_SUBST(GAIL_LIBS)
+
 # check for target-specific dependencies
 if test "$with_target" = "directfb"; then
    PKG_CHECK_MODULES(CAIRO, cairo-directfb >= $CAIRO_REQUIRED_VERSION)