18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright 2008, The Android Open Source Project
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  * Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
163298a7d84b96ade73c6b170671711a8f2792ae59Steve Block * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
253298a7d84b96ade73c6b170671711a8f2792ae59Steve Block
26a3054d2b31d3e00563e3865d398ef93d25b8b2e0Cary Clark#define LOG_TAG "webviewglue"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
28dea0c131566f424923425970fe5621305d136e5aJohn Reck#include "config.h"
29dea0c131566f424923425970fe5621305d136e5aJohn Reck
300df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark#include "BidiResolver.h"
312525b58059d38fb2f98efc6fa54ee85859d26ed2Ben Murdoch#include "BidiRunList.h"
32dea0c131566f424923425970fe5621305d136e5aJohn Reck#include "GLExtras.h"
3387962ce00229855c098ba12cee8d5c015a835289Cary Clark#include "LayerAndroid.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SelectText.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkBitmap.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkBounder.h"
37dea0c131566f424923425970fe5621305d136e5aJohn Reck#include "SkCanvas.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkPicture.h"
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkPoint.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkRect.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "SkRegion.h"
420df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark#include "TextRun.h"
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4487962ce00229855c098ba12cee8d5c015a835289Cary Clark#ifdef DEBUG_NAV_UI
4579768700a853c40c66ff0b0591957958667fdd9eSteve Block#include <wtf/text/CString.h>
4687962ce00229855c098ba12cee8d5c015a835289Cary Clark#endif
4787962ce00229855c098ba12cee8d5c015a835289Cary Clark
48a3054d2b31d3e00563e3865d398ef93d25b8b2e0Cary Clark#define VERBOSE_LOGGING 0
49a3054d2b31d3e00563e3865d398ef93d25b8b2e0Cary Clark// #define EXTRA_NOISY_LOGGING 1
5062740ff35119cc54e82b6af582a01dd34b9e027eJohn Reck#define DEBUG_TOUCH_HANDLES 0
51e94313e95fb5e08870a58c7a4b593da08cc3d424John Reck#if DEBUG_TOUCH_HANDLES
52a09e7cf49f43950a799f936bf42a9912d696547bSteve Block#define DBG_HANDLE_LOG(format, ...) ALOGD("%s " format, __FUNCTION__, __VA_ARGS__)
53e94313e95fb5e08870a58c7a4b593da08cc3d424John Reck#else
54e94313e95fb5e08870a58c7a4b593da08cc3d424John Reck#define DBG_HANDLE_LOG(...)
55e94313e95fb5e08870a58c7a4b593da08cc3d424John Reck#endif
56a3054d2b31d3e00563e3865d398ef93d25b8b2e0Cary Clark
570df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark// TextRunIterator has been copied verbatim from GraphicsContext.cpp
580df9dc35976c248d3f486a51e719d54cb02d7351Cary Clarknamespace WebCore {
590df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
600df9dc35976c248d3f486a51e719d54cb02d7351Cary Clarkclass TextRunIterator {
610df9dc35976c248d3f486a51e719d54cb02d7351Cary Clarkpublic:
620df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    TextRunIterator()
630df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        : m_textRun(0)
640df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        , m_offset(0)
650df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    {
660df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    }
670df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
680df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    TextRunIterator(const TextRun* textRun, unsigned offset)
690df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        : m_textRun(textRun)
700df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        , m_offset(offset)
710df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    {
720df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    }
730df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
740df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    TextRunIterator(const TextRunIterator& other)
750df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        : m_textRun(other.m_textRun)
760df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        , m_offset(other.m_offset)
770df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    {
780df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    }
790df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
800df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    unsigned offset() const { return m_offset; }
810df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    void increment() { m_offset++; }
820df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bool atEnd() const { return !m_textRun || m_offset >= m_textRun->length(); }
830df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    UChar current() const { return (*m_textRun)[m_offset]; }
840df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    WTF::Unicode::Direction direction() const { return atEnd() ? WTF::Unicode::OtherNeutral : WTF::Unicode::direction(current()); }
850df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
860df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bool operator==(const TextRunIterator& other)
870df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    {
880df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        return m_offset == other.m_offset && m_textRun == other.m_textRun;
890df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    }
900df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
910df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bool operator!=(const TextRunIterator& other) { return !operator==(other); }
920df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
930df9dc35976c248d3f486a51e719d54cb02d7351Cary Clarkprivate:
940df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    const TextRun* m_textRun;
950df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    int m_offset;
960df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark};
970df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
980df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark// ReverseBidi is a trimmed-down version of GraphicsContext::drawBidiText()
990df9dc35976c248d3f486a51e719d54cb02d7351Cary Clarkvoid ReverseBidi(UChar* chars, int len) {
1000df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    using namespace WTF::Unicode;
1010df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    WTF::Vector<UChar> result;
1020df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    result.reserveCapacity(len);
1030df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    TextRun run(chars, len);
1040df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
1052525b58059d38fb2f98efc6fa54ee85859d26ed2Ben Murdoch    BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
1060df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bidiResolver.setStatus(BidiStatus(LeftToRight, LeftToRight, LeftToRight,
1070df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        BidiContext::create(0, LeftToRight, false)));
1080df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bidiResolver.setPosition(TextRunIterator(&run, 0));
1090df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    bidiResolver.createBidiRunsForLine(TextRunIterator(&run, len));
1102525b58059d38fb2f98efc6fa54ee85859d26ed2Ben Murdoch    if (!bidiRuns.runCount())
1110df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        return;
1122525b58059d38fb2f98efc6fa54ee85859d26ed2Ben Murdoch    BidiCharacterRun* bidiRun = bidiRuns.firstRun();
1130df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    while (bidiRun) {
1140df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        int bidiStart = bidiRun->start();
1150df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        int bidiStop = bidiRun->stop();
1160df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        int size = result.size();
1170df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        int bidiCount = bidiStop - bidiStart;
1180df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        result.append(chars + bidiStart, bidiCount);
1190df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        if (bidiRun->level() % 2) {
1200df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            UChar* start = &result[size];
1210df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            UChar* end = start + bidiCount;
1220df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            // reverse the order of any RTL substrings
1230df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            while (start < end) {
1240df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                UChar temp = *start;
1250df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                *start++ = *--end;
1260df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                *end = temp;
1270df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            }
1280df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            start = &result[size];
1290df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            end = start + bidiCount - 1;
1300df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            // if the RTL substring had a surrogate pair, restore its order
1310df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            while (start < end) {
1320df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                UChar trail = *start++;
1330df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                if (!U16_IS_SURROGATE(trail))
1340df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                    continue;
1350df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                start[-1] = *start; // lead
1360df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark                *start++ = trail;
1370df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark            }
1380df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        }
1390df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark        bidiRun = bidiRun->next();
1400df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    }
1412525b58059d38fb2f98efc6fa54ee85859d26ed2Ben Murdoch    bidiRuns.deleteRuns();
1420df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark    memcpy(chars, &result[0], len * sizeof(UChar));
1430df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark}
1440df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
1450df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark}
1460df9dc35976c248d3f486a51e719d54cb02d7351Cary Clark
147