void RenderSVGContainer::layout() { ASSERT(needsLayout()); calcViewport(); // Arbitrary affine transforms are incompatible with LayoutState. view()->disableLayoutState(); IntRect oldBounds; IntRect oldOutlineBox; bool checkForRepaint = checkForRepaintDuringLayout(); if (selfNeedsLayout() && checkForRepaint) { oldBounds = m_absoluteBounds; oldOutlineBox = absoluteOutlineBox(); } RenderObject* child = firstChild(); while (child) { if (!child->isRenderPath() || static_cast<RenderPath*>(child)->hasRelativeValues()) child->setNeedsLayout(true); child->layoutIfNeeded(); ASSERT(!child->needsLayout()); child = child->nextSibling(); } calcWidth(); calcHeight(); m_absoluteBounds = absoluteClippedOverflowRect(); if (!parent()->isSVGContainer()) { SVGSVGElement* svg = static_cast<SVGSVGElement*>(element()); m_width = static_cast<int>(static_cast<float>(m_width) * svg->currentScale()); m_height = static_cast<int>(static_cast<float>(m_height) * svg->currentScale()); } if (selfNeedsLayout() && checkForRepaint) repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); view()->enableLayoutState(); setNeedsLayout(false); }
void RenderView::layout() { if (!document()->paginated()) setPageLogicalHeight(0); if (printing()) 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 = !printing() && (!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); 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; if (needsLayout()) { RenderBlock::layout(); if (hasRenderNamedFlowThreads()) flowThreadController()->layoutRenderNamedFlowThreads(); } ASSERT(layoutDelta() == LayoutSize()); ASSERT(m_layoutStateDisableCount == 0); ASSERT(m_layoutState == &state); m_layoutState = 0; setNeedsLayout(false); }
void RenderReplaced::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); setHeight(minimumReplacedHeight()); updateLogicalWidth(); updateLogicalHeight(); m_overflow.clear(); addVisualEffectOverflow(); updateLayerTransform(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGRoot::layout() { ASSERT(needsLayout()); m_resourcesNeedingToInvalidateClients.clear(); // Arbitrary affine transforms are incompatible with LayoutState. LayoutStateDisabler layoutStateDisabler(view()); bool needsLayout = selfNeedsLayout(); LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout); LayoutSize oldSize(width(), height()); computeLogicalWidth(); computeLogicalHeight(); buildLocalToBorderBoxTransform(); SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize != size()); SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filtersForceContainerLayout(this)); m_isLayoutSizeChanged = false; if (!m_resourcesNeedingToInvalidateClients.isEmpty()) { // Invalidate resource clients, which may mark some nodes for layout. HashSet<RenderSVGResourceContainer*>::iterator end = m_resourcesNeedingToInvalidateClients.end(); for (HashSet<RenderSVGResourceContainer*>::iterator it = m_resourcesNeedingToInvalidateClients.begin(); it != end; ++it) (*it)->removeAllClientsFromCache(); m_isLayoutSizeChanged = false; SVGRenderSupport::layoutChildren(this, false); } // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (m_needsBoundariesOrTransformUpdate) { updateCachedBoundaries(); m_needsBoundariesOrTransformUpdate = false; } repainter.repaintAfterLayout(); setNeedsLayout(false); }
bool RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, ColorSpace colorSpace, RenderObject* object) { GraphicsContext* maskImageContext = maskerData->maskImage->context(); ASSERT(maskImageContext); // Eventually adjust the mask image context according to the target objectBoundingBox. AffineTransform maskContentTransformation; if (maskElement().maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { FloatRect objectBoundingBox = object->objectBoundingBox(); maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y()); maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); maskImageContext->concatCTM(maskContentTransformation); } // Draw the content into the ImageBuffer. auto children = childrenOfType<SVGElement>(maskElement()); for (auto it = children.begin(), end = children.end(); it != end; ++it) { SVGElement& child = *it; auto renderer = child.renderer(); if (!renderer) continue; if (renderer->needsLayout()) return false; const RenderStyle& style = renderer->style(); if (style.display() == NONE || style.visibility() != VISIBLE) continue; SVGRenderingContext::renderSubtreeToImageBuffer(maskerData->maskImage.get(), *renderer, maskContentTransformation); } #if !USE(CG) maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, colorSpace); #else UNUSED_PARAM(colorSpace); #endif ASSERT(style().svgStyle()); // Create the luminance mask. if (style().svgStyle()->maskType() == MT_LUMINANCE) maskerData->maskImage->convertToLuminanceMask(); return true; }
void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const { ASSERT(!needsLayout()); startOverhang = 0; endOverhang = 0; RenderRubyBase* rubyBase = this->rubyBase(); RenderRubyText* rubyText = this->rubyText(); if (!rubyBase || !rubyText) return; if (!rubyBase->firstRootBox()) return; int logicalWidth = this->logicalWidth(); int logicalLeftOverhang = numeric_limits<int>::max(); int logicalRightOverhang = numeric_limits<int>::max(); for (RootInlineBox* rootInlineBox = rubyBase->firstRootBox(); rootInlineBox; rootInlineBox = rootInlineBox->nextRootBox()) { logicalLeftOverhang = min<int>(logicalLeftOverhang, rootInlineBox->logicalLeft()); logicalRightOverhang = min<int>(logicalRightOverhang, logicalWidth - rootInlineBox->logicalRight()); } startOverhang = style()->isLeftToRightDirection() ? logicalLeftOverhang : logicalRightOverhang; endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; if (!startRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) startOverhang = 0; if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) endOverhang = 0; // We overhang a ruby only if the neighboring render object is a text. // We can overhang the ruby by no more than half the width of the neighboring text // and no more than half the font size. int halfWidthOfFontSize = rubyText->style(firstLine)->fontSize() / 2; if (startOverhang) startOverhang = min<int>(startOverhang, min<int>(toRenderText(startRenderer)->minLogicalWidth(), halfWidthOfFontSize)); if (endOverhang) endOverhang = min<int>(endOverhang, min<int>(toRenderText(endRenderer)->minLogicalWidth(), halfWidthOfFontSize)); }
void RenderLayerModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { ASSERT(!needsLayout()); if (!shouldCheckForPaintInvalidation(paintInvalidationState)) return; bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer(); const RenderLayerModelObject& newPaintInvalidationContainer = *adjustCompositedContainerForSpecialAncestors(establishesNewPaintInvalidationContainer ? this : &paintInvalidationState.paintInvalidationContainer()); // FIXME: This assert should be re-enabled when we move paint invalidation to after compositing update. crbug.com/360286 // ASSERT(&newPaintInvalidationContainer == containerForPaintInvalidation()); PaintInvalidationReason reason = invalidatePaintIfNeeded(paintInvalidationState, newPaintInvalidationContainer); clearPaintInvalidationState(paintInvalidationState); PaintInvalidationState childTreeWalkState(paintInvalidationState, *this, newPaintInvalidationContainer); if (reason == PaintInvalidationLocationChange) childTreeWalkState.setForceCheckForPaintInvalidation(); invalidatePaintOfSubtreesIfNeeded(childTreeWalkState); }
IntRect RenderListMarker::selectionRect(bool clipToVisibleContent) { ASSERT(!needsLayout()); if (selectionState() == SelectionNone || !inlineBoxWrapper()) return IntRect(); RootInlineBox* root = inlineBoxWrapper()->root(); IntRect rect(0, root->selectionTop() - yPos(), width(), root->selectionHeight()); if (clipToVisibleContent) computeAbsoluteRepaintRect(rect); else { int absx, absy; absolutePosition(absx, absy); rect.move(absx, absy); } return rect; }
void RenderReplaced::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); setHeight(minimumReplacedHeight()); updateLogicalWidth(); updateLogicalHeight(); clearOverflow(); addVisualEffectOverflow(); updateLayerTransform(); invalidateBackgroundObscurationStatus(); repainter.repaintAfterLayout(); clearNeedsLayout(); }
bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode) { ASSERT(object); ASSERT(context); ASSERT(style()); ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode); ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); clearInvalidationMask(); FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordinates(); if (paintInvalidationRect.isEmpty() || !element()->hasChildren()) return false; // Content layer start. context->beginTransparencyLayer(1, &paintInvalidationRect); return true; }
void RenderWidget::updateOnWidgetChange() { Widget* widget = this->widget(); if (!widget) return; if (!style()) return; if (!needsLayout()) updateWidgetGeometry(); if (style()->visibility() != VISIBLE) { widget->hide(); } else { widget->show(); // FIXME: Why do we repaint in this case, but not the other? repaint(); } }
void LayoutPart::updateOnWidgetChange() { Widget* widget = this->widget(); if (!widget) return; if (!style()) return; if (!needsLayout()) updateWidgetGeometryInternal(); if (style()->visibility() != VISIBLE) { widget->hide(); } else { widget->show(); // FIXME: Why do we issue a full paint invalidation in this case, but not the other? setShouldDoFullPaintInvalidation(); } }
void RenderFrameSet::layout() { ASSERT(needsLayout()); bool doFullRepaint = selfNeedsLayout() && checkForRepaintDuringLayout(); IntRect oldBounds; if (doFullRepaint) oldBounds = absoluteClippedOverflowRect(); if (!parent()->isFrameSet() && !document()->printing()) { setWidth(view()->viewWidth()); setHeight(view()->viewHeight()); } size_t cols = frameSet()->totalCols(); size_t rows = frameSet()->totalRows(); if (m_rows.m_sizes.size() != rows || m_cols.m_sizes.size() != cols) { m_rows.resize(rows); m_cols.resize(cols); } int borderThickness = frameSet()->border(); layOutAxis(m_rows, frameSet()->rowLengths(), height() - (rows - 1) * borderThickness); layOutAxis(m_cols, frameSet()->colLengths(), width() - (cols - 1) * borderThickness); positionFrames(); RenderBox::layout(); computeEdgeInfo(); if (doFullRepaint) { view()->repaintViewRectangle(oldBounds); IntRect newBounds = absoluteClippedOverflowRect(); if (newBounds != oldBounds) view()->repaintViewRectangle(newBounds); } setNeedsLayout(false); }
void RenderSVGRoot::layout() { ASSERT(needsLayout()); // Arbitrary affine transforms are incompatible with LayoutState. ForceHorriblySlowRectMapping slowRectMapping(*this); bool needsLayout = selfNeedsLayout(); LayoutSize oldSize = size(); updateLogicalWidth(); updateLogicalHeight(); buildLocalToBorderBoxTransform(); SVGRenderSupport::layoutResourcesIfNeeded(this); SVGSVGElement* svg = toSVGSVGElement(node()); ASSERT(svg); m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize != size()); SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filtersForceContainerLayout(this)); if (m_needsBoundariesOrTransformUpdate) { updateCachedBoundaries(); m_needsBoundariesOrTransformUpdate = false; } m_overflow.clear(); addVisualEffectOverflow(); if (!shouldApplyViewportClip()) { FloatRect contentRepaintRect = paintInvalidationRectInLocalCoordinates(); contentRepaintRect = m_localToBorderBoxTransform.mapRect(contentRepaintRect); addVisualOverflow(enclosingLayoutRect(contentRepaintRect)); } updateLayerTransformAfterLayout(); m_hasBoxDecorationBackground = isDocumentElement() ? calculateHasBoxDecorations() : hasBoxDecorationBackground(); invalidateBackgroundObscurationStatus(); clearNeedsLayout(); }
void FrameView::scheduleRelayout() { ASSERT(m_frame->view() == this); if (isSubtreeLayout()) { m_layoutSubtreeRoot->markContainingBlocksForLayout(false); m_layoutSubtreeRoot = 0; } if (!m_layoutSchedulingEnabled) return; if (!needsLayout()) return; if (!m_frame->document()->isActive()) return; if (m_hasPendingLayout) return; m_hasPendingLayout = true; m_frame->document()->scheduleVisualUpdate(); }
void RenderSVGImage::layout() { ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); SVGImageElement* image = static_cast<SVGImageElement*>(node()); m_localTransform = image->animatedLocalTransform(); // minimum height setHeight(errorOccurred() ? intrinsicSize().height() : 0); calcWidth(); calcHeight(); m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image)); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGText::layout() { ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); // Best guess for a relative starting point SVGTextElement* text = static_cast<SVGTextElement*>(node()); int xOffset = (int)(text->x()->getFirst().value(text)); int yOffset = (int)(text->y()->getFirst().value(text)); setLocation(xOffset, yOffset); if (m_needsTransformUpdate) { m_localTransform = text->animatedLocalTransform(); m_needsTransformUpdate = false; } RenderBlock::layout(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
int RenderFrameSet::hitTestSplit(const GridAxis& axis, int position) const { if (needsLayout()) return noSplit; int borderThickness = frameSetElement().border(); if (borderThickness <= 0) return noSplit; size_t size = axis.m_sizes.size(); if (!size) return noSplit; int splitPosition = axis.m_sizes[0]; for (size_t i = 1; i < size; ++i) { if (position >= splitPosition && position < splitPosition + borderThickness) return i; splitPosition += borderThickness + axis.m_sizes[i]; } return noSplit; }
void RenderForeignObject::layout() { ASSERT(needsLayout()); // Arbitrary affine transforms are incompatible with LayoutState. view()->disableLayoutState(); // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root LayoutRepainter repainter(*this, checkForRepaintDuringLayout(), &m_absoluteBounds); calculateLocalTransform(); RenderBlock::layout(); m_absoluteBounds = absoluteClippedOverflowRect(); repainter.repaintAfterLayout(); view()->enableLayoutState(); setNeedsLayout(false); }
void RenderReplaced::layout() { ASSERT(needsLayout()); LayoutRect oldContentRect = replacedContentRect(); setHeight(minimumReplacedHeight()); updateLogicalWidth(); updateLogicalHeight(); m_overflow.clear(); addVisualEffectOverflow(); updateLayerTransformAfterLayout(); invalidateBackgroundObscurationStatus(); clearNeedsLayout(); if (replacedContentRect() != oldContentRect) setShouldDoFullPaintInvalidation(); }
void LayoutListMarker::layout() { ASSERT(needsLayout()); LayoutAnalyzer::Scope analyzer(*this); LayoutUnit blockOffset; for (LayoutBox* o = parentBox(); o && o != listItem(); o = o->parentBox()) { blockOffset += o->logicalTop(); } if (listItem()->style()->isLeftToRightDirection()) { m_lineOffset = listItem()->logicalLeftOffsetForLine( blockOffset, DoNotIndentText, LayoutUnit()); } else { m_lineOffset = listItem()->logicalRightOffsetForLine( blockOffset, DoNotIndentText, LayoutUnit()); } if (isImage()) { updateMarginsAndContent(); LayoutSize imageSize(imageBulletSize()); setWidth(imageSize.width()); setHeight(imageSize.height()); } else { const SimpleFontData* fontData = style()->font().primaryFont(); DCHECK(fontData); setLogicalWidth(minPreferredLogicalWidth()); setLogicalHeight( LayoutUnit(fontData ? fontData->getFontMetrics().height() : 0)); } setMarginStart(LayoutUnit()); setMarginEnd(LayoutUnit()); Length startMargin = style()->marginStart(); Length endMargin = style()->marginEnd(); if (startMargin.isFixed()) setMarginStart(LayoutUnit(startMargin.value())); if (endMargin.isFixed()) setMarginEnd(LayoutUnit(endMargin.value())); clearNeedsLayout(); }
void RenderSVGText::layout() { ASSERT(needsLayout()); // FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware setNeedsLayout(true); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); // Best guess for a relative starting point SVGTextElement* text = static_cast<SVGTextElement*>(node()); int xOffset = (int)(text->x()->getFirst().value(text)); int yOffset = (int)(text->y()->getFirst().value(text)); setLocation(xOffset, yOffset); m_localTransform = text->animatedLocalTransform(); RenderBlock::layout(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void LayoutReplaced::layout() { ASSERT(needsLayout()); LayoutAnalyzer::Scope analyzer(*this); LayoutRect oldContentRect = replacedContentRect(); setHeight(minimumReplacedHeight()); updateLogicalWidth(); updateLogicalHeight(); m_overflow.clear(); addVisualEffectOverflow(); updateLayerTransformAfterLayout(); invalidateBackgroundObscurationStatus(); clearNeedsLayout(); if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && replacedContentRect() != oldContentRect) setShouldDoFullPaintInvalidation(); }
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); } } if (!needsLayout()) return; RenderFlexibleBox::layout(); clearNeedsLayout(); }
void RenderSVGRoot::layout() { ASSERT(needsLayout()); // Arbitrary affine transforms are incompatible with LayoutState. LayoutStateDisabler layoutStateDisabler(view()); bool needsLayout = selfNeedsLayout(); LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout); LayoutSize oldSize(width(), height()); computeLogicalWidth(); computeLogicalHeight(); calcViewport(); SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); m_isLayoutSizeChanged = svg->hasRelativeLengths() && oldSize != size(); if (view() && view()->frameView() && view()->frameView()->embeddedContentBox()) { if (!m_needsSizeNegotiationWithHostDocument) m_needsSizeNegotiationWithHostDocument = !m_everHadLayout || oldSize != size(); } else ASSERT(!m_needsSizeNegotiationWithHostDocument); SVGRenderSupport::layoutChildren(this, needsLayout); m_isLayoutSizeChanged = false; // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (m_needsBoundariesOrTransformUpdate) { updateCachedBoundaries(); m_needsBoundariesOrTransformUpdate = false; } repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderReplaced::layout() { ASSERT(needsLayout()); IntRect oldBounds; IntRect oldOutlineBox; bool checkForRepaint = checkForRepaintDuringLayout(); if (checkForRepaint) { oldBounds = absoluteClippedOverflowRect(); oldOutlineBox = absoluteOutlineBox(); } m_height = minimumReplacedHeight(); calcWidth(); calcHeight(); adjustOverflowForBoxShadow(); if (checkForRepaint) repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); setNeedsLayout(false); }
void RenderBlockFlow::layoutBlock(bool relayoutChildren) { ASSERT(needsLayout()); ASSERT(isInlineBlock() || !isInline()); if (!relayoutChildren && simplifiedLayout()) return; SubtreeLayoutScope layoutScope(*this); layoutBlockFlow(relayoutChildren, layoutScope); updateLayerTransformAfterLayout(); // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if // we overflow or not. updateScrollInfoAfterLayout(); if (m_paintInvalidationLogicalTop != m_paintInvalidationLogicalBottom) setShouldInvalidateOverflowForPaint(true); clearNeedsLayout(); }
void RenderSVGContainer::layout() { ASSERT(needsLayout()); // Arbitrary affine transforms are incompatible with LayoutState. view()->disableLayoutState(); IntRect oldBounds; IntRect oldOutlineBox; bool checkForRepaint = checkForRepaintDuringLayout() && selfWillPaint(); if (checkForRepaint) { oldBounds = m_absoluteBounds; oldOutlineBox = absoluteOutlineBounds(); } calculateLocalTransform(); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { // Only force our kids to layout if we're being asked to relayout as a result of a parent changing // FIXME: We should be able to skip relayout of non-relative kids when only bounds size has changed // that's a possible future optimization using LayoutState // http://bugs.webkit.org/show_bug.cgi?id=15391 if (selfNeedsLayout()) child->setNeedsLayout(true); child->layoutIfNeeded(); ASSERT(!child->needsLayout()); } calcBounds(); if (checkForRepaint) repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); view()->enableLayoutState(); setNeedsLayout(false); }
void RenderView::layout() { if (printing()) m_minPrefWidth = m_maxPrefWidth = width(); // Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account. bool relayoutChildren = !printing() && (!m_frameView || width() != viewWidth() || height() != viewHeight()); if (relayoutChildren) { setChildNeedsLayout(true, false); for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { if (child->style()->height().isPercent() || child->style()->minHeight().isPercent() || child->style()->maxHeight().isPercent()) child->setChildNeedsLayout(true, false); } } ASSERT(!m_layoutState); LayoutState state; // FIXME: May be better to push a clip and avoid issuing offscreen repaints. state.m_clipped = false; m_layoutState = &state; if (needsLayout()) RenderBlock::layout(); // Reset overflowWidth and overflowHeight, since they act as a lower bound for docWidth() and docHeight(). setOverflowWidth(width()); setOverflowHeight(height()); setOverflowWidth(docWidth()); setOverflowHeight(docHeight()); ASSERT(layoutDelta() == IntSize()); ASSERT(m_layoutStateDisableCount == 0); ASSERT(m_layoutState == &state); m_layoutState = 0; setNeedsLayout(false); }
void RenderRubyRun::getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const { ASSERT(!needsLayout()); startOverhang = 0; endOverhang = 0; RenderRubyBase* rubyBase = this->rubyBase(); RenderRubyText* rubyText = this->rubyText(); if (!rubyBase || !rubyText) return; if (!rubyBase->firstRootBox()) return; int logicalWidth = this->logicalWidth(); // No more than half a ruby is allowed to overhang. int logicalLeftOverhang = rubyText->style(firstLine)->fontSize() / 2; int logicalRightOverhang = logicalLeftOverhang; for (RootInlineBox* rootInlineBox = rubyBase->firstRootBox(); rootInlineBox; rootInlineBox = rootInlineBox->nextRootBox()) { logicalLeftOverhang = min<int>(logicalLeftOverhang, rootInlineBox->logicalLeft()); logicalRightOverhang = min<int>(logicalRightOverhang, logicalWidth - rootInlineBox->logicalRight()); } startOverhang = style()->isLeftToRightDirection() ? logicalLeftOverhang : logicalRightOverhang; endOverhang = style()->isLeftToRightDirection() ? logicalRightOverhang : logicalLeftOverhang; if (!startRenderer || !startRenderer->isText() || startRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) startOverhang = 0; if (!endRenderer || !endRenderer->isText() || endRenderer->style(firstLine)->fontSize() > rubyBase->style(firstLine)->fontSize()) endOverhang = 0; }