summaryrefslogtreecommitdiffstats
path: root/WebKit/android/nav
diff options
context:
space:
mode:
authorCary Clark <cary@android.com>2011-02-14 14:26:57 -0500
committerCary Clark <cary@android.com>2011-02-14 14:26:57 -0500
commit99a3d689283e80afdfb9e7711900dd9906f4c1f4 (patch)
treecf96c198600efde0591b274d8f61769071e4ce19 /WebKit/android/nav
parente5c90f700f64667817813fbb2e8478ddb7a6927b (diff)
downloadexternal_webkit-99a3d689283e80afdfb9e7711900dd9906f4c1f4.zip
external_webkit-99a3d689283e80afdfb9e7711900dd9906f4c1f4.tar.gz
external_webkit-99a3d689283e80afdfb9e7711900dd9906f4c1f4.tar.bz2
don't combine single image bitmaps
Anchors and other links often contain multiple bitmaps, which must be stitched together when analyzing the picture data to determine if the anchor is fully visible, partially occluded, or fully hidden. For instance, nine-patches in WebKit appear as adjacent bitmaps. If a website design has two or more bitmaps adjacent to each other, these may be mistakenly joined. By tracking whether the original node contained exactly one img element, combining bitmaps based on their location is avoided unncessarily. bug:3373743 Change-Id: I5bcbdaec3097a2b839ee2444e512a0def6a016d0
Diffstat (limited to 'WebKit/android/nav')
-rw-r--r--WebKit/android/nav/CacheBuilder.cpp16
-rw-r--r--WebKit/android/nav/CacheBuilder.h3
-rw-r--r--WebKit/android/nav/CachedFrame.cpp4
-rw-r--r--WebKit/android/nav/CachedFrame.h2
-rw-r--r--WebKit/android/nav/CachedNode.cpp5
-rw-r--r--WebKit/android/nav/CachedNode.h5
-rw-r--r--WebKit/android/nav/CachedRoot.cpp17
-rw-r--r--WebKit/android/nav/CachedRoot.h3
8 files changed, 33 insertions, 22 deletions
diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp
index 56bce1e..d2ae0a4 100644
--- a/WebKit/android/nav/CacheBuilder.cpp
+++ b/WebKit/android/nav/CacheBuilder.cpp
@@ -547,6 +547,7 @@ void CacheBuilder::Debug::groups() {
IntRect clipBounds = IntRect(0, 0, INT_MAX, INT_MAX);
IntRect focusBounds = IntRect(0, 0, INT_MAX, INT_MAX);
IntRect* rectPtr = &focusBounds;
+ int imageCount = 0;
if (node->isTextNode()) {
Text* textNode = (Text*) node;
if (CacheBuilder::ConstructTextRects(textNode, 0, textNode,
@@ -556,7 +557,7 @@ void CacheBuilder::Debug::groups() {
} else {
IntRect nodeBounds = node->getRect();
if (CacheBuilder::ConstructPartRects(node, nodeBounds, rectPtr,
- globalOffsetX, globalOffsetY, &rects) == false)
+ globalOffsetX, globalOffsetY, &rects, &imageCount) == false)
continue;
}
unsigned arraySize = rects.size();
@@ -592,8 +593,8 @@ void CacheBuilder::Debug::groups() {
mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d, %d, %d",
textBox->x(), textBox->y(), textBox->logicalWidth(), textBox->logicalHeight());
int baseline = textBox->renderer()->style(textBox->isFirstLineStyle())->font().ascent();
- mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d }, // %d ",
- baseline, ++rectIndex);
+ mIndex += snprintf(&mBuffer[mIndex], mBufferSize - mIndex, ", %d, %d }, // %d ",
+ baseline, imageCount, ++rectIndex);
wideString(node->textContent().characters() + textBox->start(), textBox->len(), true);
DUMP_NAV_LOGD("%.*s\n", mIndex, mBuffer);
textBox = textBox->nextTextBox();
@@ -1129,6 +1130,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
bool isFocus = node == focused;
bool takesFocus = false;
int columnGap = 0;
+ int imageCount = 0;
TextDirection direction = LTR;
String exported;
CachedNodeType type = NORMAL_CACHEDNODETYPE;
@@ -1328,7 +1330,8 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedNode.setBounds(bounds);
cachedNode.mCursorRing.append(bounds);
} else if (ConstructPartRects(node, bounds, &cachedNode.mBounds,
- globalOffsetX, globalOffsetY, &cachedNode.mCursorRing) == false)
+ globalOffsetX, globalOffsetY, &cachedNode.mCursorRing,
+ &imageCount) == false)
continue;
keepTextNode:
if (nodeRenderer) { // area tags' node->renderer() == 0
@@ -1412,6 +1415,7 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame,
cachedNode.setOriginalAbsoluteBounds(originalAbsBounds);
cachedNode.setParentIndex(last->mCachedNodeIndex);
cachedNode.setParentGroup(ParentWithChildren(node));
+ cachedNode.setSingleImage(imageCount == 1);
cachedNode.setTabIndex(tabIndex);
cachedNode.setType(type);
if (type == TEXT_INPUT_CACHEDNODETYPE) {
@@ -3024,7 +3028,8 @@ bool CacheBuilder::AddPartRect(IntRect& bounds, int x, int y,
}
bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds,
- IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result)
+ IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result,
+ int* imageCountPtr)
{
WTF::Vector<ClipColumnTracker> clipTracker(1);
ClipColumnTracker* baseTracker = clipTracker.data(); // sentinel
@@ -3075,6 +3080,7 @@ bool CacheBuilder::ConstructPartRects(Node* node, const IntRect& bounds,
bounds.intersect(clipBounds);
if (AddPartRect(bounds, x, y, result, focusBounds) == false)
return false;
+ *imageCountPtr += 1;
continue;
}
if (hasClip == false) {
diff --git a/WebKit/android/nav/CacheBuilder.h b/WebKit/android/nav/CacheBuilder.h
index d229df0..d48a045 100644
--- a/WebKit/android/nav/CacheBuilder.h
+++ b/WebKit/android/nav/CacheBuilder.h
@@ -83,7 +83,8 @@ public:
void allowAllTextDetection() { mAllowableTypes = ALL_CACHEDNODE_BITS; }
void buildCache(CachedRoot* root);
static bool ConstructPartRects(Node* node, const IntRect& bounds,
- IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result);
+ IntRect* focusBounds, int x, int y, WTF::Vector<IntRect>* result,
+ int* imageCountPtr);
Node* currentFocus() const;
void disallowAddressDetection() { mAllowableTypes = (CachedNodeBits) (
mAllowableTypes & ~ADDRESS_CACHEDNODE_BIT); }
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index b25ad7d..419be14 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -153,11 +153,9 @@ bool CachedFrame::checkBetween(BestData* best, Direction direction)
}
bool CachedFrame::checkRings(const CachedNode* node,
- const WTF::Vector<WebCore::IntRect>& rings,
- const WebCore::IntRect& nodeBounds,
const WebCore::IntRect& testBounds) const
{
- return mRoot->checkRings(picture(node), rings, nodeBounds, testBounds);
+ return mRoot->checkRings(picture(node), node, testBounds);
}
bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const
diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h
index 8ca73cf..470f522 100644
--- a/WebKit/android/nav/CachedFrame.h
+++ b/WebKit/android/nav/CachedFrame.h
@@ -83,8 +83,6 @@ public:
WebCore::IntRect unadjustBounds(const CachedNode*,
const WebCore::IntRect& ) const;
bool checkRings(const CachedNode* node,
- const WTF::Vector<WebCore::IntRect>& rings,
- const WebCore::IntRect& nodeBounds,
const WebCore::IntRect& testBounds) const;
bool checkVisited(const CachedNode* , CachedFrame::Direction ) const;
size_t childCount() { return mCachedFrames.size(); }
diff --git a/WebKit/android/nav/CachedNode.cpp b/WebKit/android/nav/CachedNode.cpp
index 4ba7b48..e3ba34d 100644
--- a/WebKit/android/nav/CachedNode.cpp
+++ b/WebKit/android/nav/CachedNode.cpp
@@ -110,7 +110,7 @@ void CachedNode::fixUpCursorRects(const CachedFrame* frame)
mFixedUpCursorRects = true;
// if the hit-test rect doesn't intersect any other rect, use it
if (mHitBounds != mBounds && mHitBounds.contains(mBounds) &&
- frame->checkRings(this, mCursorRing, mBounds, mHitBounds)) {
+ frame->checkRings(this, mHitBounds)) {
DBG_NAV_LOGD("use mHitBounds (%d,%d,%d,%d)", mHitBounds.x(),
mHitBounds.y(), mHitBounds.width(), mHitBounds.height());
mUseHitBounds = true;
@@ -122,7 +122,7 @@ void CachedNode::fixUpCursorRects(const CachedFrame* frame)
// any other cursor ring bounds, use it
IntRect sloppyBounds = mBounds;
sloppyBounds.inflate(2); // give it a couple of extra pixels
- if (frame->checkRings(this, mCursorRing, mBounds, sloppyBounds)) {
+ if (frame->checkRings(this, sloppyBounds)) {
DBG_NAV_LOGD("use mBounds (%d,%d,%d,%d)", mBounds.x(),
mBounds.y(), mBounds.width(), mBounds.height());
mUseBounds = true;
@@ -424,6 +424,7 @@ void CachedNode::Debug::print() const
DEBUG_PRINT_BOOL(mLast);
DEBUG_PRINT_BOOL(mUseBounds);
DEBUG_PRINT_BOOL(mUseHitBounds);
+ DEBUG_PRINT_BOOL(mSingleImage);
}
#endif
diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h
index 961018b..f9bcbed 100644
--- a/WebKit/android/nav/CachedNode.h
+++ b/WebKit/android/nav/CachedNode.h
@@ -145,8 +145,10 @@ public:
void* parentGroup() const { return mParentGroup; }
int parentIndex() const { return mParentIndex; }
bool partRectsContains(const CachedNode* other) const;
+ const WebCore::IntRect& rawBounds() const { return mBounds; }
void reset();
WebCore::IntRect ring(const CachedFrame* , size_t part) const;
+ const WTF::Vector<WebCore::IntRect>& rings() const { return mCursorRing; }
void setBounds(const WebCore::IntRect& bounds) { mBounds = bounds; }
void setClippedOut(bool clipped) { mClippedOut = clipped; }
void setColorIndex(int index) { mColorIndex = index; }
@@ -170,9 +172,11 @@ public:
void setNavableRects() { mNavableRects = mCursorRing.size(); }
void setParentGroup(void* group) { mParentGroup = group; }
void setParentIndex(int parent) { mParentIndex = parent; }
+ void setSingleImage(bool single) { mSingleImage = single; }
void setTabIndex(int index) { mTabIndex = index; }
void setType(CachedNodeType type) { mType = type; }
void show() { mIsHidden = false; }
+ bool singleImage() const { return mSingleImage; }
int tabIndex() const { return mTabIndex; }
int textInputIndex() const { return isTextInput() ? mDataIndex : -1; }
const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; }
@@ -210,6 +214,7 @@ private:
bool mIsTransparent : 1;
bool mIsUnclipped : 1;
bool mLast : 1; // true if this is the last node in a group
+ bool mSingleImage : 1;
bool mUseBounds : 1;
bool mUseHitBounds : 1;
#ifdef BROWSER_DEBUG
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 2f0e74d..8239c8d 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -675,10 +675,12 @@ public:
class RingCheck : public CommonCheck {
public:
RingCheck(const WTF::Vector<WebCore::IntRect>& rings,
- const WebCore::IntRect& bitBounds, const WebCore::IntRect& testBounds)
+ const WebCore::IntRect& bitBounds, const WebCore::IntRect& testBounds,
+ bool singleImage)
: mTestBounds(testBounds)
, mBitBounds(bitBounds)
, mPushPop(false)
+ , mSingleImage(singleImage)
{
const WebCore::IntRect* r;
for (r = rings.begin(); r != rings.end(); r++) {
@@ -910,7 +912,7 @@ protected:
&& mType != kDrawSprite_Type && mType != kDrawBitmap_Type)
return false;
if (mLayerTypes.isEmpty() || mLayerTypes.last() != mType
- || !mAppendLikeTypes || mPushPop
+ || !mAppendLikeTypes || mPushPop || mSingleImage
// if the last and current were not glyphs,
// and the two bounds have a gap between, don't join them -- push
// an empty between them
@@ -1054,6 +1056,7 @@ private:
char mCh;
bool mAppendLikeTypes;
bool mPushPop;
+ bool mSingleImage;
};
class RingCanvas : public BoundsCanvas {
@@ -1205,16 +1208,16 @@ void CachedRoot::checkForJiggle(int* xDeltaPtr) const
*xDeltaPtr = jiggleCheck.jiggle();
}
-bool CachedRoot::checkRings(SkPicture* picture,
- const WTF::Vector<WebCore::IntRect>& rings,
- const WebCore::IntRect& nodeBounds,
+bool CachedRoot::checkRings(SkPicture* picture, const CachedNode* node,
const WebCore::IntRect& testBounds) const
{
if (!picture)
return false;
+ const WTF::Vector<WebCore::IntRect>& rings = node->rings();
+ const WebCore::IntRect& nodeBounds = node->rawBounds();
IntRect bitBounds;
calcBitBounds(nodeBounds, &bitBounds);
- RingCheck ringCheck(rings, bitBounds, testBounds);
+ RingCheck ringCheck(rings, bitBounds, testBounds, node->singleImage());
RingCanvas checker(&ringCheck);
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(),
@@ -1576,7 +1579,7 @@ bool CachedRoot::maskIfHidden(BestData* best) const
const WebCore::IntRect& bounds = bestNode->bounds(frame);
IntRect bitBounds;
calcBitBounds(bounds, &bitBounds);
- RingCheck ringCheck(rings, bitBounds, bounds);
+ RingCheck ringCheck(rings, bitBounds, bounds, bestNode->singleImage());
RingCanvas checker(&ringCheck);
SkBitmap bitmap;
bitmap.setConfig(SkBitmap::kARGB_8888_Config, bitBounds.width(),
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index a09e4fb..1f8b851 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -52,8 +52,7 @@ public:
void calcBitBounds(const IntRect& , IntRect* ) const;
int checkForCenter(int x, int y) const;
void checkForJiggle(int* ) const;
- bool checkRings(SkPicture* , const WTF::Vector<WebCore::IntRect>& rings,
- const WebCore::IntRect& nodeBounds,
+ bool checkRings(SkPicture* , const CachedNode* ,
const WebCore::IntRect& testBounds) const;
WebCore::IntPoint cursorLocation() const;
int documentHeight() { return mContents.height(); }