Ignore:
Timestamp:
Jun 2, 2016, 10:27:53 PM (10 years ago)
Author:
Alan Bujtas
Message:

Repaint issue with vertical text in an out of flow container.
https://bugs.webkit.org/show_bug.cgi?id=102665
<rdar://problem/26605298>

Reviewed by David Hyatt.

Since the renderer’s offset for positioned objects is always physical, we only
need to flip the repaint rect(always logical) for writing root, when we see the first positioned object.
All subsequent writing root changes for positioned objects are okay and they don't need flipping.

Source/WebCore:

Test: fast/repaint/vertical-text-repaint.html

  • rendering/RenderBox.cpp:

(WebCore::RenderBox::computeRectForRepaint):

  • rendering/RenderBox.h:

(WebCore::RenderBox::computeRectForRepaint):

  • rendering/RenderInline.cpp:

(WebCore::RenderInline::computeRectForRepaint):

  • rendering/RenderInline.h:

(WebCore::RenderInline::computeRectForRepaint):

  • rendering/RenderObject.cpp:

(WebCore::RenderObject::computeRectForRepaint):

  • rendering/RenderObject.h:

(WebCore::RenderObject::computeAbsoluteRepaintRect):
(WebCore::RenderObject::computeRectForRepaint):

  • rendering/RenderTableCell.cpp:

(WebCore::RenderTableCell::computeRectForRepaint):

  • rendering/RenderTableCell.h:
  • rendering/RenderView.cpp:

(WebCore::RenderView::computeRectForRepaint):

  • rendering/RenderView.h:
  • rendering/svg/RenderSVGForeignObject.cpp:

(WebCore::RenderSVGForeignObject::computeRectForRepaint):

  • rendering/svg/RenderSVGForeignObject.h:
  • rendering/svg/RenderSVGRoot.cpp:

(WebCore::RenderSVGRoot::computeFloatRectForRepaint):

  • rendering/svg/RenderSVGText.cpp:

(WebCore::RenderSVGText::computeRectForRepaint):

  • rendering/svg/RenderSVGText.h:

LayoutTests:

  • fast/repaint/vertical-text-repaint-expected.txt: Added.
  • fast/repaint/vertical-text-repaint.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderBox.cpp

    r201498 r201635  
    22072207}
    22082208
    2209 LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, bool fixed) const
     2209LayoutRect RenderBox::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const
    22102210{
    22112211    // The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space.
     
    22462246    }
    22472247
    2248     bool containerSkipped;
    2249     auto* renderer = container(repaintContainer, containerSkipped);
    2250     if (!renderer)
     2248    bool repaintContainerIsSkipped;
     2249    auto* container = this->container(repaintContainer, repaintContainerIsSkipped);
     2250    if (!container)
    22512251        return adjustedRect;
    22522252   
    2253     EPosition position = styleToUse.position();
    2254 
    22552253    // This code isn't necessary for in-flow RenderFlowThreads.
    22562254    // Don't add the location of the region in the flow thread for absolute positioned
     
    22602258    // The same logic applies for elements flowed directly into the flow thread. Their topLeft member
    22612259    // will already contain the portion rect of the region.
    2262     if (renderer->isOutOfFlowRenderFlowThread() && position != AbsolutePosition && containingBlock() != flowThreadContainingBlock()) {
     2260    EPosition position = styleToUse.position();
     2261    if (container->isOutOfFlowRenderFlowThread() && position != AbsolutePosition && containingBlock() != flowThreadContainingBlock()) {
    22632262        RenderRegion* firstRegion = nullptr;
    22642263        RenderRegion* lastRegion = nullptr;
    2265         if (downcast<RenderFlowThread>(*renderer).getRegionRangeForBox(this, firstRegion, lastRegion))
     2264        if (downcast<RenderFlowThread>(*container).getRegionRangeForBox(this, firstRegion, lastRegion))
    22662265            adjustedRect.moveBy(firstRegion->flowThreadPortionRect().location());
    22672266    }
    22682267
    2269     if (isWritingModeRoot() && !isOutOfFlowPositioned())
    2270         flipForWritingMode(adjustedRect);
     2268    if (isWritingModeRoot()) {
     2269        if (!isOutOfFlowPositioned() || !context.m_dirtyRectIsFlipped) {
     2270            flipForWritingMode(adjustedRect);
     2271            context.m_dirtyRectIsFlipped = true;
     2272        }
     2273    }
    22712274
    22722275    LayoutSize locationOffset = this->locationOffset();
     
    22832286    // in the parent's coordinate space that encloses us.
    22842287    if (hasLayer() && layer()->transform()) {
    2285         fixed = position == FixedPosition;
     2288        context.m_hasPositionFixedDescendant = position == FixedPosition;
    22862289        adjustedRect = LayoutRect(encloseRectToDevicePixels(layer()->transform()->mapRect(adjustedRect), document().deviceScaleFactor()));
    22872290        topLeft = adjustedRect.location();
    22882291        topLeft.move(locationOffset);
    22892292    } else if (position == FixedPosition)
    2290         fixed = true;
    2291 
    2292     if (position == AbsolutePosition && renderer->isInFlowPositioned() && is<RenderInline>(*renderer))
    2293         topLeft += downcast<RenderInline>(*renderer).offsetForInFlowPositionedInline(this);
     2293        context.m_hasPositionFixedDescendant = true;
     2294
     2295    if (position == AbsolutePosition && container->isInFlowPositioned() && is<RenderInline>(*container))
     2296        topLeft += downcast<RenderInline>(*container).offsetForInFlowPositionedInline(this);
    22942297    else if (styleToUse.hasInFlowPosition() && layer()) {
    22952298        // Apply the relative position offset when invalidating a rectangle.  The layer
     
    23032306    // its controlClipRect will be wrong. For overflow clip we use the values cached by the layer.
    23042307    adjustedRect.setLocation(topLeft);
    2305     if (renderer->hasOverflowClip()) {
    2306         RenderBox& containerBox = downcast<RenderBox>(*renderer);
     2308    if (container->hasOverflowClip()) {
     2309        RenderBox& containerBox = downcast<RenderBox>(*container);
    23072310        if (shouldApplyContainersClipAndOffset(repaintContainer, &containerBox)) {
    23082311            containerBox.applyCachedClipAndScrollOffsetForRepaint(adjustedRect);
     
    23122315    }
    23132316
    2314     if (containerSkipped) {
    2315         // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates.
    2316         LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(*renderer);
     2317    if (repaintContainerIsSkipped) {
     2318        // If the repaintContainer is below container, then we need to map the rect into repaintContainer's coordinates.
     2319        LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(*container);
    23172320        adjustedRect.move(-containerOffset);
    23182321        return adjustedRect;
    23192322    }
    2320     return renderer->computeRectForRepaint(adjustedRect, repaintContainer, fixed);
     2323    return container->computeRectForRepaint(adjustedRect, repaintContainer, context);
    23212324}
    23222325
Note: See TracChangeset for help on using the changeset viewer.