Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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));
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
void RenderReplaced::layout()
{
    StackStats::LayoutCheckPoint layoutCheckPoint;
    ASSERT(needsLayout());
    
    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
    
    setHeight(minimumReplacedHeight());

    updateLogicalWidth();
    updateLogicalHeight();

    clearOverflow();
    addVisualEffectOverflow();
    updateLayerTransform();
    invalidateBackgroundObscurationStatus();

    repainter.repaintAfterLayout();
    clearNeedsLayout();
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
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();
    }
}
Ejemplo n.º 13
0
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);
}
Ejemplo n.º 14
0
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();
}
Ejemplo n.º 15
0
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();
}
Ejemplo n.º 16
0
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);
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
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);
}
Ejemplo n.º 20
0
void RenderReplaced::layout()
{
    ASSERT(needsLayout());

    LayoutRect oldContentRect = replacedContentRect();

    setHeight(minimumReplacedHeight());

    updateLogicalWidth();
    updateLogicalHeight();

    m_overflow.clear();
    addVisualEffectOverflow();
    updateLayerTransformAfterLayout();
    invalidateBackgroundObscurationStatus();

    clearNeedsLayout();

    if (replacedContentRect() != oldContentRect)
        setShouldDoFullPaintInvalidation();
}
Ejemplo n.º 21
0
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();
}
Ejemplo n.º 22
0
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);
}
Ejemplo n.º 23
0
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();
}
Ejemplo n.º 24
0
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();
}
Ejemplo n.º 25
0
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);
}
Ejemplo n.º 26
0
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);
}
Ejemplo n.º 27
0
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();
}
Ejemplo n.º 28
0
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);
}
Ejemplo n.º 29
0
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);
}
Ejemplo n.º 30
0
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;
}