mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
628 lines
30 KiB
C++
628 lines
30 KiB
C++
/*
|
|
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
|
|
* (C) 1999 Antti Koivisto (koivisto@kde.org)
|
|
* Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef SKY_ENGINE_CORE_RENDERING_RENDERBOX_H_
|
|
#define SKY_ENGINE_CORE_RENDERING_RENDERBOX_H_
|
|
|
|
#include "flutter/sky/engine/core/rendering/RenderBoxModelObject.h"
|
|
#include "flutter/sky/engine/core/rendering/RenderOverflow.h"
|
|
|
|
namespace blink {
|
|
|
|
struct LayerPaintingInfo;
|
|
struct PaintInfo;
|
|
class HitTestingTransformState;
|
|
class TransformationMatrix;
|
|
|
|
enum SizeType { MainOrPreferredSize, MinSize, MaxSize };
|
|
enum AvailableLogicalHeightType { ExcludeMarginBorderPadding, IncludeMarginBorderPadding };
|
|
enum MarginDirection { BlockDirection, InlineDirection };
|
|
|
|
enum ShouldComputePreferred { ComputeActual, ComputePreferred };
|
|
|
|
enum ContentsClipBehavior { ForceContentsClip, SkipContentsClipIfPossible };
|
|
|
|
struct RenderBoxRareData {
|
|
WTF_MAKE_NONCOPYABLE(RenderBoxRareData); WTF_MAKE_FAST_ALLOCATED;
|
|
public:
|
|
RenderBoxRareData()
|
|
: m_inlineBoxWrapper(0)
|
|
, m_overrideLogicalContentHeight(-1)
|
|
, m_overrideLogicalContentWidth(-1)
|
|
{
|
|
}
|
|
|
|
// For inline replaced elements, the inline box that owns us.
|
|
InlineBox* m_inlineBoxWrapper;
|
|
LayoutUnit m_overrideLogicalContentHeight;
|
|
LayoutUnit m_overrideLogicalContentWidth;
|
|
};
|
|
|
|
enum LayerType {
|
|
NoLayer,
|
|
NormalLayer,
|
|
// An overflow clip layer is required for bookkeeping purposes,
|
|
// but does not force a layer to be self painting.
|
|
OverflowClipLayer,
|
|
};
|
|
|
|
struct FontBaselineOrAuto {
|
|
FontBaselineOrAuto()
|
|
: m_auto(true)
|
|
, m_baseline(AlphabeticBaseline)
|
|
{
|
|
}
|
|
FontBaselineOrAuto(FontBaseline baseline)
|
|
: m_auto(false)
|
|
, m_baseline(baseline)
|
|
{
|
|
}
|
|
bool m_auto;
|
|
FontBaseline m_baseline;
|
|
};
|
|
|
|
class RenderBox : public RenderBoxModelObject {
|
|
public:
|
|
explicit RenderBox();
|
|
|
|
// hasAutoZIndex only returns true if the element is positioned or a flex-item since
|
|
// position:static elements that are not flex-items get their z-index coerced to auto.
|
|
virtual LayerType layerTypeRequired() const
|
|
{
|
|
if (isPositioned() || createsGroup() || hasClipPath() || hasTransform() || !style()->hasAutoZIndex())
|
|
return NormalLayer;
|
|
if (hasOverflowClip())
|
|
return OverflowClipLayer;
|
|
return NoLayer;
|
|
}
|
|
|
|
void destroyLayer();
|
|
void createLayer(LayerType);
|
|
bool hasSelfPaintingLayer() const;
|
|
RenderLayer* layer() const { return m_layer.get(); }
|
|
|
|
// Use this with caution! No type checking is done!
|
|
RenderBox* firstChildBox() const;
|
|
RenderBox* lastChildBox() const;
|
|
|
|
LayoutUnit x() const { return m_frameRect.x(); }
|
|
LayoutUnit y() const { return m_frameRect.y(); }
|
|
LayoutUnit width() const { return m_frameRect.width(); }
|
|
LayoutUnit height() const { return m_frameRect.height(); }
|
|
|
|
int pixelSnappedWidth() const { return m_frameRect.pixelSnappedWidth(); }
|
|
int pixelSnappedHeight() const { return m_frameRect.pixelSnappedHeight(); }
|
|
|
|
// These represent your location relative to your container as a physical offset.
|
|
// In layout related methods you almost always want the logical location (e.g. x() and y()).
|
|
LayoutUnit top() const { return location().y(); }
|
|
LayoutUnit left() const { return location().x(); }
|
|
|
|
void setX(LayoutUnit x) { m_frameRect.setX(x); }
|
|
void setY(LayoutUnit y) { m_frameRect.setY(y); }
|
|
void setWidth(LayoutUnit width) { m_frameRect.setWidth(width); }
|
|
void setHeight(LayoutUnit height) { m_frameRect.setHeight(height); }
|
|
|
|
LayoutUnit logicalLeft() const { return x(); }
|
|
LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
|
|
LayoutUnit logicalTop() const { return y(); }
|
|
LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
|
|
LayoutUnit logicalWidth() const { return width(); }
|
|
LayoutUnit logicalHeight() const { return height(); }
|
|
|
|
LayoutUnit constrainLogicalWidthByMinMax(LayoutUnit, LayoutUnit, RenderBlock*) const;
|
|
LayoutUnit constrainLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
|
|
LayoutUnit constrainContentBoxLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
|
|
|
|
int pixelSnappedLogicalHeight() const { return pixelSnappedHeight(); }
|
|
int pixelSnappedLogicalWidth() const { return pixelSnappedWidth(); }
|
|
|
|
void setLogicalLeft(LayoutUnit left)
|
|
{
|
|
setX(left);
|
|
}
|
|
void setLogicalTop(LayoutUnit top)
|
|
{
|
|
setY(top);
|
|
}
|
|
void setLogicalLocation(const LayoutPoint& location)
|
|
{
|
|
setLocation(location);
|
|
}
|
|
void setLogicalWidth(LayoutUnit size)
|
|
{
|
|
setWidth(size);
|
|
}
|
|
void setLogicalHeight(LayoutUnit size)
|
|
{
|
|
setHeight(size);
|
|
}
|
|
void setLogicalSize(const LayoutSize& size)
|
|
{
|
|
setSize(size);
|
|
}
|
|
|
|
LayoutPoint location() const { return m_frameRect.location(); }
|
|
LayoutSize locationOffset() const { return LayoutSize(x(), y()); }
|
|
LayoutSize size() const { return m_frameRect.size(); }
|
|
IntSize pixelSnappedSize() const { return m_frameRect.pixelSnappedSize(); }
|
|
|
|
void setLocation(const LayoutPoint& location) { m_frameRect.setLocation(location); }
|
|
|
|
void setSize(const LayoutSize& size) { m_frameRect.setSize(size); }
|
|
void move(LayoutUnit dx, LayoutUnit dy) { m_frameRect.move(dx, dy); }
|
|
|
|
LayoutRect frameRect() const { return m_frameRect; }
|
|
IntRect pixelSnappedFrameRect() const { return pixelSnappedIntRect(m_frameRect); }
|
|
void setFrameRect(const LayoutRect& rect) { m_frameRect = rect; }
|
|
|
|
LayoutRect borderBoxRect() const { return LayoutRect(LayoutPoint(), size()); }
|
|
LayoutRect paddingBoxRect() const { return LayoutRect(borderLeft(), borderTop(), clientWidth(), clientHeight()); }
|
|
IntRect pixelSnappedBorderBoxRect() const { return IntRect(IntPoint(), m_frameRect.pixelSnappedSize()); }
|
|
virtual IntRect borderBoundingBox() const override final { return pixelSnappedBorderBoxRect(); }
|
|
|
|
// The content area of the box (excludes padding - and intrinsic padding for table cells, etc... - and border).
|
|
LayoutRect contentBoxRect() const { return LayoutRect(borderLeft() + paddingLeft(), borderTop() + paddingTop(), contentWidth(), contentHeight()); }
|
|
// The content box in absolute coords. Ignores transforms.
|
|
IntRect absoluteContentBox() const;
|
|
// The content box converted to absolute coords (taking transforms into account).
|
|
FloatQuad absoluteContentQuad() const;
|
|
|
|
FloatPoint perspectiveOrigin() const;
|
|
|
|
// This returns the content area of the box (excluding padding and border). The only difference with contentBoxRect is that computedCSSContentBoxRect
|
|
// does include the intrinsic padding in the content box as this is what some callers expect (like getComputedStyle).
|
|
LayoutRect computedCSSContentBoxRect() const { return LayoutRect(borderLeft() + computedCSSPaddingLeft(), borderTop() + computedCSSPaddingTop(), clientWidth() - computedCSSPaddingLeft() - computedCSSPaddingRight(), clientHeight() - computedCSSPaddingTop() - computedCSSPaddingBottom()); }
|
|
|
|
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderBox* paintContainer = 0) const override;
|
|
|
|
// Use this with caution! No type checking is done!
|
|
RenderBox* previousSiblingBox() const;
|
|
RenderBox* nextSiblingBox() const;
|
|
RenderBox* parentBox() const;
|
|
|
|
// Visual and layout overflow are in the coordinate space of the box. This means that they aren't purely physical directions.
|
|
// For horizontal-tb and vertical-lr they will match physical directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right
|
|
// respectively are flipped when compared to their physical counterparts. For example minX is on the left in vertical-lr,
|
|
// but it is on the right in vertical-rl.
|
|
LayoutRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : paddingBoxRect(); }
|
|
IntRect pixelSnappedLayoutOverflowRect() const { return pixelSnappedIntRect(layoutOverflowRect()); }
|
|
LayoutSize maxLayoutOverflow() const { return LayoutSize(layoutOverflowRect().maxX(), layoutOverflowRect().maxY()); }
|
|
LayoutUnit logicalLeftLayoutOverflow() const { return layoutOverflowRect().x(); }
|
|
LayoutUnit logicalRightLayoutOverflow() const { return layoutOverflowRect().maxX(); }
|
|
|
|
virtual LayoutRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : borderBoxRect(); }
|
|
LayoutUnit logicalLeftVisualOverflow() const { return visualOverflowRect().x(); }
|
|
LayoutUnit logicalRightVisualOverflow() const { return visualOverflowRect().maxX(); }
|
|
|
|
LayoutRect contentsVisualOverflowRect() const { return m_overflow ? m_overflow->contentsVisualOverflowRect() : LayoutRect(); }
|
|
|
|
void addLayoutOverflow(const LayoutRect&);
|
|
void addVisualOverflow(const LayoutRect&);
|
|
|
|
// Clipped by the contents clip, if one exists.
|
|
void addContentsVisualOverflow(const LayoutRect&);
|
|
|
|
void addVisualEffectOverflow();
|
|
LayoutBoxExtent computeVisualEffectOverflowExtent() const;
|
|
void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, child->locationOffset()); }
|
|
void addOverflowFromChild(RenderBox* child, const LayoutSize& delta);
|
|
void clearLayoutOverflow();
|
|
void clearAllOverflows() { m_overflow.clear(); }
|
|
|
|
void updateLayerTransformAfterLayout();
|
|
|
|
// This transform has the transform-origin baked in.
|
|
TransformationMatrix* transform() const { return m_transform.get(); }
|
|
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
|
|
|
|
LayoutUnit contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
|
|
LayoutUnit contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
|
|
LayoutUnit contentLogicalWidth() const { return contentWidth(); }
|
|
LayoutUnit contentLogicalHeight() const { return contentHeight(); }
|
|
|
|
// IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow)
|
|
// to return the remaining width on a given line (and the height of a single line).
|
|
virtual LayoutUnit offsetWidth() const override { return width(); }
|
|
virtual LayoutUnit offsetHeight() const override { return height(); }
|
|
|
|
virtual int pixelSnappedOffsetWidth() const override final;
|
|
virtual int pixelSnappedOffsetHeight() const override final;
|
|
|
|
// More IE extensions. clientWidth and clientHeight represent the interior of an object
|
|
// excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth.
|
|
LayoutUnit clientLeft() const { return borderLeft(); }
|
|
LayoutUnit clientTop() const { return borderTop(); }
|
|
LayoutUnit clientWidth() const;
|
|
LayoutUnit clientHeight() const;
|
|
LayoutUnit clientLogicalWidth() const { return clientWidth(); }
|
|
LayoutUnit clientLogicalHeight() const { return clientHeight(); }
|
|
LayoutUnit clientLogicalBottom() const { return borderBefore() + clientLogicalHeight(); }
|
|
LayoutRect clientBoxRect() const { return LayoutRect(clientLeft(), clientTop(), clientWidth(), clientHeight()); }
|
|
|
|
int pixelSnappedClientWidth() const;
|
|
int pixelSnappedClientHeight() const;
|
|
|
|
virtual LayoutUnit marginTop() const override { return m_marginBox.top(); }
|
|
virtual LayoutUnit marginBottom() const override { return m_marginBox.bottom(); }
|
|
virtual LayoutUnit marginLeft() const override { return m_marginBox.left(); }
|
|
virtual LayoutUnit marginRight() const override { return m_marginBox.right(); }
|
|
void setMarginTop(LayoutUnit margin) { m_marginBox.setTop(margin); }
|
|
void setMarginBottom(LayoutUnit margin) { m_marginBox.setBottom(margin); }
|
|
void setMarginLeft(LayoutUnit margin) { m_marginBox.setLeft(margin); }
|
|
void setMarginRight(LayoutUnit margin) { m_marginBox.setRight(margin); }
|
|
|
|
LayoutUnit marginLogicalLeft() const { return m_marginBox.logicalLeft(); }
|
|
LayoutUnit marginLogicalRight() const { return m_marginBox.logicalRight(); }
|
|
|
|
virtual LayoutUnit marginBefore(const RenderStyle* overrideStyle = 0) const override final { return m_marginBox.before(); }
|
|
virtual LayoutUnit marginAfter(const RenderStyle* overrideStyle = 0) const override final { return m_marginBox.after(); }
|
|
virtual LayoutUnit marginStart(const RenderStyle* overrideStyle = 0) const override final
|
|
{
|
|
const RenderStyle* styleToUse = overrideStyle ? overrideStyle : style();
|
|
return m_marginBox.start(styleToUse->direction());
|
|
}
|
|
virtual LayoutUnit marginEnd(const RenderStyle* overrideStyle = 0) const override final
|
|
{
|
|
const RenderStyle* styleToUse = overrideStyle ? overrideStyle : style();
|
|
return m_marginBox.end(styleToUse->direction());
|
|
}
|
|
void setMarginBefore(LayoutUnit value, const RenderStyle* overrideStyle = 0) { m_marginBox.setBefore(value); }
|
|
void setMarginAfter(LayoutUnit value, const RenderStyle* overrideStyle = 0) { m_marginBox.setAfter(value); }
|
|
void setMarginStart(LayoutUnit value, const RenderStyle* overrideStyle = 0)
|
|
{
|
|
const RenderStyle* styleToUse = overrideStyle ? overrideStyle : style();
|
|
m_marginBox.setStart(styleToUse->direction(), value);
|
|
}
|
|
void setMarginEnd(LayoutUnit value, const RenderStyle* overrideStyle = 0)
|
|
{
|
|
const RenderStyle* styleToUse = overrideStyle ? overrideStyle : style();
|
|
m_marginBox.setEnd(styleToUse->direction(), value);
|
|
}
|
|
|
|
virtual void absoluteQuads(Vector<FloatQuad>&) const override;
|
|
|
|
bool hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer,
|
|
const HitTestRequest& request, HitTestResult& result,
|
|
const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
|
|
const HitTestingTransformState* transformState = 0, double* zOffset = 0);
|
|
|
|
void paintLayer(GraphicsContext*, const LayerPaintingInfo&);
|
|
|
|
virtual void layout() override;
|
|
virtual void paint(PaintInfo&, const LayoutPoint&, Vector<RenderBox*>& layers) override;
|
|
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) override;
|
|
|
|
virtual LayoutUnit minPreferredLogicalWidth() const override;
|
|
virtual LayoutUnit maxPreferredLogicalWidth() const override;
|
|
|
|
void setMinPreferredLogicalWidth(LayoutUnit);
|
|
void setMaxPreferredLogicalWidth(LayoutUnit);
|
|
|
|
// FIXME: We should rename these back to overrideLogicalHeight/Width and have them store
|
|
// the border-box height/width like the regular height/width accessors on RenderBox.
|
|
// Right now, these are different than contentHeight/contentWidth because they still
|
|
// include the scrollbar height/width.
|
|
LayoutUnit overrideLogicalContentWidth() const;
|
|
LayoutUnit overrideLogicalContentHeight() const;
|
|
bool hasOverrideHeight() const;
|
|
bool hasOverrideWidth() const;
|
|
void setOverrideLogicalContentHeight(LayoutUnit);
|
|
void setOverrideLogicalContentWidth(LayoutUnit);
|
|
void clearOverrideSize();
|
|
void clearOverrideLogicalContentHeight();
|
|
void clearOverrideLogicalContentWidth();
|
|
|
|
virtual LayoutSize offsetFromContainer(const RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const override;
|
|
|
|
LayoutUnit adjustBorderBoxLogicalWidthForBoxSizing(LayoutUnit width) const;
|
|
LayoutUnit adjustBorderBoxLogicalHeightForBoxSizing(LayoutUnit height) const;
|
|
LayoutUnit adjustContentBoxLogicalWidthForBoxSizing(LayoutUnit width) const;
|
|
LayoutUnit adjustContentBoxLogicalHeightForBoxSizing(LayoutUnit height) const;
|
|
|
|
struct ComputedMarginValues {
|
|
ComputedMarginValues() { }
|
|
|
|
LayoutUnit m_before;
|
|
LayoutUnit m_after;
|
|
LayoutUnit m_start;
|
|
LayoutUnit m_end;
|
|
};
|
|
struct LogicalExtentComputedValues {
|
|
LogicalExtentComputedValues() { }
|
|
|
|
LayoutUnit m_extent;
|
|
LayoutUnit m_position;
|
|
ComputedMarginValues m_margins;
|
|
};
|
|
// Resolve auto margins in the chosen direction of the containing block so that objects can be pushed to the start, middle or end
|
|
// of the containing block.
|
|
void computeMarginsForDirection(MarginDirection forDirection, const RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd, Length marginStartLength, Length marginStartEnd) const;
|
|
|
|
// Used to resolve margins in the containing block's block-flow direction.
|
|
void computeAndSetBlockDirectionMargins(const RenderBlock* containingBlock);
|
|
|
|
void positionLineBox(InlineBox*);
|
|
|
|
virtual InlineBox* createInlineBox();
|
|
void dirtyLineBoxes(bool fullLayout);
|
|
|
|
// For inline replaced elements, this function returns the inline box that owns us. Enables
|
|
// the replaced RenderObject to quickly determine what line it is contained on and to easily
|
|
// iterate over structures on the line.
|
|
InlineBox* inlineBoxWrapper() const { return m_rareData ? m_rareData->m_inlineBoxWrapper : 0; }
|
|
void setInlineBoxWrapper(InlineBox*);
|
|
void deleteLineBoxWrapper();
|
|
|
|
LayoutUnit containingBlockLogicalHeightForContent(AvailableLogicalHeightType) const;
|
|
|
|
virtual void updateLogicalWidth();
|
|
virtual void updateLogicalHeight();
|
|
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const;
|
|
|
|
void computeLogicalWidth(LogicalExtentComputedValues&) const;
|
|
|
|
virtual LayoutSize intrinsicSize() const { return LayoutSize(); }
|
|
LayoutUnit intrinsicLogicalWidth() const { return intrinsicSize().width(); }
|
|
LayoutUnit intrinsicLogicalHeight() const { return intrinsicSize().height(); }
|
|
virtual LayoutUnit intrinsicContentLogicalHeight() const { return m_intrinsicContentLogicalHeight; }
|
|
|
|
// Whether or not the element shrinks to its intrinsic width (rather than filling the width
|
|
// of a containing block). HTML4 buttons, <select>s, <input>s, legends, and floating/compact elements do this.
|
|
bool sizesLogicalWidthToFitContent(const Length& logicalWidth) const;
|
|
|
|
LayoutUnit computeLogicalWidthUsing(SizeType, const Length& logicalWidth, LayoutUnit availableLogicalWidth, const RenderBlock* containingBlock) const;
|
|
LayoutUnit computeLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
|
|
LayoutUnit computeContentLogicalHeight(const Length& height, LayoutUnit intrinsicContentHeight) const;
|
|
LayoutUnit computeContentLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
|
|
LayoutUnit computeReplacedLogicalWidthUsing(const Length& width) const;
|
|
LayoutUnit computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit logicalWidth, ShouldComputePreferred = ComputeActual) const;
|
|
LayoutUnit computeReplacedLogicalHeightUsing(const Length& height) const;
|
|
LayoutUnit computeReplacedLogicalHeightRespectingMinMaxHeight(LayoutUnit logicalHeight) const;
|
|
|
|
virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const;
|
|
virtual LayoutUnit computeReplacedLogicalHeight() const;
|
|
|
|
// Block flows subclass availableWidth/Height to handle multi column layout (shrinking the width/height available to children when laying out.)
|
|
virtual LayoutUnit availableLogicalWidth() const { return contentLogicalWidth(); }
|
|
virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const;
|
|
LayoutUnit availableLogicalHeightUsing(const Length&, AvailableLogicalHeightType) const;
|
|
|
|
// There are a few cases where we need to refer specifically to the available physical width and available physical height.
|
|
// Relative positioning is one of those cases, since left/top offsets are physical.
|
|
LayoutUnit availableWidth() const { return availableLogicalWidth(); }
|
|
LayoutUnit availableHeight() const { return availableLogicalHeight(IncludeMarginBorderPadding); }
|
|
|
|
virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
|
|
|
|
virtual LayoutRect overflowClipRect(const LayoutPoint& location);
|
|
LayoutRect clipRect(const LayoutPoint& location);
|
|
bool pushContentsClip(PaintInfo&, const LayoutPoint& accumulatedOffset, ContentsClipBehavior);
|
|
void popContentsClip(PaintInfo&, const LayoutPoint& accumulatedOffset);
|
|
|
|
virtual void paintBoxDecorationBackground(PaintInfo&, const LayoutPoint&);
|
|
|
|
// Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
|
|
// that just updates the object's position. If the size does change, the object remains dirty.
|
|
bool tryLayoutDoingPositionedMovementOnly()
|
|
{
|
|
LayoutUnit oldWidth = width();
|
|
updateLogicalWidth();
|
|
// If we shrink to fit our width may have changed, so we still need full layout.
|
|
if (oldWidth != width())
|
|
return false;
|
|
updateLogicalHeight();
|
|
return true;
|
|
}
|
|
|
|
virtual PositionWithAffinity positionForPoint(const LayoutPoint&) override;
|
|
|
|
void removeFloatingOrPositionedChildFromBlockLists();
|
|
|
|
RenderLayer* enclosingFloatPaintingLayer() const;
|
|
|
|
virtual int firstLineBoxBaseline(FontBaselineOrAuto baselineType) const { return -1; }
|
|
virtual int inlineBlockBaseline(LineDirectionMode) const { return -1; } // Returns -1 if we should skip this box when computing the baseline of an inline-block.
|
|
|
|
bool isFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBox(); }
|
|
|
|
virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
|
|
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const override;
|
|
|
|
virtual LayoutUnit offsetLeft() const override;
|
|
virtual LayoutUnit offsetTop() const override;
|
|
|
|
LayoutRect layoutOverflowRectForPropagation() const;
|
|
|
|
bool hasRenderOverflow() const { return m_overflow; }
|
|
bool hasVisualOverflow() const { return m_overflow && !borderBoxRect().contains(m_overflow->visualOverflowRect()); }
|
|
|
|
virtual bool needsPreferredWidthsRecalculation() const;
|
|
virtual void computeIntrinsicRatioInformation(FloatSize& /* intrinsicSize */, double& /* intrinsicRatio */) const { }
|
|
|
|
virtual bool hasRelativeLogicalHeight() const;
|
|
|
|
bool hasSameDirectionAs(const RenderBox* object) const { return style()->direction() == object->style()->direction(); }
|
|
|
|
protected:
|
|
virtual void willBeDestroyed() override;
|
|
|
|
virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) override;
|
|
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
|
|
|
|
void paintBackground(const PaintInfo&, const LayoutRect&, const Color& backgroundColor, BackgroundBleedAvoidance = BackgroundBleedNone);
|
|
void paintFillLayer(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, BackgroundBleedAvoidance, RenderObject* backgroundObject, bool skipBaseColor = false);
|
|
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone, RenderObject* backgroundObject = 0);
|
|
void paintBoxDecorationBackgroundWithRect(PaintInfo&, const LayoutPoint&, const LayoutRect&);
|
|
|
|
// Information extracted from RenderStyle for box painting.
|
|
// These are always needed during box painting and recomputing them takes time.
|
|
struct BoxDecorationData {
|
|
BoxDecorationData(const RenderStyle&);
|
|
|
|
Color backgroundColor;
|
|
bool hasBackground;
|
|
bool hasBorder;
|
|
};
|
|
|
|
BackgroundBleedAvoidance determineBackgroundBleedAvoidance(GraphicsContext*, const BoxDecorationData&) const;
|
|
bool backgroundHasOpaqueTopLayer() const;
|
|
|
|
void computePositionedLogicalWidth(LogicalExtentComputedValues&) const;
|
|
|
|
LayoutUnit computeIntrinsicLogicalWidthUsing(const Length& logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const;
|
|
LayoutUnit computeIntrinsicLogicalContentHeightUsing(const Length& logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const;
|
|
|
|
virtual bool shouldComputeSizeAsReplaced() const { return isReplaced() && !isInlineBlock(); }
|
|
|
|
virtual void mapLocalToContainer(const RenderBox* paintInvalidationContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip) const override;
|
|
|
|
void updateIntrinsicContentLogicalHeight(LayoutUnit intrinsicContentLogicalHeight) const { m_intrinsicContentLogicalHeight = intrinsicContentLogicalHeight; }
|
|
|
|
private:
|
|
void updateTransformationMatrix();
|
|
void updateTransform(const RenderStyle* oldStyle);
|
|
void updateFromStyle();
|
|
|
|
PassRefPtr<HitTestingTransformState> createLocalTransformState(
|
|
RenderLayer* rootLayer, RenderLayer* containerLayer,
|
|
const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
|
|
const HitTestingTransformState* containerTransformState) const;
|
|
bool hitTestNonLayerDescendants(const HitTestRequest& request, HitTestResult& result,
|
|
const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation);
|
|
|
|
void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&);
|
|
|
|
void shrinkToFitWidth(const LayoutUnit availableSpace, const LayoutUnit logicalLeftValue, const LayoutUnit bordersPlusPadding, LogicalExtentComputedValues&) const;
|
|
|
|
bool skipContainingBlockForPercentHeightCalculation(const RenderBox* containingBlock) const;
|
|
|
|
LayoutUnit containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock) const;
|
|
LayoutUnit containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock) const;
|
|
|
|
void computePositionedLogicalHeight(LogicalExtentComputedValues&) const;
|
|
void computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
|
|
LayoutUnit containerLogicalWidth, LayoutUnit bordersPlusPadding,
|
|
const Length& logicalLeft, const Length& logicalRight, const Length& marginLogicalLeft,
|
|
const Length& marginLogicalRight, LogicalExtentComputedValues&) const;
|
|
void computePositionedLogicalHeightUsing(Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
|
|
LayoutUnit containerLogicalHeight, LayoutUnit bordersPlusPadding, LayoutUnit logicalHeight,
|
|
const Length& logicalTop, const Length& logicalBottom, const Length& marginLogicalTop,
|
|
const Length& marginLogicalBottom, LogicalExtentComputedValues&) const;
|
|
|
|
void computePositionedLogicalHeightReplaced(LogicalExtentComputedValues&) const;
|
|
void computePositionedLogicalWidthReplaced(LogicalExtentComputedValues&) const;
|
|
|
|
LayoutUnit fillAvailableMeasure(LayoutUnit availableLogicalWidth) const;
|
|
|
|
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
|
|
|
|
// This function calculates the minimum and maximum preferred widths for an object.
|
|
// These values are used in shrink-to-fit layout systems.
|
|
// These include tables, positioned objects, floats and flexible boxes.
|
|
virtual void computePreferredLogicalWidths() { clearPreferredLogicalWidthsDirty(); }
|
|
|
|
RenderBoxRareData& ensureRareData()
|
|
{
|
|
if (!m_rareData)
|
|
m_rareData = adoptPtr(new RenderBoxRareData());
|
|
return *m_rareData.get();
|
|
}
|
|
|
|
bool logicalHeightComputesAsNone(SizeType) const;
|
|
|
|
bool isBox() const = delete; // This will catch anyone doing an unnecessary check.
|
|
|
|
// The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent).
|
|
LayoutRect m_frameRect;
|
|
|
|
// Our intrinsic height, used for min-height: min-content etc. Maintained by
|
|
// updateLogicalHeight. This is logicalHeight() before it is clamped to
|
|
// min/max.
|
|
mutable LayoutUnit m_intrinsicContentLogicalHeight;
|
|
|
|
protected:
|
|
LayoutBoxExtent m_marginBox;
|
|
|
|
// The preferred logical width of the element if it were to break its lines at every possible opportunity.
|
|
LayoutUnit m_minPreferredLogicalWidth;
|
|
|
|
// The preferred logical width of the element if it never breaks any lines at all.
|
|
LayoutUnit m_maxPreferredLogicalWidth;
|
|
|
|
// Our overflow information.
|
|
OwnPtr<RenderOverflow> m_overflow;
|
|
|
|
// TODO(ojan): Move these two into RenderBoxRareData.
|
|
OwnPtr<TransformationMatrix> m_transform;
|
|
|
|
private:
|
|
OwnPtr<RenderLayer> m_layer;
|
|
OwnPtr<RenderBoxRareData> m_rareData;
|
|
};
|
|
|
|
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBox, isBox());
|
|
|
|
inline RenderBox* RenderBox::previousSiblingBox() const
|
|
{
|
|
return toRenderBox(previousSibling());
|
|
}
|
|
|
|
inline RenderBox* RenderBox::nextSiblingBox() const
|
|
{
|
|
return toRenderBox(nextSibling());
|
|
}
|
|
|
|
inline RenderBox* RenderBox::parentBox() const
|
|
{
|
|
return toRenderBox(parent());
|
|
}
|
|
|
|
inline RenderBox* RenderBox::firstChildBox() const
|
|
{
|
|
return toRenderBox(slowFirstChild());
|
|
}
|
|
|
|
inline RenderBox* RenderBox::lastChildBox() const
|
|
{
|
|
return toRenderBox(slowLastChild());
|
|
}
|
|
|
|
inline void RenderBox::setInlineBoxWrapper(InlineBox* boxWrapper)
|
|
{
|
|
if (boxWrapper) {
|
|
ASSERT(!inlineBoxWrapper());
|
|
// m_inlineBoxWrapper should already be 0. Deleting it is a safeguard against security issues.
|
|
// Otherwise, there will two line box wrappers keeping the reference to this renderer, and
|
|
// only one will be notified when the renderer is getting destroyed. The second line box wrapper
|
|
// will keep a stale reference.
|
|
if (UNLIKELY(inlineBoxWrapper() != 0))
|
|
deleteLineBoxWrapper();
|
|
}
|
|
|
|
ensureRareData().m_inlineBoxWrapper = boxWrapper;
|
|
}
|
|
|
|
} // namespace blink
|
|
|
|
#endif // SKY_ENGINE_CORE_RENDERING_RENDERBOX_H_
|