diff options
author | George Mount <mount@google.com> | 2012-03-21 11:09:27 -0700 |
---|---|---|
committer | George Mount <mount@google.com> | 2012-03-28 07:14:49 -0700 |
commit | 304991de60a64b43bffd0c910655ee4ef1e9683c (patch) | |
tree | fb352c7dbcb3e0f85f8eccc8262b2df7ab787797 /Source/WebKit | |
parent | ec2823d23ab1a53b60599e9192d86b37f2e44d5f (diff) | |
download | external_webkit-304991de60a64b43bffd0c910655ee4ef1e9683c.zip external_webkit-304991de60a64b43bffd0c910655ee4ef1e9683c.tar.gz external_webkit-304991de60a64b43bffd0c910655ee4ef1e9683c.tar.bz2 |
Snap selection handles to text.
Bug 6198286
Framework Change: I3c51ed5f6988d58440badfbe8b076fd83d48ae2a
Change-Id: I55604f3ec28586beaec5fd98a27c9f4b8a59a8a5
Diffstat (limited to 'Source/WebKit')
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 40 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.h | 1 | ||||
-rw-r--r-- | Source/WebKit/android/nav/SelectText.h | 3 | ||||
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 67 |
4 files changed, 96 insertions, 15 deletions
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index bb76c80..3fc17e3 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -1667,10 +1667,50 @@ SelectText* WebViewCore::createSelectText(const VisibleSelection& selection) selectTextContainer->setCaretRect(SelectText::EndHandle, endHandle); selectTextContainer->setText(range->text()); + selectTextContainer->setTextRect(SelectText::StartHandle, + positionToTextRect(selection.start())); + selectTextContainer->setTextRect(SelectText::EndHandle, + positionToTextRect(selection.end())); return selectTextContainer; } +IntRect WebViewCore::positionToTextRect(const Position& position) +{ + IntRect textRect; + InlineBox* inlineBox; + int offset; + position.getInlineBoxAndOffset(VP_DEFAULT_AFFINITY, inlineBox, offset); + if (inlineBox && inlineBox->isInlineTextBox()) { + InlineTextBox* box = static_cast<InlineTextBox*>(inlineBox); + RootInlineBox* root = box->root(); + RenderText* renderText = box->textRenderer(); + int left = root->logicalLeft(); + int width = root->logicalWidth(); + int top = root->selectionTop(); + int height = root->selectionHeight(); + + Node* node = position.anchorNode(); + LayerAndroid* layer = 0; + int layerId = platformLayerIdFromNode(node, &layer); + IntPoint layerOffset; + layerToAbsoluteOffset(layer, layerOffset); + + if (!renderText->style()->isHorizontalWritingMode()) { + swap(left, top); + swap(width, height); + } + FloatPoint origin(left, top); + FloatPoint absoluteOrigin = renderText->localToAbsolute(origin); + + textRect.setX(absoluteOrigin.x() - layerOffset.x()); + textRect.setWidth(width); + textRect.setY(absoluteOrigin.y() - layerOffset.y()); + textRect.setHeight(height); + } + return textRect; +} + IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, WebCore::Frame* frame) { if (!frame) frame = focusedFrame(); diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index d770117..5926991 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -752,6 +752,7 @@ namespace android { static bool isAutoCompleteEnabled(WebCore::Node* node); WebCore::IntRect boundingRect(WebCore::Node* node, WebCore::LayerAndroid* layer); + static WebCore::IntRect positionToTextRect(const WebCore::Position& position); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); diff --git a/Source/WebKit/android/nav/SelectText.h b/Source/WebKit/android/nav/SelectText.h index 904b2b9..50bc82e 100644 --- a/Source/WebKit/android/nav/SelectText.h +++ b/Source/WebKit/android/nav/SelectText.h @@ -43,6 +43,8 @@ public: IntRect& caretRect(HandleId id) { return m_caretRects[mapId(id)]; } void setCaretRect(HandleId id, const IntRect& rect) { m_caretRects[mapId(id)] = rect; } + IntRect& textRect(HandleId id) { return m_textRects[mapId(id)]; } + void setTextRect(HandleId id, const IntRect& rect) { m_textRects[mapId(id)] = rect; } int caretLayerId(HandleId id) { return m_caretLayerId[mapId(id)]; } void setCaretLayerId(HandleId id, int layerId) { m_caretLayerId[mapId(id)] = layerId; } @@ -56,6 +58,7 @@ private: HandleId mapId(HandleId id); IntRect m_caretRects[2]; + IntRect m_textRects[2]; int m_caretLayerId[2]; bool m_baseIsFirst; String m_text; diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index ddb9bcb..37291de 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -125,6 +125,10 @@ struct JavaGlue { jfieldID m_rectTop; jmethodID m_rectWidth; jmethodID m_rectHeight; + jfieldID m_quadFP1; + jfieldID m_quadFP2; + jfieldID m_quadFP3; + jfieldID m_quadFP4; AutoJObject object(JNIEnv* env) { return getRealObject(env, m_obj); } @@ -156,6 +160,14 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl, WTF::String drawableDir, m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); env->DeleteLocalRef(rectClass); + jclass quadFClass = env->FindClass("android/webkit/QuadF"); + ALOG_ASSERT(quadFClass, "Could not find QuadF class"); + m_javaGlue.m_quadFP1 = env->GetFieldID(quadFClass, "p1", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP2 = env->GetFieldID(quadFClass, "p2", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP3 = env->GetFieldID(quadFClass, "p3", "Landroid/graphics/PointF;"); + m_javaGlue.m_quadFP4 = env->GetFieldID(quadFClass, "p4", "Landroid/graphics/PointF;"); + env->DeleteLocalRef(quadFClass); + env->SetIntField(javaWebView, gWebViewField, (jint)this); m_viewImpl = (WebViewCore*) viewImpl; m_generation = 0; @@ -578,12 +590,20 @@ void setTextSelection(SelectText *selection) { setDrawExtra(selection, DrawExtrasSelection); } -int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { +int getHandleLayerId(SelectText::HandleId handleId, SkIPoint& cursorPoint, + FloatQuad& textBounds) { SelectText* selectText = static_cast<SelectText*>(getDrawExtra(DrawExtrasSelection)); if (!selectText || !m_baseLayer) return -1; int layerId = selectText->caretLayerId(handleId); - cursorRect = selectText->caretRect(handleId); + IntRect cursorRect = selectText->caretRect(handleId); + IntRect textRect = selectText->textRect(handleId); + // Rects exclude the last pixel on right/bottom. We want only included pixels. + cursorPoint.set(cursorRect.x(), cursorRect.maxY() - 1); + textRect.setHeight(textRect.height() - 1); + textRect.setWidth(textRect.width() - 1); + textBounds = FloatQuad(textRect); + if (layerId != -1) { // We need to make sure the drawTransform is up to date as this is // called before a draw() or drawGL() @@ -594,13 +614,8 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { const TransformationMatrix* transform = layer->drawTransform(); // We're overloading the concept of Rect to be just the two // points (bottom-left and top-right. - // TODO: Use FloatQuad instead. - IntPoint bottomLeft = transform->mapPoint(IntPoint(cursorRect.fLeft, - cursorRect.fBottom)); - IntPoint topRight = transform->mapPoint(IntPoint(cursorRect.fRight, - cursorRect.fTop)); - cursorRect.setLTRB(bottomLeft.x(), topRight.y(), topRight.x(), - bottomLeft.y()); + cursorPoint = transform->mapPoint(cursorPoint); + textBounds = transform->mapQuad(textBounds); } } return layerId; @@ -617,6 +632,23 @@ void mapLayerRect(int layerId, SkIRect& rect) { } } +void floatQuadToQuadF(JNIEnv* env, const FloatQuad& nativeTextQuad, + jobject textQuad) +{ + jobject p1 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP1); + jobject p2 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP2); + jobject p3 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP3); + jobject p4 = env->GetObjectField(textQuad, m_javaGlue.m_quadFP4); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p1(), env, p1); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p2(), env, p2); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p3(), env, p3); + GraphicsJNI::point_to_jpointf(nativeTextQuad.p4(), env, p4); + env->DeleteLocalRef(p1); + env->DeleteLocalRef(p2); + env->DeleteLocalRef(p3); + env->DeleteLocalRef(p4); +} + // This is called when WebView switches rendering modes in a more permanent fashion // such as when the layer type is set or the view is attached/detached from the window int setHwAccelerated(bool hwAccelerated) { @@ -1140,13 +1172,18 @@ static void nativeSetTextSelection(JNIEnv *env, jobject obj, jint nativeView, } static jint nativeGetHandleLayerId(JNIEnv *env, jobject obj, jint nativeView, - jint handleIndex, jobject cursorRect) + jint handleIndex, jobject cursorPoint, + jobject textQuad) { WebView* webview = reinterpret_cast<WebView*>(nativeView); - SkIRect nativeRect; - int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, nativeRect); - if (cursorRect) - GraphicsJNI::irect_to_jrect(nativeRect, env, cursorRect); + SkIPoint nativePoint; + FloatQuad nativeTextQuad; + int layerId = webview->getHandleLayerId((SelectText::HandleId) handleIndex, + nativePoint, nativeTextQuad); + if (cursorPoint) + GraphicsJNI::ipoint_to_jpoint(nativePoint, env, cursorPoint); + if (textQuad) + webview->floatQuadToQuadF(env, nativeTextQuad, textQuad); return layerId; } @@ -1247,7 +1284,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeSetPauseDrawing }, { "nativeSetTextSelection", "(II)V", (void*) nativeSetTextSelection }, - { "nativeGetHandleLayerId", "(IILandroid/graphics/Rect;)I", + { "nativeGetHandleLayerId", "(IILandroid/graphics/Point;Landroid/webkit/QuadF;)I", (void*) nativeGetHandleLayerId }, { "nativeIsBaseFirst", "(I)Z", (void*) nativeIsBaseFirst }, |