diff options
Diffstat (limited to 'WebKit')
| -rw-r--r-- | WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp | 10 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/ChromeClientAndroid.h | 8 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/FileSystemClient.h | 41 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 4 | ||||
| -rw-r--r-- | WebKit/android/WebCoreSupport/PlatformBridge.cpp | 20 | ||||
| -rw-r--r-- | WebKit/android/jni/JavaBridge.cpp | 19 | ||||
| -rw-r--r-- | WebKit/android/jni/JavaSharedClient.cpp | 12 | ||||
| -rw-r--r-- | WebKit/android/jni/JavaSharedClient.h | 4 | ||||
| -rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 24 | ||||
| -rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 23 | ||||
| -rw-r--r-- | WebKit/android/nav/SelectText.cpp | 104 | ||||
| -rw-r--r-- | WebKit/android/nav/SelectText.h | 6 |
12 files changed, 246 insertions, 29 deletions
diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp index b59689d..ead81e0 100644 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp @@ -57,11 +57,16 @@ static unsigned long long tryToReclaimDatabaseQuota(SecurityOrigin* originNeedin #if USE(ACCELERATED_COMPOSITING) -void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client) +void ChromeClientAndroid::layersSync() { if (!m_rootGraphicsLayer) return; + if (!m_needsLayerSync) + return; + + m_needsLayerSync = false; + if (m_webFrame) { FrameView* frameView = m_webFrame->page()->mainFrame()->view(); if (frameView && frameView->syncCompositingStateRecursive()) { @@ -77,8 +82,7 @@ void ChromeClientAndroid::syncTimerFired(Timer<ChromeClientAndroid>* client) void ChromeClientAndroid::scheduleCompositingLayerSync() { - if (!m_syncTimer.isActive()) - m_syncTimer.startOneShot(0); + m_needsLayerSync = true; } void ChromeClientAndroid::setNeedsOneShotDrawingSynchronization() diff --git a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h index 902d84c..28f2546 100644 --- a/WebKit/android/WebCoreSupport/ChromeClientAndroid.h +++ b/WebKit/android/WebCoreSupport/ChromeClientAndroid.h @@ -46,8 +46,7 @@ namespace android { ChromeClientAndroid() : m_webFrame(0), m_geolocationPermissions(0) #if USE(ACCELERATED_COMPOSITING) , m_rootGraphicsLayer(0) - , m_askToDrawAgain(false) - , m_syncTimer(this, &ChromeClientAndroid::syncTimerFired) + , m_needsLayerSync(false) #endif , m_triedToReclaimDBQuota(false) { } @@ -170,7 +169,7 @@ namespace android { virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer* g); virtual void setNeedsOneShotDrawingSynchronization(); virtual void scheduleCompositingLayerSync(); - void syncTimerFired(Timer<ChromeClientAndroid>*); + void layersSync(); #endif private: @@ -179,8 +178,7 @@ namespace android { OwnPtr<GeolocationPermissions> m_geolocationPermissions; #if USE(ACCELERATED_COMPOSITING) WebCore::GraphicsLayer* m_rootGraphicsLayer; - bool m_askToDrawAgain; - Timer<ChromeClientAndroid> m_syncTimer; + bool m_needsLayerSync; #endif WTF::ThreadCondition m_quotaThreadCondition; WTF::Mutex m_quotaThreadLock; diff --git a/WebKit/android/WebCoreSupport/FileSystemClient.h b/WebKit/android/WebCoreSupport/FileSystemClient.h new file mode 100644 index 0000000..8847bda --- /dev/null +++ b/WebKit/android/WebCoreSupport/FileSystemClient.h @@ -0,0 +1,41 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FILESYSTEM_CLIENT_H +#define FILESYSTEM_CLIENT_H + +#include "PlatformString.h" + +using namespace WebCore; + +namespace android { + +class FileSystemClient { +public: + virtual ~FileSystemClient() { } + virtual String resolveFileNameForContentUri(const String&) = 0; +}; +} +#endif diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp index 697f7b9..79c64fd 100644 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp @@ -395,7 +395,9 @@ void FrameLoaderClientAndroid::dispatchDidFinishLoad() { void FrameLoaderClientAndroid::dispatchDidFirstLayout() { ASSERT(m_frame); - m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY); + // set EXTRA_LAYOUT_DELAY if the loader is not completed yet + if (!m_frame->loader()->isComplete()) + m_frame->document()->setExtraLayoutDelay(EXTRA_LAYOUT_DELAY); // we need to do this here instead of dispatchDidFirstVisuallyNonEmptyLayout // so that about:blank will update the screen. if (!m_frame->tree()->parent()) { diff --git a/WebKit/android/WebCoreSupport/PlatformBridge.cpp b/WebKit/android/WebCoreSupport/PlatformBridge.cpp index 05aa42b..c64bb9d 100644 --- a/WebKit/android/WebCoreSupport/PlatformBridge.cpp +++ b/WebKit/android/WebCoreSupport/PlatformBridge.cpp @@ -27,9 +27,12 @@ #include <PlatformBridge.h> #include "CookieClient.h" +#include "FileSystemClient.h" +#include "FrameView.h" #include "JavaSharedClient.h" #include "KeyGeneratorClient.h" #include "PluginView.h" +#include "WebCoreFrameBridge.h" #include "WebViewCore.h" #include "npruntime.h" #include <wtf/android/AndroidThreading.h> @@ -135,11 +138,28 @@ bool PlatformBridge::isWebViewPaused(const WebCore::FrameView* frameView) return webViewCore->isPaused(); } +bool PlatformBridge::canScroll(const WebCore::FrameView* frameView) +{ + // We want to ignore requests to scroll that were not initiated by the + // user. An example of this is when text is inserted into a + // textfield/area, which results in a scroll. We ignore this because + // we know how to do this ourselves in the UI thread. + // An example of it being initiated by the user is if the user clicks + // an anchor element which simply scrolls the page. + return android::WebFrame::getWebFrame(frameView->frame())->userInitiatedClick(); +} + bool PlatformBridge::popupsAllowed(NPP) { return false; } +String PlatformBridge::resolveFileNameForContentUri(const String& contentUri) +{ + FileSystemClient* client = JavaSharedClient::GetFileSystemClient(); + return client->resolveFileNameForContentUri(contentUri); +} + } // namespace WebCore diff --git a/WebKit/android/jni/JavaBridge.cpp b/WebKit/android/jni/JavaBridge.cpp index 0e65e1c..2d95f87 100644 --- a/WebKit/android/jni/JavaBridge.cpp +++ b/WebKit/android/jni/JavaBridge.cpp @@ -31,6 +31,7 @@ #include "Cache.h" #include "Connection.h" #include "CookieClient.h" +#include "FileSystemClient.h" #include "JavaSharedClient.h" #include "KeyGeneratorClient.h" #include "KURL.h" @@ -62,7 +63,7 @@ static jfieldID gJavaBridge_ObjectID; // ---------------------------------------------------------------------------- -class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient +class JavaBridge : public TimerClient, public CookieClient, public PluginClient, public KeyGeneratorClient, public FileSystemClient { public: JavaBridge(JNIEnv* env, jobject obj); @@ -84,6 +85,7 @@ public: virtual WTF::Vector<String> getSupportedKeyStrengthList(); virtual WebCore::String getSignedPublicKeyAndChallengeString(unsigned index, const WebCore::String& challenge, const WebCore::KURL& url); + virtual WebCore::String resolveFileNameForContentUri(const WebCore::String& uri); //////////////////////////////////////////// @@ -120,6 +122,7 @@ private: jmethodID mSignalFuncPtrQueue; jmethodID mGetKeyStrengthList; jmethodID mGetSignedPublicKey; + jmethodID mResolveFileNameForContentUri; }; static void (*sSharedTimerFiredCallback)(); @@ -139,6 +142,7 @@ JavaBridge::JavaBridge(JNIEnv* env, jobject obj) mSignalFuncPtrQueue = env->GetMethodID(clazz, "signalServiceFuncPtrQueue", "()V"); mGetKeyStrengthList = env->GetMethodID(clazz, "getKeyStrengthList", "()[Ljava/lang/String;"); mGetSignedPublicKey = env->GetMethodID(clazz, "getSignedPublicKey", "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); + mResolveFileNameForContentUri = env->GetMethodID(clazz, "resolveFileNameForContentUri", "(Ljava/lang/String;)Ljava/lang/String;"); LOG_ASSERT(mSetSharedTimer, "Could not find method setSharedTimer"); LOG_ASSERT(mStopSharedTimer, "Could not find method stopSharedTimer"); @@ -154,6 +158,7 @@ JavaBridge::JavaBridge(JNIEnv* env, jobject obj) JavaSharedClient::SetCookieClient(this); JavaSharedClient::SetPluginClient(this); JavaSharedClient::SetKeyGeneratorClient(this); + JavaSharedClient::SetFileSystemClient(this); } JavaBridge::~JavaBridge() @@ -168,6 +173,7 @@ JavaBridge::~JavaBridge() JavaSharedClient::SetCookieClient(NULL); JavaSharedClient::SetPluginClient(NULL); JavaSharedClient::SetKeyGeneratorClient(NULL); + JavaSharedClient::SetFileSystemClient(NULL); } void @@ -308,6 +314,17 @@ WebCore::String JavaBridge::getSignedPublicKeyAndChallengeString(unsigned index, return ret; } +WebCore::String JavaBridge::resolveFileNameForContentUri(const WebCore::String& uri) { + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jstring jUri = env->NewString(uri.characters(), uri.length()); + AutoJObject obj = getRealObject(env, mJavaObject); + jstring path = static_cast<jstring>(env->CallObjectMethod(obj.get(), mResolveFileNameForContentUri, jUri)); + WebCore::String ret = to_string(env, path); + env->DeleteLocalRef(jUri); + env->DeleteLocalRef(path); + return ret; +} + // ---------------------------------------------------------------------------- void JavaBridge::Constructor(JNIEnv* env, jobject obj) diff --git a/WebKit/android/jni/JavaSharedClient.cpp b/WebKit/android/jni/JavaSharedClient.cpp index ce46570..e884c99 100644 --- a/WebKit/android/jni/JavaSharedClient.cpp +++ b/WebKit/android/jni/JavaSharedClient.cpp @@ -24,6 +24,7 @@ */ #include "config.h" +#include "FileSystemClient.h" #include "JavaSharedClient.h" #include "TimerClient.h" #include "SkDeque.h" @@ -50,6 +51,11 @@ namespace android { return gKeyGeneratorClient; } + FileSystemClient* JavaSharedClient::GetFileSystemClient() + { + return gFileSystemClient; + } + void JavaSharedClient::SetTimerClient(TimerClient* client) { gTimerClient = client; @@ -70,10 +76,16 @@ namespace android { gKeyGeneratorClient = client; } + void JavaSharedClient::SetFileSystemClient(FileSystemClient* client) + { + gFileSystemClient = client; + } + TimerClient* JavaSharedClient::gTimerClient = NULL; CookieClient* JavaSharedClient::gCookieClient = NULL; PluginClient* JavaSharedClient::gPluginClient = NULL; KeyGeneratorClient* JavaSharedClient::gKeyGeneratorClient = NULL; + FileSystemClient* JavaSharedClient::gFileSystemClient = NULL; /////////////////////////////////////////////////////////////////////////// diff --git a/WebKit/android/jni/JavaSharedClient.h b/WebKit/android/jni/JavaSharedClient.h index d33df67..9a09280 100644 --- a/WebKit/android/jni/JavaSharedClient.h +++ b/WebKit/android/jni/JavaSharedClient.h @@ -32,6 +32,7 @@ namespace android { class CookieClient; class PluginClient; class KeyGeneratorClient; + class FileSystemClient; class JavaSharedClient { @@ -40,11 +41,13 @@ namespace android { static CookieClient* GetCookieClient(); static PluginClient* GetPluginClient(); static KeyGeneratorClient* GetKeyGeneratorClient(); + static FileSystemClient* GetFileSystemClient(); static void SetTimerClient(TimerClient* client); static void SetCookieClient(CookieClient* client); static void SetPluginClient(PluginClient* client); static void SetKeyGeneratorClient(KeyGeneratorClient* client); + static void SetFileSystemClient(FileSystemClient* client); // can be called from any thread, to be executed in webkit thread static void EnqueueFunctionPtr(void (*proc)(void*), void* payload); @@ -56,6 +59,7 @@ namespace android { static CookieClient* gCookieClient; static PluginClient* gPluginClient; static KeyGeneratorClient* gKeyGeneratorClient; + static FileSystemClient* gFileSystemClient; }; } #endif diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 9ecb121..de172cd 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -116,6 +116,7 @@ using namespace JSC::Bindings; static String* gUploadFileLabel; static String* gResetLabel; static String* gSubmitLabel; +static String* gNoFileChosenLabel; String* WebCore::PlatformBridge::globalLocalizedName( WebCore::PlatformBridge::rawResId resId) @@ -127,6 +128,9 @@ String* WebCore::PlatformBridge::globalLocalizedName( return gResetLabel; case WebCore::PlatformBridge::SubmitLabel: return gSubmitLabel; + case WebCore::PlatformBridge::FileUploadNoFileChosenLabel: + return gNoFileChosenLabel; + default: return 0; } @@ -148,6 +152,9 @@ void initGlobalLocalizedName(WebCore::PlatformBridge::rawResId resId, case WebCore::PlatformBridge::SubmitLabel: pointer = &gSubmitLabel; break; + case WebCore::PlatformBridge::FileUploadNoFileChosenLabel: + pointer = &gNoFileChosenLabel; + break; default: return; } @@ -320,19 +327,6 @@ static jobject createJavaMapFromHTTPHeaders(JNIEnv* env, const WebCore::HTTPHead return hashMap; } -// In WebViewCore.java, we artificially append the filename to the URI so that -// webkit treats the actual display name of the file as the filename, rather -// than the last segment of the URI (which will simply be a number). When we -// pass the URI up to BrowserFrame, we no longer need the appended name (in fact -// it causes problems), so remove it here. -// FIXME: If we rewrite pathGetFileName (the current version is in -// FileSystemPOSIX), we can get the filename that way rather than appending it. -static jstring uriFromUriFileName(JNIEnv* env, const WebCore::String& name) -{ - const WebCore::String fileName = name.left(name.reverseFind('/')); - return env->NewString(fileName.characters(), fileName.length()); -} - // This class stores the URI and the size of each file for upload. The URI is // stored so we do not have to create it again. The size is stored so we can // compare the actual size of the file with the stated size. If the actual size @@ -341,7 +335,7 @@ static jstring uriFromUriFileName(JNIEnv* env, const WebCore::String& name) class FileInfo { public: FileInfo(JNIEnv* env, const WebCore::String& name) { - m_uri = uriFromUriFileName(env, name); + m_uri = env->NewString(name.characters(), name.length()); checkException(env); m_size = 0; m_env = env; @@ -940,7 +934,7 @@ static void CreateFrame(JNIEnv* env, jobject obj, jobject javaview, jobject jAss WebCore::RenderSkinAndroid::Init(am, directory); } for (int i = WebCore::PlatformBridge::FileUploadLabel; - i <= WebCore::PlatformBridge::SubmitLabel; i++) + i <= WebCore::PlatformBridge::FileUploadNoFileChosenLabel; i++) initGlobalLocalizedName( static_cast<WebCore::PlatformBridge::rawResId>(i), webFrame); } diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 50611c7..45356f8 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -308,7 +308,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_scrollBy = GetJMethod(env, clazz, "contentScrollBy", "(IIZ)V"); m_javaGlue->m_contentDraw = GetJMethod(env, clazz, "contentDraw", "()V"); m_javaGlue->m_requestListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[I[I)V"); - m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "()Ljava/lang/String;"); + m_javaGlue->m_openFileChooser = GetJMethod(env, clazz, "openFileChooser", "(Ljava/lang/String;)Ljava/lang/String;"); m_javaGlue->m_requestSingleListBox = GetJMethod(env, clazz, "requestListBox", "([Ljava/lang/String;[II)V"); m_javaGlue->m_jsAlert = GetJMethod(env, clazz, "jsAlert", "(Ljava/lang/String;Ljava/lang/String;)V"); m_javaGlue->m_jsConfirm = GetJMethod(env, clazz, "jsConfirm", "(Ljava/lang/String;Ljava/lang/String;)Z"); @@ -884,6 +884,12 @@ bool WebViewCore::recordContent(SkRegion* region, SkIPoint* point) region->getBounds().fTop, region->getBounds().fRight, region->getBounds().fBottom); DBG_SET_LOG("end"); + +#if USE(ACCELERATED_COMPOSITING) + // We update the layers + ChromeClientAndroid* chromeC = static_cast<ChromeClientAndroid*>(m_mainFrame->page()->chrome()->client()); + chromeC->layersSync(); +#endif return true; } @@ -1969,15 +1975,24 @@ void WebViewCore::openFileChooser(PassRefPtr<WebCore::FileChooser> chooser) { if (!chooser) return; JNIEnv* env = JSC::Bindings::getJNIEnv(); + + WebCore::String acceptType = chooser->acceptTypes(); + jstring jAcceptType = env->NewString(const_cast<unsigned short*>(acceptType.characters()), acceptType.length()); jstring jName = (jstring) env->CallObjectMethod( - m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser); + m_javaGlue->object(env).get(), m_javaGlue->m_openFileChooser, jAcceptType); checkException(env); - const UChar* string = (const UChar*) env->GetStringChars(jName, NULL); + env->DeleteLocalRef(jAcceptType); + + const UChar* string = static_cast<const UChar*>(env->GetStringChars(jName, NULL)); + if (!string) return; + WebCore::String webcoreString = to_string(env, jName); env->ReleaseStringChars(jName, string); - chooser->chooseFile(webcoreString); + + if (webcoreString.length()) + chooser->chooseFile(webcoreString); } void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, size_t count, const int enabled[], size_t enabledCount, diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp index 0fcbe95..29d47e5 100644 --- a/WebKit/android/nav/SelectText.cpp +++ b/WebKit/android/nav/SelectText.cpp @@ -26,6 +26,7 @@ #define LOG_TAG "webcoreglue" #include "CachedPrefix.h" +#include "BidiResolver.h" #include "CachedRoot.h" #include "LayerAndroid.h" #include "SelectText.h" @@ -39,11 +40,101 @@ #include "SkRect.h" #include "SkRegion.h" #include "SkUtils.h" +#include "TextRun.h" #ifdef DEBUG_NAV_UI #include <wtf/text/CString.h> #endif +// TextRunIterator has been copied verbatim from GraphicsContext.cpp +namespace WebCore { + +class TextRunIterator { +public: + TextRunIterator() + : m_textRun(0) + , m_offset(0) + { + } + + TextRunIterator(const TextRun* textRun, unsigned offset) + : m_textRun(textRun) + , m_offset(offset) + { + } + + TextRunIterator(const TextRunIterator& other) + : m_textRun(other.m_textRun) + , m_offset(other.m_offset) + { + } + + unsigned offset() const { return m_offset; } + void increment() { m_offset++; } + bool atEnd() const { return !m_textRun || m_offset >= m_textRun->length(); } + UChar current() const { return (*m_textRun)[m_offset]; } + WTF::Unicode::Direction direction() const { return atEnd() ? WTF::Unicode::OtherNeutral : WTF::Unicode::direction(current()); } + + bool operator==(const TextRunIterator& other) + { + return m_offset == other.m_offset && m_textRun == other.m_textRun; + } + + bool operator!=(const TextRunIterator& other) { return !operator==(other); } + +private: + const TextRun* m_textRun; + int m_offset; +}; + +// ReverseBidi is a trimmed-down version of GraphicsContext::drawBidiText() +void ReverseBidi(UChar* chars, int len) { + using namespace WTF::Unicode; + WTF::Vector<UChar> result; + result.reserveCapacity(len); + TextRun run(chars, len); + BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver; + bidiResolver.setStatus(BidiStatus(LeftToRight, LeftToRight, LeftToRight, + BidiContext::create(0, LeftToRight, false))); + bidiResolver.setPosition(TextRunIterator(&run, 0)); + bidiResolver.createBidiRunsForLine(TextRunIterator(&run, len)); + if (!bidiResolver.runCount()) + return; + BidiCharacterRun* bidiRun = bidiResolver.firstRun(); + while (bidiRun) { + int bidiStart = bidiRun->start(); + int bidiStop = bidiRun->stop(); + int size = result.size(); + int bidiCount = bidiStop - bidiStart; + result.append(chars + bidiStart, bidiCount); + if (bidiRun->level() % 2) { + UChar* start = &result[size]; + UChar* end = start + bidiCount; + // reverse the order of any RTL substrings + while (start < end) { + UChar temp = *start; + *start++ = *--end; + *end = temp; + } + start = &result[size]; + end = start + bidiCount - 1; + // if the RTL substring had a surrogate pair, restore its order + while (start < end) { + UChar trail = *start++; + if (!U16_IS_SURROGATE(trail)) + continue; + start[-1] = *start; // lead + *start++ = trail; + } + } + bidiRun = bidiRun->next(); + } + bidiResolver.deleteRuns(); + memcpy(chars, &result[0], len * sizeof(UChar)); +} + +} + namespace android { class CommonCheck : public SkBounder { @@ -264,6 +355,19 @@ public: } WebCore::String text() { + // the text has been copied in visual order. Reverse as needed if + // result contains right-to-left characters. + const uint16_t* start = mSelectText.begin(); + const uint16_t* end = mSelectText.end(); + while (start < end) { + SkUnichar ch = SkUTF16_NextUnichar(&start); + WTF::Unicode::Direction charDirection = WTF::Unicode::direction(ch); + if (WTF::Unicode::RightToLeftArabic == charDirection + || WTF::Unicode::RightToLeft == charDirection) { + WebCore::ReverseBidi(mSelectText.begin(), mSelectText.count()); + break; + } + } return WebCore::String(mSelectText.begin(), mSelectText.count()); } diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h index 8174046..2e17a74 100644 --- a/WebKit/android/nav/SelectText.h +++ b/WebKit/android/nav/SelectText.h @@ -81,4 +81,10 @@ private: } +namespace WebCore { + +void ReverseBidi(UChar* chars, int len); + +} + #endif |
