示例#1
0
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;
}
示例#2
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);
}
示例#3
0
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);
}