diff options
author | Cary Clark <cary@android.com> | 2009-07-29 14:38:23 -0400 |
---|---|---|
committer | Cary Clark <cary@android.com> | 2009-07-31 13:15:23 -0400 |
commit | fa768f11d82c34980cce020f442329299efb08ca (patch) | |
tree | 775331596b3c453e37ff85d70411cafa628defe0 /WebKit | |
parent | 686f7d9aacbb54b81e6f8c51b1a07103ca90f703 (diff) | |
download | external_webkit-fa768f11d82c34980cce020f442329299efb08ca.zip external_webkit-fa768f11d82c34980cce020f442329299efb08ca.tar.gz external_webkit-fa768f11d82c34980cce020f442329299efb08ca.tar.bz2 |
rebuild the nav cache on mouse clicks during page load
While the page is loading, the nav cache is not rebuilt.
Double-click zooms out the web page by using the nav cache to
find the left edge of the column -- but fails to work during
page load. This change rebuilds the nav cache (if the page is
loading) each time a mouse click is sent to webkit.
This doesn't fix the bug where the first double click doesn't
align the column correctly, but helps with subsequent clicks.
Also, pass scale information to getBlockLeftEdge so it can
restrict its search to the area that will be zoomed to. Default
to the point clicked if no alignment info can be found.
Diffstat (limited to 'WebKit')
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 23 | ||||
-rw-r--r-- | WebKit/android/jni/WebViewCore.h | 1 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 46 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.h | 2 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 11 |
5 files changed, 59 insertions, 24 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index da19aba..726f724 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -362,13 +362,19 @@ WebCore::Node* WebViewCore::currentFocus() void WebViewCore::recordPicture(SkPicture* picture) { // if there is no document yet, just return - if (!m_mainFrame->document()) + if (!m_mainFrame->document()) { + DBG_NAV_LOG("no document"); return; + } // Call layout to ensure that the contentWidth and contentHeight are correct - if (!layoutIfNeededRecursive(m_mainFrame)) + if (!layoutIfNeededRecursive(m_mainFrame)) { + DBG_NAV_LOG("layout failed"); return; + } // draw into the picture's recording canvas WebCore::FrameView* view = m_mainFrame->view(); + DBG_NAV_LOGD("view=(w=%d,h=%d)", view->contentsWidth(), + view->contentsHeight()); SkAutoPictureRecord arp(picture, view->contentsWidth(), view->contentsHeight(), PICT_RECORD_FLAGS); SkAutoMemoryUsageProbe mup(__FUNCTION__); @@ -1141,6 +1147,12 @@ void WebViewCore::updateFrameCache() gFrameCacheMutex.unlock(); } +void WebViewCore::updateFrameCacheIfLoading() +{ + if (!m_check_domtree_version) + updateFrameCache(); +} + /////////////////////////////////////////////////////////////////////////////// void WebViewCore::addPlugin(PluginWidgetAndroid* w) @@ -2116,6 +2128,11 @@ static jstring WebCoreStringToJString(JNIEnv *env, WebCore::String string) return ret; } +static void UpdateFrameCacheIfLoading(JNIEnv *env, jobject obj) +{ + GET_NATIVE_VIEW(env, obj)->updateFrameCacheIfLoading(); +} + static void SetSize(JNIEnv *env, jobject obj, jint width, jint height, jint screenWidth, jfloat scale, jint realScreenWidth, jint screenHeight) { @@ -2715,6 +2732,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = { { "nativeFreeMemory", "()V", (void*) FreeMemory }, { "nativeSetJsFlags", "(Ljava/lang/String;)V", (void*) SetJsFlags }, { "nativeUpdatePluginState", "(III)V", (void*) UpdatePluginState }, + { "nativeUpdateFrameCacheIfLoading", "()V", + (void*) UpdateFrameCacheIfLoading }, }; int register_webviewcore(JNIEnv* env) diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h index 64f4857..a2737c8 100644 --- a/WebKit/android/jni/WebViewCore.h +++ b/WebKit/android/jni/WebViewCore.h @@ -371,6 +371,7 @@ namespace android { float scale() const { return m_scale; } float screenWidthScale() const { return m_screenWidthScale; } WebCore::Frame* mainFrame() const { return m_mainFrame; } + void updateFrameCacheIfLoading(); // utility to split slow parts of the picture set void splitContent(); diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index cf029c2..2a8e3e6 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -342,7 +342,7 @@ class LeftCheck : public CommonCheck { public: LeftCheck(int x, int y) : mX(x), mY(y), mHitLeft(INT_MAX), mMostLeft(INT_MAX) { - mHit.set(x - SLOP, y - SLOP, x + SLOP, y + SLOP); + mHit.set(x - (HIT_SLOP << 1), y - HIT_SLOP, x, y + HIT_SLOP); mPartial.setEmpty(); mBounds.setEmpty(); } @@ -350,7 +350,7 @@ public: int left() { if (isTextType(mType)) doRect(); // process the final line of text - return mMostLeft != INT_MAX ? mMostLeft : mX; + return mMostLeft != INT_MAX ? mMostLeft : mX >> 1; } // FIXME: this is identical to CenterCheck::onIRect() @@ -385,13 +385,14 @@ public: if (SkIRect::Intersects(mPartial, mHit)) { if (mHitLeft > mPartial.fLeft) mHitLeft = mPartial.fLeft; - DBG_NAV_LOGD("mHitLeft=%d", mHitLeft); + DBG_NAV_LOGD("LeftCheck mHitLeft=%d", mHitLeft); } else if (mHitLeft == INT_MAX) return; // wait for intersect success /* If text is too far away vertically, don't consider it */ if (!mBounds.isEmpty() && (mPartial.fTop > mBounds.fBottom + SLOP || mPartial.fBottom < mBounds.fTop - SLOP)) { - DBG_NAV_LOGD("stop mPartial=(%d, %d, %d, %d) mBounds=(%d, %d, %d, %d)", + DBG_NAV_LOGD("LeftCheck stop mPartial=(%d, %d, %d, %d)" + " mBounds=(%d, %d, %d, %d)", mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom, mBounds.fLeft, mBounds.fTop, mBounds.fRight, mBounds.fBottom); mHitLeft = INT_MAX; // and disable future comparisons @@ -400,24 +401,27 @@ public: /* If the considered text is completely to the left or right of the touch coordinates, skip it, turn off further detection */ if (mPartial.fLeft > mX || mPartial.fRight < mX) { - DBG_NAV_LOGD("stop mX=%d mPartial=(%d, %d, %d, %d)", mX, + DBG_NAV_LOGD("LeftCheck stop mX=%d mPartial=(%d, %d, %d, %d)", mX, mPartial.fLeft, mPartial.fTop, mPartial.fRight, mPartial.fBottom); mHitLeft = INT_MAX; return; } /* record the smallest margins on the left and right */ if (mMostLeft > mPartial.fLeft) { - DBG_NAV_LOGD("new mMostLeft=%d (old=%d)", mPartial.fLeft, mMostLeft); + DBG_NAV_LOGD("LeftCheck new mMostLeft=%d (old=%d)", mPartial.fLeft, + mMostLeft); mMostLeft = mPartial.fLeft; } if (mBounds.isEmpty()) mBounds = mPartial; else if (mPartial.fBottom > mBounds.fBottom) { - DBG_NAV_LOGD("new bottom=%d (old=%d)", mPartial.fBottom, mBounds.fBottom); + DBG_NAV_LOGD("LeftCheck new bottom=%d (old=%d)", mPartial.fBottom, + mBounds.fBottom); mBounds.fBottom = mPartial.fBottom; } } + static const int HIT_SLOP = 5; // space between text parts and lines static const int SLOP = 30; // space between text parts and lines /* const */ SkIRect mHit; // sloppy hit rectangle SkIRect mBounds; // reference bounds @@ -816,9 +820,11 @@ int CachedRoot::getAndResetSelectionStart() return start; } -int CachedRoot::getBlockLeftEdge(int x, int y) const +int CachedRoot::getBlockLeftEdge(int x, int y, float scale) const { - DBG_NAV_LOGD("x=%d y=%d", x, y); + DBG_NAV_LOGD("x=%d y=%d scale=%g mViewBounds=(%d,%d,%d,%d)", x, y, scale, + mViewBounds.x(), mViewBounds.y(), mViewBounds.width(), + mViewBounds.height()); // if (x, y) is in a textArea or textField, return that const int slop = 1; WebCore::IntRect rect = WebCore::IntRect(x - slop, y - slop, @@ -826,18 +832,26 @@ int CachedRoot::getBlockLeftEdge(int x, int y) const const CachedFrame* frame; int fx, fy; const CachedNode* node = findAt(rect, &frame, &fx, &fy, true); - if (node && (node->isTextArea() || node->isTextField() || node->isPlugin())) + if (node && (node->isTextArea() || node->isTextField() || node->isPlugin())) { + DBG_NAV_LOGD("x=%d (%s)", node->bounds().x(), + node->isTextArea() || node->isTextField() ? "text" : "plugin"); return node->bounds().x(); - LeftCheck leftCheck(x - mViewBounds.x(), y - mViewBounds.y()); + } + int halfW = (int) (mViewBounds.width() * scale * 0.5f); + int fullW = halfW << 1; + int halfH = (int) (mViewBounds.height() * scale * 0.5f); + int fullH = halfH << 1; + LeftCheck leftCheck(fullW, halfH); BoundsCanvas checker(&leftCheck); SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, mViewBounds.width(), - mViewBounds.height()); + bitmap.setConfig(SkBitmap::kARGB_8888_Config, fullW, fullH); checker.setBitmapDevice(bitmap); - checker.translate(SkIntToScalar(-mViewBounds.x()), - SkIntToScalar(-mViewBounds.y())); + checker.translate(SkIntToScalar(fullW - x), SkIntToScalar(halfH - y)); checker.drawPicture(*mPicture); - return leftCheck.left(); + int result = x + leftCheck.left() - fullW; + DBG_NAV_LOGD("halfW=%d halfH=%d mMostLeft=%d x=%d", + halfW, halfH, leftCheck.mMostLeft, result); + return result; } void CachedRoot::getSimulatedMousePosition(WebCore::IntPoint* point) const diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h index 23cc126..123e7d2 100644 --- a/WebKit/android/nav/CachedRoot.h +++ b/WebKit/android/nav/CachedRoot.h @@ -66,7 +66,7 @@ public: SkPicture* getPicture() { return mPicture; } int getAndResetSelectionEnd(); int getAndResetSelectionStart(); - int getBlockLeftEdge(int x, int y) const; + int getBlockLeftEdge(int x, int y, float scale) const; void getSimulatedMousePosition(WebCore::IntPoint* ) const; void init(WebCore::Frame* , CachedHistory* ); bool innerDown(const CachedNode* , BestData* ) const; diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index cbc91ae..ced21d2 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -966,11 +966,11 @@ bool motionUp(int x, int y, int slop) return pageScrolled; } -int getBlockLeftEdge(int x, int y) +int getBlockLeftEdge(int x, int y, float scale) { CachedRoot* root = getFrameCache(AllowNewer); if (root) - return root->getBlockLeftEdge(x, y); + return root->getBlockLeftEdge(x, y, scale); return -1; } @@ -1857,13 +1857,14 @@ static void nativeUpdateCachedTextfield(JNIEnv *env, jobject obj, jstring update checkException(env); } -static jint nativeGetBlockLeftEdge(JNIEnv *env, jobject obj, jint x, jint y) +static jint nativeGetBlockLeftEdge(JNIEnv *env, jobject obj, jint x, jint y, + jfloat scale) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); if (!view) return -1; - return view->getBlockLeftEdge(x, y); + return view->getBlockLeftEdge(x, y, scale); } static void nativeDestroy(JNIEnv *env, jobject obj) @@ -2085,7 +2086,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeTextGeneration }, { "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V", (void*) nativeUpdateCachedTextfield }, - { "nativeGetBlockLeftEdge", "(II)I", + { "nativeGetBlockLeftEdge", "(IIF)I", (void*) nativeGetBlockLeftEdge }, { "nativeUpdatePluginReceivesEvents", "()V", (void*) nativeUpdatePluginReceivesEvents } |