Changeset 45760 in webkit


Ignore:
Timestamp:
Jul 12, 2009 10:25:21 AM (15 years ago)
Author:
xan@webkit.org
Message:

2009-07-12 Xan Lopez <xlopez@igalia.com>

Reviewed by Gustavo Noronha.

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

Create a PangoLayout that properly represents the visual
appearance of the text in the web page so that the line boundary
modes of getText{At,Before,After}Offset work correctly.

  • accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: (UTF16ToUTF8): (g_substr): (convertUniCharToUTF8): (getPangoLayoutForAtk):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r45759 r45760  
     12009-07-12  Xan Lopez  <xlopez@igalia.com>
     2
     3        Reviewed by Gustavo Noronha.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=25415
     6        [GTK][ATK] Please implement support for get_text_at_offset
     7
     8        Create a PangoLayout that properly represents the visual
     9        appearance of the text in the web page so that the line boundary
     10        modes of getText{At,Before,After}Offset work correctly.
     11
     12        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
     13        (UTF16ToUTF8):
     14        (g_substr):
     15        (convertUniCharToUTF8):
     16        (getPangoLayoutForAtk):
     17
    1182009-07-11  Oliver Hunt  <oliver@apple.com>
    219
  • trunk/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp

    r45549 r45760  
    4444#include "HostWindow.h"
    4545#include "HTMLNames.h"
     46#include "InlineTextBox.h"
    4647#include "IntRect.h"
    4748#include "NotImplemented.h"
     49#include "RenderText.h"
    4850
    4951#include <atk/atk.h>
     
    514516}
    515517
     518#define IS_HIGH_SURROGATE(u)  ((UChar)(u) >= (UChar)0xd800 && (UChar)(u) <= (UChar)0xdbff)
     519#define IS_LOW_SURROGATE(u)   ((UChar)(u) >= (UChar)0xdc00 && (UChar)(u) <= (UChar)0xdfff)
     520
     521static void UTF16ToUTF8(const UChar* aText, gint aLength, char* &text, gint &length)
     522{
     523    gboolean needCopy = FALSE;
     524    int i;
     525
     526    for (i = 0; i < aLength; i++) {
     527        if (!aText[i] || IS_LOW_SURROGATE(aText[i])) {
     528            needCopy = TRUE;
     529            break;
     530        } else if (IS_HIGH_SURROGATE(aText[i])) {
     531            if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
     532                i++;
     533            else {
     534                needCopy = TRUE;
     535                break;
     536            }
     537        }
     538    }
     539
     540    if (needCopy) {
     541        /* Pango doesn't correctly handle nuls.  We convert them to 0xff. */
     542        /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */
     543
     544        UChar* p = (UChar*)g_memdup(aText, aLength * sizeof(aText[0]));
     545
     546        /* don't need to reset i */
     547        for (i = 0; i < aLength; i++) {
     548            if (!p[i] || IS_LOW_SURROGATE(p[i]))
     549                p[i] = 0xFFFD;
     550            else if (IS_HIGH_SURROGATE(p[i])) {
     551                if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1]))
     552                    i++;
     553                else
     554                    p[i] = 0xFFFD;
     555            }
     556        }
     557
     558        aText = p;
     559    }
     560
     561    glong items_written;
     562    text = g_utf16_to_utf8(reinterpret_cast<const gunichar2*>(aText), aLength, NULL, &items_written, NULL);
     563    length = items_written;
     564
     565    if (needCopy)
     566        g_free((gpointer)aText);
     567
     568}
     569
     570static gchar* g_substr(const gchar* string, gint start, gint end)
     571{
     572    gsize len = end - start + 1;
     573    gchar* output = static_cast<gchar*>(g_malloc0(len + 1));
     574    return g_utf8_strncpy(output, string +start, len);
     575}
     576
     577// This function is not completely general, is it's tied to the
     578// internals of WebCore's text presentation.
     579static gchar* convertUniCharToUTF8(const UChar* characters, gint length, int from, int to)
     580{
     581    gchar* utf8 = 0;
     582    gint newLength = 0;
     583    UTF16ToUTF8(characters, length, utf8, newLength);
     584    if (!utf8)
     585        return NULL;
     586
     587    gchar *pos = g_substr(utf8, from, to);
     588    g_free(utf8);
     589    gint len = strlen(pos);
     590    GString* ret = g_string_new_len(NULL, len);
     591
     592    // WebCore introduces line breaks in the text that do not reflect
     593    // the layout you see on the screen, replace them with spaces
     594    while (len > 0) {
     595        gint index, start;
     596        pango_find_paragraph_boundary(pos, len, &index, &start);
     597        g_string_append_len(ret, pos, index);
     598        if (index == start)
     599            break;
     600        g_string_append_c(ret, ' ');
     601        pos += start;
     602        len -= start;
     603    }
     604
     605    return g_string_free(ret, FALSE);
     606}
     607
    516608static PangoLayout* getPangoLayoutForAtk(AtkText* textObject)
    517609{
     
    531623    g_signal_connect(webView, "style-set", G_CALLBACK(updateLayout), textObject);
    532624    g_signal_connect(webView, "direction-changed", G_CALLBACK(updateLayout), textObject);
    533     PangoLayout* layout = gtk_widget_create_pango_layout(static_cast<GtkWidget*>(webView), webkit_accessible_text_get_text(textObject, 0, -1));
     625
     626    GString* str = g_string_new(NULL);
     627
     628    AccessibilityRenderObject* accObject = static_cast<AccessibilityRenderObject*>(coreObject);
     629    if (!accObject)
     630        return 0;
     631    RenderText* renderText = static_cast<RenderText*>(accObject->renderer());
     632    if (!renderText)
     633        return 0;
     634
     635    // Create a string with the layout as it appears on the screen
     636    InlineTextBox* box = renderText->firstTextBox();
     637    while (box) {
     638        gchar *text = convertUniCharToUTF8(renderText->characters(), renderText->textLength(), box->start(), box->end());
     639        g_string_append(str, text);
     640        g_string_append(str, "\n");
     641        box = box->nextTextBox();
     642    }
     643
     644    PangoLayout* layout = gtk_widget_create_pango_layout(static_cast<GtkWidget*>(webView), g_string_free(str, FALSE));
    534645    g_object_set_data_full(G_OBJECT(textObject), "webkit-accessible-pango-layout", layout, g_object_unref);
    535646    return layout;
Note: See TracChangeset for help on using the changeset viewer.