summaryrefslogtreecommitdiffstats
path: root/WebKit/android
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/android')
-rw-r--r--WebKit/android/nav/CachedFrame.cpp2
-rw-r--r--WebKit/android/nav/CachedNode.cpp20
-rw-r--r--WebKit/android/nav/CachedNode.h7
-rw-r--r--WebKit/android/nav/CachedRoot.cpp49
-rw-r--r--WebKit/android/nav/CachedRoot.h5
-rw-r--r--WebKit/android/nav/WebView.cpp19
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)