InlineFormattingContext.h [plain text]
#pragma once
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
#include "DisplayBox.h"
#include "FormattingContext.h"
#include "InlineRun.h"
#include <wtf/IsoMalloc.h>
namespace WebCore {
namespace Layout {
class InlineFormattingState;
class InlineRunProvider;
class InlineFormattingContext : public FormattingContext {
WTF_MAKE_ISO_ALLOCATED(InlineFormattingContext);
public:
InlineFormattingContext(const Box& formattingContextRoot, FormattingState&);
void layout() const override;
private:
class Line {
public:
void init(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimalHeight);
void close();
void appendContent(const InlineRunProvider::Run&, const LayoutSize&);
void adjustLogicalLeft(LayoutUnit delta);
void adjustLogicalRight(LayoutUnit delta);
bool hasContent() const { return !m_inlineRuns.isEmpty(); }
bool isClosed() const { return m_closed; }
bool isFirstLine() const { return m_isFirstLine; }
Vector<InlineRun>& runs() { return m_inlineRuns; }
LayoutUnit contentLogicalRight() const;
LayoutUnit contentLogicalLeft() const { return m_logicalRect.left(); }
LayoutUnit availableWidth() const { return m_availableWidth; }
Optional<InlineRunProvider::Run::Type> lastRunType() const { return m_lastRunType; }
LayoutUnit logicalTop() const { return m_logicalRect.top(); }
LayoutUnit logicalBottom() const { return m_logicalRect.bottom(); }
LayoutUnit logicalHeight() const { return logicalBottom() - logicalTop(); }
private:
struct TrailingTrimmableContent {
LayoutUnit width;
unsigned length;
};
Optional<TrailingTrimmableContent> m_trailingTrimmableContent;
Optional<InlineRunProvider::Run::Type> m_lastRunType;
bool m_lastRunCanExpand { false };
Display::Box::Rect m_logicalRect;
LayoutUnit m_availableWidth;
Vector<InlineRun> m_inlineRuns;
bool m_isFirstLine { true };
bool m_closed { true };
};
enum class IsLastLine { No, Yes };
class Geometry : public FormattingContext::Geometry {
public:
static HeightAndMargin inlineBlockHeightAndMargin(const LayoutState&, const Box&);
static WidthAndMargin inlineBlockWidthAndMargin(LayoutState&, const Box&);
static void alignRuns(TextAlignMode, Line&, IsLastLine);
static void computeExpansionOpportunities(Line&, const InlineRunProvider::Run&, InlineRunProvider::Run::Type lastRunType);
static LayoutUnit runWidth(const InlineContent&, const InlineItem&, ItemPosition from, unsigned length, LayoutUnit contentLogicalLeft);
private:
static void justifyRuns(Line&);
};
void layoutInlineContent(const InlineRunProvider&) const;
void initializeNewLine(Line&) const;
void closeLine(Line&, IsLastLine) const;
void appendContentToLine(Line&, const InlineRunProvider::Run&, const LayoutSize&) const;
void postProcessInlineRuns(Line&, IsLastLine) const;
void createFinalRuns(Line&) const;
void splitInlineRunIfNeeded(const InlineRun&, InlineRuns& splitRuns) const;
void layoutFormattingContextRoot(const Box&) const;
void computeWidthAndHeightForReplacedInlineBox(const Box&) const;
void computeHeightAndMargin(const Box&) const;
void computeWidthAndMargin(const Box&) const;
void computeFloatPosition(const FloatingContext&, Line&, const Box&) const;
void placeInFlowPositionedChildren(unsigned firstRunIndex) const;
void collectInlineContent(InlineRunProvider&) const;
void collectInlineContentForSubtree(const Box& root, InlineRunProvider&) const;
InstrinsicWidthConstraints instrinsicWidthConstraints() const override;
InlineFormattingState& inlineFormattingState() const { return downcast<InlineFormattingState>(formattingState()); }
};
}
}
#endif