void write(TextStream& ts, const RenderObject& o, int indent) { #if ENABLE(SVG) if (o.isRenderPath()) { write(ts, *toRenderPath(&o), indent); return; } if (o.isSVGContainer()) { writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { if (!o.isText()) writeSVGText(ts, *toRenderBlock(&o), indent); else writeSVGInlineText(ts, *toRenderText(&o), indent); return; } if (o.isSVGImage()) { writeSVGImage(ts, *toRenderImage(&o), indent); return; } #endif writeIndent(ts, indent); ts << o << "\n"; if (o.isText() && !o.isBR()) { const RenderText& text = *toRenderText(&o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1); } if (o.isWidget()) { Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); if (root) { view->layout(); RenderLayer* l = root->layer(); if (l) writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1); } } } }
TEST_F(ScrollingCoordinatorChromiumTest, touchOverflowScrolling) { registerMockedHttpURLLoad("touch-overflow-scrolling.html"); navigateTo(m_baseURL + "touch-overflow-scrolling.html"); // Verify the properties of the accelerated scrolling element starting from the RenderObject // all the way to the WebLayer. Element* scrollableElement = m_webViewImpl->mainFrameImpl()->frame()->document()->getElementById("scrollable"); ASSERT(scrollableElement); RenderObject* renderer = scrollableElement->renderer(); ASSERT_TRUE(renderer->isBoxModelObject()); ASSERT_TRUE(renderer->hasLayer()); RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); ASSERT_TRUE(layer->usesCompositedScrolling()); ASSERT_TRUE(layer->isComposited()); RenderLayerBacking* layerBacking = layer->backing(); ASSERT_TRUE(layerBacking->hasScrollingLayer()); ASSERT(layerBacking->scrollingContentsLayer()); GraphicsLayerChromium* graphicsLayerChromium = static_cast<GraphicsLayerChromium*>(layerBacking->scrollingContentsLayer()); ASSERT_EQ(layer, graphicsLayerChromium->scrollableArea()); WebLayer* webScrollLayer = static_cast<WebLayer*>(layerBacking->scrollingContentsLayer()->platformLayer()); ASSERT_TRUE(webScrollLayer->scrollable()); }
TEST_F(ScrollingCoordinatorChromiumTest, fastScrollingForFixedPosition) { registerMockedHttpURLLoad("fixed-position.html"); navigateTo(m_baseURL + "fixed-position.html"); Page* page = m_webViewImpl->mainFrameImpl()->frame()->page(); ASSERT_TRUE(page->scrollingCoordinator()->supportsFixedPositionLayers()); // Fixed position should not fall back to main thread scrolling. WebLayer* rootScrollLayer = getRootScrollLayer(); ASSERT_FALSE(rootScrollLayer->shouldScrollOnMainThread()); // Verify the properties of the fixed position element starting from the RenderObject all the // way to the WebLayer. Element* fixedElement = m_webViewImpl->mainFrameImpl()->frame()->document()->getElementById("fixed"); ASSERT(fixedElement); RenderObject* renderer = fixedElement->renderer(); ASSERT_TRUE(renderer->isBoxModelObject()); ASSERT_TRUE(renderer->hasLayer()); RenderLayer* layer = toRenderBoxModelObject(renderer)->layer(); ASSERT_TRUE(layer->isComposited()); RenderLayerBacking* layerBacking = layer->backing(); WebLayer* webLayer = static_cast<WebLayer*>(layerBacking->graphicsLayer()->platformLayer()); ASSERT_TRUE(webLayer->fixedToContainerLayer()); }
IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer) { // Only run-ins are allowed in here during layout. ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn()); if (!firstLineBox() && !continuation()) return IntRect(); // Find our leftmost position. IntRect boundingBox(linesBoundingBox()); int left = boundingBox.x(); int top = boundingBox.y(); // Now invalidate a rectangle. int ow = style() ? style()->outlineSize() : 0; // We need to add in the relative position offsets of any inlines (including us) up to our // containing block. RenderBlock* cb = containingBlock(); for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInline() && inlineFlow != cb; inlineFlow = inlineFlow->parent()) { if (inlineFlow->style()->position() == RelativePosition && inlineFlow->hasLayer()) toRenderBox(inlineFlow)->layer()->relativePositionOffset(left, top); } IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2); if (cb->hasColumns()) cb->adjustRectForColumns(r); if (cb->hasOverflowClip()) { // cb->height() is inaccurate if we're in the middle of a layout of |cb|, so use the // layer's size instead. Even if the layer's size is wrong, the layer itself will repaint // anyway if its size does change. int x = r.x(); int y = r.y(); IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height()); cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden. IntRect repaintRect(x, y, r.width(), r.height()); r = intersection(repaintRect, boxRect); } ASSERT(repaintContainer != this); cb->computeRectForRepaint(r, repaintContainer); if (ow) { for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (!curr->isText()) { IntRect childRect = curr->rectWithOutlineForRepaint(repaintContainer, ow); r.unite(childRect); } } if (continuation() && !continuation()->isInline()) { IntRect contRect = continuation()->rectWithOutlineForRepaint(repaintContainer, ow); r.unite(contRect); } } return r; }
// Hit Testing bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction action) { // Table rows cannot ever be hit tested. Effectively they do not exist. // Just forward to our children always. for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { // FIXME: We have to skip over inline flows, since they can show up inside table rows // at the moment (a demoted inline <form> for example). If we ever implement a // table-specific hit-test method (which we should do for performance reasons anyway), // then we can remove this check. if (!child->hasLayer() && !child->isInlineFlow() && child->nodeAtPoint(request, result, x, y, tx, ty, action)) { updateHitTestResult(result, IntPoint(x - tx, y - ty)); return true; } } return false; }
bool ScrollingCoordinator::hasVisibleSlowRepaintViewportConstrainedObjects(FrameView* frameView) const { const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects(); if (!viewportConstrainedObjects) return false; for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) { RenderObject* viewportConstrainedObject = *it; if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer()) return true; RenderLayer* layer = toRenderBoxModelObject(viewportConstrainedObject)->layer(); // Any explicit reason that a fixed position element is not composited shouldn't cause slow scrolling. if (!layer->isComposited() && layer->viewportConstrainedNotCompositedReason() == RenderLayer::NoNotCompositedReason) return true; } return false; }
void RenderTableRow::paint(PaintInfo& paintInfo, int tx, int ty) { ASSERT(m_layer); if (!m_layer) return; for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isTableCell()) { // Paint the row background behind the cell. if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) { RenderTableCell* cell = static_cast<RenderTableCell*>(child); cell->paintBackgroundsBehindCell(paintInfo, tx, ty, this); } if (!child->hasLayer()) child->paint(paintInfo, tx, ty); } } }
String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior) { frame->document()->updateLayout(); RenderObject* o = frame->contentRenderer(); if (!o) return String(); TextStream ts; #if ENABLE(SVG) writeRenderResources(ts, o->document()); #endif if (o->hasLayer()) { RenderLayer* l = toRenderBox(o)->layer(); writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), 0, behavior); writeSelection(ts, o); } return ts.release(); }
bool ScrollingCoordinator::hasNonLayerFixedObjects(FrameView* frameView) const { const FrameView::ViewportConstrainedObjectSet* viewportConstrainedObjects = frameView->viewportConstrainedObjects(); if (!viewportConstrainedObjects) return false; #if USE(ACCELERATED_COMPOSITING) for (FrameView::ViewportConstrainedObjectSet::const_iterator it = viewportConstrainedObjects->begin(), end = viewportConstrainedObjects->end(); it != end; ++it) { RenderObject* viewportConstrainedObject = *it; if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer()) return true; RenderBoxModelObject* viewportConstrainedBoxModelObject = toRenderBoxModelObject(viewportConstrainedObject); if (!viewportConstrainedBoxModelObject->layer()->backing()) return true; } return false; #else return viewportConstrainedObjects->size(); #endif }
void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior) { writeIndent(ts, indent); RenderTreeAsText::writeRenderObject(ts, o, behavior); ts << "\n"; if (o.isText()) { const RenderText& text = toRenderText(o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.slowFirstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1, behavior); } }
String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior) { PrintContext printContext(frame); if (behavior & RenderAsTextPrintingMode) { if (!frame->contentRenderer()) return String(); printContext.begin(frame->contentRenderer()->width()); } frame->document()->updateLayout(); RenderObject* o = frame->contentRenderer(); if (!o) return String(); TextStream ts; if (o->hasLayer()) { RenderLayer* l = toRenderBox(o)->layer(); writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), 0, behavior); writeSelection(ts, o); } return ts.release(); }
void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior) { #if ENABLE(SVG) if (o.isSVGShape()) { write(ts, *toRenderSVGShape(&o), indent); return; } if (o.isSVGGradientStop()) { writeSVGGradientStop(ts, *toRenderSVGGradientStop(&o), indent); return; } if (o.isSVGResourceContainer()) { writeSVGResourceContainer(ts, o, indent); return; } if (o.isSVGContainer()) { writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { writeSVGText(ts, *toRenderSVGText(&o), indent); return; } if (o.isSVGInlineText()) { writeSVGInlineText(ts, *toRenderSVGInlineText(&o), indent); return; } if (o.isSVGImage()) { writeSVGImage(ts, *toRenderSVGImage(&o), indent); return; } #endif writeIndent(ts, indent); RenderTreeAsText::writeRenderObject(ts, o, behavior); ts << "\n"; if (o.isText() && !o.isBR()) { const RenderText& text = *toRenderText(&o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1, behavior); } if (o.isWidget()) { Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); if (root) { view->layout(); RenderLayer* l = root->layer(); if (l) writeLayers(ts, l, l, l->rect(), indent + 1, behavior); } } } }