diff options
Diffstat (limited to 'WebKit/android')
-rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 2 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.cpp | 20 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.h | 7 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 49 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.h | 5 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 19 |
6 files changed, 90 insertions, 12 deletions
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index 57054e1..f68c2f2 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -305,7 +305,7 @@ const CachedNode* CachedFrame::currentFocus(const CachedFrame** framePtr) const const CachedFrame* frame = hasFrame(result); if (frame != NULL) return frame->currentFocus(framePtr); - (const_cast<CachedNode*>(result))->fixUpFocusRects(); + (const_cast<CachedNode*>(result))->fixUpFocusRects(mRoot); return result; } diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp index b786677..07d3491 100644 --- a/WebKit/android/nav/CachedNode.cpp +++ b/WebKit/android/nav/CachedNode.cpp @@ -24,8 +24,8 @@ */ #include "CachedPrefix.h" -#include "CachedFrame.h" #include "CachedHistory.h" +#include "CachedRoot.h" #include "Node.h" #include "PlatformString.h" @@ -78,13 +78,29 @@ bool CachedNode::clip(const WebCore::IntRect& bounds) #define OVERLAP 3 -void CachedNode::fixUpFocusRects() +void CachedNode::fixUpFocusRects(const CachedRoot* root) { if (mFixedUpFocusRects) return; mFixedUpFocusRects = true; + // if the hit-test rect doesn't intersect any other rect, use it + if (mHitBounds != mBounds && mHitBounds.contains(mBounds) && + root->checkRings(mFocusRing, mHitBounds)) { + DBG_NAV_LOGD("use mHitBounds (%d,%d,%d,%d)", mHitBounds.x(), + mHitBounds.y(), mHitBounds.width(), mHitBounds.height()); + mUseHitBounds = true; + return; + } if (mNavableRects <= 1) return; + // if there is more than 1 rect, and the bounds doesn't intersect + // any other focus ring bounds, use it + if (root->checkRings(mFocusRing, mBounds)) { + DBG_NAV_LOGD("use mBounds (%d,%d,%d,%d)", mBounds.x(), + mBounds.y(), mBounds.width(), mBounds.height()); + mUseBounds = true; + return; + } #if DEBUG_NAV_UI { WebCore::IntRect* boundsPtr = mFocusRing.begin() - 1; diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h index aa64982..bdde9e0 100644 --- a/WebKit/android/nav/CachedNode.h +++ b/WebKit/android/nav/CachedNode.h @@ -40,6 +40,7 @@ namespace WebCore { namespace android { class CachedFrame; +class CachedRoot; class CachedNode { public: @@ -95,7 +96,7 @@ public: bool clippedOut() { return mClippedOut; } bool disabled() const { return mDisabled; } const CachedNode* document() const { return &this[-mIndex]; } - void fixUpFocusRects(); + void fixUpFocusRects(const CachedRoot* root); void focusRingBounds(WebCore::IntRect* ) const; WTF::Vector<WebCore::IntRect>& focusRings() { return mFocusRing; } const WTF::Vector<WebCore::IntRect>& focusRings() const { return mFocusRing; } @@ -169,6 +170,8 @@ public: const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } int textSize() const { return mTextSize; } CachedNodeType type() const { return mType; } + bool useBounds() const { return mUseBounds; } + bool useHitBounds() const { return mUseHitBounds; } private: WebCore::String mExport; WebCore::String mName; @@ -203,6 +206,8 @@ private: bool mIsTransparent : 1; bool mIsUnclipped : 1; bool mLast : 1; // true if this is the last node in a group + bool mUseBounds : 1; + bool mUseHitBounds : 1; bool mWantsKeyEvents : 1; // true for nodes like plugins #ifdef BROWSER_DEBUG public: diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp index a123e55..3b8871a 100644 --- a/WebKit/android/nav/CachedRoot.cpp +++ b/WebKit/android/nav/CachedRoot.cpp @@ -24,6 +24,7 @@ */ #include "CachedPrefix.h" +#include "android_graphics.h" #include "CachedHistory.h" #include "CachedNode.h" #include "SkBitmap.h" @@ -530,6 +531,37 @@ public: int mMaxWidth; }; +class RingCheck : public CommonCheck { +public: + RingCheck(const WTF::Vector<WebCore::IntRect>& rings, + const WebCore::IntPoint& location) : mSuccess(true) { + const WebCore::IntRect* r; + for (r = rings.begin(); r != rings.end(); r++) { + SkIRect fatter = {r->x(), r->y(), r->right(), r->bottom()}; + fatter.inset(-FOCUS_RING_HIT_TEST_RADIUS, -FOCUS_RING_HIT_TEST_RADIUS); + DBG_NAV_LOGD("%s fat=(%d,%d,r=%d,b=%d)", fatter.fLeft, fatter.fTop, + fatter.fRight, fatter.fBottom); + mRings.op(fatter, SkRegion::kUnion_Op); + } + DBG_NAV_LOGD("translate=(%d,%d)", -location.x(), -location.y()); + mRings.translate(-location.x(), -location.y()); + } + + virtual bool onIRect(const SkIRect& rect) { + if (mSuccess && mType == kDrawGlyph_Type) { + DBG_NAV_LOGD("contains (%d,%d,r=%d,b=%d) == %s", rect.fLeft, rect.fTop, + rect.fRight, rect.fBottom, mRings.contains(rect) ? "true" : + "false"); + mSuccess &= mRings.contains(rect); + } + return false; + } + + bool success() { return mSuccess; } + SkRegion mRings; + bool mSuccess; +}; + bool CachedRoot::adjustForScroll(BestData* best, CachedFrame::Direction direction, WebCore::IntPoint* scrollPtr, bool findClosest) { @@ -591,6 +623,23 @@ void CachedRoot::checkForJiggle(int* xDeltaPtr) const *xDeltaPtr = jiggleCheck.jiggle(); } +bool CachedRoot::checkRings(const WTF::Vector<WebCore::IntRect>& rings, + const WebCore::IntRect& bounds) const +{ + RingCheck ringCheck(rings, bounds.location()); + BoundsCanvas checker(&ringCheck); + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), + bounds.height()); + checker.setBitmapDevice(bitmap); + checker.translate(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())); + checker.drawPicture(*mPicture); + DBG_NAV_LOGD("bounds=(%d,%d,r=%d,b=%d) success=%s", + bounds.x(), bounds.y(), bounds.right(), bounds.bottom(), + ringCheck.success() ? "true" : "false"); + return ringCheck.success(); +} + const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect, const CachedFrame** framePtr, int* x, int* y) const { diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h index ab1b823..d06e46c 100644 --- a/WebKit/android/nav/CachedRoot.h +++ b/WebKit/android/nav/CachedRoot.h @@ -27,8 +27,9 @@ #define CachedRoot_H #include "CachedFrame.h" -#include "IntPoint.h" +#include "IntRect.h" #include "SkPicture.h" +#include "wtf/Vector.h" class SkRect; @@ -43,6 +44,8 @@ public: bool findClosest); int checkForCenter(int x, int y) const; void checkForJiggle(int* ) const; + bool checkRings(const WTF::Vector<WebCore::IntRect>& rings, + const WebCore::IntRect& bounds) const; int documentHeight() { return mContents.height(); } int documentWidth() { return mContents.width(); } const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** , diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index 7b98e56..c259501 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -700,12 +700,11 @@ void drawFocusRing(SkCanvas* canvas) DBG_NAV_LOG("!node->hasFocusRing()"); return; } - const WTF::Vector<WebCore::IntRect>& rings = node->focusRings(); - if (!rings.size()) { - DBG_NAV_LOG("!rings.size()"); + const WTF::Vector<WebCore::IntRect>* rings = &node->focusRings(); + if (!rings->size()) { + DBG_NAV_LOG("!rings->size()"); return; } - bool isButton = false; m_viewImpl->gButtonMutex.lock(); // If this is a button drawn by us (rather than webkit) do not draw the @@ -731,6 +730,7 @@ void drawFocusRing(SkCanvas* canvas) return; } FocusRing::Flavor flavor = FocusRing::NORMAL_FLAVOR; + WTF::Vector<WebCore::IntRect> oneRing; if (!isButton) { flavor = node->type() != NORMAL_CACHEDNODETYPE ? FocusRing::FAKE_FLAVOR : node->nodePointer() == m_invalidNode ? @@ -738,15 +738,20 @@ void drawFocusRing(SkCanvas* canvas) if (flavor != FocusRing::INVALID_FLAVOR && m_followedLink) { flavor = (FocusRing::Flavor) (flavor + FocusRing::NORMAL_ANIMATING); } + bool useHitBounds = node->useHitBounds(); + if (useHitBounds || node->useBounds()) { + oneRing.append(useHitBounds ? node->hitBounds() : node->bounds()); + rings = &oneRing; + } #if DEBUG_NAV_UI - const WebCore::IntRect& ring = rings[0]; + const WebCore::IntRect& ring = (*rings)[0]; DBG_NAV_LOGD("cachedFocusNode=%d (nodePointer=%p) flavor=%s rings=%d" " (%d, %d, %d, %d)", node->index(), node->nodePointer(), flavor == FocusRing::FAKE_FLAVOR ? "FAKE_FLAVOR" : flavor == FocusRing::INVALID_FLAVOR ? "INVALID_FLAVOR" : flavor == FocusRing::NORMAL_ANIMATING ? "NORMAL_ANIMATING" : flavor == FocusRing::FAKE_ANIMATING ? "FAKE_ANIMATING" : "NORMAL_FLAVOR", - rings.size(), ring.x(), ring.y(), ring.width(), ring.height()); + rings->size(), ring.x(), ring.y(), ring.width(), ring.height()); #endif } if (isButton || flavor >= FocusRing::NORMAL_ANIMATING) { @@ -761,7 +766,7 @@ void drawFocusRing(SkCanvas* canvas) } } if (!isButton) - FocusRing::DrawRing(canvas, rings, flavor); + FocusRing::DrawRing(canvas, *rings, flavor); } OutOfFocusFix fixOutOfDateFocus(bool useReplay) |