Пример #1
0
// 'region' is in contents coordinates relative to the frame containing 'node'
// 'remainingFingerRegion' and 'intersectingRegions' will always be in main frame contents
// coordinates.
// Thus, before comparing, we need to map the former to main frame contents coordinates.
bool FatFingers::checkFingerIntersection(const Platform::IntRectRegion& region,
                                         const Platform::IntRectRegion& remainingFingerRegion,
                                         Node* node, Vector<IntersectingRegion>& intersectingRegions)
{
    ASSERT(node);

    Platform::IntRectRegion regionCopy(region);
    WebCore::IntPoint framePos(m_webPage->frameOffset(node->document()->frame()));
    regionCopy.move(framePos.x(), framePos.y());

    Platform::IntRectRegion intersection = intersectRegions(regionCopy, remainingFingerRegion);
    if (intersection.isEmpty())
        return false;

#if DEBUG_FAT_FINGERS
    String nodeName;
    if (node->isTextNode())
        nodeName = "text node";
    else if (node->isElementNode())
        nodeName = String::format("%s node", toElement(node)->tagName().latin1().data());
    else
        nodeName = "unknown node";
    log(LogLevelInfo, "%s has region %s, intersecting at %s (area %d)", nodeName.latin1().data(),
        regionCopy.toString().c_str(), intersection.toString().c_str(), intersection.area());
#endif

    intersectingRegions.append(std::make_pair(node, intersection));
    return true;
}
Пример #2
0
bool FatFingers::checkForClickableElement(Element* curElement,
                                          Vector<IntersectingRegion>& intersectingRegions,
                                          IntRectRegion& remainingFingerRegion,
                                          RenderLayer*& lowestPositionedEnclosingLayerSoFar)
{
    ASSERT(curElement);

    bool intersects = false;
    IntRectRegion elementRegion;

    bool isClickableElement = isElementClickable(curElement);
    if (isClickableElement) {
        if (curElement->isLink()) {
            // Links can wrap lines, and in such cases Node::boundingBox() can give us
            // not accurate rects, since it unites all InlineBox's rects. In these
            // cases, we can process each line of the link separately with our
            // intersection rect, getting a more accurate clicking.
            Vector<FloatQuad> quads;
            curElement->renderer()->absoluteFocusRingQuads(quads);

            size_t n = quads.size();
            ASSERT(n);

            for (size_t i = 0; i < n; ++i)
                elementRegion = unionRegions(elementRegion, Platform::IntRect(quads[i].enclosingBoundingBox()));
        } else
            elementRegion = IntRectRegion(curElement->renderer()->absoluteBoundingBoxRect(true /*use transforms*/));

    } else
        elementRegion = IntRectRegion(curElement->renderer()->absoluteBoundingBoxRect(true /*use transforms*/));

    if (lowestPositionedEnclosingLayerSoFar) {
        RenderLayer* curElementRenderLayer = m_webPage->enclosingPositionedAncestorOrSelfIfPositioned(curElement->renderer()->enclosingLayer());
        if (curElementRenderLayer != lowestPositionedEnclosingLayerSoFar) {

            // elementRegion will always be in contents coordinates of its container frame. It needs to be
            // mapped to main frame contents coordinates in order to intersect the fingerRegion, then.
            WebCore::IntPoint framePos(m_webPage->frameOffset(curElement->document()->frame()));
            IntRectRegion layerRegion(Platform::IntRect(lowestPositionedEnclosingLayerSoFar->renderer()->absoluteBoundingBoxRect(true/*use transforms*/)));
            layerRegion.move(framePos.x(), framePos.y());

            remainingFingerRegion = intersectRegions(remainingFingerRegion, layerRegion);

            lowestPositionedEnclosingLayerSoFar = curElementRenderLayer;
        }
    } else
        lowestPositionedEnclosingLayerSoFar = m_webPage->enclosingPositionedAncestorOrSelfIfPositioned(curElement->renderer()->enclosingLayer());

    if (isClickableElement)
        intersects = checkFingerIntersection(elementRegion, remainingFingerRegion, curElement, intersectingRegions);

    return intersects;
}