summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2009-07-29 14:38:23 -0400
committerCary Clark <cary@android.com>2009-07-31 13:15:23 -0400
commitfa768f11d82c34980cce020f442329299efb08ca (patch)
tree775331596b3c453e37ff85d70411cafa628defe0
parent686f7d9aacbb54b81e6f8c51b1a07103ca90f703 (diff)
downloadexternal_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.
-rw-r--r--WebKit/android/jni/WebViewCore.cpp23
-rw-r--r--WebKit/android/jni/WebViewCore.h1
-rw-r--r--WebKit/android/nav/CachedRoot.cpp46
-rw-r--r--WebKit/android/nav/CachedRoot.h2
-rw-r--r--WebKit/android/nav/WebView.cpp11
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 }