diff options
Diffstat (limited to 'WebKit/android/nav/CachedFrame.cpp')
| -rw-r--r-- | WebKit/android/nav/CachedFrame.cpp | 252 |
1 files changed, 159 insertions, 93 deletions
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp index 299dc53..bd36bfb 100644 --- a/WebKit/android/nav/CachedFrame.cpp +++ b/WebKit/android/nav/CachedFrame.cpp @@ -36,6 +36,18 @@ namespace android { +WebCore::IntRect CachedFrame::adjustBounds(const CachedNode* node, + const WebCore::IntRect& rect) const +{ + DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)", + node, node->index(), rect.x(), rect.y(), rect.width(), rect.height()); +#if USE(ACCELERATED_COMPOSITING) + return layer(node)->adjustBounds(mRoot->rootLayer(), rect); +#else + return rect; +#endif +} + bool CachedFrame::CheckBetween(Direction direction, const WebCore::IntRect& bestRect, const WebCore::IntRect& prior, WebCore::IntRect* result) { @@ -105,6 +117,13 @@ bool CachedFrame::checkBetween(BestData* best, Direction direction) return true; } +bool CachedFrame::checkRings(const CachedNode* node, + const WTF::Vector<WebCore::IntRect>& rings, + const WebCore::IntRect& bounds) const +{ + return mRoot->checkRings(picture(node), rings, bounds); +} + bool CachedFrame::checkVisited(const CachedNode* node, Direction direction) const { return history()->checkVisited(node, direction); @@ -121,12 +140,11 @@ void CachedFrame::clearCursor() } // returns 0 if test is preferable to best, 1 if not preferable, or -1 if unknown -int CachedFrame::compare(BestData& testData, const BestData& bestData, - const CachedNode* cursor) const +int CachedFrame::compare(BestData& testData, const BestData& bestData) const { if (testData.mNode->tabIndex() != bestData.mNode->tabIndex()) { if (testData.mNode->tabIndex() < bestData.mNode->tabIndex() - || (cursor && cursor->tabIndex() < bestData.mNode->tabIndex())) { + || (mRoot->mCursor && mRoot->mCursor->tabIndex() < bestData.mNode->tabIndex())) { testData.mNode->setCondition(CachedNode::HIGHER_TAB_INDEX); return REJECT_TEST; } @@ -297,7 +315,7 @@ const CachedNode* CachedFrame::currentCursor(const CachedFrame** framePtr) const const CachedFrame* frame = hasFrame(result); if (frame != NULL) return frame->currentCursor(framePtr); - (const_cast<CachedNode*>(result))->fixUpCursorRects(mRoot); + (const_cast<CachedNode*>(result))->fixUpCursorRects(this); return result; } @@ -351,15 +369,25 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, size_t parts = test->navableRects(); BestData testData; testData.mNode = test; - testData.mMouseBounds = testData.mNodeBounds = test->getBounds(); + testData.mFrame = this; + WebCore::IntRect bounds = test->bounds(this); + testData.setMouseBounds(bounds); + testData.setNodeBounds(bounds); bool checkForHidden = checkForHiddenStart; for (size_t part = 0; part < parts; part++) { - if (test->cursorRings().at(part).intersects(rect)) { + WebCore::IntRect testRect = test->ring(this, part); + if (test->isInLayer()) { + DBG_NAV_LOGD("[%d] intersects=%ss testRect=(%d,%d,w=%d,h=%d)" + " rect=(%d,%d,w=%d,h=%d)", test->index(), + testRect.intersects(rect) ? "true" : "false", + testRect.x(), testRect.y(), testRect.width(), testRect.height(), + rect.x(), rect.y(), rect.width(), rect.height()); + } + if (testRect.intersects(rect)) { if (checkForHidden && mRoot->maskIfHidden(&testData) == true) break; checkForHidden = false; - WebCore::IntRect testRect = test->cursorRings().at(part); - testRect.intersect(testData.mMouseBounds); + testRect.intersect(testData.mouseBounds()); if (testRect.contains(center)) { // We have a direct hit. if (*directHit == NULL) { @@ -370,7 +398,7 @@ const CachedNode* CachedFrame::findBestAt(const WebCore::IntRect& rect, } else { // We have hit another one before const CachedNode* d = *directHit; - if (d->getBounds().contains(testRect)) { + if (d->bounds(this).contains(testRect)) { // This rectangle is inside the other one, so it is // the best one. *directHit = test; @@ -455,16 +483,18 @@ const CachedNode* CachedFrame::findBestHitAt(const WebCore::IntRect& rect, test != mCachedNodes.begin() - 1; test--) { if (test->disabled()) continue; - const WebCore::IntRect& testRect = test->hitBounds(); + WebCore::IntRect testRect = test->hitBounds(this); if (testRect.intersects(rect) == false) continue; BestData testData; testData.mNode = test; - testData.mMouseBounds = testData.mNodeBounds = testRect; + testData.mFrame = this; + testData.setMouseBounds(testRect); + testData.setNodeBounds(testRect); if (mRoot->maskIfHidden(&testData) == true) continue; - for (unsigned i = 0; i < test->cursorRings().size(); i++) { - const WebCore::IntRect& cursorRect = test->cursorRings().at(i); + for (int i = 0; i < test->navableRects(); i++) { + WebCore::IntRect cursorRect = test->ring(this, i); if (cursorRect.intersects(rect)) { WebCore::IntRect intersection(cursorRect); intersection.intersect(rect); @@ -492,13 +522,13 @@ void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, } if (test->noSecondChance()) continue; - if (test->isNavable(*clip) == false) + if (test->isNavable(this, *clip) == false) continue; if (checkVisited(test, originalDirection) == false) continue; size_t partMax = test->navableRects(); for (size_t part = 0; part < partMax; part++) { - WebCore::IntRect testBounds = test->cursorRings().at(part); + WebCore::IntRect testBounds = test->ring(this, part); if (clip->intersects(testBounds) == false) continue; if (clip->contains(testBounds) == false) { @@ -538,8 +568,9 @@ void CachedFrame::findClosest(BestData* bestData, Direction originalDirection, bestData->mNode = test; bestData->mFrame = this; bestData->mDistance = distance; - bestData->mMouseBounds = bestData->mNodeBounds = - test->cursorRings().at(part); + WebCore::IntRect rect = test->ring(this, part); + bestData->setMouseBounds(rect); + bestData->setNodeBounds(rect); CachedHistory* cachedHistory = history(); switch (direction) { case LEFT: @@ -577,29 +608,29 @@ void CachedFrame::finishInit() frameParent->setFocusIndex(indexInParent()); } -const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* cursor) const +const CachedNode* CachedFrame::frameDown(const CachedNode* test, + const CachedNode* limit, BestData* bestData) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameDown, test, bestData, cursor)) + if (moveInFrame(&CachedFrame::frameDown, test, bestData)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) continue; if (checkVisited(test, DOWN) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->cursorRings().at(part); + testData.setNodeBounds(test->ring(this, part)); if (testData.setDownDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, cursor); + int result = framePartCommon(testData, test, bestData); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameDown(document(), test, &innerData, cursor); + frameDown(document(), test, &innerData); if (checkVisited(innerData.mNode, DOWN)) { *bestData = innerData; continue; @@ -609,7 +640,7 @@ const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNod *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); - ASSERT(cursor == NULL || bestData->mNode != cursor); + ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); // does the best contain something (or, is it contained by an area which is not the cursor?) // if so, is the conainer/containee should have been chosen, but wasn't -- so there's a better choice // in the doc list prior to this choice @@ -617,29 +648,29 @@ const CachedNode* CachedFrame::frameDown(const CachedNode* test, const CachedNod return bestData->mNode; } -const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* cursor) const +const CachedNode* CachedFrame::frameLeft(const CachedNode* test, + const CachedNode* limit, BestData* bestData) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameLeft, test, bestData, cursor)) + if (moveInFrame(&CachedFrame::frameLeft, test, bestData)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) continue; if (checkVisited(test, LEFT) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->cursorRings().at(part); + testData.setNodeBounds(test->ring(this, part)); if (testData.setLeftDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, cursor); + int result = framePartCommon(testData, test, bestData); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameLeft(document(), test, &innerData, cursor); + frameLeft(document(), test, &innerData); if (checkVisited(innerData.mNode, LEFT)) { *bestData = innerData; continue; @@ -649,12 +680,12 @@ const CachedNode* CachedFrame::frameLeft(const CachedNode* test, const CachedNod *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(cursor == NULL || bestData->mNode != cursor); + ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); return bestData->mNode; } -int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, BestData* bestData, BestData* originalData, - const CachedNode* cursor) const +int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, + BestData* bestData, BestData* originalData) const { testData.mFrame = this; testData.mNode = test; @@ -663,53 +694,34 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes testData.mNode->setCondition(CachedNode::DISABLED); return REJECT_TEST; } - if (mRoot->scrolledBounds().intersects(test->bounds()) == false) { + if (mRoot->scrolledBounds().intersects(test->bounds(this)) == false) { testData.mNode->setCondition(CachedNode::NAVABLE); return REJECT_TEST; } + if (mRoot->rootLayer() && !test->isInLayer() + && !mRoot->baseUncovered().intersects(test->bounds(this))) { + testData.mNode->setCondition(CachedNode::UNDER_LAYER); + return REJECT_TEST; + } // if (isNavable(test, &testData.mNodeBounds, walk) == false) { // testData.mNode->setCondition(CachedNode::NAVABLE); // return REJECT_TEST; // } // - if (test == cursor) { + if (test == mRoot->mCursor) { testData.mNode->setCondition(CachedNode::NOT_CURSOR_NODE); return REJECT_TEST; } -// if (test->bounds().contains(mRoot->cursorBounds())) { +// if (test->bounds().contains(mRoot->mCursorBounds)) { // testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); // return REJECT_TEST; // } - void* par = cursor ? cursor->parentGroup() : NULL; + void* par = mRoot->mCursor ? mRoot->mCursor->parentGroup() : NULL; testData.mCursorChild = par ? test->parentGroup() == par : false; -#if 0 // not debugged - if (cursor && cursor->hasMouseOver() && test->hasMouseOver() == false && - cursor->bounds().contains(test->bounds())) - return REJECT_TEST; -#endif if (bestData->mNode == NULL) return TEST_IS_BEST; -#if 0 // not debugged - if (cursor && cursor->hasMouseOver() && test->hasMouseOver() == false && - cursor->bounds().contains(test->bounds())) - return REJECT_TEST; - if (test->hasMouseOver() != bestData->mNode->hasMouseOver()) { - if (test->hasMouseOver()) { - if (test->bounds().contains(bestData->mNode->bounds())) { - const_cast<CachedNode*>(bestData->mNode)->setDisabled(true); - bestData->mNode = NULL; // force part tests to be ignored, yet still set up remaining test data for later comparison - return TEST_IS_BEST; - } - } else { - if (bestData->mNode->bounds().contains(test->bounds())) { - test->setCondition(CachedNode::ANCHOR_IN_ANCHOR); - return REJECT_TEST; - } - } - } -#endif - if (cursor && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { - int cursorParentIndex = cursor->parentIndex(); + if (mRoot->mCursor && testData.mNode->parentIndex() != bestData->mNode->parentIndex()) { + int cursorParentIndex = mRoot->mCursor->parentIndex(); if (cursorParentIndex >= 0) { if (bestData->mNode->parentIndex() == cursorParentIndex) return REJECT_TEST; @@ -745,15 +757,17 @@ int CachedFrame::frameNodeCommon(BestData& testData, const CachedNode* test, Bes } int CachedFrame::framePartCommon(BestData& testData, - const CachedNode* test, BestData* bestData, const CachedNode* cursor) const + const CachedNode* test, BestData* bestData) const { - if (cursor && testData.mNodeBounds.contains(cursor->bounds()) && !test->wantsKeyEvents()) { + if (mRoot->mCursor + && testData.bounds().contains(mRoot->mCursorBounds) + && !test->wantsKeyEvents()) { testData.mNode->setCondition(CachedNode::NOT_ENCLOSING_CURSOR); return REJECT_TEST; } testData.setDistances(); if (bestData->mNode != NULL) { - int compared = compare(testData, *bestData, cursor); + int compared = compare(testData, *bestData); if (compared == 0 && test->isArea() == false && bestData->mNode->isArea() == false) goto pickTest; if (compared >= 0) @@ -763,29 +777,29 @@ pickTest: return -1; // pick test } -const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* cursor) const +const CachedNode* CachedFrame::frameRight(const CachedNode* test, + const CachedNode* limit, BestData* bestData) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameRight, test, bestData, cursor)) + if (moveInFrame(&CachedFrame::frameRight, test, bestData)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) continue; if (checkVisited(test, RIGHT) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->cursorRings().at(part); + testData.setNodeBounds(test->ring(this, part)); if (testData.setRightDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, cursor); + int result = framePartCommon(testData, test, bestData); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameRight(document(), test, &innerData, cursor); + frameRight(document(), test, &innerData); if (checkVisited(innerData.mNode, RIGHT)) { *bestData = innerData; continue; @@ -795,33 +809,33 @@ const CachedNode* CachedFrame::frameRight(const CachedNode* test, const CachedNo *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); - ASSERT(cursor == NULL || bestData->mNode != cursor); + ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); return bestData->mNode; } -const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* limit, BestData* bestData, - const CachedNode* cursor) const +const CachedNode* CachedFrame::frameUp(const CachedNode* test, + const CachedNode* limit, BestData* bestData) const { BestData originalData = *bestData; do { - if (moveInFrame(&CachedFrame::frameUp, test, bestData, cursor)) + if (moveInFrame(&CachedFrame::frameUp, test, bestData)) continue; BestData testData; - if (frameNodeCommon(testData, test, bestData, &originalData, cursor) == REJECT_TEST) + if (frameNodeCommon(testData, test, bestData, &originalData) == REJECT_TEST) continue; if (checkVisited(test, UP) == false) continue; size_t parts = test->navableRects(); for (size_t part = 0; part < parts; part++) { - testData.mNodeBounds = test->cursorRings().at(part); + testData.setNodeBounds(test->ring(this, part)); if (testData.setUpDirection(history())) continue; - int result = framePartCommon(testData, test, bestData, cursor); + int result = framePartCommon(testData, test, bestData); if (result == REJECT_TEST) continue; if (result == 0 && limit == NULL) { // retry all data up to this point, since smaller may have replaced node preferable to larger BestData innerData = testData; - frameUp(document(), test, &innerData, cursor); + frameUp(document(), test, &innerData); if (checkVisited(innerData.mNode, UP)) { *bestData = innerData; continue; @@ -831,7 +845,7 @@ const CachedNode* CachedFrame::frameUp(const CachedNode* test, const CachedNode* *bestData = testData; } } while ((test = test->traverseNextNode()) != limit); // FIXME ??? left and up should use traversePreviousNode to choose reverse document order - ASSERT(cursor == NULL || bestData->mNode != cursor); + ASSERT(mRoot->mCursor == NULL || bestData->mNode != mRoot->mCursor); return bestData->mNode; } @@ -868,6 +882,29 @@ void CachedFrame::init(const CachedRoot* root, int childFrameIndex, mIndexInParent = childFrameIndex; } +#if USE(ACCELERATED_COMPOSITING) +const CachedLayer* CachedFrame::layer(const CachedNode* node) const +{ + if (!node->isInLayer()) + return 0; + CachedLayer test; + test.setCachedNodeIndex(node->index()); + return std::lower_bound(mCachedLayers.begin(), mCachedLayers.end(), test); +} +#endif + +WebCore::IntRect CachedFrame::localBounds(const CachedNode* node, + const WebCore::IntRect& rect) const +{ + DBG_NAV_LOGD("node=%p [%d] rect=(%d,%d,w=%d,h=%d)", + node, node->index(), rect.x(), rect.y(), rect.width(), rect.height()); +#if USE(ACCELERATED_COMPOSITING) + return layer(node)->localBounds(rect); +#else + return rect; +#endif +} + int CachedFrame::minWorkingHorizontal() const { return history()->minWorkingHorizontal(); @@ -889,7 +926,7 @@ int CachedFrame::maxWorkingVertical() const } const CachedNode* CachedFrame::nextTextField(const CachedNode* start, - const CachedFrame** framePtr, bool includeTextAreas) const + const CachedFrame** framePtr) const { CachedNode* test; if (start) { @@ -902,11 +939,10 @@ const CachedNode* CachedFrame::nextTextField(const CachedNode* start, CachedFrame* frame = const_cast<CachedFrame*>(hasFrame(test)); if (frame) { const CachedNode* node - = frame->nextTextField(0, framePtr, includeTextAreas); + = frame->nextTextField(0, framePtr); if (node) return node; - } else if (test->isTextField(this) - || (includeTextAreas && test->isTextInput())) { + } else if (test->isTextInput()) { if (framePtr) *framePtr = this; return test; @@ -917,8 +953,7 @@ const CachedNode* CachedFrame::nextTextField(const CachedNode* start, } bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, - const CachedNode* test, BestData* bestData, - const CachedNode* cursor) const + const CachedNode* test, BestData* bestData) const { const CachedFrame* frame = hasFrame(test); if (frame == NULL) @@ -926,7 +961,7 @@ bool CachedFrame::moveInFrame(MoveInDirection moveInDirection, const CachedNode* childDoc = frame->validDocument(); if (childDoc == NULL) return true; - (frame->*moveInDirection)(childDoc, NULL, bestData, cursor); + (frame->*moveInDirection)(childDoc, NULL, bestData); return true; } @@ -935,6 +970,15 @@ const WebCore::IntRect& CachedFrame::_navBounds() const return history()->navBounds(); } +SkPicture* CachedFrame::picture(const CachedNode* node) const +{ +#if USE(ACCELERATED_COMPOSITING) + if (node->isInLayer()) + return layer(node)->picture(mRoot->rootLayer()); +#endif + return mRoot->mPicture; +} + void CachedFrame::resetClippedOut() { for (CachedNode* test = mCachedNodes.begin(); test != mCachedNodes.end(); test++) @@ -950,6 +994,20 @@ void CachedFrame::resetClippedOut() } } +void CachedFrame::resetLayers() +{ +#if USE(ACCELERATED_COMPOSITING) + for (CachedLayer* test = mCachedLayers.begin(); test != mCachedLayers.end(); + test++) { + test->reset(); + } + for (CachedFrame* frame = mCachedFrames.begin(); frame != mCachedFrames.end(); + frame++) { + frame->resetLayers(); + } +#endif +} + bool CachedFrame::sameFrame(const CachedFrame* test) const { ASSERT(test); @@ -1005,9 +1063,8 @@ bool CachedFrame::setCursor(WebCore::Frame* frame, WebCore::Node* node, if (test->nodePointer() != node && first) continue; size_t partMax = test->navableRects(); - WTF::Vector<WebCore::IntRect>& cursorRings = test->cursorRings(); for (size_t part = 0; part < partMax; part++) { - const WebCore::IntRect& testBounds = cursorRings.at(part); + WebCore::IntRect testBounds = test->ring(this, part); if (testBounds.contains(x, y) == false) continue; if (test->isCursor()) { @@ -1324,6 +1381,7 @@ void CachedFrame::Debug::print() const DEBUG_PRINT_RECT("//", CONTENTS, mContents); DEBUG_PRINT_RECT("", BOUNDS, mLocalViewBounds); DEBUG_PRINT_RECT("//", VIEW, mViewBounds); + DUMP_NAV_LOGD("// CachedNode mCachedNodes={ // count=%d\n", b->mCachedNodes.size()); for (CachedNode* node = b->mCachedNodes.begin(); node != b->mCachedNodes.end(); node++) { @@ -1333,6 +1391,14 @@ void CachedFrame::Debug::print() const input->mDebug.print(); } DUMP_NAV_LOGD("// }; // end of nodes\n"); +#if USE(ACCELERATED_COMPOSITING) + DUMP_NAV_LOGD("// CachedLayer mCachedLayers={ // count=%d\n", b->mCachedLayers.size()); + for (CachedLayer* layer = b->mCachedLayers.begin(); + layer != b->mCachedLayers.end(); layer++) { + layer->mDebug.print(); + } + DUMP_NAV_LOGD("// }; // end of layers\n"); +#endif // USE(ACCELERATED_COMPOSITING) DUMP_NAV_LOGD("// CachedFrame mCachedFrames={ // count=%d\n", b->mCachedFrames.size()); for (CachedFrame* child = b->mCachedFrames.begin(); child != b->mCachedFrames.end(); child++) |
