void ScrollingCoordinator::updateMainFrameScrollPosition(const IntPoint& scrollPosition, bool programmaticScroll, SetOrSyncScrollingLayerPosition scrollingLayerPositionAction) { ASSERT(isMainThread()); if (!m_page) return; FrameView* frameView = m_page->mainFrame()->view(); if (!frameView) return; bool oldProgrammaticScroll = frameView->inProgrammaticScroll(); frameView->setInProgrammaticScroll(programmaticScroll); frameView->setConstrainsScrollingToContentEdge(false); frameView->notifyScrollPositionChanged(scrollPosition); frameView->setConstrainsScrollingToContentEdge(true); frameView->setInProgrammaticScroll(oldProgrammaticScroll); #if USE(ACCELERATED_COMPOSITING) if (GraphicsLayer* scrollLayer = scrollLayerForFrameView(frameView)) { if (programmaticScroll || scrollingLayerPositionAction == SetScrollingLayerPosition) scrollLayer->setPosition(-frameView->scrollPosition()); else { scrollLayer->syncPosition(-frameView->scrollPosition()); LayoutRect viewportRect = frameView->visibleContentRect(); viewportRect.setLocation(IntPoint(frameView->scrollOffsetForFixedPosition())); syncChildPositions(viewportRect); } } #else UNUSED_PARAM(scrollingLayerPositionAction); #endif }
LayoutRect InlineBox::logicalRectToPhysicalRect(const LayoutRect& current) { LayoutRect retval = current; if (!isHorizontal()) { retval = retval.transposedRect(); } retval.setLocation(logicalPositionToPhysicalPoint(FloatPoint(retval.location()), FloatSize(retval.size())).toLayoutPoint()); return retval; }
void InlineBox::logicalRectToPhysicalRect(LayoutRect& current) const { if (isHorizontal() && !lineLayoutItem().hasFlippedBlocksWritingMode()) return; if (!isHorizontal()) { current = current.transposedRect(); } current.setLocation(logicalPositionToPhysicalPoint(current.location(), current.size())); return; }
bool RenderWidget::updateWidgetGeometry() { LayoutRect contentBox = contentBoxRect(); LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox()); if (m_widget->isFrameView()) { contentBox.setLocation(absoluteContentBox.location()); return setWidgetGeometry(contentBox); } return setWidgetGeometry(absoluteContentBox); }
void RenderRegion::computeOverflowFromFlowThread() { ASSERT(isValid()); LayoutRect layoutRect = overflowRectForFlowThreadPortion(flowThreadPortionRect(), isFirstRegion(), isLastRegion(), LayoutOverflow); layoutRect.setLocation(contentBoxRect().location() + (layoutRect.location() - m_flowThreadPortionRect.location())); // FIXME: Correctly adjust the layout overflow for writing modes. addLayoutOverflow(layoutRect); updateLayerTransform(); updateScrollInfoAfterLayout(); }
bool LayoutPart::updateWidgetGeometry() { Widget* widget = this->widget(); ASSERT(widget); LayoutRect contentBox = contentBoxRect(); LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox()); if (widget->isFrameView()) { contentBox.setLocation(absoluteContentBox.location()); return setWidgetGeometry(contentBox); } return setWidgetGeometry(absoluteContentBox); }
bool LayoutPart::updateWidgetGeometryInternal() { Widget* widget = this->widget(); ASSERT(widget); LayoutRect contentBox = contentBoxRect(); LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(FloatRect(contentBox))).boundingBox()); if (widget->isFrameView()) { if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) contentBox.setLocation(absoluteContentBox.location()); return setWidgetGeometry(contentBox); } // TODO(chrishtr): why are these widgets using an absolute rect for their frameRect? return setWidgetGeometry(absoluteContentBox); }
void RenderRegion::computeOverflowFromFlowThread() { ASSERT(isValid()); LayoutRect layoutRect; { // When getting the overflow from the flow thread we need to temporarly reset the current flow thread because // we're changing flows. CurrentRenderFlowThreadMaintainer flowThreadMaintainer(m_flowThread); layoutRect = layoutOverflowRectForBox(m_flowThread); } layoutRect.setLocation(contentBoxRect().location() + (layoutRect.location() - m_flowThreadPortionRect.location())); // FIXME: Correctly adjust the layout overflow for writing modes. addLayoutOverflow(layoutRect); RenderFlowThread* enclosingRenderFlowThread = flowThreadContainingBlock(); if (enclosingRenderFlowThread) enclosingRenderFlowThread->addRegionsLayoutOverflow(this, layoutRect); updateLayerTransform(); updateScrollInfoAfterLayout(); }
void BackgroundImageGeometry::calculate( const LayoutBoxModelObject& obj, const LayoutBoxModelObject* paintContainer, const GlobalPaintFlags globalPaintFlags, const FillLayer& fillLayer, const LayoutRect& paintRect) { LayoutUnit left; LayoutUnit top; LayoutSize positioningAreaSize; bool isLayoutView = obj.isLayoutView(); const LayoutBox* rootBox = nullptr; if (isLayoutView) { // It is only possible reach here when root element has a box. Element* documentElement = obj.document().documentElement(); DCHECK(documentElement); DCHECK(documentElement->layoutObject()); DCHECK(documentElement->layoutObject()->isBox()); rootBox = toLayoutBox(documentElement->layoutObject()); } const LayoutBoxModelObject& positioningBox = isLayoutView ? static_cast<const LayoutBoxModelObject&>(*rootBox) : obj; // Determine the background positioning area and set destRect to the // background painting area. destRect will be adjusted later if the // background is non-repeating. // FIXME: transforms spec says that fixed backgrounds behave like scroll // inside transforms. bool fixedAttachment = fillLayer.attachment() == FixedBackgroundAttachment; if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) { // As a side effect of an optimization to blit on scroll, we do not honor // the CSS property "background-attachment: fixed" because it may result in // rendering artifacts. Note, these artifacts only appear if we are blitting // on scroll of a page that has fixed background images. fixedAttachment = false; } if (!fixedAttachment) { setDestRect(paintRect); LayoutUnit right; LayoutUnit bottom; // Scroll and Local. if (fillLayer.origin() != BorderFillBox) { left = LayoutUnit(positioningBox.borderLeft()); right = LayoutUnit(positioningBox.borderRight()); top = LayoutUnit(positioningBox.borderTop()); bottom = LayoutUnit(positioningBox.borderBottom()); if (fillLayer.origin() == ContentFillBox) { left += positioningBox.paddingLeft(); right += positioningBox.paddingRight(); top += positioningBox.paddingTop(); bottom += positioningBox.paddingBottom(); } } if (isLayoutView) { // The background of the box generated by the root element covers the // entire canvas and will be painted by the view object, but the we should // still use the root element box for positioning. positioningAreaSize = rootBox->size() - LayoutSize(left + right, top + bottom), rootBox->location(); // The input paint rect is specified in root element local coordinate // (i.e. a transform is applied on the context for painting), and is // expanded to cover the whole canvas. Since left/top is relative to the // paint rect, we need to offset them back. left -= paintRect.x(); top -= paintRect.y(); } else { positioningAreaSize = paintRect.size() - LayoutSize(left + right, top + bottom); } } else { setHasNonLocalGeometry(); LayoutRect viewportRect = obj.viewRect(); if (fixedBackgroundPaintsInLocalCoordinates(obj, globalPaintFlags)) { viewportRect.setLocation(LayoutPoint()); } else { if (FrameView* frameView = obj.view()->frameView()) viewportRect.setLocation(IntPoint(frameView->scrollOffsetInt())); // Compensate the translations created by ScrollRecorders. // TODO(trchen): Fix this for SP phase 2. crbug.com/529963. viewportRect.moveBy( accumulatedScrollOffsetForFixedBackground(obj, paintContainer)); } if (paintContainer) viewportRect.moveBy( LayoutPoint(-paintContainer->localToAbsolute(FloatPoint()))); setDestRect(viewportRect); positioningAreaSize = destRect().size(); } LayoutSize fillTileSize( calculateFillTileSize(positioningBox, fillLayer, positioningAreaSize)); // It's necessary to apply the heuristic here prior to any further // calculations to avoid incorrectly using sub-pixel values that won't be // present in the painted tile. setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); EFillRepeat backgroundRepeatX = fillLayer.repeatX(); EFillRepeat backgroundRepeatY = fillLayer.repeatY(); LayoutUnit unsnappedAvailableWidth = positioningAreaSize.width() - fillTileSize.width(); LayoutUnit unsnappedAvailableHeight = positioningAreaSize.height() - fillTileSize.height(); positioningAreaSize = LayoutSize(snapSizeToPixel(positioningAreaSize.width(), m_destRect.x()), snapSizeToPixel(positioningAreaSize.height(), m_destRect.y())); LayoutUnit availableWidth = positioningAreaSize.width() - tileSize().width(); LayoutUnit availableHeight = positioningAreaSize.height() - tileSize().height(); LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer.xPosition(), availableWidth); if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > LayoutUnit() && fillTileSize.width() > LayoutUnit()) { int nrTiles = std::max( 1, roundToInt(positioningAreaSize.width() / fillTileSize.width())); LayoutUnit roundedWidth = positioningAreaSize.width() / nrTiles; // Maintain aspect ratio if background-size: auto is set if (fillLayer.size().size.height().isAuto() && backgroundRepeatY != RoundFill) { fillTileSize.setHeight(fillTileSize.height() * roundedWidth / fillTileSize.width()); } fillTileSize.setWidth(roundedWidth); setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); setPhaseX(tileSize().width() ? LayoutUnit(roundf( tileSize().width() - fmodf((computedXPosition + left), tileSize().width()))) : LayoutUnit()); setSpaceSize(LayoutSize()); } LayoutUnit computedYPosition = roundedMinimumValueForLength(fillLayer.yPosition(), availableHeight); if (backgroundRepeatY == RoundFill && positioningAreaSize.height() > LayoutUnit() && fillTileSize.height() > LayoutUnit()) { int nrTiles = std::max( 1, roundToInt(positioningAreaSize.height() / fillTileSize.height())); LayoutUnit roundedHeight = positioningAreaSize.height() / nrTiles; // Maintain aspect ratio if background-size: auto is set if (fillLayer.size().size.width().isAuto() && backgroundRepeatX != RoundFill) { fillTileSize.setWidth(fillTileSize.width() * roundedHeight / fillTileSize.height()); } fillTileSize.setHeight(roundedHeight); setTileSize(applySubPixelHeuristicToImageSize(fillTileSize, m_destRect)); setPhaseY(tileSize().height() ? LayoutUnit(roundf( tileSize().height() - fmodf((computedYPosition + top), tileSize().height()))) : LayoutUnit()); setSpaceSize(LayoutSize()); } if (backgroundRepeatX == RepeatFill) { setRepeatX(fillLayer, fillTileSize.width(), availableWidth, unsnappedAvailableWidth, left); } else if (backgroundRepeatX == SpaceFill && tileSize().width() > LayoutUnit()) { LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.width(), tileSize().width()); if (space >= LayoutUnit()) setSpaceX(space, availableWidth, left); else backgroundRepeatX = NoRepeatFill; } if (backgroundRepeatX == NoRepeatFill) { LayoutUnit xOffset = fillLayer.backgroundXOrigin() == RightEdge ? availableWidth - computedXPosition : computedXPosition; setNoRepeatX(left + xOffset); } if (backgroundRepeatY == RepeatFill) { setRepeatY(fillLayer, fillTileSize.height(), availableHeight, unsnappedAvailableHeight, top); } else if (backgroundRepeatY == SpaceFill && tileSize().height() > LayoutUnit()) { LayoutUnit space = getSpaceBetweenImageTiles(positioningAreaSize.height(), tileSize().height()); if (space >= LayoutUnit()) setSpaceY(space, availableHeight, top); else backgroundRepeatY = NoRepeatFill; } if (backgroundRepeatY == NoRepeatFill) { LayoutUnit yOffset = fillLayer.backgroundYOrigin() == BottomEdge ? availableHeight - computedYPosition : computedYPosition; setNoRepeatY(top + yOffset); } if (fixedAttachment) useFixedAttachment(paintRect.location()); // Clip the final output rect to the paint rect m_destRect.intersect(paintRect); // Snap as-yet unsnapped values. setDestRect(LayoutRect(pixelSnappedIntRect(m_destRect))); }