diff options
author | Cary Clark <cary@android.com> | 2011-02-14 14:26:57 -0500 |
---|---|---|
committer | Cary Clark <cary@android.com> | 2011-02-14 14:26:57 -0500 |
commit | 99a3d689283e80afdfb9e7711900dd9906f4c1f4 (patch) | |
tree | cf96c198600efde0591b274d8f61769071e4ce19 /WebKit/android/nav | |
parent | e5c90f700f64667817813fbb2e8478ddb7a6927b (diff) | |
download | external_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.cpp | 16 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.h | 3 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 4 | ||||
-rw-r--r-- | WebKit/android/nav/CachedFrame.h | 2 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.cpp | 5 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.h | 5 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.cpp | 17 | ||||
-rw-r--r-- | WebKit/android/nav/CachedRoot.h | 3 |
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(); } |