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