InlineContentBreaker.h [plain text]
#pragma once
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "LayoutUnits.h"
namespace WebCore {
class RenderStyle;
namespace Layout {
class InlineItem;
struct TrailingTextContent;
class InlineContentBreaker {
public:
struct PartialRun {
size_t length { 0 };
InlineLayoutUnit logicalWidth { 0 };
Optional<InlineLayoutUnit> hyphenWidth { };
};
enum class IsEndOfLine { No, Yes };
struct Result {
enum class Action {
Keep, Break, Wrap, WrapWithHyphen, RevertToLastWrapOpportunity, RevertToLastNonOverflowingWrapOpportunity };
struct PartialTrailingContent {
size_t trailingRunIndex { 0 };
Optional<PartialRun> partialRun; };
Action action { Action::Keep };
IsEndOfLine isEndOfLine { IsEndOfLine::No };
Optional<PartialTrailingContent> partialTrailingContent { };
const InlineItem* lastWrapOpportunityItem { nullptr };
};
struct ContinuousContent {
InlineLayoutUnit logicalWidth() const { return m_logicalWidth; }
InlineLayoutUnit collapsibleLogicalWidth() const { return m_collapsibleLogicalWidth; }
InlineLayoutUnit nonCollapsibleLogicalWidth() const { return logicalWidth() - collapsibleLogicalWidth(); }
bool hasTrailingCollapsibleContent() const { return !!collapsibleLogicalWidth(); }
bool isFullyCollapsible() const { return logicalWidth() == collapsibleLogicalWidth(); }
void append(const InlineItem&, InlineLayoutUnit logicalWidth, Optional<InlineLayoutUnit> collapsibleWidth);
void reset();
struct Run {
Run(const InlineItem&, InlineLayoutUnit logicalWidth);
Run(const Run&);
Run& operator=(const Run&);
const InlineItem& inlineItem;
InlineLayoutUnit logicalWidth { 0 };
};
using RunList = Vector<Run, 3>;
const RunList& runs() const { return m_runs; }
private:
RunList m_runs;
InlineLayoutUnit m_logicalWidth { 0 };
InlineLayoutUnit m_collapsibleLogicalWidth { 0 };
};
struct LineStatus {
InlineLayoutUnit contentLogicalRight { 0 };
InlineLayoutUnit availableWidth { 0 };
InlineLayoutUnit collapsibleWidth { 0 };
Optional<InlineLayoutUnit> trailingSoftHyphenWidth;
bool hasFullyCollapsibleTrailingRun { false };
bool isEmpty { true };
};
Result processInlineContent(const ContinuousContent&, const LineStatus&);
void setHyphenationDisabled() { n_hyphenationIsDisabled = true; }
private:
Result processOverflowingContent(const ContinuousContent&, const LineStatus&) const;
Optional<TrailingTextContent> processOverflowingTextContent(const ContinuousContent&, const LineStatus&) const;
Optional<PartialRun> tryBreakingTextRun(const ContinuousContent::Run& overflowRun, InlineLayoutUnit logicalLeft, InlineLayoutUnit availableWidth) const;
enum class WordBreakRule {
NoBreak,
AtArbitraryPosition,
OnlyHyphenationAllowed
};
WordBreakRule wordBreakBehavior(const RenderStyle&) const;
bool shouldKeepEndOfLineWhitespace(const ContinuousContent&) const;
bool n_hyphenationIsDisabled { false };
bool m_hasWrapOpportunityAtPreviousPosition { false };
};
inline InlineContentBreaker::ContinuousContent::Run::Run(const InlineItem& inlineItem, InlineLayoutUnit logicalWidth)
: inlineItem(inlineItem)
, logicalWidth(logicalWidth)
{
}
inline InlineContentBreaker::ContinuousContent::Run::Run(const Run& other)
: inlineItem(other.inlineItem)
, logicalWidth(other.logicalWidth)
{
}
}
}
#endif