chromium/ui/gfx/render_text_unittest.cc

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

#include "ui/gfx/render_text.h"

#include <limits.h>
#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <numeric>
#include <set>
#include <tuple>

#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/i18n/base_i18n_switches.h"
#include "base/i18n/break_iterator.h"
#include "base/i18n/char_iterator.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "cc/paint/paint_record.h"
#include "cc/paint/paint_recorder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkFontStyle.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/break_list.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/decorated_text.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_fallback.h"
#include "ui/gfx/font_names_testing.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/range/range.h"
#include "ui/gfx/range/range_f.h"
#include "ui/gfx/render_text_harfbuzz.h"
#include "ui/gfx/render_text_test_api.h"
#include "ui/gfx/test/scoped_default_font_description.h"
#include "ui/gfx/text_constants.h"
#include "ui/gfx/text_elider.h"
#include "ui/gfx/text_utils.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif

#if BUILDFLAG(IS_APPLE)
#include "base/mac/mac_util.h"
#endif

namespace gfx {

namespace {

// Various weak, LTR, RTL, and Bidi string cases with three characters each.
const char16_t kWeak[] =;
const char16_t kLtr[] =;
const char16_t kRtl[] =;
const char16_t kLtrRtl[] =;
const char16_t kLtrRtlLtr[] =;
const char16_t kRtlLtr[] =;
const char16_t kRtlLtrRtl[] =;

constexpr bool kUseWordWrap =;
constexpr bool kUseObscuredText =;

// Bitmasks based on gfx::TextStyle.
enum {};

FontSpan;

bool IsFontsSmoothingEnabled() {}

// Checks whether |range| contains |index|. This is not the same as calling
// range.Contains(Range(index)), which returns true if |index| == |range.end()|.
bool IndexInRange(const Range& range, size_t index) {}

std::u16string GetSelectedText(RenderText* render_text) {}

// A test utility function to set the application default text direction.
void SetRTL(bool rtl) {}

// Execute MoveCursor on the given |render_text| instance for the given
// arguments and verify the selected range matches |expected|. Also, clears the
// expectations.
void RunMoveCursorTestAndClearExpectations(RenderText* render_text,
                                           BreakType break_type,
                                           VisualCursorDirection direction,
                                           SelectionBehavior selection_behavior,
                                           std::vector<Range>* expected) {}

// Execute MoveCursor on the given |render_text| instance for the given
// arguments and verify the line matches |expected|. Also, clears the
// expectations.
void RunMoveCursorTestAndClearExpectations(RenderText* render_text,
                                           BreakType break_type,
                                           VisualCursorDirection direction,
                                           SelectionBehavior selection_behavior,
                                           std::vector<size_t>* expected) {}

// Ensure cursor movement in the specified |direction| yields |expected| values.
void RunMoveCursorLeftRightTest(RenderText* render_text,
                                const std::vector<SelectionModel>& expected,
                                VisualCursorDirection direction) {}

// Creates a RangedAttribute instance for a single character range at the
// given |index| with the given |weight| and |style_mask|. |index| is the
// index of the character in the DecoratedText instance and |font_index| is
// used to retrieve the font used from |font_spans|.
DecoratedText::RangedAttribute CreateRangedAttribute(
    const std::vector<FontSpan>& font_spans,
    int index,
    int font_index,
    Font::Weight weight,
    int style_mask) {}

// Verifies the given DecoratedText instances are equal by comparing the
// respective strings and attributes for each index. Note, corresponding
// ranged attributes from |expected| and |actual| can't be compared since the
// partition of |actual| into RangedAttributes will depend on the text runs
// generated.
void VerifyDecoratedWordsAreEqual(const DecoratedText& expected,
                                  const DecoratedText& actual) {}

// Helper method to return an obscured string of the given |length|, with the
// |reveal_index| filled with |reveal_char|.
std::u16string GetObscuredString(size_t length,
                                 size_t reveal_index,
                                 char16_t reveal_char) {}

// Helper method to return an obscured string of the given |length|.
std::u16string GetObscuredString(size_t length) {}

// Returns the combined character range from all text runs on |line|.
Range LineCharRange(const internal::Line& line) {}

struct GlyphCountAndColor {};

class TextLog {};

// The class which records the drawing operations so that the test case can
// verify where exactly the glyphs are drawn.
class TestSkiaTextRenderer : public internal::SkiaTextRenderer {};

class TestRenderTextCanvas : public SkCanvas {};

// Given a buffer to test against, this can be used to test various areas of the
// rectangular buffer against a specific color value.
class TestRectangleBuffer {};

}  // namespace

// Test fixture class used to run parameterized tests for all RenderText
// implementations.
class RenderTextTest : public testing::Test {};

TEST_F(RenderTextTest, DefaultStyles) {}

TEST_F(RenderTextTest, SetStyles) {}

TEST_F(RenderTextTest, ApplyStyles) {}

TEST_F(RenderTextTest, ApplyStyleSurrogatePair) {}

TEST_F(RenderTextTest, ApplyStyleGrapheme) {}

TEST_F(RenderTextTest, ApplyStyleMultipleGraphemes) {}

TEST_F(RenderTextTest, ApplyColorSurrogatePair) {}

TEST_F(RenderTextTest, ApplyColorLongEmoji) {}

TEST_F(RenderTextTest, ApplyFillStyle) {}

TEST_F(RenderTextTest, ApplyColorObscuredEmoji) {}

TEST_F(RenderTextTest, ApplyColorArabicDiacritics) {}

TEST_F(RenderTextTest, ApplyColorArabicLigature) {}

TEST_F(RenderTextTest, ApplyEliding) {}

TEST_F(RenderTextTest, ApplyElidingGrapheme) {}

TEST_F(RenderTextTest, ApplyElidingAndTruncate) {}

TEST_F(RenderTextTest, AppendTextKeepsStyles) {}

TEST_F(RenderTextTest, SetSelection) {}

TEST_F(RenderTextTest, SelectRangeColored) {}

// Tests that when a selection is made and the selection background is
// translucent, the selection renders properly. See crbug.com/1134440.
TEST_F(RenderTextTest, SelectWithTranslucentBackground) {}

TEST_F(RenderTextTest, SelectRangeColoredGrapheme) {}

TEST_F(RenderTextTest, SelectRangeMultiple) {}

TEST_F(RenderTextTest, SetCompositionRangeColored) {}

TEST_F(RenderTextTest, SetCompositionRangeColoredGrapheme) {}

void TestVisualCursorMotionInObscuredField(
    RenderText* render_text,
    const std::u16string& text,
    SelectionBehavior selection_behavior) {}

TEST_F(RenderTextTest, ObscuredText) {}

TEST_F(RenderTextTest, ObscuredTextMultiline) {}

TEST_F(RenderTextTest, ObscuredTextMultilineNewline) {}

TEST_F(RenderTextTest, RevealObscuredText) {}

TEST_F(RenderTextTest, ObscuredEmoji) {}

TEST_F(RenderTextTest, ObscuredEmojiRevealed) {}

struct TextIndexConversionCase {};

TextIndexConversionParam;

class RenderTextTestWithTextIndexConversionCase
    : public RenderTextTest,
      public ::testing::WithParamInterface<TextIndexConversionParam> {};

TEST_P(RenderTextTestWithTextIndexConversionCase, TextIndexConversion) {}

const TextIndexConversionCase kTextIndexConversionCases[] =;

// Validate that conversion text and between display text indexes are consistent
// even when text obscured and reveal character features are used.
INSTANTIATE_TEST_SUITE_P();

struct RunListCase {};

class RenderTextTestWithRunListCase
    : public RenderTextTest,
      public ::testing::WithParamInterface<RunListCase> {};

TEST_P(RenderTextTestWithRunListCase, ItemizeTextToRuns) {}

const RunListCase kBasicsRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

// see 'Unicode Bidirectional Algorithm': http://unicode.org/reports/tr9/
const RunListCase kBidiRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

const RunListCase kBracketsRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

// Test cases to ensure the extraction of script extensions are taken into
// account while performing the text itemization.
// See table 7 from http://www.unicode.org/reports/tr24/tr24-29.html
const RunListCase kScriptExtensionRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

// Test cases to ensure ItemizeTextToRuns is splitting text based on unicode
// script (intersection of script extensions).
// See ScriptExtensions.txt and Scripts.txt from
// http://www.unicode.org/reports/tr24/tr24-29.html
const RunListCase kScriptsRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

// Test cases to ensure ItemizeTextToRuns is splitting emoji correctly.
// see: http://www.unicode.org/reports/tr51
// see: http://www.unicode.org/emoji/charts/full-emoji-list.html
const RunListCase kEmojiRunListCases[] =;

INSTANTIATE_TEST_SUITE_P();

struct ElideTextTestOptions {};

const bool kForceNoWhitespaceElision =;
const bool kForceWhitespaceElision =;

struct ElideTextCase {};

ElideTextCaseParam;

class RenderTextTestWithElideTextCase
    : public RenderTextTest,
      public ::testing::WithParamInterface<ElideTextCaseParam> {};

TEST_P(RenderTextTestWithElideTextCase, ElideText) {}

const ElideTextCase kElideHeadTextCases[] =;

INSTANTIATE_TEST_SUITE_P();

const ElideTextCase kElideTailTextCases[] =;

INSTANTIATE_TEST_SUITE_P();

const ElideTextCase kElideTruncateTextCases[] =;

INSTANTIATE_TEST_SUITE_P();

const ElideTextCase kElideEmailTextCases[] =;

INSTANTIATE_TEST_SUITE_P();

TEST_F(RenderTextTest, ElidedText_NoTrimWhitespace) {}

TEST_F(RenderTextTest, SetElideBehavior) {}

TEST_F(RenderTextTest, SetWhitespaceElision) {}

TEST_F(RenderTextTest, ElidedObscuredText) {}

TEST_F(RenderTextTest, MultilineElide) {}

TEST_F(RenderTextTest, MultilineElideWrap) {}

// TODO(crbug.com/40586307): The current implementation of eliding is not aware
// of text styles. The elide text algorithm doesn't take into account the style
// properties when eliding the text. This lead to incorrect text size when the
// styles are applied.
TEST_F(RenderTextTest, DISABLED_MultilineElideWrapWithStyle) {}

TEST_F(RenderTextTest, MultilineElideWrapStress) {}

// TODO(crbug.com/40586307): The current implementation of eliding is not aware
// of text styles. The elide text algorithm doesn't take into account the style
// properties when eliding the text. This lead to incorrect text size when the
// styles are applied.
TEST_F(RenderTextTest, DISABLED_MultilineElideWrapStressWithStyle) {}

TEST_F(RenderTextTest, ElidedFallbackFonts) {}

TEST_F(RenderTextTest, MultilineElideRTL) {}

TEST_F(RenderTextTest, MultilineElideBiDi) {}

TEST_F(RenderTextTest, MultilineElideLinebreak) {}

TEST_F(RenderTextTest, ElidedStyledTextRtl) {}

TEST_F(RenderTextTest, ElidedEmail) {}

TEST_F(RenderTextTest, TruncatedText) {}

TEST_F(RenderTextTest, TruncatedObscuredText) {}

TEST_F(RenderTextTest, TruncatedObscuredTextWithGraphemes) {}

TEST_F(RenderTextTest, TruncatedCursorMovementLTR) {}

TEST_F(RenderTextTest, TruncatedCursorMovementRTL) {}

TEST_F(RenderTextTest, MoveCursor_Character) {}

TEST_F(RenderTextTest, MoveCursor_Word) {}

TEST_F(RenderTextTest, MoveCursor_Word_RTL) {}

TEST_F(RenderTextTest, MoveCursor_Line) {}

TEST_F(RenderTextTest, MoveCursor_UpDown) {}

TEST_F(RenderTextTest, MoveCursor_UpDown_Newline) {}

TEST_F(RenderTextTest, MoveCursor_UpDown_EmptyLines) {}

TEST_F(RenderTextTest, MoveCursor_UpDown_Cache) {}

TEST_F(RenderTextTest, MoveCursorWithNewline) {}

TEST_F(RenderTextTest, GetTextDirectionInvalidation) {}

TEST_F(RenderTextTest, GetDisplayTextDirectionInvalidation) {}

TEST_F(RenderTextTest, GetTextDirectionWithDifferentDirection) {}

TEST_F(RenderTextTest, DirectionalityInvalidation) {}

TEST_F(RenderTextTest, MoveCursor_UpDown_Scroll) {}

TEST_F(RenderTextTest, GetDisplayTextDirection) {}

struct GetTextIndexOfLineCase {};

class RenderTextTestWithGetTextIndexOfLineCase
    : public RenderTextTest,
      public ::testing::WithParamInterface<GetTextIndexOfLineCase> {};

TEST_P(RenderTextTestWithGetTextIndexOfLineCase, GetTextIndexOfLine) {}

const GetTextIndexOfLineCase kGetTextIndexOfLineCases[] =;

INSTANTIATE_TEST_SUITE_P();

TEST_F(RenderTextTest, MoveCursorLeftRightInLtr) {}

TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtl) {}

TEST_F(RenderTextTest, MoveCursorLeftRightInLtrRtlLtr) {}

TEST_F(RenderTextTest, MoveCursorLeftRightInRtl) {}

TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtr) {}

TEST_F(RenderTextTest, MoveCursorLeftRightInRtlLtrRtl) {}

TEST_F(RenderTextTest, MoveCursorLeftRight_ComplexScript) {}

TEST_F(RenderTextTest, MoveCursorLeftRight_MeiryoUILigatures) {}

TEST_F(RenderTextTest, GraphemeIterator) {}

TEST_F(RenderTextTest, GraphemeBoundaries) {}

TEST_F(RenderTextTest, GraphemePositions) {}

TEST_F(RenderTextTest, MidGraphemeSelectionBounds) {}

TEST_F(RenderTextTest, FindCursorPosition) {}

TEST_F(RenderTextTest, GetCursorBoundsMultilineLTR) {}

TEST_F(RenderTextTest, GetCursorBoundsMultilineCarriageReturn) {}

TEST_F(RenderTextTest, GetCursorBoundsMultilineRTL) {}

// Tests that FindCursorPosition behaves correctly for multi-line text.
TEST_F(RenderTextTest, FindCursorPositionMultiline) {}

// Ensure FindCursorPosition returns positions only at valid grapheme
// boundaries.
TEST_F(RenderTextTest, FindCursorPosition_GraphemeBoundaries) {}

TEST_F(RenderTextTest, EdgeSelectionModels) {}

TEST_F(RenderTextTest, SelectAll) {}

TEST_F(RenderTextTest, MoveCursorLeftRightWithSelection) {}

TEST_F(RenderTextTest, MoveCursorLeftRightWithSelection_Multiline) {}

TEST_F(RenderTextTest, CenteredDisplayOffset) {}

void MoveLeftRightByWordVerifier(RenderText* render_text, const char16_t* str) {}

#if BUILDFLAG(IS_WIN)
// TODO(aleventhal): https://crbug.com/906308 Fix bugs, update verifier code
// above, and enable for Windows.
#define MAYBE_MoveLeftRightByWordInBidiText
#else
#define MAYBE_MoveLeftRightByWordInBidiText
#endif
TEST_F(RenderTextTest, MAYBE_MoveLeftRightByWordInBidiText) {}

TEST_F(RenderTextTest, MoveLeftRightByWordInBidiText_TestEndOfText) {}

TEST_F(RenderTextTest, MoveLeftRightByWordInTextWithMultiSpaces) {}

TEST_F(RenderTextTest, MoveLeftRightByWordInThaiText) {}

// TODO(crbug.com/40585744): Chinese and Japanese tokenization doesn't work on
// mobile.
#if !BUILDFLAG(IS_ANDROID)
TEST_F(RenderTextTest, MoveLeftRightByWordInChineseText) {}
#endif

// Test the correct behavior of undirected selections: selections where the
// "end" of the selection that holds the cursor is only determined after the
// first cursor movement.
TEST_F(RenderTextTest, DirectedSelections) {}

TEST_F(RenderTextTest, DirectedSelections_Multiline) {}

TEST_F(RenderTextTest, StringSizeSanity) {}

TEST_F(RenderTextTest, StringSizeLongStrings) {}

TEST_F(RenderTextTest, StringSizeEmptyString) {}

TEST_F(RenderTextTest, StringSizeRespectsFontListMetrics) {}

TEST_F(RenderTextTest, StringSizeMultiline) {}

TEST_F(RenderTextTest, MinLineHeight) {}

// Check that, for Latin characters, typesetting text in the default fonts and
// sizes does not discover any glyphs that would exceed the line spacing
// recommended by gfx::Font.
TEST_F(RenderTextTest, DefaultLineHeights) {}

TEST_F(RenderTextTest, TextSize) {}

TEST_F(RenderTextTest, TextSizeMultiline) {}

TEST_F(RenderTextTest, LineSizeMultiline) {}

TEST_F(RenderTextTest, TextPosition) {}

TEST_F(RenderTextTest, SetFontList) {}

TEST_F(RenderTextTest, StringSizeBoldWidth) {}

TEST_F(RenderTextTest, StringSizeHeight) {}

TEST_F(RenderTextTest, GetBaselineSanity) {}

TEST_F(RenderTextTest, GetCursorBoundsInReplacementMode) {}

TEST_F(RenderTextTest, GetCursorBoundsWithGraphemes) {}

TEST_F(RenderTextTest, GetTextOffset) {}

TEST_F(RenderTextTest, GetTextOffsetHorizontalDefaultInRTL) {}

TEST_F(RenderTextTest, GetTextOffsetVerticalAlignment) {}

TEST_F(RenderTextTest, GetTextOffsetVerticalAlignment_Multiline) {}

TEST_F(RenderTextTest, SetDisplayOffset) {}

TEST_F(RenderTextTest, SameFontForParentheses) {}

// Make sure the caret width is always >=1 so that the correct
// caret is drawn at high DPI. crbug.com/164100.
TEST_F(RenderTextTest, CaretWidth) {}

TEST_F(RenderTextTest, SelectWord) {}

// Make sure the last word is selected when the cursor is at text.length().
TEST_F(RenderTextTest, LastWordSelected) {}

// When given a non-empty selection, SelectWord should expand the selection to
// nearest word boundaries.
TEST_F(RenderTextTest, SelectMultipleWords) {}

TEST_F(RenderTextTest, DisplayRectShowsCursorLTR) {}

TEST_F(RenderTextTest, DisplayRectShowsCursorRTL) {}

// Changing colors between or inside ligated glyphs should not break shaping.
TEST_F(RenderTextTest, SelectionKeepsLigatures) {}

// Test that characters commonly used in the context of several scripts do not
// cause text runs to break. For example the Japanese "long sound symbol" --
// normally only used in a Katakana script, is also used on occasion when in
// Hiragana scripts. It shouldn't cause a Hiragana text run break since that
// could upset kerning.
TEST_F(RenderTextTest, ScriptExtensionsDoNotBreak) {}

// Test that whitespace breaks runs of text. E.g. this can permit better fonts
// to be chosen by the fallback mechanism when a font does not provide
// whitespace glyphs for all scripts. See http://crbug.com/731563.
TEST_F(RenderTextTest, WhitespaceDoesBreak) {}

// Ensure strings wrap onto multiple lines for a small available width.
TEST_F(RenderTextTest, Multiline_MinWidth) {}

// Ensure strings wrap onto multiple lines for a normal available width.
TEST_F(RenderTextTest, Multiline_NormalWidth) {}

// Ensure strings don't wrap onto multiple lines for a sufficient available
// width.
TEST_F(RenderTextTest, Multiline_SufficientWidth) {}

TEST_F(RenderTextTest, Multiline_Newline) {}

// Make sure that multiline mode ignores elide behavior.
TEST_F(RenderTextTest, Multiline_IgnoreElide) {}

TEST_F(RenderTextTest, Multiline_NewlineCharacterReplacement) {}

// Ensure horizontal alignment works in multiline mode.
TEST_F(RenderTextTest, Multiline_HorizontalAlignment) {}

TEST_F(RenderTextTest, Multiline_WordWrapBehavior) {}

TEST_F(RenderTextTest, Multiline_LineBreakerBehavior) {}

// Test that Surrogate pairs or combining character sequences do not get
// separated by line breaking.
TEST_F(RenderTextTest, Multiline_SurrogatePairsOrCombiningChars) {}

// Test that Zero width characters have the correct line breaking behavior.
TEST_F(RenderTextTest, Multiline_ZeroWidthChars) {}

TEST_F(RenderTextTest, Multiline_ZeroWidthNewline) {}

TEST_F(RenderTextTest, Multiline_GetLineContainingCaret) {}

TEST_F(RenderTextTest, NewlineWithoutMultilineFlag) {}

TEST_F(RenderTextTest, ControlCharacterReplacement) {}

TEST_F(RenderTextTest, PrivateUseCharacterReplacement) {}

TEST_F(RenderTextTest, AppleSpecificPrivateUseCharacterReplacement) {}

TEST_F(RenderTextTest, MicrosoftSpecificPrivateUseCharacterReplacement) {}

TEST_F(RenderTextTest, InvalidSurrogateCharacterReplacement) {}

// Make sure the horizontal positions of runs in a line (left-to-right for
// LTR languages and right-to-left for RTL languages).
TEST_F(RenderTextTest, HarfBuzz_HorizontalPositions) {}

// Test TextRunHarfBuzz's cluster finding logic.
TEST_F(RenderTextTest, HarfBuzz_Clusters) {}

// Ensures GetClusterAt does not crash on invalid conditions. crbug.com/724880
TEST_F(RenderTextTest, HarfBuzz_NoCrashOnTextRunGetClusterAt) {}

// Ensure that graphemes with multiple code points do not get split.
TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemeCases) {}

// Test the partition of a multi-grapheme cluster into grapheme ranges.
TEST_F(RenderTextTest, HarfBuzz_SubglyphGraphemePartition) {}

TEST_F(RenderTextTest, HarfBuzz_RunDirection) {}

TEST_F(RenderTextTest, HarfBuzz_RunDirection_URLs) {}

TEST_F(RenderTextTest, HarfBuzz_BreakRunsByUnicodeBlocks) {}

TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmoji) {}

TEST_F(RenderTextTest, HarfBuzz_BreakRunsByNewline) {}

TEST_F(RenderTextTest, HarfBuzz_BreakRunsByEmojiVariationSelectors) {}

TEST_F(RenderTextTest, HarfBuzz_OrphanedVariationSelector) {}

TEST_F(RenderTextTest, HarfBuzz_AsciiVariationSelector) {}

TEST_F(RenderTextTest, HarfBuzz_LeadingVariationSelector) {}

TEST_F(RenderTextTest, HarfBuzz_TrailingVariationSelector) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsWithMissingGlyphCJK) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsWithMissingGlyphSmallCaps) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsWithMissingGlyphSmallCapsAdjacent) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsWithMissingGlyphDiacDev) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsInFontCJKAndLatin) {}

TEST_F(RenderTextTest, HarfBuzz_SplitRunsInFontCJKAndLatinWithEliding) {}

TEST_F(RenderTextTest, HarfBuzz_MultipleVariationSelectorEmoji) {}

TEST_F(RenderTextTest, HarfBuzz_BreakRunsByAscii) {}

// Test that, on Mac, font fallback mechanisms and Harfbuzz configuration cause
// the correct glyphs to be chosen for unicode regional indicators.
TEST_F(RenderTextTest, EmojiFlagGlyphCount) {}

TEST_F(RenderTextTest, HarfBuzz_ShapeRunsWithMultipleFonts) {}

TEST_F(RenderTextTest, GlyphBounds) {}

// Ensure that shaping with a non-existent font does not cause a crash.
TEST_F(RenderTextTest, HarfBuzz_NonExistentFont) {}

// Ensure an empty run returns sane values to queries.
TEST_F(RenderTextTest, HarfBuzz_EmptyRun) {}

TEST_F(RenderTextTest, HarfBuzz_HistogramMissingGlyphsNone) {}

TEST_F(RenderTextTest, HarfBuzz_HistogramMissingGlyphsCount) {}

// Ensure the line breaker doesn't compute the word's width bigger than the
// actual size. See http://crbug.com/470073
TEST_F(RenderTextTest, HarfBuzz_WordWidthWithDiacritics) {}

// Ensure a string fits in a display rect with a width equal to the string's.
TEST_F(RenderTextTest, StringFitsOwnWidth) {}

// TODO(crbug.com/40585825): Figure out why this fails on Android.
#if !BUILDFLAG(IS_ANDROID)
// Ensure that RenderText examines all of the fonts in its FontList before
// falling back to other fonts.
TEST_F(RenderTextTest, HarfBuzz_FontListFallback) {}
#endif  // !BUILDFLAG(IS_ANDROID)

// Ensure that the fallback fonts offered by GetFallbackFonts() are tried. Note
// this test assumes the font "Arial" doesn't provide a unicode glyph for a
// particular character, and that there is a system fallback font which does.
// TODO(msw): Fallback doesn't find a glyph on Linux and Android.
#if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
TEST_F(RenderTextTest, HarfBuzz_UnicodeFallback) {
  RenderTextHarfBuzz* render_text = GetRenderText();
  render_text->SetFontList(FontList("Arial, 12px"));

  // An invalid Unicode character that somehow yields Korean character "han".
  render_text->SetText(u"\ud55c");
  const internal::TextRunList* run_list = GetHarfBuzzRunList();
  ASSERT_EQ(1U, run_list->size());
  EXPECT_EQ(0U, run_list->MissingGlyphCount());
}
#endif  // !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) &&
        // !BUILDFLAG(IS_ANDROID)

// Ensure that the fallback fonts offered by GetFallbackFont() support glyphs
// for different languages.
TEST_F(RenderTextTest, HarfBuzz_FallbackFontsSupportGlyphs) {}

// Ensure that the fallback fonts offered by GetFallbackFont() support glyphs
// for different languages.
TEST_F(RenderTextTest, HarfBuzz_MultiRunsSupportGlyphs) {}

struct FallbackFontCase {};

class RenderTextTestWithFallbackFontCase
    : public RenderTextTest,
      public ::testing::WithParamInterface<FallbackFontCase> {};

TEST_P(RenderTextTestWithFallbackFontCase, FallbackFont) {}

const FallbackFontCase kUnicodeDecomposeCases[] =;

INSTANTIATE_TEST_SUITE_P();

// Ensures that RenderText is finding an appropriate font and that every
// codepoint can be rendered by the font. An error here can be by an incorrect
// ItemizeText(...) leading to an invalid fallback font.
const FallbackFontCase kComplexTextCases[] =;

INSTANTIATE_TEST_SUITE_P();

// Test cases to ensures the COMMON unicode script is split by unicode code
// block. These tests work on Windows and Mac default fonts installation.
// On other platforms, the fonts are mock (see test_fonts).
const FallbackFontCase kCommonScriptCases[] =;

INSTANTIATE_TEST_SUITE_P();

#if BUILDFLAG(IS_WIN)
// Ensures that locale is used for fonts selection.
TEST_F(RenderTextTest, CJKFontWithLocale) {
  const char16_t kCJKTest[] = u"\u8AA4\u904E\u9AA8";
  static const char* kLocaleTests[] = {"zh-CN", "ja-JP", "ko-KR"};

  std::set<std::string> tested_font_names;
  for (const auto* locale : kLocaleTests) {
    base::i18n::SetICUDefaultLocale(locale);
    ResetRenderTextInstance();

    RenderTextHarfBuzz* render_text = GetRenderText();
    render_text->SetText(kCJKTest);

    const std::vector<FontSpan> font_spans = GetFontSpans();
    ASSERT_EQ(font_spans.size(), 1U);

    // Expect the font name to be different for each locale.
    bool unique_font_name =
        tested_font_names.insert(font_spans[0].first.GetFontName()).second;
    EXPECT_TRUE(unique_font_name);
  }
}
#endif  // BUILDFLAG(IS_WIN)

TEST_F(RenderTextTest, SameFontAccrossIgnorableCodepoints) {}

TEST_F(RenderTextTest, ZeroWidthCharacters) {}

// Ensure that the width reported by RenderText is sufficient for drawing. Draws
// to a canvas and checks if any pixel beyond the bounding rectangle is colored.
TEST_F(RenderTextTest, DISABLED_TextDoesntClip) {}

// Ensure that the text will clip to the display rect. Draws to a canvas and
// checks whether any pixel beyond the bounding rectangle is colored.
TEST_F(RenderTextTest, DISABLED_TextDoesClip) {}

// Ensure color changes are picked up by the RenderText implementation.
TEST_F(RenderTextTest, ColorChange) {}

// Ensure style information propagates to the typeface on the text renderer.
TEST_F(RenderTextTest, StylePropagated) {}

// Ensure the painter adheres to RenderText::subpixel_rendering_suppressed().
TEST_F(RenderTextTest, SubpixelRenderingSuppressed) {}

// Ensure the SkFont Edging is computed accurately.
TEST_F(RenderTextTest, SkFontEdging) {}

// Verify GetWordLookupDataAtPoint returns the correct baseline point and
// decorated word for an LTR string.
TEST_F(RenderTextTest, GetWordLookupDataAtPoint_LTR) {}

// Verify GetWordLookupDataAtPoint returns the correct baseline point and
// decorated word for an RTL string.
TEST_F(RenderTextTest, GetWordLookupDataAtPoint_RTL) {}

// Test that GetWordLookupDataAtPoint behaves correctly for multiline text.
TEST_F(RenderTextTest, GetWordLookupDataAtPoint_Multiline) {}

// Verify the boolean return value of GetWordLookupDataAtPoint.
TEST_F(RenderTextTest, GetWordLookupDataAtPoint_Return) {}

// Test that GetLookupDataAtPoint behaves correctly when the range spans lines.
TEST_F(RenderTextTest, GetLookupDataAtRange_Multiline) {}

// Test that GetLookupDataForRange returns the expected sizes for each range.
TEST_F(RenderTextTest, GetLookupDataAtRange_Size) {}

// Tests text selection made at end points of individual lines of multiline
// text.
TEST_F(RenderTextTest, LineEndSelections) {}

TEST_F(RenderTextTest, GetSubstringBounds) {}

// Tests that GetSubstringBounds rounds outward when glyphs have floating-point
// widths.
TEST_F(RenderTextTest, GetSubstringBoundsFloatingPoint) {}

// Tests that GetSubstringBounds handles integer glypth widths correctly.
TEST_F(RenderTextTest, GetSubstringBoundsInt) {}

// Tests that GetSubstringBounds returns the correct bounds for multiline text.
TEST_F(RenderTextTest, GetSubstringBoundsMultiline) {}

// Tests that RenderText doesn't crash even if it's passed an invalid font. Test
// for crbug.com/668058.
TEST_F(RenderTextTest, InvalidFont) {}

TEST_F(RenderTextTest, ExpandToBeVerticallySymmetric) {}

TEST_F(RenderTextTest, MergeIntersectingRects) {}

// Ensures that text is centered vertically and consistently when either the
// display rectangle height changes, or when the minimum line height changes.
// The difference between the two is the selection rectangle, which should match
// the line height.
TEST_F(RenderTextTest, BaselineWithLineHeight) {}

TEST_F(RenderTextTest, TeluguGraphemeBoundaries) {}

// Test cursor bounds for Emoji flags (unicode regional indicators) when the
// flag does not merge into a single glyph.
TEST_F(RenderTextTest, MissingFlagEmoji) {}

// Ensures that glyph spacing is correctly applied to obscured text.
TEST_F(RenderTextTest, ObscuredGlyphSpacing) {}

// Ensures that glyph spacing is ignored for non-obscured text.
TEST_F(RenderTextTest, ObscuredGlyphSpacingOnNonObscuredText) {}

// Ensure font size overrides propagate through to text runs.
TEST_F(RenderTextTest, FontSizeOverride) {}

TEST_F(RenderTextTest, DrawVisualText_WithSelection) {}

TEST_F(RenderTextTest, DrawVisualText_WithSelectionOnObcuredEmoji) {}

TEST_F(RenderTextTest, DrawSelectAll) {}

TEST_F(RenderTextTest, GetLookupDataForRange_Obscured) {}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
TEST_F(RenderTextTest, StringSizeUpdatedWhenDeviceScaleFactorChanges) {}
#endif

// This test case is a unit test version of the clusterfuzz issue found in
// crbug.com/1298286, an integer-overflow undefined behavior.
TEST_F(RenderTextTest, Clusterfuzz_Issue_1298286) {}

// This test case is a unit test version of the clusterfuzz issue found in
// crbug.com/1299054, an integer-overflow undefined behavior.
TEST_F(RenderTextTest, Clusterfuzz_Issue_1299054) {}

TEST_F(RenderTextTest, Clusterfuzz_Issue_1287804) {}

TEST_F(RenderTextTest, Clusterfuzz_Issue_1193815) {}

class RenderTextDirectionTest
    : public testing::Test,
      public testing::WithParamInterface<std::string> {};

INSTANTIATE_TEST_SUITE_P();

TEST_P(RenderTextDirectionTest, GetCurrentHorizontalAlignment) {}

}  // namespace gfx