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); if (flattenFrameSet()) positionFramesWithFlattening(); else positionFrames(); RenderBox::layout(); computeEdgeInfo(); if (doFullRepaint) { view()->repaintViewRectangle(oldBounds); IntRect newBounds = absoluteClippedOverflowRect(); if (newBounds != oldBounds) view()->repaintViewRectangle(newBounds); } setNeedsLayout(false); }
void RenderSVGForeignObject::layout() { ASSERT(needsLayout()); ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree. LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); SVGForeignObjectElement* foreign = static_cast<SVGForeignObjectElement*>(node()); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { m_localTransform = foreign->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } FloatRect oldViewport = m_viewport; // Cache viewport boundaries FloatPoint viewportLocation(foreign->x().value(foreign), foreign->y().value(foreign)); m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width().value(foreign), foreign->height().value(foreign))); if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldViewport != m_viewport; // Set box origin to the foreignObject x/y translation, so positioned objects in XHTML content get correct // positions. A regular RenderBoxModelObject would pull this information from RenderStyle - in SVG those // properties are ignored for non <svg> elements, so we mimic what happens when specifying them through CSS. // FIXME: Investigate in location rounding issues - only affects RenderSVGForeignObject & RenderSVGText setLocation(roundedIntPoint(viewportLocation)); bool layoutChanged = m_everHadLayout && selfNeedsLayout(); RenderBlock::layout(); ASSERT(!needsLayout()); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGBlock::setNeedsBoundariesUpdate(); // Invalidate all resources of this client if our layout changed. if (layoutChanged) SVGResourcesCache::clientLayoutChanged(this); repainter.repaintAfterLayout(); }
void RenderSVGRoot::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; 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 = size(); updateLogicalWidth(); updateLogicalHeight(); buildLocalToBorderBoxTransform(); SVGSVGElement* svg = static_cast<SVGSVGElement*>(node()); m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize != size()); SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filtersForceContainerLayout(this)); 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); }
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 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 RenderSVGShape::layout() { LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && selfNeedsLayout()); SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node()); bool updateCachedBoundariesInParents = false; bool needsShapeUpdate = m_needsShapeUpdate; if (needsShapeUpdate || m_needsBoundariesUpdate) { setIsPaintingFallback(false); m_path.clear(); createShape(); m_needsShapeUpdate = false; updateCachedBoundariesInParents = true; } if (m_needsTransformUpdate) { m_localTransform = element->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } // Invalidate all resources of this client if our layout changed. if (everHadLayout() && selfNeedsLayout()) { SVGResourcesCache::clientLayoutChanged(this); m_markerLayoutInfo.clear(); } // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (needsShapeUpdate || m_needsBoundariesUpdate) { updateCachedBoundaries(); m_needsBoundariesUpdate = false; } // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGModelObject::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderReplaced::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); setHeight(minimumReplacedHeight()); updateLogicalWidth(); updateLogicalHeight(); clearOverflow(); addVisualEffectOverflow(); updateLayerTransform(); invalidateBackgroundObscurationStatus(); repainter.repaintAfterLayout(); clearNeedsLayout(); }
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); }
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 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()); // 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 RenderPath::layout() { IntRect oldBounds; IntRect oldOutlineBox; bool checkForRepaint = checkForRepaintDuringLayout(); if (selfNeedsLayout() && checkForRepaint) { oldBounds = m_absoluteBounds; oldOutlineBox = absoluteOutlineBox(); } setPath(static_cast<SVGStyledElement*>(element())->toPathData()); m_absoluteBounds = absoluteClippedOverflowRect(); setWidth(m_absoluteBounds.width()); setHeight(m_absoluteBounds.height()); if (selfNeedsLayout() && checkForRepaint) repaintAfterLayoutIfNeeded(oldBounds, oldOutlineBox); setNeedsLayout(false); }
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 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 RenderSVGContainer::layout() { ASSERT(needsLayout()); // RenderSVGRoot disables layoutState for the SVG rendering tree. ASSERT(!view()->layoutStateEnabled()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout() || selfWillPaint()); // Allow RenderSVGViewportContainer to update its viewport. calcViewport(); // Allow RenderSVGTransformableContainer to update its transform. bool updatedTransform = calculateLocalTransform(); // RenderSVGViewportContainer needs to set the 'layout size changed' flag. determineIfLayoutSizeChanged(); SVGRenderSupport::layoutChildren(this, selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(this)); // Invalidate all resources of this client if our layout changed. if (everHadLayout() && needsLayout()) SVGResourcesCache::clientLayoutChanged(this); // At this point LayoutRepainter already grabbed the old bounds, // recalculate them now so repaintAfterLayout() uses the new bounds. if (m_needsBoundariesUpdate || updatedTransform) { updateCachedBoundaries(); m_needsBoundariesUpdate = false; // If our bounds changed, notify the parents. RenderSVGModelObject::setNeedsBoundariesUpdate(); } repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderFrameSet::layout() { ASSERT(needsLayout()); bool doFullRepaint = selfNeedsLayout() && checkForRepaintDuringLayout(); IntRect oldBounds; if (doFullRepaint) oldBounds = absoluteClippedOverflowRect(); if (!parent()->isFrameSet() && !document()->printing()) { #ifdef FLATTEN_FRAMESET // Force a grid recalc. m_gridCalculated = false; #endif m_width = view()->viewWidth(); m_height = 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); #ifdef FLATTEN_FRAMESET m_gridCalculated = false; #endif } #ifdef FLATTEN_FRAMESET if (!m_gridCalculated) { m_gridCalculated = true; // Make all the child framesets recalculate their grid. RenderObject* child = firstChild(); for (; child; child = child->nextSibling()) { if (child->isFrameSet()) static_cast<RenderFrameSet*>(child)->setGridNeedsLayout(); } #endif int borderThickness = frameSet()->border(); layOutAxis(m_rows, frameSet()->rowLengths(), m_height - (rows - 1) * borderThickness); layOutAxis(m_cols, frameSet()->colLengths(), m_width - (cols - 1) * borderThickness); #ifdef FLATTEN_FRAMESET } #endif positionFrames(); RenderContainer::layout(); computeEdgeInfo(); if (doFullRepaint) { view()->repaintViewRectangle(oldBounds); IntRect newBounds = absoluteClippedOverflowRect(); if (newBounds != oldBounds) view()->repaintViewRectangle(newBounds); } setNeedsLayout(false); }
void RenderSVGText::layout() { ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { SVGTextElement* text = static_cast<SVGTextElement*>(node()); m_localTransform = text->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } if (!everHadLayout()) { // When laying out initially, collect all layout attributes, build the character data map, // and propogate resulting SVGLayoutAttributes to all RenderSVGInlineText children in the subtree. ASSERT(m_layoutAttributes.isEmpty()); collectLayoutAttributes(this, m_layoutAttributes); updateFontInAllDescendants(this); m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(this); m_needsReordering = true; m_needsTextMetricsUpdate = false; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsPositioningValuesUpdate) { // When the x/y/dx/dy/rotate lists change, recompute the layout attributes, and eventually // update the on-screen font objects as well in all descendants. if (m_needsTextMetricsUpdate) { updateFontInAllDescendants(this); m_needsTextMetricsUpdate = false; } m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) { // If the root layout size changed (eg. window size changes) or the transform to the root // context has changed then recompute the on-screen font size. updateFontInAllDescendants(this, &m_layoutAttributesBuilder); ASSERT(!m_needsReordering); ASSERT(!m_needsPositioningValuesUpdate); m_needsTextMetricsUpdate = false; updateCachedBoundariesInParents = true; } checkLayoutAttributesConsistency(this, m_layoutAttributes); // Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text. // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions. ASSERT(!isInline()); ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); ASSERT(!hasColumns()); ASSERT(!positionedObjects()); ASSERT(!m_overflow); ASSERT(!isAnonymousBlock()); if (!firstChild()) setChildrenInline(true); // FIXME: We need to find a way to only layout the child boxes, if needed. FloatRect oldBoundaries = objectBoundingBox(); ASSERT(childrenInline()); forceLayoutInlineChildren(); if (m_needsReordering) m_needsReordering = false; if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); // Invalidate all resources of this client if our layout changed. if (everHadLayout() && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGBlock::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); setNeedsLayout(false); }
void RenderSVGText::layout() { ASSERT(needsLayout()); LayoutRepainter repainter(*this, checkForRepaintDuringLayout()); bool updateCachedBoundariesInParents = false; if (m_needsTransformUpdate) { SVGTextElement* text = static_cast<SVGTextElement*>(node()); m_localTransform = text->animatedLocalTransform(); m_needsTransformUpdate = false; updateCachedBoundariesInParents = true; } // If the root layout size changed (eg. window size changes) or the positioning values change, recompute the on-screen font size. if (m_needsPositioningValuesUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) { recursiveUpdateScaledFont(this); m_needsPositioningValuesUpdate = true; updateCachedBoundariesInParents = true; } if (m_needsPositioningValuesUpdate) { // Perform SVG text layout phase one (see SVGTextLayoutAttributesBuilder for details). SVGTextLayoutAttributesBuilder layoutAttributesBuilder; layoutAttributesBuilder.buildLayoutAttributesForTextSubtree(this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; } // Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text. // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions. ASSERT(!isInline()); ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); ASSERT(!hasColumns()); ASSERT(!positionedObjects()); ASSERT(!m_overflow); ASSERT(!isAnonymousBlock()); if (!firstChild()) setChildrenInline(true); // FIXME: We need to find a way to only layout the child boxes, if needed. FloatRect oldBoundaries = objectBoundingBox(); ASSERT(childrenInline()); forceLayoutInlineChildren(); if (m_needsReordering) m_needsReordering = false; if (!updateCachedBoundariesInParents) updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox(); // Invalidate all resources of this client if our layout changed. if (m_everHadLayout && selfNeedsLayout()) SVGResourcesCache::clientLayoutChanged(this); // If our bounds changed, notify the parents. if (updateCachedBoundariesInParents) RenderSVGBlock::setNeedsBoundariesUpdate(); repainter.repaintAfterLayout(); setNeedsLayout(false); }