bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, LayoutUnit offsetFromLogicalTopOfFirstPage) { if (!hasRegions() || block == this) // Not necessary, since if any region changes, we do a full pagination relayout anyway. return false; RenderRegion* startRegion; RenderRegion* endRegion; getRegionRangeForBox(block, startRegion, endRegion); for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; ASSERT(!region->needsLayout()); OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block); if (!oldInfo) continue; LayoutUnit oldLogicalWidth = oldInfo->logicalWidth(); RenderBoxRegionInfo* newInfo = block->renderBoxRegionInfo(region, offsetFromLogicalTopOfFirstPage); if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth) return true; if (region == endRegion) break; } return false; }
RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool extendLastRegion) const { ASSERT(!m_regionsInvalidated); // If no region matches the position and extendLastRegion is true, it will return // the last valid region. It is similar to auto extending the size of the last region. RenderRegion* lastValidRegion = 0; LayoutUnit accumulatedLogicalHeight = 0; // FIXME: The regions are always in order, optimize this search. for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (offset <= 0) return region; if (extendLastRegion || region->isRenderRegionSet()) lastValidRegion = region; if (region->hasOverrideHeight() && view()->normalLayoutPhase()) { accumulatedLogicalHeight += region->overrideLogicalContentHeight(); if (offset < accumulatedLogicalHeight) return region; continue; } LayoutRect regionRect = region->flowThreadPortionRect(); accumulatedLogicalHeight += isHorizontalWritingMode() ? regionRect.height() : regionRect.width(); if (offset < accumulatedLogicalHeight) return region; } return lastValidRegion; }
bool RenderFlowThread::logicalWidthChangedInRegions(const RenderBlock* block, LayoutUnit offsetFromLogicalTopOfFirstPage) { if (!hasRegions() || block == this) // Not necessary, since if any region changes, we do a full pagination relayout anyway. return false; RenderRegion* startRegion; RenderRegion* endRegion; getRegionRangeForBox(block, startRegion, endRegion); // If the block doesn't have a startRegion (and implicitly a region range) it's safe to assume the width in regions has changed (e.g. the region chain was invalidated). if (!startRegion) return true; for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; ASSERT(!region->needsLayout()); OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block); if (!oldInfo) continue; LayoutUnit oldLogicalWidth = oldInfo->logicalWidth(); RenderBoxRegionInfo* newInfo = block->renderBoxRegionInfo(region, offsetFromLogicalTopOfFirstPage); if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth) return true; if (region == endRegion) break; } return false; }
RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool extendLastRegion) const { ASSERT(!m_regionsInvalidated); // If no region matches the position and extendLastRegion is true, it will return // the last valid region. It is similar to auto extending the size of the last region. RenderRegion* lastValidRegion = 0; // FIXME: The regions are always in order, optimize this search. bool useHorizontalWritingMode = isHorizontalWritingMode(); for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; if (offset <= 0) return region; LayoutRect regionRect = region->flowThreadPortionRect(); if ((useHorizontalWritingMode && offset < regionRect.maxY()) || (!useHorizontalWritingMode && offset < regionRect.maxX())) return region; if (extendLastRegion || region->isRenderRegionSet()) lastValidRegion = region; } return lastValidRegion; }
void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box) { if (!hasRegions()) return; RenderRegion* startRegion; RenderRegion* endRegion; getRegionRangeForBox(box, startRegion, endRegion); for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; region->removeRenderBoxRegionInfo(box); if (region == endRegion) break; } #ifndef NDEBUG // We have to make sure we did not leave any RenderBoxRegionInfo attached. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; ASSERT(!region->renderBoxRegionInfo(box)); } #endif m_regionRangeMap.remove(box); }
LayoutUnit RenderFlowThread::contentLogicalLeftOfFirstRegion() const { RenderRegion* firstValidRegionInFlow = firstRegion(); if (!firstValidRegionInFlow) return 0; return isHorizontalWritingMode() ? firstValidRegionInFlow->flowThreadPortionRect().x() : firstValidRegionInFlow->flowThreadPortionRect().y(); }
LayoutUnit RenderFlowThread::contentLogicalHeightOfFirstRegion() const { RenderRegion* firstValidRegionInFlow = firstRegion(); if (!firstValidRegionInFlow) return 0; return isHorizontalWritingMode() ? firstValidRegionInFlow->contentHeight() : firstValidRegionInFlow->contentWidth(); }
void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object, const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion, const RenderRegion* newStartRegion, const RenderRegion* newEndRegion) { // Clear the styles for the object in the regions. // The styles are not cleared for the regions that are contained in both ranges. bool insideOldRegionRange = false; bool insideNewRegionRange = false; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (oldStartRegion == region) insideOldRegionRange = true; if (newStartRegion == region) insideNewRegionRange = true; if (!(insideOldRegionRange && insideNewRegionRange)) region->clearObjectStyleInRegion(object); if (oldEndRegion == region) insideOldRegionRange = false; if (newEndRegion == region) insideNewRegionRange = false; } }
LayoutUnit RenderFlowThread::regionLogicalHeightForLine(LayoutUnit position) const { RenderRegion* region = renderRegionForLine(position); if (!region) return 0; return isHorizontalWritingMode() ? region->regionRect().height() : region->regionRect().width(); }
void RenderFlowThread::resetRegionsOverrideLogicalContentHeight() { ASSERT(view()->layoutState()); ASSERT(view()->normalLayoutPhase()); // We need to reset the override logical content height for regions with auto logical height // only if the flow thread content needs layout. if (!needsLayout()) return; // FIXME: optimize this to iterate the region chain only if the flow thread has auto logical height // region. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->hasAutoLogicalHeight()) continue; region->clearOverrideLogicalContentHeight(); // FIXME: We need to find a way to avoid marking all the regions ancestors for layout // as we are already inside layout. region->setNeedsLayout(true); } // Make sure we don't skip any region breaks when we do the layout again. // Using m_regionsInvalidated to force all the RenderFlowThread children do the layout again. m_regionsInvalidated = true; }
void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box) { if (!hasRegions()) return; // If the region chain was invalidated the next layout will clear the box information from all the regions. if (m_regionsInvalidated) { ASSERT(selfNeedsLayout()); return; } RenderRegion* startRegion; RenderRegion* endRegion; getRegionRangeForBox(box, startRegion, endRegion); for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; region->removeRenderBoxRegionInfo(box); if (region == endRegion) break; } #ifndef NDEBUG // We have to make sure we did not leave any RenderBoxRegionInfo attached. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; ASSERT(!region->renderBoxRegionInfo(box)); } #endif m_regionRangeMap.remove(box); }
LayoutUnit RenderFlowThread::pageLogicalHeightForOffset(LayoutUnit offset) const { RenderRegion* region = regionAtBlockOffset(offset); if (!region) return 0; return region->pageLogicalHeight(); }
void RenderFlowThread::collectLayerFragments(LayerFragments& layerFragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) { ASSERT(!m_regionsInvalidated); for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; region->collectLayerFragments(layerFragments, layerBoundingBox, dirtyRect); } }
// During the normal layout phase of the named flow the regions are initialized with a height equal to their max-height. // This way unforced breaks are automatically placed when a region is full and the content height/position correctly estimated. // Also, the region where a forced break falls is exactly the region found at the forced break offset inside the flow content. void RenderFlowThread::initializeRegionsOverrideLogicalContentHeight(RenderRegion* startRegion) { ASSERT(view()->normalLayoutPhase()); RenderRegionList::iterator regionIter = startRegion ? m_regionList.find(startRegion) : m_regionList.begin(); for (; regionIter != m_regionList.end(); ++regionIter) { RenderRegion* region = *regionIter; if (region->hasAutoLogicalHeight()) region->setOverrideLogicalContentHeight(region->maxPageLogicalHeight()); } }
void RenderFlowThread::computeLogicalWidth() { LayoutUnit logicalWidth = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; ASSERT(!region->needsLayout()); logicalWidth = max(isHorizontalWritingMode() ? region->contentWidth() : region->contentHeight(), logicalWidth); } setLogicalWidth(logicalWidth); // If the regions have non-uniform logical widths, then insert inset information for the RenderFlowThread. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; LayoutUnit regionLogicalWidth = isHorizontalWritingMode() ? region->contentWidth() : region->contentHeight(); if (regionLogicalWidth != logicalWidth) { LayoutUnit logicalLeft = style()->direction() == LTR ? zeroLayoutUnit : logicalWidth - regionLogicalWidth; region->setRenderBoxRegionInfo(this, logicalLeft, regionLogicalWidth, false); } } }
RenderRegion* RenderFlowThread::lastRegion() const { if (!hasValidRegionInfo()) return 0; for (RenderRegionList::const_reverse_iterator iter = m_regionList.rbegin(); iter != m_regionList.rend(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; return region; } return 0; }
void RenderFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const { computedValues.m_position = logicalTop; computedValues.m_extent = 0; for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; ASSERT(!region->needsLayout()); computedValues.m_extent += region->logicalHeightOfAllFlowThreadContent(); } }
// Check if the content is flown into at least a region with region styling rules. void RenderFlowThread::checkRegionsWithStyling() { bool hasRegionsWithStyling = false; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (region->hasCustomRegionStyle()) { hasRegionsWithStyling = true; break; } } m_hasRegionsWithStyling = hasRegionsWithStyling; }
void RenderFlowThread::computeOverflowStateForRegions(LayoutUnit oldClientAfterEdge) { LayoutUnit height = oldClientAfterEdge; LayoutUnit offsetBreakAdjustment = 0; // Simulate a region break at height. If it points inside an auto logical height region, // then it may determine the region override logical content height. addForcedRegionBreak(height, this, false, &offsetBreakAdjustment); // During the normal layout phase of the flow thread all the auto-height regions have the overrideLogicalContentHeight set to max height. // We need to clear the overrideLogicalContentHeight for all the regions that didn't receive any content, starting with firstEmptyRegion. RenderRegion* firstEmptyRegion = 0; if (view()->normalLayoutPhase()) firstEmptyRegion = regionAtBlockOffset(height + offsetBreakAdjustment); // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread) // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height). // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region) if (hasRenderOverflow() && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY()) || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX()))) height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX(); bool inEmptyRegionsSection = false; RenderRegion* lastReg = lastRegion(); for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x()); LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().maxY() : region->flowThreadPortionRect().maxX()); RenderRegion::RegionState previousState = region->regionState(); RenderRegion::RegionState state = RenderRegion::RegionFit; if (flowMin <= 0) state = RenderRegion::RegionEmpty; if (flowMax > 0 && region == lastReg) state = RenderRegion::RegionOverset; region->setRegionState(state); // determine whether the NamedFlow object should dispatch a regionLayoutUpdate event // FIXME: currently it cannot determine whether a region whose regionOverset state remained either "fit" or "overset" has actually // changed, so it just assumes that the NamedFlow should dispatch the event if (previousState != state || state == RenderRegion::RegionFit || state == RenderRegion::RegionOverset) setDispatchRegionLayoutUpdateEvent(true); if (region == firstEmptyRegion) inEmptyRegionsSection = true; // Clear the overrideLogicalContentHeight value for autoheight regions that didn't receive any content. if (inEmptyRegionsSection && region->hasAutoLogicalHeight()) region->clearOverrideLogicalContentHeight(); } // With the regions overflow state computed we can also set the overset flag for the named flow. // If there are no valid regions in the chain, overset is true. m_overset = lastReg ? lastReg->regionState() == RenderRegion::RegionOverset : true; }
void RenderNamedFlowThread::updateWritingMode() { RenderRegion* firstRegion = m_regionList.first(); if (!firstRegion) return; if (style()->writingMode() == firstRegion->style()->writingMode()) return; // The first region defines the principal writing mode for the entire flow. RefPtr<RenderStyle> newStyle = RenderStyle::clone(style()); newStyle->setWritingMode(firstRegion->style()->writingMode()); setStyle(newStyle.release()); }
LayoutUnit RenderFlowThread::contentLogicalLeftOfFirstRegion() const { if (!hasValidRegionInfo()) return 0; for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; return isHorizontalWritingMode() ? region->flowThreadPortionRect().x() : region->flowThreadPortionRect().y(); } ASSERT_NOT_REACHED(); return 0; }
void SGDisplayDATATYPE::HandleRedraw(SGRedrawInfo *RedrawInfo, SGMiscInfo *MiscInfo) { // First, inform the system that we are about to start rendering this item StartRendering(RedrawInfo, MiscInfo); DocRect MyRect(FormatRect); // Get my redraw position from the cached FormatRect RenderRegion *Renderer = RedrawInfo->Renderer; INT32 OnePixel = (INT32) DevicePixels(MiscInfo, 1); INT32 TwoPixels = (INT32) DevicePixels(MiscInfo, 2); Renderer->SetLineWidth(0); Renderer->SetLineColour(RedrawInfo->Transparent); // First, render the icon at the left end of our rectangle DocRect IconRect(MyRect); IconRect.hi.x = IconRect.lo.x + IconRect.Height(); // Make it a square MyRect.lo.x = IconRect.hi.x + TwoPixels; // And exclude it from 'MyRect' // Redraw the icon GridLockRect(MiscInfo, &IconRect); // Ensure it maps exactly to specific pixels IconRect.Inflate(-OnePixel, -OnePixel); // Leave a bit of space around the edge Renderer->SetFillColour(DocColour(COLOUR_RED)); Renderer->DrawRect(&IconRect); GridLockRect(MiscInfo, &MyRect); // Ensure the new 'MyRect' is pixel-grid-aligned // Set up the colours for rendering our text, and fill the background if selected if (Flags.Selected) { // Fill the entire background with the 'selected' colour, so we don't // get gaps between bits of text or uneven rectangles in multiple selections Renderer->SetFillColour(RedrawInfo->SelBackground); Renderer->DrawRect(&MyRect); Renderer->SetFixedSystemTextColours(&RedrawInfo->SelForeground, &RedrawInfo->SelBackground); } else Renderer->SetFixedSystemTextColours(&RedrawInfo->Foreground, &RedrawInfo->Background); MyRect.lo.x += SG_GapBeforeText; // Leave a small gap before text begins // And render the text String_256 MyText; GetNameText(&MyText); Renderer->DrawFixedSystemText(&MyText, MyRect); // Finally, inform the system that we have completed rendering this item StopRendering(RedrawInfo, MiscInfo); }
void RenderFlowThread::updateRegionsFlowThreadPortionRect() { LayoutUnit logicalHeight = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; LayoutUnit regionLogicalWidth = region->pageLogicalWidth(); LayoutUnit regionLogicalHeight = region->logicalHeightOfAllFlowThreadContent(); LayoutRect regionRect(style()->direction() == LTR ? LayoutUnit() : logicalWidth() - regionLogicalWidth, logicalHeight, regionLogicalWidth, regionLogicalHeight); // When a flow thread has more than one auto logical height region, // we have to take into account the override logical content height value, // if computed for an auto logical height region, and use it to set the height // for the region rect. This way, the regions in the chain following the auto // logical height region, will be able to fragment the right part of their // associated flow thread content (and compute their overrideComputedLogicalHeight properly). if (view()->normalLayoutPhase()) { ASSERT(region->hasOverrideHeight() || !region->hasAutoLogicalHeight()); if (region->hasOverrideHeight()) regionLogicalHeight = region->overrideLogicalContentHeight(); regionRect.setHeight(regionLogicalHeight); } region->setFlowThreadPortionRect(isHorizontalWritingMode() ? regionRect : regionRect.transposedRect()); logicalHeight += regionLogicalHeight; } }
void RenderFlowThread::computeLogicalHeight() { LayoutUnit logicalHeight = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; ASSERT(!region->needsLayout()); logicalHeight += isHorizontalWritingMode() ? region->contentHeight() : region->contentWidth(); } setLogicalHeight(logicalHeight); }
void RenderFlowThread::updateLogicalWidth() { LayoutUnit logicalWidth = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; ASSERT(!region->needsLayout()); logicalWidth = max(region->pageLogicalWidth(), logicalWidth); } setLogicalWidth(logicalWidth); // If the regions have non-uniform logical widths, then insert inset information for the RenderFlowThread. for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; LayoutUnit regionLogicalWidth = region->pageLogicalWidth(); if (regionLogicalWidth != logicalWidth) { LayoutUnit logicalLeft = style()->direction() == LTR ? ZERO_LAYOUT_UNIT : logicalWidth - regionLogicalWidth; region->setRenderBoxRegionInfo(this, logicalLeft, regionLogicalWidth, false); } } }
void RenderFlowThread::updateLogicalHeight() { LayoutUnit logicalHeight = 0; for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (!region->isValid()) continue; ASSERT(!region->needsLayout()); logicalHeight += region->logicalHeightOfAllFlowThreadContent(); } setLogicalHeight(logicalHeight); }
void RenderNamedFlowThread::checkInvalidRegions() { for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; // The only reason a region would be invalid is because it has a parent flow thread. ASSERT(region->isValid() || region->parentNamedFlowThread()); if (region->isValid() || region->parentNamedFlowThread()->dependsOn(this)) continue; region->parentNamedFlowThread()->m_observerThreadsSet.remove(this); addDependencyOnFlowThread(region->parentNamedFlowThread()); region->setIsValid(true); invalidateRegions(); } if (m_observerThreadsSet.isEmpty()) return; // Notify all the flow threads that were dependent on this flow. // Create a copy of the list first. That's because observers might change the list when calling checkInvalidRegions. Vector<RenderNamedFlowThread*> observers; copyToVector(m_observerThreadsSet, observers); for (size_t i = 0; i < observers.size(); ++i) { RenderNamedFlowThread* flowThread = observers.at(i); flowThread->checkInvalidRegions(); } }
LayoutUnit RenderFlowThread::regionRemainingLogicalHeightForLine(LayoutUnit position, PageBoundaryRule pageBoundaryRule) const { RenderRegion* region = renderRegionForLine(position); if (!region) return 0; LayoutUnit regionLogicalBottom = isHorizontalWritingMode() ? region->regionRect().maxY() : region->regionRect().maxX(); LayoutUnit remainingHeight = regionLogicalBottom - position; if (pageBoundaryRule == IncludePageBoundary) { // If IncludePageBoundary is set, the line exactly on the top edge of a // region will act as being part of the previous region. LayoutUnit regionHeight = isHorizontalWritingMode() ? region->regionRect().height() : region->regionRect().width(); remainingHeight = layoutMod(remainingHeight, regionHeight); } return remainingHeight; }
LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule pageBoundaryRule) const { RenderRegion* region = regionAtBlockOffset(offset); if (!region) return 0; LayoutUnit pageLogicalTop = region->pageLogicalTopForOffset(offset); LayoutUnit pageLogicalHeight = region->pageLogicalHeight(); LayoutUnit pageLogicalBottom = pageLogicalTop + pageLogicalHeight; LayoutUnit remainingHeight = pageLogicalBottom - offset; if (pageBoundaryRule == IncludePageBoundary) { // If IncludePageBoundary is set, the line exactly on the top edge of a // region will act as being part of the previous region. remainingHeight = intMod(remainingHeight, pageLogicalHeight); } return remainingHeight; }
void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect, bool immediate) const { if (!shouldRepaint(repaintRect) || !hasValidRegionInfo()) return; LayoutStateDisabler layoutStateDisabler(view()); // We can't use layout state to repaint, since the regions are somewhere else. // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used. // Let each region figure out the proper enclosing flow thread. CurrentRenderFlowThreadDisabler disabler(view()); for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; region->repaintFlowThreadContent(repaintRect, immediate); } }