diff options
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 32 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 4 | ||||
-rw-r--r-- | WebKit/android/nav/FindCanvas.cpp | 7 | ||||
-rw-r--r-- | WebKit/android/nav/FindCanvas.h | 1 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 96 |
5 files changed, 90 insertions, 50 deletions
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index c0851dd..b0c2629 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -349,6 +349,38 @@ bool LayerAndroid::prepareContext(bool force) return m_recordingPicture; } +SkRect LayerAndroid::subtractLayers(const SkRect& visibleRect) const +{ + SkRect result; + if (m_recordingPicture) { + SkRect globalRect = bounds(); + globalRect.offset(-getPosition()); // localToGlobal adds in position + SkMatrix globalMatrix; + localToGlobal(&globalMatrix); + globalMatrix.mapRect(&globalRect); + SkIRect roundedGlobal; + globalRect.round(&roundedGlobal); + SkIRect iVisibleRect; + visibleRect.round(&iVisibleRect); + SkRegion visRegion(iVisibleRect); + visRegion.op(roundedGlobal, SkRegion::kDifference_Op); + result.set(visRegion.getBounds()); +#if DEBUG_NAV_UI + SkDebugf("%s visibleRect=(%g,%g,r=%g,b=%g) globalRect=(%g,%g,r=%g,b=%g)" + "result=(%g,%g,r=%g,b=%g)", __FUNCTION__, + visibleRect.fLeft, visibleRect.fTop, + visibleRect.fRight, visibleRect.fBottom, + globalRect.fLeft, globalRect.fTop, + globalRect.fRight, globalRect.fBottom, + result.fLeft, result.fTop, result.fRight, result.fBottom); +#endif + } else + result = visibleRect; + for (int i = 0; i < countChildren(); i++) + result = getChild(i)->subtractLayers(result); + return result; +} + // Debug tools : dump the layers tree in a file. // The format is simple: // properties have the form: key = value; diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 3cd7e36..2554fb9 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -119,6 +119,10 @@ public: SkPicture* picture() const { return m_recordingPicture; } + // remove layers bounds from visible rectangle to show what can be + // scrolled into view; returns original minus layer bounds in global space. + SkRect subtractLayers(const SkRect& visibleRect) const; + void dumpLayers(FILE*, int indentLevel) const; void dumpToLog() const; diff --git a/WebKit/android/nav/FindCanvas.cpp b/WebKit/android/nav/FindCanvas.cpp index 5f02888..e4beb88 100644 --- a/WebKit/android/nav/FindCanvas.cpp +++ b/WebKit/android/nav/FindCanvas.cpp @@ -522,6 +522,13 @@ IntRect FindOnPage::currentMatchBounds() const { return info.getLocation().getBounds(); } +bool FindOnPage::currentMatchIsInLayer() const { + if (!m_matches || !m_matches->size()) + return false; + MatchInfo& info = (*m_matches)[m_findIndex]; + return info.isInLayer(); +} + // This function is only used by findNext and setMatches. In it, we store // upper left corner of the match specified by m_findIndex in // m_currentMatchLocation. diff --git a/WebKit/android/nav/FindCanvas.h b/WebKit/android/nav/FindCanvas.h index 0b896b8..b9dbeea 100644 --- a/WebKit/android/nav/FindCanvas.h +++ b/WebKit/android/nav/FindCanvas.h @@ -220,6 +220,7 @@ public: virtual ~FindOnPage() { delete m_matches; } void clearCurrentLocation() { m_hasCurrentLocation = false; } IntRect currentMatchBounds() const; + bool currentMatchIsInLayer() const; virtual void draw(SkCanvas* , LayerAndroid* ); void findNext(bool forward); void setMatches(WTF::Vector<MatchInfo>* matches); diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 40e96bf..37bee07 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -103,6 +103,7 @@ enum DrawExtras { // keep this in sync with WebView.java struct JavaGlue { jweak m_obj; + jmethodID m_calcOurContentVisibleRect; jmethodID m_clearTextEntry; jmethodID m_overrideLoading; jmethodID m_scrollBy; @@ -114,7 +115,6 @@ struct JavaGlue { jmethodID m_getScaledMaxXScroll; jmethodID m_getScaledMaxYScroll; jmethodID m_getVisibleRect; - jmethodID m_getViewMetrics; jmethodID m_rebuildWebTextView; jmethodID m_viewInvalidate; jmethodID m_viewInvalidateRect; @@ -123,11 +123,6 @@ struct JavaGlue { jfieldID m_rectTop; jmethodID m_rectWidth; jmethodID m_rectHeight; - jfieldID m_metricsScrollX; - jfieldID m_metricsScrollY; - jfieldID m_metricsWidth; - jfieldID m_metricsHeight; - jfieldID m_metricsInvScale; AutoJObject object(JNIEnv* env) { return getRealObject(env, m_obj); } @@ -140,6 +135,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : // m_javaGlue = new JavaGlue; m_javaGlue.m_obj = env->NewWeakGlobalRef(javaWebView); m_javaGlue.m_scrollBy = GetJMethod(env, clazz, "setContentScrollBy", "(IIZ)Z"); + m_javaGlue.m_calcOurContentVisibleRect = GetJMethod(env, clazz, "calcOurContentVisibleRect", "(Landroid/graphics/Rect;)V"); m_javaGlue.m_clearTextEntry = GetJMethod(env, clazz, "clearTextEntry", "(Z)V"); m_javaGlue.m_overrideLoading = GetJMethod(env, clazz, "overrideLoading", "(Ljava/lang/String;)V"); m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V"); @@ -150,7 +146,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I"); m_javaGlue.m_getScaledMaxYScroll = GetJMethod(env, clazz, "getScaledMaxYScroll", "()I"); m_javaGlue.m_getVisibleRect = GetJMethod(env, clazz, "sendOurVisibleRect", "()Landroid/graphics/Rect;"); - m_javaGlue.m_getViewMetrics = GetJMethod(env, clazz, "getViewMetrics", "()Landroid/webkit/WebView$Metrics;"); m_javaGlue.m_rebuildWebTextView = GetJMethod(env, clazz, "rebuildWebTextView", "()V"); m_javaGlue.m_viewInvalidate = GetJMethod(env, clazz, "viewInvalidate", "()V"); m_javaGlue.m_viewInvalidateRect = GetJMethod(env, clazz, "viewInvalidate", "(IIII)V"); @@ -162,13 +157,6 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) : m_javaGlue.m_rectTop = env->GetFieldID(rectClass, "top", "I"); m_javaGlue.m_rectWidth = GetJMethod(env, rectClass, "width", "()I"); m_javaGlue.m_rectHeight = GetJMethod(env, rectClass, "height", "()I"); - jclass metricsClass = env->FindClass("android/webkit/WebView$Metrics"); - m_javaGlue.m_metricsScrollX = env->GetFieldID(metricsClass, "mScrollX", "I"); - m_javaGlue.m_metricsScrollY = env->GetFieldID(metricsClass, "mScrollY", "I"); - m_javaGlue.m_metricsWidth = env->GetFieldID(metricsClass, "mWidth", "I"); - m_javaGlue.m_metricsHeight = env->GetFieldID(metricsClass, "mHeight", "I"); - m_javaGlue.m_metricsInvScale = env->GetFieldID(metricsClass, "mInvScale", "F"); - env->SetIntField(javaWebView, gWebViewField, (jint)this); m_viewImpl = (WebViewCore*) viewImpl; m_frameCacheUI = 0; @@ -296,35 +284,57 @@ void nativeRecordButtons(bool hasFocus, bool pressed, bool invalidate) } } +// The caller has already determined that the desired document rect corresponds +// to the main picture, and not a layer void scrollRectOnScreen(const IntRect& rect) { if (rect.isEmpty()) return; - WebCore::IntRect visible; - getVisibleRect(&visible); + SkRect visible; + calcOurContentVisibleRect(&visible); + if (m_rootLayer) { + m_rootLayer->updatePositions(visible); + visible = m_rootLayer->subtractLayers(visible); + } int dx = 0; int left = rect.x(); int right = rect.right(); - if (left < visible.x()) { - dx = left - visible.x(); + if (left < visible.fLeft) { + dx = left - visible.fLeft; // Only scroll right if the entire width can fit on screen. - } else if (right > visible.right() && right - left < visible.width()) { - dx = right - visible.right(); + } else if (right > visible.fRight && right - left < visible.width()) { + dx = right - visible.fRight; } int dy = 0; int top = rect.y(); int bottom = rect.bottom(); - if (top < visible.y()) { - dy = top - visible.y(); + if (top < visible.fTop) { + dy = top - visible.fTop; // Only scroll down if the entire height can fit on screen - } else if (bottom > visible.bottom() && bottom - top < visible.height()) { - dy = bottom - visible.bottom(); + } else if (bottom > visible.fBottom && bottom - top < visible.height()) { + dy = bottom - visible.fBottom; } if ((dx|dy) == 0 || !scrollBy(dx, dy)) return; viewInvalidate(); } +void calcOurContentVisibleRect(SkRect* r) +{ + JNIEnv* env = JSC::Bindings::getJNIEnv(); + jclass rectClass = env->FindClass("android/graphics/Rect"); + jmethodID init = env->GetMethodID(rectClass, "<init>", "(IIII)V"); + jobject jRect = env->NewObject(rectClass, init, 0, 0, 0, 0); + env->CallVoidMethod(m_javaGlue.object(env).get(), + m_javaGlue.m_calcOurContentVisibleRect, jRect); + r->fLeft = env->GetIntField(jRect, m_javaGlue.m_rectLeft); + r->fTop = env->GetIntField(jRect, m_javaGlue.m_rectTop); + r->fRight = r->fLeft + env->CallIntMethod(jRect, m_javaGlue.m_rectWidth); + r->fBottom = r->fTop + env->CallIntMethod(jRect, m_javaGlue.m_rectHeight); + env->DeleteLocalRef(jRect); + checkException(env); +} + void resetCursorRing() { m_ring.m_followedLink = false; @@ -405,11 +415,11 @@ void drawExtras(SkCanvas* canvas, int extras) if (!m_rootLayer) return; m_rootLayer->setExtra(extra); - SkRect viewMetrics; - getViewMetrics(&viewMetrics); + SkRect visible; + calcOurContentVisibleRect(&visible); // call this to be sure we've adjusted for any scrolling or animations // before we actually draw - m_rootLayer->updatePositions(viewMetrics); + m_rootLayer->updatePositions(visible); m_rootLayer->draw(canvas); #endif } @@ -531,12 +541,12 @@ CachedRoot* getFrameCache(FrameCachePermission allowNewer) m_frameCacheUI->setRootLayer(m_rootLayer); #if USE(ACCELERATED_COMPOSITING) if (layerId >= 0) { - SkRect viewMetrics; - getViewMetrics(&viewMetrics); + SkRect visible; + calcOurContentVisibleRect(&visible); LayerAndroid* layer = const_cast<LayerAndroid*>( m_frameCacheUI->rootLayer()); if (layer) { - layer->updatePositions(viewMetrics); + layer->updatePositions(visible); } } #endif @@ -599,23 +609,6 @@ void getVisibleRect(WebCore::IntRect* rect) checkException(env); } -void getViewMetrics(SkRect* viewMetrics) -{ - JNIEnv* env = JSC::Bindings::getJNIEnv(); - jobject jMetrics = env->CallObjectMethod(m_javaGlue.object(env).get(), - m_javaGlue.m_getViewMetrics); - checkException(env); - int scrollX = env->GetIntField(jMetrics, m_javaGlue.m_metricsScrollX); - int scrollY = env->GetIntField(jMetrics, m_javaGlue.m_metricsScrollY); - int width = env->GetIntField(jMetrics, m_javaGlue.m_metricsWidth); - int height = env->GetIntField(jMetrics, m_javaGlue.m_metricsHeight); - float invScale = env->GetFloatField(jMetrics, m_javaGlue.m_metricsInvScale); - viewMetrics->set(scrollX * invScale, scrollY * invScale, - (scrollX + width) * invScale, (scrollY + height) * invScale); - env->DeleteLocalRef(jMetrics); - checkException(env); -} - static CachedFrame::Direction KeyToDirection(KeyCode keyCode) { switch (keyCode) { @@ -999,7 +992,8 @@ void sendMotionUp( void findNext(bool forward) { m_findOnPage.findNext(forward); - scrollRectOnScreen(m_findOnPage.currentMatchBounds()); + if (!m_findOnPage.currentMatchIsInLayer()) + scrollRectOnScreen(m_findOnPage.currentMatchBounds()); viewInvalidate(); } @@ -1008,7 +1002,8 @@ void findNext(bool forward) void setMatches(WTF::Vector<MatchInfo>* matches) { m_findOnPage.setMatches(matches); - scrollRectOnScreen(m_findOnPage.currentMatchBounds()); + if (!m_findOnPage.currentMatchIsInLayer()) + scrollRectOnScreen(m_findOnPage.currentMatchBounds()); viewInvalidate(); } @@ -1717,7 +1712,8 @@ static bool nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj) const_cast<CachedNode*>(next)); view->sendMoveFocus(static_cast<WebCore::Frame*>(frame->framePointer()), static_cast<WebCore::Node*>(next->nodePointer())); - view->scrollRectOnScreen(bounds); + if (!next->isInLayer()) + view->scrollRectOnScreen(bounds); view->getWebViewCore()->m_moveGeneration++; return true; } |