static void applyClipRects(const ClipRectsContext& context, const LayoutObject& layoutObject, LayoutPoint offset, ClipRects& clipRects) { ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip() || layoutObject.style()->containsPaint()); LayoutView* view = layoutObject.view(); ASSERT(view); if (clipRects.fixed() && context.rootLayer->layoutObject() == view) offset -= toIntSize(view->frameView()->scrollPosition()); if (layoutObject.hasOverflowClip() || layoutObject.style()->containsPaint()) { ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(offset, context.scrollbarRelevancy); newOverflowClip.setHasRadius(layoutObject.style()->hasBorderRadius()); clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); if (layoutObject.isPositioned()) clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); if (layoutObject.isLayoutView()) clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect())); if (layoutObject.style()->containsPaint()) { clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.fixedClipRect())); } } if (layoutObject.hasClip()) { LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect()).setIsClippedByClipCss()); clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()).setIsClippedByClipCss()); } }
static inline bool fullyClipsContents(Node* node) { LayoutObject* renderer = node->layoutObject(); if (!renderer || !renderer->isBox() || !renderer->hasOverflowClip()) return false; return toLayoutBox(renderer)->size().isEmpty(); }
void PaintInvalidationState::applyClipIfNeeded(const LayoutObject& layoutObject) { if (!layoutObject.hasOverflowClip()) return; const LayoutBox& box = toLayoutBox(layoutObject); // Do not clip scroll layer contents because the compositor expects the whole layer // to be always invalidated in-time. if (box.usesCompositedScrolling()) ASSERT(!m_clipped); // The box should establish paint invalidation container, so no m_clipped inherited. else addClipRectRelativeToPaintOffset(LayoutSize(box.layer()->size())); m_paintOffset -= box.scrolledContentOffset(); }
void IntersectionObservation::clipToRoot(LayoutRect& rect) { // Map and clip rect into root element coordinates. // TODO(szager): the writing mode flipping needs a test. ASSERT(m_target); LayoutObject* rootLayoutObject = m_observer->rootLayoutObject(); LayoutObject* targetLayoutObject = target()->layoutObject(); targetLayoutObject->mapToVisibleRectInAncestorSpace(toLayoutBoxModelObject(rootLayoutObject), rect, nullptr); if (rootLayoutObject->hasOverflowClip()) { LayoutBox* rootLayoutBox = toLayoutBox(rootLayoutObject); LayoutRect clipRect(LayoutPoint(), LayoutSize(rootLayoutBox->layer()->size())); m_observer->applyRootMargin(clipRect); rootLayoutBox->flipForWritingMode(rect); rect.intersect(clipRect); rootLayoutBox->flipForWritingMode(rect); } }
static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (!object.isBoxModelObject() || !object.hasOverflowClip()) return nullptr; PaintLayer* layer = toLayoutBoxModelObject(object).layer(); ASSERT(layer); DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); if (scrollOffset.isZero() && !layer->scrollsOverflow()) return nullptr; RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height()), FloatPoint3D(), context.currentTransform); context.currentTransform = newTransformNodeForScrollTranslation.get(); return newTransformNodeForScrollTranslation.release(); }
void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.hasOverflowClip()) { const LayoutBox& box = toLayoutBox(object); const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); IntSize scrollOffset = box.scrolledContentOffset(); if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { TransformationMatrix matrix = TransformationMatrix().translate( -scrollOffset.width(), -scrollOffset.height()); object.getMutableForPainting() .ensurePaintProperties() .updateScrollTranslation( context.current.transform, matrix, FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); IntSize scrollClip = scrollableArea->visibleContentRect().size(); IntSize scrollBounds = scrollableArea->contentsSize(); bool userScrollableHorizontal = scrollableArea->userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = scrollableArea->userInputScrollable(VerticalScrollbar); object.getMutableForPainting().ensurePaintProperties().updateScroll( context.current.scroll, object.paintProperties()->scrollTranslation(), scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); } else { // Ensure pre-existing properties are cleared when there is no // scrolling. auto* properties = object.getMutableForPainting().paintProperties(); if (properties) { properties->clearScrollTranslation(); properties->clearScroll(); } } } if (object.paintProperties() && object.paintProperties()->scroll()) { context.current.transform = object.paintProperties()->scrollTranslation(); const auto* scroll = object.paintProperties()->scroll(); // TODO(pdr): Remove this const cast. context.current.scroll = const_cast<ScrollPaintPropertyNode*>(scroll); context.current.shouldFlattenInheritedTransform = false; } }
void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (!object.isBoxModelObject() || !object.hasOverflowClip()) return; PaintLayer* layer = toLayoutBoxModelObject(object).layer(); ASSERT(layer); DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); if (scrollOffset.isZero() && !layer->scrollsOverflow()) return; RefPtr<TransformPaintPropertyNode> scrollTranslation = TransformPaintPropertyNode::create( TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.height()), FloatPoint3D(), context.currentTransform); context.currentTransform = scrollTranslation.get(); object.getMutableForPainting().ensureObjectPaintProperties().setScrollTranslation(scrollTranslation.release()); }
void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (object.hasOverflowClip()) { const LayoutBox& box = toLayoutBox(object); const PaintLayerScrollableArea* scrollableArea = box.getScrollableArea(); IntSize scrollOffset = box.scrolledContentOffset(); if (!scrollOffset.isZero() || scrollableArea->scrollsOverflow()) { TransformationMatrix matrix = TransformationMatrix().translate( -scrollOffset.width(), -scrollOffset.height()); context.current.transform = object.getMutableForPainting() .ensurePaintProperties() .updateScrollTranslation( context.current.transform, matrix, FloatPoint3D(), context.current.shouldFlattenInheritedTransform, context.current.renderingContextID); IntSize scrollClip = scrollableArea->visibleContentRect().size(); IntSize scrollBounds = scrollableArea->contentsSize(); bool userScrollableHorizontal = scrollableArea->userInputScrollable(HorizontalScrollbar); bool userScrollableVertical = scrollableArea->userInputScrollable(VerticalScrollbar); context.current.scroll = object.getMutableForPainting().ensurePaintProperties().updateScroll( context.current.scroll, context.current.transform, scrollClip, scrollBounds, userScrollableHorizontal, userScrollableVertical); context.current.shouldFlattenInheritedTransform = false; return; } } if (auto* properties = object.getMutableForPainting().paintProperties()) { properties->clearScrollTranslation(); properties->clearScroll(); } }