bool CachedNode::Clip(const WebCore::IntRect& outer, WebCore::IntRect* inner, WTF::Vector<WebCore::IntRect>* rings) { if (outer.contains(*inner)) return true; // DBG_NAV_LOGD("outer:{%d,%d,%d,%d} does not contain inner:{%d,%d,%d,%d}", // outer.x(), outer.y(), outer.width(), outer.height(), // inner->x(), inner->y(), inner->width(), inner->height()); bool intersects = outer.intersects(*inner); size_t size = intersects ? rings->size() : 0; *inner = WebCore::IntRect(0, 0, 0, 0); if (intersects) { WebCore::IntRect * const start = rings->begin(); WebCore::IntRect* ring = start + size - 1; do { ring->intersect(outer); if (ring->isEmpty()) { if ((size_t) (ring - start) != --size) *ring = start[size]; } else inner->unite(*ring); } while (ring-- != start); } rings->shrink(size); // DBG_NAV_LOGD("size:%d", size); return size != 0; }
void WebPageCompositorPrivate::findFixedElementRect(LayerCompositingThread* layer, WebCore::IntRect& fixedElementRect) { if ((layer->hasFixedContainer() || layer->isFixedPosition() || layer->hasFixedAncestorInDOMTree()) && layer->layerRenderer()) { IntRect fixedRect = layer->layerRenderer()->toPixelViewportCoordinates(layer->boundingBox()); // FIXME: It's possible that the rects don't intersect now, but will be connected by a fixed rect found later. // We need to handle it as well. if (fixedElementRect.isEmpty() || fixedElementRect.intersects(fixedRect)) // Unite rects if they intersect each other. fixedElementRect.unite(fixedRect); else if (fixedRect.y() < fixedElementRect.y()) // Replace the fixedElementRect with fixedRect if fixedRect is above it (closer to top). fixedElementRect = fixedRect; } const Vector<RefPtr<LayerCompositingThread> >& sublayers = layer->sublayers(); for (size_t i = 0; i < sublayers.size(); i++) findFixedElementRect(sublayers[i].get(), fixedElementRect); }
void CachedNode::fixUpFocusRects() { if (mFixedUpFocusRects) return; mFixedUpFocusRects = true; if (mNavableRects <= 1) return; #if DEBUG_NAV_UI { WebCore::IntRect* boundsPtr = mFocusRing.begin() - 1; const WebCore::IntRect* const boundsEnd = mFocusRing.begin() + mFocusRing.size(); while (++boundsPtr < boundsEnd) LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, boundsPtr - mFocusRing.begin(), boundsPtr->x(), boundsPtr->y(), boundsPtr->width(), boundsPtr->height()); } #endif // q: need to know when rects are for drawing and hit-testing, but not mouse down calcs? bool again; do { again = false; size_t size = mFocusRing.size(); WebCore::IntRect* unitBoundsPtr = mFocusRing.begin() - 1; const WebCore::IntRect* const unitBoundsEnd = mFocusRing.begin() + size; while (++unitBoundsPtr < unitBoundsEnd) { // any other unitBounds to the left or right of this one? int unitTop = unitBoundsPtr->y(); int unitBottom = unitBoundsPtr->bottom(); int unitLeft = unitBoundsPtr->x(); int unitRight = unitBoundsPtr->right(); WebCore::IntRect* testBoundsPtr = mFocusRing.begin() - 1; while (++testBoundsPtr < unitBoundsEnd) { if (unitBoundsPtr == testBoundsPtr) continue; int testTop = testBoundsPtr->y(); int testBottom = testBoundsPtr->bottom(); int testLeft = testBoundsPtr->x(); int testRight = testBoundsPtr->right(); int candidateTop = unitTop > testTop ? unitTop : testTop; int candidateBottom = unitBottom < testBottom ? unitBottom : testBottom; int candidateLeft = unitRight < testLeft ? unitRight : testRight; int candidateRight = unitRight > testLeft ? unitLeft : testLeft; bool leftRight = true; if (candidateTop + OVERLAP >= candidateBottom || candidateLeft + OVERLAP >= candidateRight) { candidateTop = unitBottom < testTop ? unitBottom : testBottom; candidateBottom = unitBottom > testTop ? unitTop : testTop; candidateLeft = unitLeft > testLeft ? unitLeft : testLeft; candidateRight = unitRight < testRight ? unitRight : testRight; if (candidateTop + OVERLAP >= candidateBottom || candidateLeft + OVERLAP >= candidateRight) continue; leftRight = false; } // construct candidate to add WebCore::IntRect candidate = WebCore::IntRect(candidateLeft, candidateTop, candidateRight - candidateLeft, candidateBottom - candidateTop); // does a different unit bounds intersect the candidate? if so, don't add WebCore::IntRect* checkBoundsPtr = mFocusRing.begin() - 1; while (++checkBoundsPtr < unitBoundsEnd) { if (checkBoundsPtr->intersects(candidate) == false) continue; if (leftRight) { if (candidateTop >= checkBoundsPtr->y() && candidateBottom > checkBoundsPtr->bottom()) candidateTop = checkBoundsPtr->bottom(); else if (candidateTop < checkBoundsPtr->y() && candidateBottom <= checkBoundsPtr->bottom()) candidateBottom = checkBoundsPtr->y(); else goto nextCheck; } else { if (candidateLeft >= checkBoundsPtr->x() && candidateRight > checkBoundsPtr->right()) candidateLeft = checkBoundsPtr->right(); else if (candidateLeft < checkBoundsPtr->x() && candidateRight <= checkBoundsPtr->right()) candidateRight = checkBoundsPtr->x(); else goto nextCheck; } } candidate = WebCore::IntRect(candidateLeft, candidateTop, candidateRight - candidateLeft, candidateBottom - candidateTop); ASSERT(candidate.isEmpty() == false); #if DEBUG_NAV_UI LOGD("%s %d:(%d, %d, %d, %d)\n", __FUNCTION__, mFocusRing.size(), candidate.x(), candidate.y(), candidate.width(), candidate.height()); #endif mFocusRing.append(candidate); again = true; goto tryAgain; nextCheck: continue; } } tryAgain: ; } while (again); }