void RenderBlockFlow::invalidatePaintForOverflow() { // FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines // it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either. LayoutUnit paintInvalidationLogicalLeft = logicalLeftVisualOverflow(); LayoutUnit paintInvalidationLogicalRight = logicalRightVisualOverflow(); if (hasOverflowClip()) { // If we have clipped overflow, we should use layout overflow as well, since visual overflow from lines didn't propagate to our block's overflow. // Note the old code did this as well but even for overflow:visible. The addition of hasOverflowClip() at least tightens up the hack a bit. // layoutInlineChildren should be patched to compute the entire paint invalidation rect. paintInvalidationLogicalLeft = std::min(paintInvalidationLogicalLeft, logicalLeftLayoutOverflow()); paintInvalidationLogicalRight = std::max(paintInvalidationLogicalRight, logicalRightLayoutOverflow()); } LayoutRect paintInvalidationRect = LayoutRect(paintInvalidationLogicalLeft, m_paintInvalidationLogicalTop, paintInvalidationLogicalRight - paintInvalidationLogicalLeft, m_paintInvalidationLogicalBottom - m_paintInvalidationLogicalTop); if (hasOverflowClip()) { // Adjust the paint invalidation rect for scroll offset paintInvalidationRect.move(-scrolledContentOffset()); // Don't allow this rect to spill out of our overflow box. paintInvalidationRect.intersect(LayoutRect(LayoutPoint(), size())); } // Make sure the rect is still non-empty after intersecting for overflow above if (!paintInvalidationRect.isEmpty()) { // Hits in media/event-attributes.html DisableCompositingQueryAsserts disabler; invalidatePaintRectangle(paintInvalidationRect); // We need to do a partial paint invalidation of our content. } m_paintInvalidationLogicalTop = 0; m_paintInvalidationLogicalBottom = 0; }
void RenderImage::paintInvalidationOrMarkForLayout(const IntRect* rect) { ASSERT(isRooted()); LayoutSize oldIntrinsicSize = intrinsicSize(); LayoutSize newIntrinsicSize = m_imageResource->intrinsicSize(); updateIntrinsicSizeIfNeeded(newIntrinsicSize); bool imageSourceHasChangedSize = oldIntrinsicSize != newIntrinsicSize; if (imageSourceHasChangedSize) setPreferredLogicalWidthsDirty(); // If the actual area occupied by the image has changed and it is not constrained by style then a layout is required. bool imageSizeIsConstrained = style()->logicalWidth().isSpecified() && style()->logicalHeight().isSpecified(); // FIXME: We only need to recompute the containing block's preferred size if the containing block's size // depends on the image's size (i.e., the container uses shrink-to-fit sizing). // There's no easy way to detect that shrink-to-fit is needed, always force a layout. bool containingBlockNeedsToRecomputePreferredSize = style()->logicalWidth().isPercent() || style()->logicalMaxWidth().isPercent() || style()->logicalMinWidth().isPercent(); if (imageSourceHasChangedSize && (!imageSizeIsConstrained || containingBlockNeedsToRecomputePreferredSize)) { setNeedsLayoutAndFullPaintInvalidation(); return; } // The image hasn't changed in size or its style constrains its size, so a paint invalidation will suffice. if (everHadLayout() && !selfNeedsLayout()) { // The inner content rectangle is calculated during layout, but may need an update now // (unless the box has already been scheduled for layout). In order to calculate it, we // may need values from the containing block, though, so make sure that we're not too // early. It may be that layout hasn't even taken place once yet. updateInnerContentRect(); } LayoutRect paintInvalidationRect; if (rect) { // The image changed rect is in source image coordinates, // so map from the bounds of the image to the contentsBox. paintInvalidationRect = enclosingIntRect(mapRect(*rect, FloatRect(FloatPoint(), m_imageResource->imageSize()), contentBoxRect())); // Guard against too-large changed rects. paintInvalidationRect.intersect(contentBoxRect()); } else { paintInvalidationRect = contentBoxRect(); } { // FIXME: We should not be allowing paint invalidations during layout. crbug.com/339584 AllowPaintInvalidationScope scoper(frameView()); DisableCompositingQueryAsserts disabler; invalidatePaintRectangle(paintInvalidationRect); } // Tell any potential compositing layers that the image needs updating. contentChanged(ImageChanged); }
void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const { ASSERT(isValid()); // We only have to issue a repaint in this region if the region rect intersects the repaint rect. LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect); LayoutRect flippedFlowThreadPortionOverflowRect(flowThreadPortionOverflowRect); flowThread()->flipForWritingMode(flippedFlowThreadPortionRect); // Put the region rects into physical coordinates. flowThread()->flipForWritingMode(flippedFlowThreadPortionOverflowRect); LayoutRect clippedRect(repaintRect); clippedRect.intersect(flippedFlowThreadPortionOverflowRect); if (clippedRect.isEmpty()) return; // Put the region rect into the region's physical coordinate space. clippedRect.setLocation(regionLocation + (clippedRect.location() - flippedFlowThreadPortionRect.location())); // Now switch to the region's writing mode coordinate space and let it repaint itself. flipForWritingMode(clippedRect); // Issue the repaint. invalidatePaintRectangle(clippedRect); }