示例#1
0
LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
{
    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.height();

    if (style()->logicalHeight().isSpecified() || style()->logicalMaxHeight().isSpecified())
        return RenderReplaced::computeReplacedLogicalHeight();

    if (svgSVGElement().heightAttributeEstablishesViewport()) {
        Length height = svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
        if (height.isPercent()) {
            RenderBlock* cb = containingBlock();
            ASSERT(cb);
            while (cb->isAnonymous() && !cb->isRenderView()) {
                cb = cb->containingBlock();
                cb->addPercentHeightDescendant(const_cast<RenderSVGRoot&>(*this));
            }
        } else
            RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot&>(*this));

        return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding), &view());
    }

    // SVG embedded through object/embed/iframe.
    if (isEmbeddedThroughFrameContainingSVGDocument())
        return frame().ownerRenderer()->availableLogicalHeight(IncludeMarginBorderPadding);

    // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
    return RenderReplaced::computeReplacedLogicalHeight();
}
示例#2
0
LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
{
    SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
    ASSERT(svg);

    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.height();

    if (hasReplacedLogicalHeight())
        return RenderReplaced::computeReplacedLogicalHeight();

    if (svg->heightAttributeEstablishesViewport()) {
        Length height = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
        if (height.isPercent()) {
            RenderBlock* cb = containingBlock();
            ASSERT(cb);
            while (cb->isAnonymous()) {
                cb = cb->containingBlock();
                cb->addPercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
            }
        } else
            RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));

        return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight());
    }

    // Only SVGs embedded in <object> reach this point.
    ASSERT(isEmbeddedThroughFrameContainingSVGDocument());
    return document()->frame()->ownerRenderer()->availableLogicalHeight();
}
示例#3
0
bool RenderVTTCue::shouldSwitchDirection(InlineFlowBox* firstLineBox, LayoutUnit step) const
{
    LayoutUnit top = y();
    LayoutUnit left = x();
    LayoutUnit bottom = top + firstLineBox->height();
    LayoutUnit right = left + firstLineBox->width();

    // 12. Horizontal: If step is negative and the top of the first line
    // box in boxes is now above the top of the video's rendering area,
    // or if step is positive and the bottom of the first line box in
    // boxes is now below the bottom of the video's rendering area, jump
    // to the step labeled switch direction.
    LayoutUnit parentHeight = containingBlock()->height();
    if (m_cue->getWritingDirection() == VTTCue::Horizontal && ((step < 0 && top < 0) || (step > 0 && bottom > parentHeight)))
        return true;

    // 12. Vertical: If step is negative and the left edge of the first line
    // box in boxes is now to the left of the left edge of the video's
    // rendering area, or if step is positive and the right edge of the
    // first line box in boxes is now to the right of the right edge of
    // the video's rendering area, jump to the step labeled switch direction.
    LayoutUnit parentWidth = containingBlock()->width();
    if (m_cue->getWritingDirection() != VTTCue::Horizontal && ((step < 0 && left < 0) || (step > 0 && right > parentWidth)))
        return true;

    return false;
}
IntRect RenderReplaced::selectionRect(bool clipToVisibleContent)
{
    ASSERT(!needsLayout());

    if (!isSelected())
        return IntRect();
    if (!m_inlineBoxWrapper)
        // We're a block-level replaced element.  Just return our own dimensions.
        return absoluteBoundingBoxRect();

    RenderBlock* cb =  containingBlock();
    if (!cb)
        return IntRect();

    RootInlineBox* root = m_inlineBoxWrapper->root();
    IntRect rect(0, root->selectionTop() - yPos(), width(), root->selectionHeight());

    if (clipToVisibleContent)
        computeAbsoluteRepaintRect(rect);
    else {
        int absx, absy;
        absolutePositionForContent(absx, absy);
        rect.move(absx, absy);
    }

    return rect;
}
示例#5
0
void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel)
{
    for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox())
        rects.append(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width(), curr->height()));

    for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
        if (!curr->isText())
            curr->absoluteRects(rects, tx + curr->xPos(), ty + curr->yPos(), false);
    }

    if (continuation() && topLevel)
        continuation()->absoluteRects(rects, 
                                      tx - containingBlock()->xPos() + continuation()->xPos(),
                                      ty - containingBlock()->yPos() + continuation()->yPos(),
                                      topLevel);
}
IntRect RenderSVGInlineText::computeAbsoluteRectForRange(int startPos, int endPos)
{
    IntRect rect;

    RenderBlock* cb = containingBlock();
    if (!cb || !cb->container())
        return rect;

    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return rect;

    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
        rect.unite(box->selectionRect(0, 0, startPos, endPos));

    // Mimic RenderBox::computeAbsoluteRepaintRect() functionality. But only the subset needed for SVG and respecting SVG transformations.
    int x, y;
    cb->container()->absolutePosition(x, y);

    // Remove HTML parent translation offsets here! These need to be retrieved from the RenderSVGRoot object.
    // But do take the containingBlocks's container position into account, ie. SVG text in scrollable <div>.
    AffineTransform htmlParentCtm = root->RenderContainer::absoluteTransform();

    FloatRect fixedRect(narrowPrecisionToFloat(rect.x() + x - xPos() - htmlParentCtm.e()), narrowPrecisionToFloat(rect.y() + y - yPos() - htmlParentCtm.f()), rect.width(), rect.height());
    return enclosingIntRect(absoluteTransform().mapRect(fixedRect));
}
示例#7
0
IntRect RenderReplaced::selectionRect()
{
    if (!isSelected())
        return IntRect();
    if (!m_inlineBoxWrapper)
        // We're a block-level replaced element.  Just return our own dimensions.
        return absoluteBoundingBoxRect();

    RenderBlock* cb =  containingBlock();
    if (!cb)
        return IntRect();
    
    RootInlineBox* root = m_inlineBoxWrapper->root();
    int selectionTop = root->selectionTop();
    int selectionHeight = root->selectionHeight();
    int selectionLeft = xPos();
    int selectionRight = xPos() + width();
    
    int absx, absy;
    cb->absolutePosition(absx, absy);
    if (cb->hasOverflowClip())
        cb->layer()->subtractScrollOffset(absx, absy);

    return IntRect(selectionLeft + absx, selectionTop + absy, selectionRight - selectionLeft, selectionHeight);
}
示例#8
0
void RenderDialog::layout()
{
    LayoutRepainter repainter(*this, true);
    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());

    RenderBlock::layout();

    RenderStyle* styleToUse = style();
    if (styleToUse->position() != AbsolutePosition || !styleToUse->top().isAuto() || !styleToUse->bottom().isAuto()) {
        statePusher.pop();
        return;
    }

    // Adjust the dialog's position to be centered in or at the top of the viewport.
    // FIXME: Figure out what to do in vertical writing mode.
    FrameView* frameView = document()->view();
    int scrollTop = frameView->scrollOffset().height();
    FloatPoint absolutePoint(0, scrollTop);
    int visibleHeight = frameView->visibleContentRect(true).height();
    if (height() < visibleHeight)
        absolutePoint.move(0, (visibleHeight - height()) / 2);
    FloatPoint localPoint = containingBlock()->absoluteToLocal(absolutePoint);
    LayoutUnit localTop = LayoutSize(localPoint.x(), localPoint.y()).height();
    setY(localTop);

    statePusher.pop();
    // FIXME: Since there is always a layer here, repainter shouldn't be necessary. But without it, the dialog is sometimes not painted (see bug 90670).
    repainter.repaintAfterLayout();
}
示例#9
0
void RenderTextTrackCue::moveIfNecessaryToKeepWithinContainer()
{
    IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
    IntRect cueRect = absoluteBoundingBoxRect();

    int topOverflow = cueRect.y() - containerRect.y();
    int bottomOverflow = containerRect.maxY() - cueRect.maxY();

    int verticalAdjustment = 0;
    if (topOverflow < 0)
        verticalAdjustment = -topOverflow;
    else if (bottomOverflow < 0)
        verticalAdjustment = bottomOverflow;

    if (verticalAdjustment)
        setY(y() + verticalAdjustment);

    int leftOverflow = cueRect.x() - containerRect.x();
    int rightOverflow = containerRect.maxX() - cueRect.maxX();

    int horizontalAdjustment = 0;
    if (leftOverflow < 0)
        horizontalAdjustment = -leftOverflow;
    else if (rightOverflow < 0)
        horizontalAdjustment = rightOverflow;

    if (horizontalAdjustment)
        setX(x() + horizontalAdjustment);
}
示例#10
0
LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
{
    if (style()->logicalWidth().isSpecified() || style()->logicalWidth().isIntrinsic())
        return computeReplacedLogicalWidthRespectingMinMaxWidth(computeReplacedLogicalWidthUsing(style()->logicalWidth()), shouldComputePreferred);

    // 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width
    double intrinsicRatio = 0;
    FloatSize constrainedSize;
    computeAspectRatioInformationForRenderBox(constrainedSize, intrinsicRatio);

    if (style()->logicalWidth().isAuto()) {
        bool computedHeightIsAuto = hasAutoHeightOrContainingBlockWithAutoHeight();
        bool hasIntrinsicWidth = constrainedSize.width() > 0;

        // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
        if (computedHeightIsAuto && hasIntrinsicWidth)
            return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred);

        bool hasIntrinsicHeight = constrainedSize.height() > 0;
        if (intrinsicRatio) {
            // If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
            // or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value
            // of 'width' is: (used height) * (intrinsic ratio)
            if (intrinsicRatio && ((computedHeightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !computedHeightIsAuto)) {
                LayoutUnit logicalHeight = computeReplacedLogicalHeight();
                return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred);
            }

            // If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of
            // 'width' is undefined in CSS 2.1. However, it is suggested that, if the containing block's width does not itself depend on the replaced element's width, then
            // the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
            if (computedHeightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) {
                if (shouldComputePreferred == ComputePreferred)
                    return 0;
                // The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow:
                // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
                LayoutUnit logicalWidth = containingBlock()->availableLogicalWidth();

                // This solves above equation for 'width' (== logicalWidth).
                LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), logicalWidth);
                LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), logicalWidth);
                logicalWidth = std::max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth())));
                return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred);
            }
        }

        // Otherwise, if 'width' has a computed value of 'auto', and the element has an intrinsic width, then that intrinsic width is the used value of 'width'.
        if (hasIntrinsicWidth)
            return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred);

        // Otherwise, if 'width' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'width' becomes 300px. If 300px is too
        // wide to fit the device, UAs should use the width of the largest rectangle that has a 2:1 ratio and fits the device instead.
        // Note: We fall through and instead return intrinsicLogicalWidth() here - to preserve existing WebKit behavior, which might or might not be correct, or desired.
        // Changing this to return cDefaultWidth, will affect lots of test results. Eg. some tests assume that a blank <img> tag (which implies width/height=auto)
        // has no intrinsic size, which is wrong per CSS 2.1, but matches our behavior since a long time.
    }

    return computeReplacedLogicalWidthRespectingMinMaxWidth(intrinsicLogicalWidth(), shouldComputePreferred);
}
示例#11
0
void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
                             RenderObject* newChild, RenderFlow* oldCont)
{
    RenderBlock* pre = 0;
    RenderBlock* block = containingBlock();
    
    // Delete our line boxes before we do the inline split into continuations.
    block->deleteLineBoxTree();
    
    bool madeNewBeforeBlock = false;
    if (block->isAnonymousBlock() && (!block->parent() || !block->parent()->createsAnonymousWrapper())) {
        // We can reuse this block and make it the preBlock of the next continuation.
        pre = block;
        block = block->containingBlock();
    } else {
        // No anonymous block available for use.  Make one.
        pre = block->createAnonymousBlock();
        madeNewBeforeBlock = true;
    }

    RenderBlock* post = block->createAnonymousBlock();

    RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling();
    if (madeNewBeforeBlock)
        block->insertChildNode(pre, boxFirst);
    block->insertChildNode(newBlockBox, boxFirst);
    block->insertChildNode(post, boxFirst);
    block->setChildrenInline(false);
    
    if (madeNewBeforeBlock) {
        RenderObject* o = boxFirst;
        while (o) {
            RenderObject* no = o;
            o = no->nextSibling();
            pre->appendChildNode(block->removeChildNode(no));
            no->setNeedsLayoutAndPrefWidthsRecalc();
        }
    }

    splitInlines(pre, post, newBlockBox, beforeChild, oldCont);

    // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting
    // time in makeChildrenNonInline by just setting this explicitly up front.
    newBlockBox->setChildrenInline(false);

    // We don't just call addChild, since it would pass things off to the
    // continuation, so we call addChildToFlow explicitly instead.  We delayed
    // adding the newChild until now so that the |newBlockBox| would be fully
    // connected, thus allowing newChild access to a renderArena should it need
    // to wrap itself in additional boxes (e.g., table construction).
    newBlockBox->addChildToFlow(newChild, 0);

    // Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
    // get deleted properly.  Because objects moves from the pre block into the post block, we want to
    // make new line boxes instead of leaving the old line boxes around.
    pre->setNeedsLayoutAndPrefWidthsRecalc();
    block->setNeedsLayoutAndPrefWidthsRecalc();
    post->setNeedsLayoutAndPrefWidthsRecalc();
}
IntRect RenderInline::clippedOverflowRectForRepaint(RenderBox* repaintContainer)
{
    // Only run-ins are allowed in here during layout.
    ASSERT(!view() || !view()->layoutStateEnabled() || isRunIn());

    if (!firstLineBox() && !continuation())
        return IntRect();

    // Find our leftmost position.
    IntRect boundingBox(linesBoundingBox());
    int left = boundingBox.x();
    int top = boundingBox.y();

    // Now invalidate a rectangle.
    int ow = style() ? style()->outlineSize() : 0;
    
    // We need to add in the relative position offsets of any inlines (including us) up to our
    // containing block.
    RenderBlock* cb = containingBlock();
    for (RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInline() && inlineFlow != cb; 
         inlineFlow = inlineFlow->parent()) {
         if (inlineFlow->style()->position() == RelativePosition && inlineFlow->hasLayer())
            toRenderBox(inlineFlow)->layer()->relativePositionOffset(left, top);
    }

    IntRect r(-ow + left, -ow + top, boundingBox.width() + ow * 2, boundingBox.height() + ow * 2);
    if (cb->hasColumns())
        cb->adjustRectForColumns(r);

    if (cb->hasOverflowClip()) {
        // cb->height() is inaccurate if we're in the middle of a layout of |cb|, so use the
        // layer's size instead.  Even if the layer's size is wrong, the layer itself will repaint
        // anyway if its size does change.
        int x = r.x();
        int y = r.y();
        IntRect boxRect(0, 0, cb->layer()->width(), cb->layer()->height());
        cb->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden.
        IntRect repaintRect(x, y, r.width(), r.height());
        r = intersection(repaintRect, boxRect);
    }
    ASSERT(repaintContainer != this);
    cb->computeRectForRepaint(r, repaintContainer);

    if (ow) {
        for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
            if (!curr->isText()) {
                IntRect childRect = curr->rectWithOutlineForRepaint(repaintContainer, ow);
                r.unite(childRect);
            }
        }

        if (continuation() && !continuation()->isInline()) {
            IntRect contRect = continuation()->rectWithOutlineForRepaint(repaintContainer, ow);
            r.unite(contRect);
        }
    }

    return r;
}
示例#13
0
void RenderListMarker::setSelectionState(SelectionState state)
{
    m_selectionState = state;
    if (InlineBox* box = inlineBoxWrapper())
        if (RootInlineBox* root = box->root())
            root->setHasSelectedChildren(state != SelectionNone);
    containingBlock()->setSelectionState(state);
}
示例#14
0
void RenderReplaced::setSelectionState(SelectionState s)
{
    m_selectionState = s;
    if (m_inlineBoxWrapper) {
        RootInlineBox* line = m_inlineBoxWrapper->root();
        if (line)
            line->setHasSelectedChildren(isSelected());
    }

    containingBlock()->setSelectionState(s);
}
示例#15
0
LayoutUnit LayoutSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
{
    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.width();

    if (isEmbeddedThroughFrameContainingSVGDocument())
        return containingBlock()->availableLogicalWidth();

    return LayoutReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
}
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    bool hadTransform = hasTransform();

    RenderObject::styleDidChange(diff, oldStyle);
    updateFromStyle();

    LayerType type = layerTypeRequired();
    if (type != NoLayer) {
        if (!layer() && layerCreationAllowedForSubtree()) {
            if (s_wasFloating && isFloating())
                setChildNeedsLayout();
            createLayer(type);
            if (parent() && !needsLayout() && containingBlock()) {
                // FIXME: This invalidation is overly broad. We should update to
                // do the correct invalidation at RenderStyle::diff time. crbug.com/349061
                if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
                    layer()->renderer()->setShouldDoFullPaintInvalidationAfterLayout(true);
                else
                    layer()->repainter().setRepaintStatus(NeedsFullRepaint);
                // Hit in animations/interpolation/perspective-interpolation.html
                // FIXME: I suspect we can remove this assert disabler now.
                DisableCompositingQueryAsserts disabler;
                layer()->updateLayerPositionRecursive();
            }
        }
    } else if (layer() && layer()->parent()) {
        setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
        setHasReflection(false);
        layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
        if (s_wasFloating && isFloating())
            setChildNeedsLayout();
        if (hadTransform)
            setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
    }

    if (layer()) {
        // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer
        // from the style.
        layer()->setLayerType(type);
        layer()->styleChanged(diff, oldStyle);
    }

    if (FrameView *frameView = view()->frameView()) {
        bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition();
        bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition();
        if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) {
            if (newStyleIsViewportConstained && layer())
                frameView->addViewportConstrainedObject(this);
            else
                frameView->removeViewportConstrainedObject(this);
        }
    }
}
示例#17
0
LayoutUnit LayoutSVGRoot::computeReplacedLogicalHeight() const
{
    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.height();

    if (isEmbeddedThroughFrameContainingSVGDocument())
        return containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding);

    return LayoutReplaced::computeReplacedLogicalHeight();
}
示例#18
0
void RenderTextTrackCue::repositionGenericCue()
{
    ASSERT(firstChild());
    InlineFlowBox* firstLineBox = toRenderInline(firstChild())->firstLineBox();
    if (static_cast<TextTrackCueGeneric*>(m_cue)->useDefaultPosition() && firstLineBox) {
        LayoutUnit parentWidth = containingBlock()->logicalWidth();
        LayoutUnit width = firstLineBox->width();
        LayoutUnit right = (parentWidth / 2) - (width / 2);
        setX(right);
    }
    repositionCueSnapToLinesNotSet();
}
int RenderSVGContainer::calcReplacedHeight() const
{
    switch (style()->height().type()) {
    case Fixed:
        return max(0, style()->height().value());
    case Percent:
    {
        RenderBlock* cb = containingBlock();
        return style()->height().calcValue(cb->availableHeight());
    }
    default:
        return 0;
    }
}
示例#20
0
void RenderVTTCue::repositionCueSnapToLinesSet()
{
    InlineFlowBox* firstLineBox;
    LayoutUnit step;
    LayoutUnit position;

    if (!findFirstLineBox(firstLineBox))
        return;

    if (!initializeLayoutParameters(firstLineBox, step, position))
        return;

    bool switched;
    placeBoxInDefaultPosition(position, switched);

    // 11. Step loop: If none of the boxes in boxes would overlap any of the boxes
    // in output and all the boxes in output are within the video's rendering area
    // then jump to the step labeled done positioning.
    while (isOutside() || isOverlapping()) {
        if (!shouldSwitchDirection(firstLineBox, step)) {
            // 13. Move all the boxes in boxes ...
            // 14. Jump back to the step labeled step loop.
            moveBoxesByStep(step);
        } else if (!switchDirection(switched, step)) {
            break;
        }

        // 19. Jump back to the step labeled step loop.
    }

    // Acommodate extra top and bottom padding, border or margin.
    // Note: this is supported only for internal UA styling, not through the cue selector.
    if (hasInlineDirectionBordersPaddingOrMargin()) {
        IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
        IntRect cueRect = absoluteBoundingBoxRect();

        int topOverflow = cueRect.y() - containerRect.y();
        int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y() - cueRect.height();

        int adjustment = 0;
        if (topOverflow < 0)
            adjustment = -topOverflow;
        else if (bottomOverflow < 0)
            adjustment = bottomOverflow;

        if (adjustment)
            setY(y() + adjustment);
    }
}
示例#21
0
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
    bool hadTransform = hasTransform();
    bool hadLayer = hasLayer();
    bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer();

    RenderObject::styleDidChange(diff, oldStyle);
    updateFromStyle();

    if (requiresLayer()) {
        if (!layer() && layerCreationAllowedForSubtree()) {
            if (s_wasFloating && isFloating())
                setChildNeedsLayout();
            createLayer();
            if (parent() && !needsLayout() && containingBlock()) {
                layer()->repainter().setRepaintStatus(NeedsFullRepaint);
                // There is only one layer to update, it is not worth using |cachedOffset| since
                // we are not sure the value will be used.
                layer()->updateLayerPositions(0);
            }
        }
    } else if (layer() && layer()->parent()) {
        setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
        setHasReflection(false);
        layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
        if (s_wasFloating && isFloating())
            setChildNeedsLayout();
        if (hadTransform)
            setNeedsLayoutAndPrefWidthsRecalc();
    }

    if (layer()) {
        layer()->styleChanged(diff, oldStyle);
        if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting)
            setChildNeedsLayout();
    }

    if (FrameView *frameView = view()->frameView()) {
        bool newStyleIsViewportConstained = style()->hasViewportConstrainedPosition();
        bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition();
        if (newStyleIsViewportConstained != oldStyleIsViewportConstrained) {
            if (newStyleIsViewportConstained && layer())
                frameView->addViewportConstrainedObject(this);
            else
                frameView->removeViewportConstrainedObject(this);
        }
    }
}
FloatQuad RenderSVGInlineText::computeRepaintQuadForRange(RenderBoxModelObject* repaintContainer, int startPos, int endPos)
{
    RenderBlock* cb = containingBlock();
    if (!cb || !cb->container())
        return FloatQuad();

    RenderSVGRoot* root = findSVGRootObject(parent());
    if (!root)
        return FloatQuad();

    IntRect rect;
    for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox())
        rect.unite(box->selectionRect(0, 0, startPos, endPos));

    return localToContainerQuad(FloatQuad(rect), repaintContainer);
}
示例#23
0
VisiblePosition RenderInline::positionForCoordinates(int x, int y)
{
    // Translate the coords from the pre-anonymous block to the post-anonymous block.
    RenderBlock* cb = containingBlock();
    int parentBlockX = cb->xPos() + x;
    int parentBlockY = cb->yPos() + y;
    for (RenderObject* c = continuation(); c; c = c->continuation()) {
        RenderObject* contBlock = c;
        if (c->isInline())
            contBlock = c->containingBlock();
        if (c->isInline() || c->firstChild())
            return c->positionForCoordinates(parentBlockX - contBlock->xPos(), parentBlockY - contBlock->yPos());
    }

    return RenderFlow::positionForCoordinates(x, y);
}
IntRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
{
    if (checkWhetherSelected && !isSelected())
        return IntRect();

    if (!m_inlineBoxWrapper)
        // We're a block-level replaced element.  Just return our own dimensions.
        return IntRect(0, 0, width(), height());

    RenderBlock* cb =  containingBlock();
    if (!cb)
        return IntRect();

    RootInlineBox* root = m_inlineBoxWrapper->root();
    return IntRect(0, root->selectionTop() - y(), width(), root->selectionHeight());
}
示例#25
0
bool RenderVTTCue::initializeLayoutParameters(InlineFlowBox*& firstLineBox, LayoutUnit& step, LayoutUnit& position)
{
    ASSERT(firstChild());

    RenderBlock* parentBlock = containingBlock();
    firstLineBox = toRenderInline(firstChild())->firstLineBox();
    if (!firstLineBox)
        firstLineBox = this->firstRootBox();

    // 1. Horizontal: Let step be the height of the first line box in boxes.
    //    Vertical: Let step be the width of the first line box in boxes.
    step = m_cue->getWritingDirection() == VTTCue::Horizontal ? firstLineBox->height() : firstLineBox->width();

    // 2. If step is zero, then jump to the step labeled done positioning below.
    if (!step)
        return false;

    // 3. Let line position be the text track cue computed line position.
    int linePosition = m_cue->calculateComputedLinePosition();

    // 4. Vertical Growing Left: Add one to line position then negate it.
    if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft)
        linePosition = -(linePosition + 1);

    // 5. Let position be the result of multiplying step and line position.
    position = step * linePosition;

    // 6. Vertical Growing Left: Decrease position by the width of the
    // bounding box of the boxes in boxes, then increase position by step.
    if (m_cue->getWritingDirection() == VTTCue::VerticalGrowingLeft) {
        position -= width();
        position += step;
    }

    // 7. If line position is less than zero...
    if (linePosition < 0) {
        // Horizontal / Vertical: ... then increase position by the
        // height / width of the video's rendering area ...
        position += m_cue->getWritingDirection() == VTTCue::Horizontal ? parentBlock->height() : parentBlock->width();

        // ... and negate step.
        step = -step;
    }

    return true;
}
示例#26
0
void RenderTextTrackCue::repositionGenericCue()
{
    TextTrackCueGeneric* cue = static_cast<TextTrackCueGeneric*>(m_cue);
    if (!cue->useDefaultPosition())
        return;

    ASSERT(firstChild());

    InlineFlowBox* firstLineBox = toRenderInline(firstChild())->firstLineBox();
    if (!firstLineBox)
        return;

    LayoutUnit parentWidth = containingBlock()->logicalWidth();
    LayoutUnit width = firstLineBox->width();
    LayoutUnit right = (parentWidth / 2) - (width / 2);
    setX(right);
}
示例#27
0
LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
{
    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.width();

    if (isEmbeddedThroughFrameContainingSVGDocument())
        return containingBlock()->availableLogicalWidth();

    if (style().logicalWidth().isSpecified() || style().logicalMaxWidth().isSpecified())
        return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);

    if (svgSVGElement().hasIntrinsicWidth())
        return resolveLengthAttributeForSVG(svgSVGElement().intrinsicWidth(), style().effectiveZoom(), containingBlock()->availableLogicalWidth(), &view());

    // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
    return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
}
示例#28
0
LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
{
    // When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
    if (!m_containerSize.isEmpty())
        return m_containerSize.height();

    if (isEmbeddedThroughFrameContainingSVGDocument())
        return containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding);

    if (style().logicalHeight().isSpecified() || style().logicalMaxHeight().isSpecified())
        return RenderReplaced::computeReplacedLogicalHeight();

    if (svgSVGElement().hasIntrinsicHeight())
        return resolveLengthAttributeForSVG(svgSVGElement().intrinsicHeight(), style().effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding).toFloat());

    // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
    return RenderReplaced::computeReplacedLogicalHeight();
}
示例#29
0
void LayoutVTTCue::adjustForTopAndBottomMarginBorderAndPadding()
{
    // Accommodate extra top and bottom padding, border or margin.
    // Note: this is supported only for internal UA styling, not through the cue selector.
    if (!hasInlineDirectionBordersPaddingOrMargin())
        return;
    IntRect containerRect = containingBlock()->absoluteBoundingBoxRect();
    IntRect cueRect = absoluteBoundingBoxRect();

    int topOverflow = cueRect.y() - containerRect.y();
    int bottomOverflow = containerRect.y() + containerRect.height() - cueRect.y() - cueRect.height();

    int adjustment = 0;
    if (topOverflow < 0)
        adjustment = -topOverflow;
    else if (bottomOverflow < 0)
        adjustment = bottomOverflow;

    if (!adjustment)
        return;

    setY(location().y() + adjustment);
}
示例#30
0
LayoutUnit LayoutReplaced::computeConstrainedLogicalWidth(
    ShouldComputePreferred shouldComputePreferred) const {
    if (shouldComputePreferred == ComputePreferred)
        return computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit(),
                ComputePreferred);
    // The aforementioned 'constraint equation' used for block-level, non-replaced
    // elements in normal flow:
    // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' +
    // 'padding-right' + 'border-right-width' + 'margin-right' = width of
    // containing block
    LayoutUnit logicalWidth = containingBlock()->availableLogicalWidth();

    // This solves above equation for 'width' (== logicalWidth).
    LayoutUnit marginStart =
        minimumValueForLength(style()->marginStart(), logicalWidth);
    LayoutUnit marginEnd =
        minimumValueForLength(style()->marginEnd(), logicalWidth);
    logicalWidth = (logicalWidth -
                    (marginStart + marginEnd + (size().width() - clientWidth())))
                   .clampNegativeToZero();
    return computeReplacedLogicalWidthRespectingMinMaxWidth(
               logicalWidth, shouldComputePreferred);
}