chromium/third_party/blink/renderer/core/layout/inline/inline_items_builder.cc

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/core/layout/inline/inline_items_builder.h"

#include <type_traits>

#include "base/containers/adapters.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/html/html_area_element.h"
#include "third_party/blink/renderer/core/layout/inline/inline_item_span.h"
#include "third_party/blink/renderer/core/layout/inline/inline_node.h"
#include "third_party/blink/renderer/core/layout/inline/inline_node_data.h"
#include "third_party/blink/renderer/core/layout/inline/offset_mapping_builder.h"
#include "third_party/blink/renderer/core/layout/inline/transformed_string.h"
#include "third_party/blink/renderer/core/layout/layout_inline.h"
#include "third_party/blink/renderer/core/layout/layout_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h"
#include "third_party/blink/renderer/platform/wtf/text/text_offset_map.h"

namespace blink {
class HTMLAreaElement;

template <typename MappingBuilder>
InlineItemsBuilderTemplate<MappingBuilder>::InlineItemsBuilderTemplate(
    LayoutBlockFlow* block_flow,
    HeapVector<InlineItem>* items,
    const String& previous_text_content,
    const SvgTextChunkOffsets* chunk_offsets)
    :{}

// Returns true if items builder is used for other than offset mapping.
template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::NeedsBoxInfo() {}

template <typename MappingBuilder>
InlineItemsBuilderTemplate<MappingBuilder>::~InlineItemsBuilderTemplate() {}

template <typename MappingBuilder>
String InlineItemsBuilderTemplate<MappingBuilder>::ToString() {}

namespace {

// TODO(curbug.com/324111880): We can't support forced-breaks in ruby-base boxes
// until ruby-columns become actually line-breakable. So we replace
// forced-breaks in ruby-base boxes with spaces for now. This flag should be
// removed before shipping RubyLineBreakable.
constexpr bool kDisableForcedBreakInRubyColumn =;

// The spec turned into a discussion that may change. Put this logic on hold
// until CSSWG resolves the issue.
// https://github.com/w3c/csswg-drafts/issues/337
#define SEGMENT_BREAK_TRANSFORMATION_FOR_EAST_ASIAN_WIDTH

#if SEGMENT_BREAK_TRANSFORMATION_FOR_EAST_ASIAN_WIDTH
// Determine "Ambiguous" East Asian Width is Wide or Narrow.
// Unicode East Asian Width
// http://unicode.org/reports/tr11/
bool IsAmbiguosEastAsianWidthWide(const ComputedStyle* style) {
  UScriptCode script = style->GetFontDescription().GetScript();
  return script == USCRIPT_KATAKANA_OR_HIRAGANA ||
         script == USCRIPT_SIMPLIFIED_HAN || script == USCRIPT_TRADITIONAL_HAN;
}

// Determine if a character has "Wide" East Asian Width.
bool IsEastAsianWidthWide(UChar32 c, const ComputedStyle* style) {
  UEastAsianWidth eaw = static_cast<UEastAsianWidth>(
      u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH));
  return eaw == U_EA_WIDE || eaw == U_EA_FULLWIDTH || eaw == U_EA_HALFWIDTH ||
         (eaw == U_EA_AMBIGUOUS && style &&
          IsAmbiguosEastAsianWidthWide(style));
}
#endif

// Determine whether a newline should be removed or not.
// CSS Text, Segment Break Transformation Rules
// https://drafts.csswg.org/css-text-3/#line-break-transform
bool ShouldRemoveNewlineSlow(const StringBuilder& before,
                             unsigned space_index,
                             const ComputedStyle* before_style,
                             const StringView& after,
                             const ComputedStyle* after_style) {}

bool ShouldRemoveNewline(const StringBuilder& before,
                         unsigned space_index,
                         const ComputedStyle* before_style,
                         const StringView& after,
                         const ComputedStyle* after_style) {}

inline InlineItem& AppendItem(HeapVector<InlineItem>* items,
                              InlineItem::InlineItemType type,
                              unsigned start,
                              unsigned end,
                              LayoutObject* layout_object) {}

inline bool ShouldIgnore(UChar c) {}

// Characters needing a separate control item than other text items.
// It makes the line breaker easier to handle.
inline bool IsControlItemCharacter(UChar c) {}

// Find the end of the collapsible spaces.
// Returns whether this space run contains a newline or not, because it changes
// the collapsing behavior.
inline bool MoveToEndOfCollapsibleSpaces(const StringView& string,
                                         unsigned* offset,
                                         UChar* c) {}

// Find the last item to compute collapsing with. Opaque items such as
// open/close or bidi controls are ignored.
// Returns nullptr if there were no previous items.
InlineItem* LastItemToCollapseWith(HeapVector<InlineItem>* items) {}

inline bool IsNonOrc16BitCharacter(UChar ch) {}

}  // anonymous namespace

template <typename MappingBuilder>
InlineItemsBuilderTemplate<MappingBuilder>::BoxInfo::BoxInfo(
    unsigned item_index,
    const InlineItem& item)
    :{}

// True if this inline box should create a box fragment when it has |child|.
template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::BoxInfo::
    ShouldCreateBoxFragmentForChild(const BoxInfo& child) const {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::BoxInfo::
    SetShouldCreateBoxFragment(HeapVector<InlineItem>* items) {}

// Append a string as a text item.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendTextItem(
    const TransformedString& transformed,
    LayoutText* layout_object) {}

template <typename MappingBuilder>
InlineItem& InlineItemsBuilderTemplate<MappingBuilder>::AppendTextItem(
    InlineItem::InlineItemType type,
    const TransformedString& transformed,
    LayoutText* layout_object) {}

// Empty text items are not needed for the layout purposes, but all LayoutObject
// must be captured in InlineItemsData to maintain states of LayoutObject in
// this inline formatting context.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendEmptyTextItem(
    LayoutText* layout_object) {}

// Same as AppendBreakOpportunity, but mark the item as IsGenerated().
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::
    AppendGeneratedBreakOpportunity(LayoutObject* layout_object) {}

template <typename MappingBuilder>
inline void InlineItemsBuilderTemplate<MappingBuilder>::DidAppendForcedBreak() {}

template <typename MappingBuilder>
inline void InlineItemsBuilderTemplate<MappingBuilder>::DidAppendTextReusing(
    const InlineItem& item) {}

template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::AppendTextReusing(
    const InlineNodeData& original_data,
    LayoutText* layout_text) {}

template <>
bool InlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendTextReusing(
    const InlineNodeData&,
    LayoutText*) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendText(
    LayoutText* layout_text,
    const InlineNodeData* previous_data) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendText(
    const String& string,
    LayoutText* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendText(
    const TransformedString& transformed,
    LayoutText& layout_object) {}

template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::AppendTextChunks(
    const TransformedString& transformed,
    LayoutText& layout_text) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendTransformedString(
    const TransformedString& transformed,
    const LayoutText& layout_text) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendCollapseWhitespace(
    const TransformedString& transformed,
    const ComputedStyle* style,
    LayoutText* layout_object) {}

template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::
    ShouldInsertBreakOpportunityAfterLeadingPreservedSpaces(
        StringView string,
        const ComputedStyle& style,
        unsigned index) const {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::
    InsertBreakOpportunityAfterLeadingPreservedSpaces(
        const TransformedString& transformed,
        const ComputedStyle& style,
        LayoutText* layout_object,
        unsigned* start) {}

// TODO(yosin): We should remove |style| and |string| parameter because of
// except for testing, we can get them from |LayoutText|.
// Even when without whitespace collapsing, control characters (newlines and
// tabs) are in their own control items to make the line breaker not special.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendPreserveWhitespace(
    const TransformedString& transformed,
    const ComputedStyle* style,
    LayoutText* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendPreserveNewline(
    const TransformedString& transformed,
    const ComputedStyle* style,
    LayoutText* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendForcedBreak(
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::
    AppendForcedBreakCollapseWhitespace(LayoutObject* layout_object) {}

template <typename MappingBuilder>
InlineItem& InlineItemsBuilderTemplate<MappingBuilder>::AppendBreakOpportunity(
    LayoutObject* layout_object) {}

// The logic is similar to AppendForcedBreak().
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::ExitAndEnterSvgTextChunk(
    LayoutText& layout_text) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::EnterSvgTextChunk(
    const ComputedStyle* style) {}

template <typename MappingBuilder>
InlineItem& InlineItemsBuilderTemplate<MappingBuilder>::Append(
    InlineItem::InlineItemType type,
    UChar character,
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendAtomicInline(
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendBlockInInline(
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendFloating(
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendOutOfFlowPositioned(
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
InlineItem& InlineItemsBuilderTemplate<MappingBuilder>::AppendOpaque(
    InlineItem::InlineItemType type,
    UChar character,
    LayoutObject* layout_object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::AppendOpaque(
    InlineItem::InlineItemType type,
    LayoutObject* layout_object) {}

// Removes the collapsible space at the end of |text_| if exists.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<
    MappingBuilder>::RemoveTrailingCollapsibleSpaceIfExists() {}

// Removes the collapsible space at the end of the specified item.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::RemoveTrailingCollapsibleSpace(
    InlineItem* item) {}

// Restore removed collapsible space at the end of items.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<
    MappingBuilder>::RestoreTrailingCollapsibleSpaceIfRemoved() {}

// Restore removed collapsible space at the end of the specified item.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<
    MappingBuilder>::RestoreTrailingCollapsibleSpace(InlineItem* item) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::EnterBidiContext(
    LayoutObject* node,
    UChar enter,
    UChar exit) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::EnterBidiContext(
    LayoutObject* node,
    const ComputedStyle* style,
    UChar ltr_enter,
    UChar rtl_enter,
    UChar exit) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::EnterBlock(
    const ComputedStyle* style) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::EnterInline(
    LayoutInline* node) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::ExitBlock() {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::ExitInline(
    LayoutObject* node) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::Exit(LayoutObject* node) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::DidFinishCollectInlines(
    InlineNodeData* data) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::SetHasInititialLetterBox() {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::SetIsSymbolMarker() {}

template <typename MappingBuilder>
bool InlineItemsBuilderTemplate<MappingBuilder>::ShouldUpdateLayoutObject()
    const {}

// Ensure this LayoutObject IsInLayoutNGInlineFormattingContext and does not
// have associated NGPaintFragment.
template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::ClearInlineFragment(
    LayoutObject* object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::ClearNeedsLayout(
    LayoutObject* object) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::UpdateShouldCreateBoxFragment(
    LayoutInline* object) {}

// |OffsetMappingBuilder| doesn't change states of |LayoutObject|
template <>
bool InlineItemsBuilderTemplate<
    OffsetMappingBuilder>::ShouldUpdateLayoutObject() const {}

// |OffsetMappingBuilder| doesn't change states of |LayoutObject|
template <>
void InlineItemsBuilderTemplate<OffsetMappingBuilder>::ClearNeedsLayout(
    LayoutObject* object) {}

// |OffsetMappingBuilder| doesn't change states of |LayoutObject|
template <>
void InlineItemsBuilderTemplate<OffsetMappingBuilder>::ClearInlineFragment(
    LayoutObject*) {}

// |OffsetMappingBuilder| doesn't change states of |LayoutInline|
template <>
void InlineItemsBuilderTemplate<
    OffsetMappingBuilder>::UpdateShouldCreateBoxFragment(LayoutInline*) {}

template <typename MappingBuilder>
void InlineItemsBuilderTemplate<MappingBuilder>::BidiContext::Trace(
    Visitor* visitor) const {}

template class CORE_TEMPLATE_EXPORT
    InlineItemsBuilderTemplate<EmptyOffsetMappingBuilder>;
template class CORE_TEMPLATE_EXPORT
    InlineItemsBuilderTemplate<OffsetMappingBuilder>;

}  // namespace blink