diff options
Diffstat (limited to 'Source/WebCore/rendering/InlineBox.h')
-rw-r--r-- | Source/WebCore/rendering/InlineBox.h | 145 |
1 files changed, 76 insertions, 69 deletions
diff --git a/Source/WebCore/rendering/InlineBox.h b/Source/WebCore/rendering/InlineBox.h index fb4c58cf7..85cd7662e 100644 --- a/Source/WebCore/rendering/InlineBox.h +++ b/Source/WebCore/rendering/InlineBox.h @@ -18,11 +18,12 @@ * */ -#ifndef InlineBox_h -#define InlineBox_h +#pragma once #include "RenderBoxModelObject.h" -#include "TextDirection.h" +#include "RenderText.h" +#include "TextFlags.h" +#include <wtf/TypeCasts.h> namespace WebCore { @@ -33,16 +34,19 @@ class RootInlineBox; // InlineBox represents a rectangle that occurs on a line. It corresponds to // some RenderObject (i.e., it represents a portion of that RenderObject). class InlineBox { + WTF_MAKE_FAST_ALLOCATED; public: virtual ~InlineBox(); + void assertNotDeleted() const; + virtual void deleteLine() = 0; virtual void extractLine() = 0; virtual void attachLine() = 0; virtual bool isLineBreak() const { return renderer().isLineBreak(); } - virtual void adjustPosition(float dx, float dy); + WEBCORE_EXPORT virtual void adjustPosition(float dx, float dy); void adjustLogicalPosition(float deltaLogicalLeft, float deltaLogicalTop) { if (isHorizontal()) @@ -66,15 +70,14 @@ public: } virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) = 0; - virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) = 0; + virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) = 0; -public: -#ifndef NDEBUG - void showTreeForThis() const; +#if ENABLE(TREE_DEBUGGING) + void showNodeTreeForThis() const; void showLineTreeForThis() const; - virtual void showBox(int = 0) const; - virtual void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0, int = 0) const; + virtual void showLineTreeAndMark(const InlineBox* markedBox, int depth) const; + virtual void showLineBox(bool mark, int depth) const; virtual const char* boxName() const; #endif @@ -85,11 +88,9 @@ public: virtual bool isInlineFlowBox() const { return false; } virtual bool isInlineTextBox() const { return false; } virtual bool isRootInlineBox() const { return false; } -#if ENABLE(SVG) virtual bool isSVGInlineTextBox() const { return false; } virtual bool isSVGInlineFlowBox() const { return false; } virtual bool isSVGRootInlineBox() const { return false; } -#endif bool hasVirtualLogicalHeight() const { return m_bitfields.hasVirtualLogicalHeight(); } void setHasVirtualLogicalHeight() { m_bitfields.setHasVirtualLogicalHeight(true); } @@ -149,6 +150,7 @@ public: InlineFlowBox* parent() const { + assertNotDeleted(); ASSERT_WITH_SECURITY_IMPLICATION(!m_hasBadParent); return m_parent; } @@ -185,10 +187,6 @@ public: else setY(left); } - int pixelSnappedLogicalLeft() const { return logicalLeft(); } - int pixelSnappedLogicalRight() const { return ceilf(logicalRight()); } - int pixelSnappedLogicalTop() const { return logicalTop(); } - int pixelSnappedLogicalBottom() const { return ceilf(logicalBottom()); } // The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line. float logicalTop() const { return isHorizontal() ? m_topLeft.y() : m_topLeft.x(); } @@ -209,12 +207,13 @@ public: float logicalHeight() const; FloatRect logicalFrameRect() const { return isHorizontal() ? FloatRect(m_topLeft.x(), m_topLeft.y(), m_logicalWidth, logicalHeight()) : FloatRect(m_topLeft.y(), m_topLeft.x(), m_logicalWidth, logicalHeight()); } + FloatRect frameRect() const { return FloatRect(topLeft(), size()); } - virtual int baselinePosition(FontBaseline baselineType) const; - virtual LayoutUnit lineHeight() const; + WEBCORE_EXPORT virtual int baselinePosition(FontBaseline baselineType) const; + WEBCORE_EXPORT virtual LayoutUnit lineHeight() const; - virtual int caretMinOffset() const; - virtual int caretMaxOffset() const; + WEBCORE_EXPORT virtual int caretMinOffset() const; + WEBCORE_EXPORT virtual int caretMaxOffset() const; unsigned char bidiLevel() const { return m_bitfields.bidiEmbeddingLevel(); } void setBidiLevel(unsigned char level) { m_bitfields.setBidiEmbeddingLevel(level); } @@ -228,20 +227,19 @@ public: bool isDirty() const { return m_bitfields.dirty(); } virtual void markDirty(bool dirty = true) { m_bitfields.setDirty(dirty); } - virtual void dirtyLineBoxes(); + WEBCORE_EXPORT virtual void dirtyLineBoxes(); - virtual RenderObject::SelectionState selectionState(); + WEBCORE_EXPORT virtual RenderObject::SelectionState selectionState(); - virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const; + WEBCORE_EXPORT virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const; // visibleLeftEdge, visibleRightEdge are in the parent's coordinate system. - virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool&); + WEBCORE_EXPORT virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool&); #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED void setHasBadParent(); + void invalidateParentChildList(); #endif - int expansion() const { return m_bitfields.expansion(); } - bool visibleToHitTesting() const { return renderer().style().visibility() == VISIBLE && renderer().style().pointerEvents() != PE_NONE; } const RenderStyle& lineStyle() const { return m_bitfields.firstLine() ? renderer().firstLineStyle() : renderer().style(); } @@ -251,9 +249,9 @@ public: // Use with caution! The type is not checked! RenderBoxModelObject* boxModelObject() const { - if (!m_renderer.isText()) - return &toRenderBoxModelObject(m_renderer); - return 0; + if (!is<RenderText>(m_renderer)) + return &downcast<RenderBoxModelObject>(m_renderer); + return nullptr; } FloatPoint locationIncludingFlipping(); @@ -268,17 +266,30 @@ public: bool dirOverride() const { return m_bitfields.dirOverride(); } void setDirOverride(bool dirOverride) { m_bitfields.setDirOverride(dirOverride); } + void setExpansion(float newExpansion) + { + m_logicalWidth -= m_expansion; + m_expansion = newExpansion; + m_logicalWidth += m_expansion; + } + void setExpansionWithoutGrowing(float newExpansion) + { + ASSERT(!m_expansion); + m_expansion = newExpansion; + } + float expansion() const { return m_expansion; } + private: - InlineBox* m_next; // The next element on the same line as us. - InlineBox* m_prev; // The previous element on the same line as us. + InlineBox* m_next { nullptr }; // The next element on the same line as us. + InlineBox* m_prev { nullptr }; // The previous element on the same line as us. - InlineFlowBox* m_parent; // The box that contains us. + InlineFlowBox* m_parent { nullptr }; // The box that contains us. RenderObject& m_renderer; public: FloatPoint m_topLeft; - float m_logicalWidth; + float m_logicalWidth { 0 }; #define ADD_BOOLEAN_BITFIELD(name, Name) \ private:\ @@ -299,13 +310,15 @@ public: , m_isHorizontal(isHorizontal) , m_endsWithBreak(false) , m_hasSelectedChildrenOrCanHaveLeadingExpansion(false) + , m_canHaveTrailingExpansion(false) , m_knownToHaveNoOverflow(true) , m_hasEllipsisBoxOrHyphen(false) , m_dirOverride(false) , m_behavesLikeText(false) + , m_forceTrailingExpansion(false) + , m_forceLeadingExpansion(false) , m_determinedIfNextOnLineExists(false) , m_nextOnLineExists(false) - , m_expansion(0) { } @@ -329,11 +342,14 @@ public: ADD_BOOLEAN_BITFIELD(endsWithBreak, EndsWithBreak); // Whether the line ends with a <br>. // shared between RootInlineBox and InlineTextBox ADD_BOOLEAN_BITFIELD(hasSelectedChildrenOrCanHaveLeadingExpansion, HasSelectedChildrenOrCanHaveLeadingExpansion); + ADD_BOOLEAN_BITFIELD(canHaveTrailingExpansion, CanHaveTrailingExpansion); ADD_BOOLEAN_BITFIELD(knownToHaveNoOverflow, KnownToHaveNoOverflow); ADD_BOOLEAN_BITFIELD(hasEllipsisBoxOrHyphen, HasEllipsisBoxOrHyphen); // for InlineTextBox ADD_BOOLEAN_BITFIELD(dirOverride, DirOverride); ADD_BOOLEAN_BITFIELD(behavesLikeText, BehavesLikeText); // Whether or not this object represents text with a non-zero height. Includes non-image list markers, text boxes, br. + ADD_BOOLEAN_BITFIELD(forceTrailingExpansion, ForceTrailingExpansion); + ADD_BOOLEAN_BITFIELD(forceLeadingExpansion, ForceLeadingExpansion); private: mutable unsigned m_determinedIfNextOnLineExists : 1; @@ -348,34 +364,20 @@ public: public: bool nextOnLineExists() const { return m_nextOnLineExists; } void setNextOnLineExists(bool nextOnLineExists) const { m_nextOnLineExists = nextOnLineExists; } - - private: - signed m_expansion : 12; // for justified text - - public: - signed expansion() const { return m_expansion; } - void setExpansion(signed expansion) { m_expansion = expansion; } }; #undef ADD_BOOLEAN_BITFIELD private: + float m_expansion { 0 }; InlineBoxBitfields m_bitfields; protected: explicit InlineBox(RenderObject& renderer) - : m_next(nullptr) - , m_prev(nullptr) - , m_parent(nullptr) - , m_renderer(renderer) - , m_logicalWidth(0) -#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED - , m_hasBadParent(false) -#endif + : m_renderer(renderer) { } - InlineBox(RenderObject& renderer, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed, - bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent) + InlineBox(RenderObject& renderer, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed, bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent) : m_next(next) , m_prev(prev) , m_parent(parent) @@ -383,9 +385,6 @@ protected: , m_topLeft(topLeft) , m_logicalWidth(logicalWidth) , m_bitfields(firstLine, constructed, dirty, extracted, isHorizontal) -#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED - , m_hasBadParent(false) -#endif { } @@ -402,40 +401,48 @@ protected: void setHasHyphen(bool hasHyphen) { m_bitfields.setHasEllipsisBoxOrHyphen(hasHyphen); } bool canHaveLeadingExpansion() const { return m_bitfields.hasSelectedChildrenOrCanHaveLeadingExpansion(); } void setCanHaveLeadingExpansion(bool canHaveLeadingExpansion) { m_bitfields.setHasSelectedChildrenOrCanHaveLeadingExpansion(canHaveLeadingExpansion); } - signed expansion() { return m_bitfields.expansion(); } - void setExpansion(signed expansion) { m_bitfields.setExpansion(expansion); } + bool canHaveTrailingExpansion() const { return m_bitfields.canHaveTrailingExpansion(); } + void setCanHaveTrailingExpansion(bool canHaveTrailingExpansion) { m_bitfields.setCanHaveTrailingExpansion(canHaveTrailingExpansion); } + void setForceTrailingExpansion() { m_bitfields.setForceTrailingExpansion(true); } + bool forceTrailingExpansion() const { return m_bitfields.forceTrailingExpansion(); } + void setForceLeadingExpansion() { m_bitfields.setForceLeadingExpansion(true); } + bool forceLeadingExpansion() const { return m_bitfields.forceLeadingExpansion(); } // For InlineFlowBox and InlineTextBox bool extracted() const { return m_bitfields.extracted(); } #if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED +protected: + bool m_isEverInChildList { true }; private: - bool m_hasBadParent; + static constexpr unsigned deletionSentinelNotDeletedValue = 0xF0F0F0F0U; + static constexpr unsigned deletionSentinelDeletedValue = 0xF0DEADF0U; + unsigned m_deletionSentinel { deletionSentinelNotDeletedValue }; + bool m_hasBadParent { false }; #endif }; -#define INLINE_BOX_OBJECT_TYPE_CASTS(ToValueTypeName, predicate) \ - TYPE_CASTS_BASE(ToValueTypeName, InlineBox, object, object->predicate, object.predicate) - #if ASSERT_WITH_SECURITY_IMPLICATION_DISABLED + inline InlineBox::~InlineBox() { } -#endif -#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED -inline void InlineBox::setHasBadParent() +inline void InlineBox::assertNotDeleted() const { - m_hasBadParent = true; } + #endif } // namespace WebCore -#ifndef NDEBUG -// Outside the WebCore namespace for ease of invocation from gdb. -void showTree(const WebCore::InlineBox*); +#define SPECIALIZE_TYPE_TRAITS_INLINE_BOX(ToValueTypeName, predicate) \ +SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \ + static bool isType(const WebCore::InlineBox& box) { return box.predicate; } \ +SPECIALIZE_TYPE_TRAITS_END() + +#if ENABLE(TREE_DEBUGGING) +// Outside the WebCore namespace for ease of invocation from the debugger. +void showNodeTree(const WebCore::InlineBox*); void showLineTree(const WebCore::InlineBox*); #endif - -#endif // InlineBox_h |