diff options
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.cpp | 51 | ||||
-rw-r--r-- | WebCore/platform/graphics/android/LayerAndroid.h | 8 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 21 |
3 files changed, 47 insertions, 33 deletions
diff --git a/WebCore/platform/graphics/android/LayerAndroid.cpp b/WebCore/platform/graphics/android/LayerAndroid.cpp index 68bdec0..ca9a0e3 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.cpp +++ b/WebCore/platform/graphics/android/LayerAndroid.cpp @@ -476,41 +476,44 @@ SkPicture* LayerAndroid::recordContext() return 0; } -bool LayerAndroid::scrollBy(int dx, int dy) { - if (!contentIsScrollable()) +bool LayerAndroid::scrollTo(int x, int y) { + SkIRect scrollBounds; + getScrollRect(&scrollBounds); + if (scrollBounds.fRight == 0 && scrollBounds.fBottom == 0) + return false; + + SkScalar newX = SkScalarPin(x, 0, scrollBounds.fRight); + SkScalar newY = SkScalarPin(y, 0, scrollBounds.fBottom); + // Check for no change. + if (newX == scrollBounds.fLeft && newY == scrollBounds.fTop) return false; + SkScalar diffX = newX - scrollBounds.fLeft; + SkScalar diffY = newY - scrollBounds.fTop; + const SkPoint& pos = getPosition(); + setPosition(pos.fX - diffX, pos.fY - diffY); + return true; +} + +void LayerAndroid::getScrollRect(SkIRect* out) const { + if (!contentIsScrollable()) + return; + // Scrollable layers have a mask layer and then the actual main layer. if (getParent() == 0 || getParent()->getParent() == 0) - return false; + return; LayerAndroid* realLayer = static_cast<LayerAndroid*>(getParent()->getParent()); SkRect scrollBounds; realLayer->bounds(&scrollBounds); const SkPoint& maskLayerPosition = getParent()->getPosition(); + const SkPoint& pos = getPosition(); // Our original position is the offset of the mask layer's position. - SkScalar maxX = -maskLayerPosition.fX; - SkScalar maxY = -maskLayerPosition.fY; - SkScalar minX = maxX - (getSize().width() - scrollBounds.width()); - SkScalar minY = maxY - (getSize().height() - scrollBounds.height()); - - // Move the layer's position by the difference and pin the result to within - // the scrollable range. - SkPoint diff; - diff.iset(dx, dy); - SkPoint pos = getPosition() - diff; - pos.fX = SkScalarPin(pos.fX, minX, maxX); - pos.fY = SkScalarPin(pos.fY, minY, maxY); - - // Update the difference to reflect the changes. - diff = getPosition() - pos; - if (diff.equals(0, 0)) - // no change - return false; - - setPosition(pos.fX, pos.fY); - return true; + out->fLeft = maskLayerPosition.fX - pos.fX; + out->fTop = maskLayerPosition.fY - pos.fY; + out->fRight = getSize().width() - scrollBounds.width(); + out->fBottom = getSize().height() - scrollBounds.height(); } bool LayerAndroid::prepareContext(bool force) diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index a9a9c69..30f5555 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -132,7 +132,13 @@ public: SkPicture* recordContext(); // Returns true if the content position has changed. - bool scrollBy(int dx, int dy); + bool scrollTo(int dx, int dy); + // Fills the rect with the current scroll offset and the maximum scroll. + // fLeft = scrollX + // fTop = scrollY + // fRight = maxX + // fBottom = maxY + void getScrollRect(SkIRect* out) const; void addAnimation(PassRefPtr<AndroidAnimation> anim); void removeAnimation(const String& name); diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 09a5c74..86f008b 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -995,15 +995,17 @@ static const LayerAndroid* findScrollableLayer(const LayerAndroid* parent, int x } #endif -int scrollableLayer(int x, int y) +int scrollableLayer(int x, int y, SkIRect* layerRect) { #if USE(ACCELERATED_COMPOSITING) const LayerAndroid* layerRoot = compositeRoot(); if (!layerRoot) return 0; const LayerAndroid* result = findScrollableLayer(layerRoot, x, y); - if (result) + if (result) { + result->getScrollRect(layerRect); return result->uniqueId(); + } #endif return 0; } @@ -2210,15 +2212,18 @@ static void nativeDumpDisplayTree(JNIEnv* env, jobject jwebview, jstring jurl) #endif } -static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y) +static int nativeScrollableLayer(JNIEnv* env, jobject jwebview, jint x, jint y, jobject rect) { WebView* view = GET_NATIVE_VIEW(env, jwebview); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); - return view->scrollableLayer(x, y); + SkIRect nativeRect; + int id = view->scrollableLayer(x, y, &nativeRect); + GraphicsJNI::irect_to_jrect(nativeRect, env, rect); + return id; } -static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint dx, - jint dy) +static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint x, + jint y) { #if ENABLE(ANDROID_OVERFLOW_SCROLL) WebView* view = GET_NATIVE_VIEW(env, obj); @@ -2228,7 +2233,7 @@ static bool nativeScrollLayer(JNIEnv* env, jobject obj, jint layerId, jint dx, LayerAndroid* layer = root->findById(layerId); if (!layer) return false; - return layer->scrollBy(dx, dy); + return layer->scrollTo(x, y); #endif return false; } @@ -2399,7 +2404,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeWordSelection }, { "nativeGetBlockLeftEdge", "(IIF)I", (void*) nativeGetBlockLeftEdge }, - { "nativeScrollableLayer", "(II)I", + { "nativeScrollableLayer", "(IILandroid/graphics/Rect;)I", (void*) nativeScrollableLayer }, { "nativeScrollLayer", "(III)Z", (void*) nativeScrollLayer }, |