summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android/nav')
-rw-r--r--WebKit/android/nav/SelectText.cpp88
-rw-r--r--WebKit/android/nav/SelectText.h4
-rw-r--r--WebKit/android/nav/WebView.cpp136
3 files changed, 124 insertions, 104 deletions
diff --git a/WebKit/android/nav/SelectText.cpp b/WebKit/android/nav/SelectText.cpp
index 9a9f8d2..d8b184a 100644
--- a/WebKit/android/nav/SelectText.cpp
+++ b/WebKit/android/nav/SelectText.cpp
@@ -35,14 +35,17 @@
#include "SkPoint.h"
#include "SkRect.h"
#include "SkRegion.h"
+#include "SkUtils.h"
class CommonCheck : public SkBounder {
public:
CommonCheck() : mMatrix(NULL), mPaint(NULL) {}
- virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y) {
+ virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y,
+ const void* text) {
mMatrix = &matrix;
mPaint = &paint;
+ mText = static_cast<const uint16_t*>(text);
mY = y;
mBase = mBottom = mTop = INT_MAX;
}
@@ -81,10 +84,11 @@ public:
protected:
const SkMatrix* mMatrix;
const SkPaint* mPaint;
+ const uint16_t* mText;
+ SkScalar mY;
int mBase;
int mBottom;
int mTop;
- SkScalar mY;
};
class FirstCheck : public CommonCheck {
@@ -162,6 +166,8 @@ public:
full.fRight = mLast.fLeft;
}
mSelectRegion->op(full, SkRegion::kUnion_Op);
+ DBG_NAV_LOGD("MultilineBuilder full=(%d,%d,r=%d,b=%d)",
+ full.fLeft, full.fTop, full.fRight, full.fBottom);
mLast = full;
mLastBase = base();
if (mStart == mEnd)
@@ -178,6 +184,66 @@ protected:
bool mCapture;
};
+class TextExtractor : public CommonCheck {
+public:
+ TextExtractor(const SkRegion& region) : mSelectRegion(region),
+ mSkipFirstSpace(true) { // don't start with a space
+ }
+
+ virtual void setUp(const SkPaint& paint, const SkMatrix& matrix, SkScalar y,
+ const void* text) {
+ INHERITED::setUp(paint, matrix, y, text);
+ SkPaint charPaint = paint;
+ charPaint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
+ mMinSpaceWidth = charPaint.measureText(" ", 1) * 3 / 4;
+ }
+
+ virtual bool onIRect(const SkIRect& rect, uint16_t glyphID) {
+ SkIRect full;
+ full.set(rect.fLeft, top(), rect.fRight, bottom());
+ if (mSelectRegion.contains(full)) {
+ if (!mSkipFirstSpace
+ && ((mLast.fTop < top() && mLast.fBottom < top() + 2)
+ || (mLast.fLeft < rect.fLeft // glyphs are LTR
+ && mLast.fRight + mMinSpaceWidth < rect.fLeft))) {
+ DBG_NAV_LOGD("TextExtractor [%02x] append space", glyphID);
+ *mSelectText.append() = ' ';
+ } else
+ mSkipFirstSpace = false;
+ DBG_NAV_LOGD("TextExtractor [%02x] append full=(%d,%d,r=%d,b=%d)",
+ glyphID, full.fLeft, full.fTop, full.fRight, full.fBottom);
+ SkUnichar uni;
+ SkPaint utfPaint = *mPaint;
+ utfPaint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
+ utfPaint.glyphsToUnichars(&glyphID, 1, &uni);
+ if (uni) {
+ uint16_t chars[2];
+ size_t count = SkUTF16_FromUnichar(uni, chars);
+ *mSelectText.append() = chars[0];
+ if (count == 2)
+ *mSelectText.append() = chars[1];
+ }
+ mLast = full;
+ } else
+ DBG_NAV_LOGD("TextExtractor [%02x] skip full=(%d,%d,r=%d,b=%d)",
+ glyphID, full.fLeft, full.fTop, full.fRight, full.fBottom);
+ return false;
+ }
+
+ WebCore::String text() {
+ return WebCore::String(mSelectText.begin(), mSelectText.count());
+ }
+
+protected:
+ const SkRegion& mSelectRegion;
+ SkTDArray<uint16_t> mSelectText;
+ SkIRect mLast;
+ SkScalar mMinSpaceWidth;
+ bool mSkipFirstSpace;
+private:
+ typedef CommonCheck INHERITED;
+};
+
class TextCanvas : public SkCanvas {
public:
@@ -218,14 +284,14 @@ public:
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint) {
- mBounder.setUp(paint, getTotalMatrix(), y);
+ mBounder.setUp(paint, getTotalMatrix(), y, text);
SkCanvas::drawText(text, byteLength, x, y, paint);
}
virtual void drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint) {
- mBounder.setUp(paint, getTotalMatrix(), constY);
+ mBounder.setUp(paint, getTotalMatrix(), constY, text);
SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
}
@@ -262,3 +328,17 @@ SkIRect CopyPaste::findClosest(const SkPicture& picture, const SkIRect& area,
_check.offsetBounds(area.fLeft, area.fTop);
return _check.bestBounds();
}
+
+WebCore::String CopyPaste::text(const SkPicture& picture, const SkIRect& area,
+ const SkRegion& region) {
+ SkRegion copy = region;
+ copy.translate(-area.fLeft, -area.fTop);
+ const SkIRect& bounds = copy.getBounds();
+ DBG_NAV_LOGD("area=(%d, %d, %d, %d) region=(%d, %d, %d, %d)",
+ area.fLeft, area.fTop, area.fRight, area.fBottom,
+ bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom);
+ TextExtractor extractor(copy);
+ TextCanvas checker(&extractor, picture, area);
+ checker.drawPicture(const_cast<SkPicture&>(picture));
+ return extractor.text();
+}
diff --git a/WebKit/android/nav/SelectText.h b/WebKit/android/nav/SelectText.h
index 3365816..32d8311 100644
--- a/WebKit/android/nav/SelectText.h
+++ b/WebKit/android/nav/SelectText.h
@@ -26,6 +26,8 @@
#ifndef SELECT_TEXT_H
#define SELECT_TEXT_H
+#include "PlatformString.h"
+
class SkPicture;
struct SkIRect;
struct SkIPoint;
@@ -37,6 +39,8 @@ public:
const SkIRect& selStart, const SkIRect& selEnd, SkRegion* region);
static SkIRect findClosest(const SkPicture& , const SkIRect& area,
int x, int y);
+ static WebCore::String text(const SkPicture& , const SkIRect& area,
+ const SkRegion& );
};
#endif
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index fd6a1da..cd767e2 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -34,6 +34,7 @@
#include "CachedFrame.h"
#include "CachedNode.h"
#include "CachedRoot.h"
+#include "CString.h"
#include "FindCanvas.h"
#include "Frame.h"
#include "GraphicsJNI.h"
@@ -98,7 +99,7 @@ enum FrameCachePermission {
};
struct JavaGlue {
- jobject m_obj;
+ jweak m_obj;
jmethodID m_clearTextEntry;
jmethodID m_overrideLoading;
jmethodID m_scrollBy;
@@ -128,7 +129,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
{
jclass clazz = env->FindClass("android/webkit/WebView");
// m_javaGlue = new JavaGlue;
- m_javaGlue.m_obj = adoptGlobalRef(env, javaWebView);
+ m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView);
m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z");
m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "()V");
m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V");
@@ -175,7 +176,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl)
if (m_javaGlue.m_obj)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- env->DeleteGlobalRef(m_javaGlue.m_obj);
+ env->DeleteWeakGlobalRef(m_javaGlue.m_obj);
m_javaGlue.m_obj = 0;
}
delete m_frameCacheUI;
@@ -216,12 +217,7 @@ void clearTextEntry()
{
DEBUG_NAV_UI_LOGD("%s", __FUNCTION__);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_clearTextEntry);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_clearTextEntry);
checkException(env);
}
@@ -648,12 +644,7 @@ int getScaledMaxXScroll()
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return 0;
- int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxXScroll);
+ int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxXScroll);
checkException(env);
return result;
}
@@ -662,12 +653,7 @@ int getScaledMaxYScroll()
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return 0;
- int result = env->CallIntMethod(obj.get(), m_javaGlue.m_getScaledMaxYScroll);
+ int result = env->CallIntMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getScaledMaxYScroll);
checkException(env);
return result;
}
@@ -676,12 +662,7 @@ void getVisibleRect(WebCore::IntRect* rect)
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- jobject jRect = env->CallObjectMethod(obj.get(), m_javaGlue.m_getVisibleRect);
+ jobject jRect = env->CallObjectMethod(m_javaGlue.object(env).get(), m_javaGlue.m_getVisibleRect);
checkException(env);
int left = (int) env->GetIntField(jRect, m_javaGlue.m_rectLeft);
checkException(env);
@@ -1003,13 +984,9 @@ int getBlockLeftEdge(int x, int y, float scale)
void overrideUrlLoading(const WebCore::String& url)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
jstring jName = env->NewString((jchar*) url.characters(), url.length());
- env->CallVoidMethod(obj.get(), m_javaGlue.m_overrideLoading, jName);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_overrideLoading, jName);
env->DeleteLocalRef(jName);
}
@@ -1056,9 +1033,15 @@ void moveSelection(int x, int y, bool extendSelection)
m_selEnd.fLeft, m_selEnd.fTop, m_selEnd.fRight, m_selEnd.fBottom);
}
-const SkRegion& getSelection()
+const String getSelection()
{
- return m_selRegion;
+ WebCore::IntRect r;
+ getVisibleRect(&r);
+ SkIRect area;
+ area.set(r.x(), r.y(), r.right(), r.bottom());
+ String result = CopyPaste::text(*m_navPictureUI, area, m_selRegion);
+ DBG_NAV_LOGD("text=%s", result.latin1().data());
+ return result;
}
void drawSelectionRegion(SkCanvas* canvas)
@@ -1133,15 +1116,10 @@ void getSelectionCaret(SkPath* path)
void sendMoveFocus(WebCore::Frame* framePtr, WebCore::Node* nodePtr)
{
- DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y);
+ DBG_NAV_LOGD("framePtr=%p nodePtr=%p", framePtr, nodePtr);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveFocus, (jint) framePtr,
- (jint) nodePtr);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_sendMoveFocus, (jint) framePtr, (jint) nodePtr);
checkException(env);
}
@@ -1149,12 +1127,7 @@ void sendMoveMouse(WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int
{
DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", framePtr, nodePtr, x, y);
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouse,
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMoveMouse,
(jint) framePtr, (jint) nodePtr, x, y);
checkException(env);
}
@@ -1163,12 +1136,8 @@ void sendMoveMouseIfLatest(bool disableFocusController)
{
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_sendMoveMouseIfLatest, disableFocusController);
checkException(env);
}
@@ -1180,12 +1149,7 @@ void sendMotionUp(
m_generation, framePtr, nodePtr, x, y);
LOG_ASSERT(m_javaGlue.m_obj, "A WebView was not associated with this WebViewNative!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_sendMotionUp,
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_sendMotionUp,
m_generation, (jint) framePtr, (jint) nodePtr, x, y);
checkException(env);
}
@@ -1254,12 +1218,7 @@ bool scrollBy(int dx, int dy)
LOG_ASSERT(m_javaGlue.m_obj, "A java object was not associated with this native WebView!");
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return false;
- bool result = env->CallBooleanMethod(obj.get(),
+ bool result = env->CallBooleanMethod(m_javaGlue.object(env).get(),
m_javaGlue.m_scrollBy, dx, dy, true);
checkException(env);
return result;
@@ -1296,24 +1255,15 @@ bool hasFocusNode()
void rebuildWebTextView()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_rebuildWebTextView);
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_rebuildWebTextView);
checkException(env);
}
void displaySoftKeyboard(bool isTextView)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(),
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
m_javaGlue.m_displaySoftKeyboard, isTextView);
checkException(env);
}
@@ -1321,37 +1271,22 @@ void displaySoftKeyboard(bool isTextView)
void viewInvalidate()
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidate);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidate);
checkException(env);
}
void viewInvalidateRect(int l, int t, int r, int b)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b);
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_viewInvalidateRect, l, r, t, b);
checkException(env);
}
void postInvalidateDelayed(int64_t delay, const WebCore::IntRect& bounds)
{
JNIEnv* env = JSC::Bindings::getJNIEnv();
- AutoJObject obj = m_javaGlue.object(env);
- // if it is called during or after DESTROY is handled, the real object of
- // WebView can be gone. Check before using it.
- if (!obj.get())
- return;
- env->CallVoidMethod(obj.get(), m_javaGlue.m_postInvalidateDelayed,
- delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom());
+ env->CallVoidMethod(m_javaGlue.object(env).get(), m_javaGlue.m_postInvalidateDelayed,
+ delay, bounds.x(), bounds.y(), bounds.right(), bounds.bottom());
checkException(env);
}
@@ -2152,7 +2087,8 @@ static jobject nativeGetSelection(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
LOG_ASSERT(view, "view not set in %s", __FUNCTION__);
- return GraphicsJNI::createRegion(env, new SkRegion(view->getSelection()));
+ String selection = view->getSelection();
+ return env->NewString((jchar*)selection.characters(), selection.length());
}
#ifdef ANDROID_DUMP_DISPLAY_TREE
@@ -2288,7 +2224,7 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeFocusNodePointer },
{ "nativeGetCursorRingBounds", "()Landroid/graphics/Rect;",
(void*) nativeGetCursorRingBounds },
- { "nativeGetSelection", "()Landroid/graphics/Region;",
+ { "nativeGetSelection", "()Ljava/lang/String;",
(void*) nativeGetSelection },
{ "nativeHasCursorNode", "()Z",
(void*) nativeHasCursorNode },