// The algorithm below assumes this is a full layout. In case there are previously computed values for regions, supplemental steps are taken // to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing // layout). // 1. The flows are laid out from the outer flow to the inner flow. This successfully computes the outer non-auto-height regions size so the // inner flows have the necessary information to correctly fragment the content. // 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase // and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions // belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height // regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout. // 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions // as detected in the previous step. void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state) { // We need to invalidate all the flows with auto-height regions if one such flow needs layout. // If none is found we do a layout a check back again afterwards. if (!flowThreadController().updateFlowThreadsNeedingLayout()) { // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed). layoutContent(state); // If we find no named flow needing a two step layout after the first layout, exit early. // Otherwise, initiate the two step layout algorithm and recompute all the flows. if (!flowThreadController().updateFlowThreadsNeedingTwoStepLayout()) return; } // Layout to recompute all the named flows with auto-height regions. layoutContent(state); // Propagate the computed auto-height values upwards. // Non-auto-height regions may invalidate the flow thread because they depended on auto-height regions, but that's ok. flowThreadController().updateFlowThreadsIntoConstrainedPhase(); // Do one last layout that should update the auto-height regions found in the main flow // and solve pathological dependencies between regions (e.g. a non-auto-height region depending // on an auto-height one). if (needsLayout()) layoutContent(state); }
void RenderView::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; if (!document()->paginated()) setPageLogicalHeight(0); if (shouldUsePrintingLayout()) m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth(); // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account. bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || width() != viewWidth() || height() != viewHeight()); if (relayoutChildren) { setChildNeedsLayout(true, MarkOnlyThis); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight()) || child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) child->setChildNeedsLayout(true, MarkOnlyThis); } } ASSERT(!m_layoutState); if (!needsLayout()) return; LayoutState state; // FIXME: May be better to push a clip and avoid issuing offscreen repaints. state.m_clipped = false; state.m_pageLogicalHeight = m_pageLogicalHeight; state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged; state.m_isPaginated = state.m_pageLogicalHeight; m_pageLogicalHeightChanged = false; m_layoutState = &state; m_layoutPhase = RenderViewNormalLayout; bool needsTwoPassLayoutForAutoLogicalHeightRegions = hasRenderNamedFlowThreads() && flowThreadController()->hasAutoLogicalHeightRegions() && flowThreadController()->hasRenderNamedFlowThreadsNeedingLayout(); if (needsTwoPassLayoutForAutoLogicalHeightRegions) flowThreadController()->resetRegionsOverrideLogicalContentHeight(); layoutContent(state); if (needsTwoPassLayoutForAutoLogicalHeightRegions) { m_layoutPhase = ConstrainedFlowThreadsLayoutInAutoLogicalHeightRegions; flowThreadController()->markAutoLogicalHeightRegionsForLayout(); layoutContent(state); } #ifndef NDEBUG checkLayoutState(state); #endif m_layoutState = 0; setNeedsLayout(false); }
void RenderView::layout() { SubtreeLayoutScope layoutScope(*this); bool relayoutChildren = (!m_frameView || width() != viewWidth() || height() != viewHeight()); if (relayoutChildren) { layoutScope.setChildNeedsLayout(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight()) || child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) layoutScope.setChildNeedsLayout(child); } } ASSERT(!m_layoutState); if (!needsLayout()) return; LayoutState rootLayoutState(*this); layoutContent(); #if ENABLE(ASSERT) checkLayoutState(); #endif clearNeedsLayout(); }
void RenderView::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; if (!document().paginated()) setPageLogicalHeight(0); if (shouldUsePrintingLayout()) m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth(); // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account. bool relayoutChildren = !shouldUsePrintingLayout() && (width() != viewWidth() || height() != viewHeight()); if (relayoutChildren) { setChildNeedsLayout(MarkOnlyThis); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (!child->isBox()) continue; RenderBox& box = toRenderBox(*child); if (box.hasRelativeLogicalHeight() || box.hasViewportPercentageLogicalHeight() || box.style()->logicalHeight().isPercent() || box.style()->logicalMinHeight().isPercent() || box.style()->logicalMaxHeight().isPercent() || box.style()->logicalHeight().isViewportPercentage() || box.style()->logicalMinHeight().isViewportPercentage() || box.style()->logicalMaxHeight().isViewportPercentage() #if ENABLE(SVG) || box.isSVGRoot() #endif ) box.setChildNeedsLayout(MarkOnlyThis); } } ASSERT(!m_layoutState); if (!needsLayout()) return; m_layoutState = std::make_unique<LayoutState>(); bool isSeamlessAncestorInFlowThread = initializeLayoutState(*m_layoutState); m_pageLogicalHeightChanged = false; if (checkTwoPassLayoutForAutoHeightRegions()) layoutContentInAutoLogicalHeightRegions(*m_layoutState); else layoutContent(*m_layoutState); layoutContentToComputeOverflowInRegions(*m_layoutState); #ifndef NDEBUG checkLayoutState(*m_layoutState); #endif m_layoutState = nullptr; clearNeedsLayout(); if (isSeamlessAncestorInFlowThread) flowThreadController().setCurrentRenderFlowThread(0); }
void UIPopupStackViewport::sltAdjustGeometry() { /* Update size-hint: */ updateSizeHint(); /* Layout content: */ layoutContent(); /* Notify parent popup-stack: */ emit sigSizeHintChanged(); }
void RenderView::layoutContentToComputeOverflowInRegions(const LayoutState& state) { if (!hasRenderNamedFlowThreads()) return; // First pass through the flow threads and mark the regions as needing a simple layout. // The regions extract the overflow from the flow thread and pass it to their containg // block chain. flowThreadController().updateFlowThreadsIntoOverflowPhase(); if (needsLayout()) layoutContent(state); // In case scrollbars resized the regions a new pass is necessary to update the flow threads // and recompute the overflow on regions. This is the final state of the flow threads. flowThreadController().updateFlowThreadsIntoFinalPhase(); if (needsLayout()) layoutContent(state); // Finally reset the layout state of the flow threads. flowThreadController().updateFlowThreadsIntoMeasureContentPhase(); }
void RenderView::layout() { if (!document().paginated()) setPageLogicalHeight(0); if (shouldUsePrintingLayout()) m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth(); SubtreeLayoutScope layoutScope(this); // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account. bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || width() != viewWidth() || height() != viewHeight()); if (relayoutChildren) { layoutScope.setChildNeedsLayout(this); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->isSVGRoot()) continue; if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight()) || child->style()->logicalHeight().isPercent() || child->style()->logicalMinHeight().isPercent() || child->style()->logicalMaxHeight().isPercent()) layoutScope.setChildNeedsLayout(child); } if (document().svgExtensions()) document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope); } ASSERT(!m_layoutState); if (!needsLayout()) return; LayoutState state; initializeLayoutState(state); m_pageLogicalHeightChanged = false; m_layoutState = &state; layoutContent(state); if (m_frameView->partialLayout().isStopping()) { m_layoutState = 0; return; } #ifndef NDEBUG checkLayoutState(state); #endif m_layoutState = 0; clearNeedsLayout(); }