void TouchEventHandler::drawTapHighlight() { Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable(); if (!elementUnderFatFinger) return; Element* element = elementForTapHighlight(elementUnderFatFinger); if (!element) return; // Get the element bounding rect in transformed coordinates so we can extract // the focus ring relative position each rect. RenderObject* renderer = element->renderer(); ASSERT(renderer); Frame* elementFrame = element->document()->frame(); ASSERT(elementFrame); FrameView* elementFrameView = elementFrame->view(); if (!elementFrameView) return; // Tell the client if the element is either in a scrollable container or in a fixed positioned container. // On the client side, this info is being used to hide the tap highlight window on scroll. RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer()); bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView(); shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScroller->d->node(); IntPoint framePos(m_webPage->frameOffset(elementFrame)); // FIXME: We can get more precise on the <map> case by calculating the rect with HTMLAreaElement::computeRect(). IntRect absoluteRect(renderer->absoluteClippedOverflowRect()); absoluteRect.move(framePos.x(), framePos.y()); IntRect clippingRect; if (elementFrame == m_webPage->mainFrame()) clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize()); else clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/)); clippingRect = intersection(absoluteRect, clippingRect); Vector<FloatQuad> focusRingQuads; renderer->absoluteFocusRingQuads(focusRingQuads); Platform::IntRectRegion region; for (size_t i = 0; i < focusRingQuads.size(); ++i) { IntRect rect = focusRingQuads[i].enclosingBoundingBox(); rect.move(framePos.x(), framePos.y()); IntRect clippedRect = intersection(clippingRect, rect); clippedRect.inflate(2); region = unionRegions(region, Platform::IntRect(clippedRect)); } Color highlightColor = element->renderStyle()->tapHighlightColor(); m_webPage->m_tapHighlight->draw(region, highlightColor.red(), highlightColor.green(), highlightColor.blue(), highlightColor.alpha(), shouldHideTapHighlightRightAfterScrolling); }
IntRect PluginView::calculateClipRect() const { FrameView* frameView = toFrameView(parent()); bool visible = frameView && isVisible(); RenderObject* renderer = m_element->renderer(); if (visible && frameView->width() && frameView->height() && renderer) { IntSize windowSize = frameView->hostWindow()->platformPageClient()->viewportSize(); // Get the clipped rectangle for this player within the current frame. IntRect visibleContentRect; IntRect contentRect = renderer->absoluteClippedOverflowRect(); FloatPoint contentLocal = renderer->absoluteToLocal(FloatPoint(contentRect.location())); contentRect.setLocation(roundedIntPoint(contentLocal)); contentRect.move(frameRect().x(), frameRect().y()); // Clip against any frames that the widget is inside. Note that if the frames are also clipped // by a div, that will not be included in this calculation. That is an improvement that still // needs to be made. const Widget* current = this; while (current->parent() && visible) { // Determine if it is visible in this scrollview. visibleContentRect = current->parent()->visibleContentRect(); // Special case for the root ScrollView. Its size does not match the actual window size. if (current->parent() == root()) visibleContentRect.setSize(windowSize); contentRect.intersect(visibleContentRect); visible = !contentRect.isEmpty(); // Offset to visible coordinates in scrollview widget's coordinate system (except in the case of // the top scroll view). if (current->parent()->parent()) contentRect.move(-visibleContentRect.x(), -visibleContentRect.y()); current = current->parent(); // Don't include the offset for the root window or we get the wrong coordinates. if (current->parent()) { // Move content rect into the parent scrollview's coordinates. IntRect curFrameRect = current->frameRect(); contentRect.move(curFrameRect.x(), curFrameRect.y()); } } return contentRect; } return IntRect(); }
IntRect RenderTableCol::absoluteClippedOverflowRect() { // For now, just repaint the whole table. // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we // might have propagated a background color or borders into. RenderObject* table = parent(); if (table && !table->isTable()) table = table->parent(); if (table && table->isTable()) return table->absoluteClippedOverflowRect(); return IntRect(); }
IntRect RenderSVGContainer::absoluteClippedOverflowRect() { IntRect repaintRect; for (RenderObject* current = firstChild(); current != 0; current = current->nextSibling()) repaintRect.unite(current->absoluteClippedOverflowRect()); #if ENABLE(SVG_EXPERIMENTAL_FEATURES) // Filters can expand the bounding box SVGResourceFilter* filter = getFilterById(document(), SVGURIReference::getTarget(style()->svgStyle()->filter())); if (filter) repaintRect.unite(enclosingIntRect(filter->filterBBoxForItemBBox(repaintRect))); #endif return repaintRect; }
// Checks if |node| is offscreen the visible area (viewport) of its container // document. In case it is, one can scroll in direction or take any different // desired action later on. bool hasOffscreenRect(Node* node, FocusDirection direction) { // Get the FrameView in which |node| is (which means the current viewport if |node| // is not in an inner document), so we can check if its content rect is visible // before we actually move the focus to it. FrameView* frameView = node->document()->view(); if (!frameView) return true; ASSERT(!frameView->needsLayout()); IntRect containerViewportRect = frameView->visibleContentRect(); // We want to select a node if it is currently off screen, but will be // exposed after we scroll. Adjust the viewport to post-scrolling position. // If the container has overflow:hidden, we cannot scroll, so we do not pass direction // and we do not adjust for scrolling. switch (direction) { case FocusDirectionLeft: containerViewportRect.setX(containerViewportRect.x() - Scrollbar::pixelsPerLineStep()); containerViewportRect.setWidth(containerViewportRect.width() + Scrollbar::pixelsPerLineStep()); break; case FocusDirectionRight: containerViewportRect.setWidth(containerViewportRect.width() + Scrollbar::pixelsPerLineStep()); break; case FocusDirectionUp: containerViewportRect.setY(containerViewportRect.y() - Scrollbar::pixelsPerLineStep()); containerViewportRect.setHeight(containerViewportRect.height() + Scrollbar::pixelsPerLineStep()); break; case FocusDirectionDown: containerViewportRect.setHeight(containerViewportRect.height() + Scrollbar::pixelsPerLineStep()); break; default: break; } RenderObject* render = node->renderer(); if (!render) return true; IntRect rect(render->absoluteClippedOverflowRect()); if (rect.isEmpty()) return true; return !containerViewportRect.intersects(rect); }
// Checks if |node| is offscreen the visible area (viewport) of its container // document. In case it is, one can scroll in direction or take any different // desired action later on. bool hasOffscreenRect(Node* node) { // Get the FrameView in which |node| is (which means the current viewport if |node| // is not in an inner document), so we can check if its content rect is visible // before we actually move the focus to it. FrameView* frameView = node->document()->view(); if (!frameView) return true; IntRect containerViewportRect = frameView->visibleContentRect(); RenderObject* render = node->renderer(); if (!render) return true; IntRect rect(render->absoluteClippedOverflowRect()); return !containerViewportRect.intersects(rect); }
QWebHitTestResultPrivate::QWebHitTestResultPrivate(const WebCore::HitTestResult &hitTest) : isContentEditable(false) , isContentSelected(false) , isScrollBar(false) { if (!hitTest.innerNode()) return; pos = hitTest.point(); boundingRect = hitTest.boundingBox(); title = hitTest.title(); linkText = hitTest.textContent(); linkUrl = hitTest.absoluteLinkURL(); linkTitle = hitTest.titleDisplayString(); alternateText = hitTest.altDisplayString(); imageUrl = hitTest.absoluteImageURL(); innerNode = hitTest.innerNode(); innerNonSharedNode = hitTest.innerNonSharedNode(); WebCore::Image *img = hitTest.image(); if (img) { QPixmap *pix = img->nativeImageForCurrentFrame(); if (pix) pixmap = *pix; } WebCore::Frame *wframe = hitTest.targetFrame(); if (wframe) linkTargetFrame = QWebFramePrivate::kit(wframe); isContentEditable = hitTest.isContentEditable(); isContentSelected = hitTest.isSelected(); isScrollBar = hitTest.scrollbar(); if (innerNonSharedNode && innerNonSharedNode->document() && innerNonSharedNode->document()->frame()) frame = QWebFramePrivate::kit(innerNonSharedNode->document()->frame()); if (Node *block = WebCore::enclosingBlock(innerNode.get())) { RenderObject *renderBlock = block->renderer(); while (renderBlock && renderBlock->isListItem()) renderBlock = renderBlock->containingBlock(); if (renderBlock) enclosingBlock = renderBlock->absoluteClippedOverflowRect(); } }
IntRect RenderSVGContainer::absoluteClippedOverflowRect() { FloatRect repaintRect; for (RenderObject* current = firstChild(); current != 0; current = current->nextSibling()) repaintRect.unite(current->absoluteClippedOverflowRect()); #if ENABLE(SVG_FILTERS) // Filters can expand the bounding box SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter()); if (filter) repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect)); #endif if (!repaintRect.isEmpty()) repaintRect.inflate(1); // inflate 1 pixel for antialiasing return enclosingIntRect(repaintRect); }