#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/core/layout/inline/line_breaker.h"
#include "base/containers/adapters.h"
#include "base/ranges/algorithm.h"
#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/block_break_token.h"
#include "third_party/blink/renderer/core/layout/constraint_space.h"
#include "third_party/blink/renderer/core/layout/constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/floats_utils.h"
#include "third_party/blink/renderer/core/layout/fragmentation_utils.h"
#include "third_party/blink/renderer/core/layout/inline/inline_break_token.h"
#include "third_party/blink/renderer/core/layout/inline/inline_cursor.h"
#include "third_party/blink/renderer/core/layout/inline/inline_item_result_ruby_column.h"
#include "third_party/blink/renderer/core/layout/inline/inline_item_segment.h"
#include "third_party/blink/renderer/core/layout/inline/inline_node.h"
#include "third_party/blink/renderer/core/layout/inline/line_break_candidate.h"
#include "third_party/blink/renderer/core/layout/inline/line_info.h"
#include "third_party/blink/renderer/core/layout/inline/ruby_utils.h"
#include "third_party/blink/renderer/core/layout/layout_object_inlines.h"
#include "third_party/blink/renderer/core/layout/layout_text_combine.h"
#include "third_party/blink/renderer/core/layout/length_utils.h"
#include "third_party/blink/renderer/core/layout/logical_fragment.h"
#include "third_party/blink/renderer/core/layout/physical_box_fragment.h"
#include "third_party/blink/renderer/core/layout/positioned_float.h"
#include "third_party/blink/renderer/core/layout/space_utils.h"
#include "third_party/blink/renderer/core/layout/svg/resolved_text_layout_attributes_iterator.h"
#include "third_party/blink/renderer/core/layout/unpositioned_float.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/svg/svg_text_content_element.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker.h"
#include "third_party/blink/renderer/platform/text/bidi_paragraph.h"
#include "third_party/blink/renderer/platform/text/character.h"
namespace blink {
namespace {
inline LineBreakStrictness StrictnessFromLineBreak(LineBreak line_break) { … }
LineBoxStrut ComputeNegativeSideBearings(
const PhysicalBoxFragment& box_fragment) { … }
bool ShouldApplyInlineKerning(const PhysicalBoxFragment& box_fragment) { … }
inline bool IsBreakableSpace(UChar c) { … }
inline bool IsBreakableSpaceOrOtherSeparator(UChar c) { … }
inline bool IsAllBreakableSpaces(const String& string,
unsigned start,
unsigned end) { … }
inline bool IsBidiTrailingSpace(UChar c) { … }
inline LayoutUnit HyphenAdvance(const ComputedStyle& style,
bool is_ltr,
const HyphenResult& hyphen_result,
std::optional<LayoutUnit>& cache) { … }
inline bool IsTrailableItemType(InlineItem::InlineItemType type) { … }
inline bool CanBreakAfterLast(const InlineItemResults& item_results) { … }
inline bool ShouldCreateLineBox(const InlineItemResults& item_results) { … }
inline bool HasUnpositionedFloats(const InlineItemResults& item_results) { … }
LayoutUnit ComputeInlineEndSize(const ConstraintSpace& space,
const ComputedStyle* style) { … }
bool NeedsAccurateEndPosition(const InlineItem& line_end_item) { … }
inline bool NeedsAccurateEndPosition(const LineInfo& line_info,
const InlineItem& line_end_item) { … }
inline void ComputeCanBreakAfter(InlineItemResult* item_result,
bool auto_wrap,
const LazyLineBreakIterator& break_iterator) { … }
inline void RemoveLastItem(LineInfo* line_info) { … }
LayoutUnit ComputeFloatAncestorInlineEndSize(
const ConstraintSpace& space,
const HeapVector<InlineItem>& items,
wtf_size_t item_index) { … }
void CollectCharIndex(void* context,
unsigned char_index,
Glyph,
gfx::Vector2dF,
float,
bool,
CanvasRotationInVertical,
const SimpleFontData*) { … }
inline LayoutTextCombine* MayBeTextCombine(const InlineItem* item) { … }
LayoutUnit MaxLineWidth(const LineInfo& base_line,
const HeapVector<LineInfo, 1>& annotation_lines) { … }
class FastMinTextContext { … };
}
inline bool LineBreaker::ShouldAutoWrap(const ComputedStyle& style) const { … }
void LineBreaker::UpdateAvailableWidth() { … }
LineBreaker::LineBreaker(InlineNode node,
LineBreakerMode mode,
const ConstraintSpace& space,
const LineLayoutOpportunity& line_opportunity,
const LeadingFloats& leading_floats,
const InlineBreakToken* break_token,
const ColumnSpannerPath* column_spanner_path,
ExclusionSpace* exclusion_space)
: … { … }
LineBreaker::~LineBreaker() = default;
void LineBreaker::SetLineOpportunity(
const LineLayoutOpportunity& line_opportunity) { … }
void LineBreaker::OverrideAvailableWidth(LayoutUnit available_width) { … }
void LineBreaker::SetBreakAt(const LineBreakPoint& offset) { … }
inline InlineItemResult* LineBreaker::AddItem(const InlineItem& item,
unsigned end_offset,
LineInfo* line_info) { … }
inline InlineItemResult* LineBreaker::AddItem(const InlineItem& item,
LineInfo* line_info) { … }
InlineItemResult* LineBreaker::AddEmptyItem(const InlineItem& item,
LineInfo* line_info) { … }
inline bool LineBreaker::HandleOverflowIfNeeded(LineInfo* line_info) { … }
void LineBreaker::SetIntrinsicSizeOutputs(
MaxSizeCache* max_size_cache,
bool* depends_on_block_constraints_out) { … }
void LineBreaker::ComputeBaseDirection() { … }
void LineBreaker::RecalcClonedBoxDecorations() { … }
LayoutUnit LineBreaker::AddHyphen(InlineItemResults* item_results,
wtf_size_t index,
InlineItemResult* item_result) { … }
LayoutUnit LineBreaker::AddHyphen(InlineItemResults* item_results,
wtf_size_t index) { … }
LayoutUnit LineBreaker::AddHyphen(InlineItemResults* item_results,
InlineItemResult* item_result) { … }
LayoutUnit LineBreaker::RemoveHyphen(InlineItemResults* item_results) { … }
void LineBreaker::RestoreLastHyphen(InlineItemResults* item_results) { … }
void LineBreaker::FinalizeHyphen(InlineItemResults* item_results) { … }
void LineBreaker::PrepareNextLine(LineInfo* line_info) { … }
void LineBreaker::NextLine(LineInfo* line_info) { … }
void LineBreaker::BreakLine(LineInfo* line_info) { … }
void LineBreaker::ComputeLineLocation(LineInfo* line_info) const { … }
bool LineBreaker::CanBreakAfterAtomicInline(const InlineItem& item) const { … }
bool LineBreaker::CanBreakAfter(const InlineItem& item) const { … }
bool LineBreaker::MayBeAtomicInline(wtf_size_t offset) const { … }
const InlineItem* LineBreaker::TryGetAtomicInlineItemAfter(
const InlineItem& item) const { … }
unsigned LineBreaker::IgnorableBidiControlLength(const InlineItem& item) const { … }
void LineBreaker::HandleText(const InlineItem& item,
const ShapeResult& shape_result,
LineInfo* line_info) { … }
void LineBreaker::SplitTextIntoSegments(const InlineItem& item,
LineInfo* line_info) { … }
bool LineBreaker::ShouldCreateNewSvgSegment() const { … }
LineBreaker::BreakResult LineBreaker::BreakText(
InlineItemResult* item_result,
const InlineItem& item,
const ShapeResult& item_shape_result,
LayoutUnit available_width,
LayoutUnit available_width_with_hyphens,
LineInfo* line_info) { … }
bool LineBreaker::BreakTextAt(InlineItemResult* item_result,
const InlineItem& item,
ShapingLineBreaker& breaker,
LineInfo* line_info) { … }
bool LineBreaker::BreakTextAtPreviousBreakOpportunity(
InlineItemResult* item_result) { … }
bool LineBreaker::HandleTextForFastMinContent(InlineItemResult* item_result,
const InlineItem& item,
const ShapeResult& shape_result,
LineInfo* line_info) { … }
void LineBreaker::HandleEmptyText(const InlineItem& item, LineInfo* line_info) { … }
const ShapeResult* LineBreaker::ShapeText(const InlineItem& item,
unsigned start,
unsigned end,
ShapeOptions options) { … }
void LineBreaker::AppendCandidates(const InlineItemResult& item_result,
const LineInfo& line_info,
LineBreakCandidateContext& context) { … }
bool LineBreaker::CanBreakInside(const LineInfo& line_info) { … }
bool LineBreaker::CanBreakInside(const InlineItemResult& item_result) { … }
const ShapeResultView* LineBreaker::TruncateLineEndResult(
const LineInfo& line_info,
const InlineItemResult& item_result,
unsigned end_offset) { … }
void LineBreaker::UpdateShapeResult(const LineInfo& line_info,
InlineItemResult* item_result) { … }
inline void LineBreaker::HandleTrailingSpaces(const InlineItem& item,
LineInfo* line_info) { … }
void LineBreaker::HandleTrailingSpaces(const InlineItem& item,
const ShapeResult* shape_result,
LineInfo* line_info) { … }
void LineBreaker::RewindTrailingOpenTags(LineInfo* line_info) { … }
void LineBreaker::RemoveTrailingCollapsibleSpace(LineInfo* line_info) { … }
LayoutUnit LineBreaker::TrailingCollapsibleSpaceWidth(LineInfo* line_info) { … }
void LineBreaker::ComputeTrailingCollapsibleSpace(LineInfo* line_info) { … }
void LineBreaker::SplitTrailingBidiPreservedSpace(LineInfo* line_info) { … }
void LineBreaker::HandleForcedLineBreak(const InlineItem* item,
LineInfo* line_info) { … }
void LineBreaker::HandleControlItem(const InlineItem& item,
LineInfo* line_info) { … }
void LineBreaker::HandleBidiControlItem(const InlineItem& item,
LineInfo* line_info) { … }
void LineBreaker::HandleAtomicInline(const InlineItem& item,
LineInfo* line_info) { … }
void LineBreaker::ComputeMinMaxContentSizeForBlockChild(
const InlineItem& item,
InlineItemResult* item_result) { … }
void LineBreaker::HandleBlockInInline(const InlineItem& item,
const BlockBreakToken* block_break_token,
LineInfo* line_info) { … }
bool LineBreaker::HandleRuby(LineInfo* line_info, LayoutUnit retry_size) { … }
bool LineBreaker::IsMonolithicRuby(
const LineInfo& base_line,
const HeapVector<LineInfo, 1>& annotation_line_list) const { … }
LineInfo LineBreaker::CreateSubLineInfo(
InlineItemTextIndex start,
wtf_size_t end_item_index,
LineBreakerMode mode,
LayoutUnit limit,
WhitespaceState initial_whitespace_state) { … }
InlineItemResult* LineBreaker::AddRubyColumnResult(
const InlineItem& item,
const LineInfo& base_line_info,
const HeapVector<LineInfo, 1>& annotation_line_list,
const Vector<AnnotationBreakTokenData, 1>& annotation_data_list,
LayoutUnit ruby_size,
bool is_continuation,
LineInfo& line_info) { … }
bool LineBreaker::CanBreakAfterRubyColumn(
const InlineItemResult& column_result,
wtf_size_t column_end_item_index) const { … }
bool LineBreaker::ShouldPushFloatAfterLine(
UnpositionedFloat* unpositioned_float,
LineInfo* line_info) { … }
void LineBreaker::HandleFloat(const InlineItem& item,
const BlockBreakToken* float_break_token,
LineInfo* line_info) { … }
void LineBreaker::UpdateLineOpportunity() { … }
void LineBreaker::RewindFloats(unsigned new_end,
LineInfo& line_info,
InlineItemResults& item_results) { … }
void LineBreaker::HandleInitialLetter(const InlineItem& item,
LineInfo* line_info) { … }
void LineBreaker::HandleOutOfFlowPositioned(const InlineItem& item,
LineInfo* line_info) { … }
bool LineBreaker::ComputeOpenTagResult(const InlineItem& item,
const ConstraintSpace& constraint_space,
bool is_in_svg_text,
InlineItemResult* item_result) { … }
void LineBreaker::HandleOpenTag(const InlineItem& item, LineInfo* line_info) { … }
void LineBreaker::HandleCloseTag(const InlineItem& item, LineInfo* line_info) { … }
void LineBreaker::HandleOverflow(LineInfo* line_info) { … }
void LineBreaker::RetryAfterOverflow(LineInfo* line_info,
InlineItemResults* item_results) { … }
void LineBreaker::RewindOverflow(unsigned new_end, LineInfo* line_info) { … }
void LineBreaker::Rewind(unsigned new_end, LineInfo* line_info) { … }
const ComputedStyle& LineBreaker::ComputeCurrentStyle(
unsigned item_result_index,
LineInfo* line_info) const { … }
void LineBreaker::SetCurrentStyle(const ComputedStyle& style) { … }
void LineBreaker::SetCurrentStyleForce(const ComputedStyle& style) { … }
bool LineBreaker::IsPreviousItemOfType(InlineItem::InlineItemType type) { … }
void LineBreaker::MoveToNextOf(const InlineItem& item) { … }
void LineBreaker::MoveToNextOf(const InlineItemResult& item_result) { … }
void LineBreaker::SetInputRange(InlineItemTextIndex start,
wtf_size_t end_item_index,
WhitespaceState initial_whitespace_state,
const LineBreaker* parent) { … }
const InlineBreakToken* LineBreaker::CreateBreakToken(
const LineInfo& line_info) { … }
}