summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.cpp10
-rw-r--r--WebKit/android/WebCoreSupport/ChromeClientAndroid.h8
-rw-r--r--WebKit/android/WebCoreSupport/FileSystemClient.h41
-rw-r--r--WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp4
-rw-r--r--WebKit/android/WebCoreSupport/PlatformBridge.cpp20
-rw-r--r--WebKit/android/jni/JavaBridge.cpp19
-rw-r--r--WebKit/android/jni/JavaSharedClient.cpp12
-rw-r--r--WebKit/android/jni/JavaSharedClient.h4
-rw-r--r--WebKit/android/jni/WebCoreFrameBridge.cpp24
-rw-r--r--WebKit/android/jni/WebViewCore.cpp23
-rw-r--r--WebKit/android/nav/SelectText.cpp104
-rw-r--r--WebKit/android/nav/SelectText.h6
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