// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of dart.ui;

/// A [TextStyle.height] value that indicates the text span should take
/// the height defined by the font, which may not be exactly the height of
/// [TextStyle.fontSize].
// To change the sentinel value, search for "kTextHeightNone" in the source code.
const double kTextHeightNone = 0.0;

/// Whether to use the italic type variation of glyphs in the font.
///
/// Some modern fonts allow this to be selected in a more fine-grained manner.
/// See [FontVariation.italic] for details.
///
/// Italic type is distinct from slanted glyphs. To control the slant of a
/// glyph, consider the [FontVariation.slant] font feature.
enum FontStyle {
  /// Use the upright ("Roman") glyphs.
  normal,

  /// Use glyphs that have a more pronounced angle and typically a cursive style
  /// ("italic type").
  italic,
}

/// The thickness of the glyphs used to draw the text.
///
/// Values must be in the range 1..1000.
///
/// Fonts are typically weighted on a 9-point scale, which, for historical
/// reasons, uses the names 100 to 900. In Flutter, these are named `w100` to
/// `w900` and have the following conventional meanings:
///
///  * [w100]: Thin, the thinnest font weight.
///
///  * [w200]: Extra light.
///
///  * [w300]: Light.
///
///  * [w400]: Normal. The constant [FontWeight.normal] is an alias for this value.
///
///  * [w500]: Medium.
///
///  * [w600]: Semi-bold.
///
///  * [w700]: Bold. The constant [FontWeight.bold] is an alias for this value.
///
///  * [w800]: Extra-bold.
///
///  * [w900]: Black, the thickest font weight.
///
/// For example, the font named "Roboto Medium" is typically exposed as a font
/// with the name "Roboto" and the weight [FontWeight.w500].
///
/// Some modern fonts allow the weight to be adjusted in arbitrary increments.
/// When using these fonts, applications can specify [FontWeight] instances
/// constructed using values other than the predefined values. For these fonts,
/// [FontWeight] will set the value of the `wght` axis (producing the same
/// results as explicitly setting that attribute using [FontVariation.weight]).
class FontWeight {
  /// Creates a [FontWeight] object, which can be added to a [TextStyle] to
  /// select the thickness of a font's glyphs.
  const FontWeight(this.value)
    : assert(value >= 1, 'Font weight must be between 1 and 1000'),
      assert(value <= 1000, 'Font weight must be between 1 and 1000');

  /// The encoded integer value of this font weight.
  @Deprecated('Use value, which is more precise.')
  int get index => (value ~/ 100 - 1).clamp(0, 8);

  /// The thickness value of this font weight.
  final int value;

  /// Thin, the least thick.
  static const FontWeight w100 = FontWeight(100);

  /// Extra-light.
  static const FontWeight w200 = FontWeight(200);

  /// Light.
  static const FontWeight w300 = FontWeight(300);

  /// Normal / regular / plain.
  static const FontWeight w400 = FontWeight(400);

  /// Medium.
  static const FontWeight w500 = FontWeight(500);

  /// Semi-bold.
  static const FontWeight w600 = FontWeight(600);

  /// Bold.
  static const FontWeight w700 = FontWeight(700);

  /// Extra-bold.
  static const FontWeight w800 = FontWeight(800);

  /// Black, the most thick.
  static const FontWeight w900 = FontWeight(900);

  /// The default font weight.
  static const FontWeight normal = w400;

  /// A commonly used font weight that is heavier than normal.
  static const FontWeight bold = w700;

  /// A list of all the font weights.
  static const List<FontWeight> values = <FontWeight>[
    w100,
    w200,
    w300,
    w400,
    w500,
    w600,
    w700,
    w800,
    w900,
  ];

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FontWeight && other.value == value;
  }

  @override
  int get hashCode => value;

  /// Linearly interpolates between two font weights.
  ///
  /// If both `a` and `b` are null, then this method will return null. Otherwise,
  /// any null values for `a` or `b` are interpreted as equivalent to [normal]
  /// (also known as [w400]).
  ///
  /// The `t` argument represents position on the timeline, with 0.0 meaning
  /// that the interpolation has not started, returning `a` (or something
  /// equivalent to `a`), 1.0 meaning that the interpolation has finished,
  /// returning `b` (or something equivalent to `b`), and values in between
  /// meaning that the interpolation is at the relevant point on the timeline
  /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and
  /// 1.0, so negative values and values greater than 1.0 are valid (and can
  /// easily be generated by curves such as [Curves.elasticInOut]). The result
  /// is clamped to the range [w100]–[w900].
  ///
  /// Values for `t` are usually obtained from an [Animation<double>], such as
  /// an [AnimationController].
  static FontWeight? lerp(FontWeight? a, FontWeight? b, double t) {
    if (a == null && b == null) {
      return null;
    }
    return FontWeight(
      _lerpInt((a ?? normal).value, (b ?? normal).value, t).round().clamp(100, 900),
    );
  }

  @override
  String toString() {
    if (value % 100 != 0) {
      return 'FontWeight($value)';
    }
    return const <int, String>{
      0: 'FontWeight.w100',
      1: 'FontWeight.w200',
      2: 'FontWeight.w300',
      3: 'FontWeight.w400',
      4: 'FontWeight.w500',
      5: 'FontWeight.w600',
      6: 'FontWeight.w700',
      7: 'FontWeight.w800',
      8: 'FontWeight.w900',
    }[index]!;
  }
}

/// A feature tag and value that affect the selection of glyphs in a font.
///
/// Different fonts support different features. Consider using a tool
/// such as <https://wakamaifondue.com/> to examine your fonts to
/// determine what features are available.
///
/// {@tool sample}
/// This example shows usage of several OpenType font features,
/// including Small Caps (selected manually using the "smcp" code),
/// old-style figures, fractional ligatures, and stylistic sets.
///
/// ** See code in examples/api/lib/ui/text/font_feature.0.dart **
/// {@end-tool}
///
/// Some fonts also support continuous font variations; see the [FontVariation]
/// class.
///
/// See also:
///
///  * <https://en.wikipedia.org/wiki/List_of_typographic_features>,
///    Wikipedia's description of these typographic features.
///
///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags>,
///    Microsoft's registry of these features.
class FontFeature {
  /// Creates a [FontFeature] object, which can be added to a [TextStyle] to
  /// change how the engine selects glyphs when rendering text.
  ///
  /// `feature` is the four-character tag that identifies the feature.
  /// These tags are specified by font formats such as OpenType.
  ///
  /// `value` is the value that the feature will be set to. The behavior
  /// of the value depends on the specific feature. Many features are
  /// flags whose value can be 1 (when enabled) or 0 (when disabled).
  ///
  /// See <https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags>
  const FontFeature(this.feature, [this.value = 1])
    : assert(feature.length == 4, 'Feature tag must be exactly four characters long.'),
      assert(value >= 0, 'Feature value must be zero or a positive integer.');

  /// Create a [FontFeature] object that enables the feature with the given tag.
  const FontFeature.enable(String feature) : this(feature, 1);

  /// Create a [FontFeature] object that disables the feature with the given tag.
  const FontFeature.disable(String feature) : this(feature, 0);

  // Features below should be alphabetic by feature tag. This makes it
  // easier to determine when a feature is missing so that we avoid
  // adding duplicates.
  //
  // The full list is extremely long, and many of the features are
  // language-specific, or indeed force-enabled for particular locales
  // by HarfBuzz, so we don't even attempt to be comprehensive here.
  // Features listed below are those we deemed "interesting enough" to
  // have their own constructor, mostly on the basis of whether we
  // could find a font where the feature had a useful effect that
  // could be demonstrated.

  // Start of feature tag list.
  // ------------------------------------------------------------------------

  /// Access alternative glyphs. (`aalt`)
  ///
  /// This feature selects the given glyph variant for glyphs in the span.
  ///
  /// {@tool sample}
  /// The Raleway font supports several alternate glyphs. The code
  /// below shows how specific glyphs can be selected. With `aalt` set
  /// to zero, the default, the normal glyphs are used. With a
  /// non-zero value, Raleway substitutes small caps for lower case
  /// letters. With value 2, the lowercase "a" changes to a stemless
  /// "a", whereas the lowercase "t" changes to a vertical bar instead
  /// of having a curve. By targeting specific letters in the text
  /// (using [widgets.Text.rich]), the desired rendering for each glyph can be
  /// achieved.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_aalt.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_alternative.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#aalt>
  const FontFeature.alternative(this.value) : feature = 'aalt';

  /// Use alternative ligatures to represent fractions. (`afrc`)
  ///
  /// When this feature is enabled (and the font supports it),
  /// sequences of digits separated by U+002F SOLIDUS character (/) or
  /// U+2044 FRACTION SLASH (⁄) are replaced by ligatures that
  /// represent the corresponding fraction. These ligatures may differ
  /// from those used by the [FontFeature.fractions] feature.
  ///
  /// This feature overrides all other features.
  ///
  /// {@tool sample}
  /// The Ubuntu Mono font supports the `afrc` feature. It causes digits
  /// before slashes to become superscripted and digits after slashes to become
  /// subscripted. This contrasts to the effect seen with [FontFeature.fractions].
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_afrc.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_alternative_fractions.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.fractions], which has a similar (but different) effect.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#afrc>
  const FontFeature.alternativeFractions() : feature = 'afrc', value = 1;

  /// Enable contextual alternates. (`calt`)
  ///
  /// With this feature enabled, specific glyphs may be replaced by
  /// alternatives based on nearby text.
  ///
  /// {@tool sample}
  /// The Barriecito font supports the `calt` feature. It causes some
  /// letters in close proximity to other instances of themselves to
  /// use different glyphs, to give the appearance of more variation
  /// in the glyphs, rather than having each letter always use a
  /// particular glyph.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_calt.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_contextual_alternates.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.randomize], which is more a rarely supported but more
  ///    powerful way to get a similar effect.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#calt>
  const FontFeature.contextualAlternates() : feature = 'calt', value = 1;

  /// Enable case-sensitive forms. (`case`)
  ///
  /// Some glyphs, for example parentheses or operators, are typically
  /// designed to fit nicely with mixed case, or even predominantly
  /// lowercase, text. When these glyphs are placed near strings of
  /// capital letters, they appear a little off-center.
  ///
  /// This feature, when supported by the font, causes these glyphs to
  /// be shifted slightly, or otherwise adjusted, so as to form a more
  /// aesthetically pleasing combination with capital letters.
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `case` feature. It causes
  /// parentheses, brackets, braces, guillemets, slashes, bullets, and
  /// some other glyphs (not shown below) to be shifted up slightly so
  /// that capital letters appear centered in comparison. When the
  /// feature is disabled, those glyphs are optimized for use with
  /// lowercase letters, and so capital letters appear to ride higher
  /// relative to the punctuation marks.
  ///
  /// The difference is very subtle. It may be most obvious when
  /// examining the square brackets compared to the capital A.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_case.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_case_sensitive_forms.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#case>
  const FontFeature.caseSensitiveForms() : feature = 'case', value = 1;

  /// Select a character variant. (`cv01` through `cv99`)
  ///
  /// Fonts may have up to 99 character variant sets, numbered 1
  /// through 99, each of which can be independently enabled or
  /// disabled.
  ///
  /// Related character variants are typically grouped into stylistic
  /// sets, controlled by the [FontFeature.stylisticSet] feature
  /// (`ssXX`).
  ///
  /// {@tool sample}
  /// The Source Code Pro font supports the `cvXX` feature for several
  /// characters. In the example below, variants 1 (`cv01`), 2
  /// (`cv02`), and 4 (`cv04`) are selected. Variant 1 changes the
  /// rendering of the "a" character, variant 2 changes the lowercase
  /// "g" character, and variant 4 changes the lowercase "i" and "l"
  /// characters. There are also variants (not shown here) that
  /// control the rendering of various greek characters such as beta
  /// and theta.
  ///
  /// Notably, this can be contrasted with the stylistic sets, where
  /// the set which affects the "a" character also affects beta, and
  /// the set which affects the "g" character also affects theta and
  /// delta.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_cvXX.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_character_variant.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.stylisticSet], which allows for groups of characters
  ///    variants to be selected at once, as opposed to individual character variants.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99>
  factory FontFeature.characterVariant(int value) {
    assert(value >= 1);
    assert(value <= 99);
    return FontFeature('cv${value.toString().padLeft(2, "0")}');
  }

  /// Display digits as denominators. (`dnom`)
  ///
  /// This is typically used automatically by the font rendering
  /// system as part of the implementation of `frac` for the denominator
  /// part of fractions (see [FontFeature.fractions]).
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `dnom` feature. It causes
  /// the digits to be rendered smaller and near the bottom of the EM box.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_dnom.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_denominator.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#dnom>
  const FontFeature.denominator() : feature = 'dnom', value = 1;

  /// Use ligatures to represent fractions. (`afrc`)
  ///
  /// When this feature is enabled (and the font supports it),
  /// sequences of digits separated by U+002F SOLIDUS character (/) or
  /// U+2044 FRACTION SLASH (⁄) are replaced by ligatures that
  /// represent the corresponding fraction.
  ///
  /// This feature may imply the [FontFeature.numerators] and
  /// [FontFeature.denominator] features.
  ///
  /// {@tool sample}
  /// The Ubuntu Mono font supports the `frac` feature. It causes
  /// digits around slashes to be turned into dedicated fraction
  /// glyphs. This contrasts to the effect seen with
  /// [FontFeature.alternativeFractions].
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_frac.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_fractions.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.alternativeFractions], which has a similar (but different) effect.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_fj#frac>
  const FontFeature.fractions() : feature = 'frac', value = 1;

  /// Use historical forms. (`hist`)
  ///
  /// Some fonts have alternatives for letters whose forms have changed
  /// through the ages. In the Latin alphabet, this is common for
  /// example with the long-form "s" or the Fraktur "k". This feature enables
  /// those alternative glyphs.
  ///
  /// This does not enable legacy ligatures, only single-character alternatives.
  /// To enable historical ligatures, use [FontFeature.historicalLigatures].
  ///
  /// This feature may override other glyph-substitution features.
  ///
  /// {@tool sample}
  /// The Cardo font supports the `hist` feature specifically for the
  /// letter "s": it changes occurrences of that letter for the glyph
  /// used by U+017F LATIN SMALL LETTER LONG S.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_historical.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_historical_forms.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_fj#hist>
  const FontFeature.historicalForms() : feature = 'hist', value = 1;

  /// Use historical ligatures. (`hlig`)
  ///
  /// Some fonts support ligatures that have fallen out of favor today,
  /// but were historically in common use. This feature enables those
  /// ligatures.
  ///
  /// For example, the "long s" glyph was historically typeset with
  /// characters such as "t" and "h" as a single ligature.
  ///
  /// This does not enable the legacy forms, only ligatures. See
  /// [FontFeature.historicalForms] to enable single characters to be
  /// replaced with their historical alternatives. Combining both is
  /// usually desired since the ligatures typically apply specifically
  /// to characters that have historical forms as well. For example,
  /// the historical forms feature might replace the "s" character
  /// with the "long s" (ſ) character, while the historical ligatures
  /// feature might specifically apply to cases where "long s" is
  /// followed by other characters such as "t". In such cases, without
  /// the historical forms being enabled, the ligatures would only
  /// apply when the "long s" is used explicitly.
  ///
  /// This feature may override other glyph-substitution features.
  ///
  /// {@tool sample}
  /// The Cardo font supports the `hlig` feature. It has legacy
  /// ligatures for "VI" and "NT", and various ligatures involving the
  /// "long s". In the example below, both historical forms (`hist 1`)
  /// and historical ligatures (`hlig 1`) are enabled, so, for
  /// instance, "fish" becomes "fiſh" which is then rendered using a
  /// ligature for the last two characters.
  ///
  /// Similarly, the word "business" is turned into "buſineſſ" by
  /// `hist`, and the `ſi` and `ſſ` pairs are ligated by `hlig`.
  /// Observe in particular the position of the dot of the "i" in
  /// "business" in the various combinations of these features.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_historical.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_historical_ligatures.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_fj#hlig>
  const FontFeature.historicalLigatures() : feature = 'hlig', value = 1;

  /// Use lining figures. (`lnum`)
  ///
  /// Some fonts have digits that, like lowercase latin letters, have
  /// both descenders and ascenders. In some situations, especially in
  /// conjunction with capital letters, this leads to an aesthetically
  /// questionable irregularity. Lining figures, on the other hand,
  /// have a uniform height, and align with the baseline and the
  /// height of capital letters. Conceptually, they can be thought of
  /// as "capital digits".
  ///
  /// This feature may conflict with [FontFeature.oldstyleFigures].
  ///
  /// {@tool sample}
  /// The Sorts Mill Goudy font supports the `lnum` feature. It causes
  /// digits to fit more seamlessly with capital letters.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_lnum.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_lining_figures.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#lnum>
  const FontFeature.liningFigures() : feature = 'lnum', value = 1;

  /// Use locale-specific glyphs. (`locl`)
  ///
  /// Some characters, most notably those in the Unicode Han
  /// Unification blocks, vary in presentation based on the locale in
  /// use. For example, the ideograph for "grass" (U+8349, 草) has a
  /// broken top line in Traditional Chinese, but a solid top line in
  /// Simplified Chinese, Japanese, Korean, and Vietnamese. This kind
  /// of variation also exists with other alphabets, for example
  /// Cyrillic characters as used in the Bulgarian and Serbian
  /// alphabets vary from their Russian counterparts.
  ///
  /// A particular font may default to the forms for the locale for
  /// which it was constructed, but still support alternative forms
  /// for other locales. When this feature is enabled, the locale (as
  /// specified using [painting.TextStyle.locale], for instance) is
  /// used to determine which glyphs to use when locale-specific
  /// alternatives exist. Disabling this feature causes the font
  /// rendering to ignore locale information and only use the default
  /// glyphs.
  ///
  /// This feature is enabled by default. Using
  /// `FontFeature.localeAware(enable: false)` disables the
  /// locale-awareness. (So does not specifying the locale in the
  /// first place, of course.)
  ///
  /// {@tool sample}
  /// The Noto Sans CJK font supports the `locl` feature for CJK characters.
  /// In this example, the `localeAware` feature is not explicitly used, as it is
  /// enabled by default. This example instead shows how to set the locale,
  /// thus demonstrating how Noto Sans adapts the glyph shapes to the locale.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_locl.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_locale_aware.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#locl>
  ///  * <https://en.wikipedia.org/wiki/Han_unification>
  ///  * <https://en.wikipedia.org/wiki/Cyrillic_script>
  const FontFeature.localeAware({bool enable = true}) : feature = 'locl', value = enable ? 1 : 0;

  /// Display alternative glyphs for numerals (alternate annotation forms). (`nalt`)
  ///
  /// Replaces glyphs used in numbering lists (e.g. 1, 2, 3...; or a, b, c...) with notational
  /// variants that might be more typographically interesting.
  ///
  /// Fonts sometimes support multiple alternatives, and the argument
  /// selects the set to use (a positive integer, or 0 to disable the
  /// feature). The default set if none is specified is 1.
  ///
  /// {@tool sample}
  /// The Gothic A1 font supports several notational variant sets via
  /// the `nalt` feature.
  ///
  /// Set 1 changes the spacing of the glyphs. Set 2 parenthesizes the
  /// latin letters and reduces the numerals to subscripts. Set 3
  /// circles the glyphs. Set 4 parenthesizes the digits. Set 5 uses
  /// reverse-video circles for the digits. Set 7 superscripts the
  /// digits.
  ///
  /// The code below shows how to select set 3.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_nalt.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_notational_forms.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#nalt>
  const FontFeature.notationalForms([this.value = 1]) : feature = 'nalt', assert(value >= 0);

  /// Display digits as numerators. (`numr`)
  ///
  /// This is typically used automatically by the font rendering
  /// system as part of the implementation of `frac` for the numerator
  /// part of fractions (see [FontFeature.fractions]).
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `numr` feature. It causes
  /// the digits to be rendered smaller and near the top of the EM box.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_numr.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_numerators.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#numr>
  const FontFeature.numerators() : feature = 'numr', value = 1;

  /// Use old style figures. (`onum`)
  ///
  /// Some fonts have variants of the figures (e.g. the digit 9) that,
  /// when this feature is enabled, render with descenders under the
  /// baseline instead of being entirely above the baseline. If the
  /// default digits are lining figures, this allows the selection of
  /// digits that fit better with mixed case (uppercase and lowercase)
  /// text.
  ///
  /// This overrides [FontFeature.slashedZero] and may conflict with
  /// [FontFeature.liningFigures].
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `onum` feature. It causes
  /// digits to extend below the baseline.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_onum.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_oldstyle_figures.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#onum>
  ///  * <https://en.wikipedia.org/wiki/Text_figures>
  const FontFeature.oldstyleFigures() : feature = 'onum', value = 1;

  /// Use ordinal forms for alphabetic glyphs. (`ordn`)
  ///
  /// Some fonts have variants of the alphabetic glyphs intended for
  /// use after numbers when expressing ordinals, as in "1st", "2nd",
  /// "3rd". This feature enables those alternative glyphs.
  ///
  /// This may override other features that substitute glyphs.
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `ordn` feature. It causes
  /// alphabetic glyphs to become smaller and superscripted.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_ordn.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_ordinal_forms.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#ordn>
  const FontFeature.ordinalForms() : feature = 'ordn', value = 1;

  /// Use proportional (varying width) figures. (`pnum`)
  ///
  /// For fonts that have both proportional and tabular (monospace) figures,
  /// this enables the proportional figures.
  ///
  /// This is mutually exclusive with [FontFeature.tabularFigures].
  ///
  /// The default behavior varies from font to font.
  ///
  /// {@tool sample}
  /// The Kufam font supports the `pnum` feature. It causes the digits
  /// to become proportionally-sized, rather than all being the same
  /// width. In this font this is especially noticeable with the digit
  /// "1": normally, the 1 has very noticeable serifs in this
  /// sans-serif font, but with the proportionally figures enabled,
  /// the digit becomes much narrower.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_pnum.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_proportional_figures.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#pnum>
  const FontFeature.proportionalFigures() : feature = 'pnum', value = 1;

  /// Randomize the alternate forms used in text. (`rand`)
  ///
  /// For example, this can be used with suitably-prepared handwriting fonts to
  /// vary the forms used for each character, so that, for instance, the word
  /// "cross-section" would be rendered with two different "c"s, two different "o"s,
  /// and three different "s"s.
  ///
  /// Contextual alternates ([FontFeature.contextualAlternates])
  /// provide a similar effect in some fonts, without using
  /// randomness.
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#rand>
  const FontFeature.randomize() : feature = 'rand', value = 1;

  /// Enable stylistic alternates. (`salt`)
  ///
  /// Some fonts have alternative forms that are not tied to a
  /// particular purpose (such as being historical forms, or
  /// contextually relevant alternatives, or ligatures, etc). This
  /// font feature enables these purely stylistic alternatives.
  ///
  /// This may override other features that substitute glyphs.
  ///
  /// {@tool sample}
  /// The Source Code Pro font supports the `salt` feature. It causes
  /// some glyphs to be rendered differently, for example the "a" and
  /// "g" glyphs change from their typographically common
  /// double-storey forms to simpler single-storey forms, the dollar
  /// sign's line changes from discontinuous to continuous (and is
  /// angled), and the "0" rendering changes from a center dot to a
  /// slash.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_salt.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_stylistic_alternates.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.contextualAlternates], which is enables alternates specific to certain contexts.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#salt>
  const FontFeature.stylisticAlternates() : feature = 'salt', value = 1;

  /// Use scientific inferiors. (`sinf`)
  ///
  /// Some fonts have variants of the figures (e.g. the digit 2) that,
  /// when this feature is enabled, render in a manner more
  /// appropriate for subscripted digits ("inferiors") used in
  /// scientific contexts, e.g. the subscripts in chemical formulae.
  ///
  /// This may override other features that substitute glyphs.
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `sinf` feature. It causes
  /// digits to be smaller and subscripted.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_sinf.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_scientific_inferiors.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#sinf>
  const FontFeature.scientificInferiors() : feature = 'sinf', value = 1;

  /// Select a stylistic set. (`ss01` through `ss20`)
  ///
  /// Fonts may have up to 20 stylistic sets, numbered 1 through 20,
  /// each of which can be independently enabled or disabled.
  ///
  /// For more fine-grained control, in some fonts individual
  /// character variants can also be controlled by the
  /// [FontFeature.characterVariant] feature (`cvXX`).
  ///
  /// {@tool sample}
  /// The Source Code Pro font supports the `ssXX` feature for several
  /// sets. In the example below, stylistic sets 2 (`ss02`), 3
  /// (`ss03`), and 4 (`ss04`) are selected. Stylistic set 2 changes
  /// the rendering of the "a" character and the beta character,
  /// stylistic set 3 changes the lowercase "g", theta, and delta
  /// characters, and stylistic set 4 changes the lowercase "i" and
  /// "l" characters.
  ///
  /// This font also supports character variants (see
  /// [FontFeature.characterVariant]).
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_ssXX_1.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_stylistic_set.0.dart **
  /// {@end-tool}
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `ssXX` feature for more
  /// elaborate stylistic effects. Set 1 turns some Latin characters
  /// into Roman numerals, set 2 enables some ASCII characters to be
  /// used to create pretty arrows, and so forth.
  ///
  /// _These_ stylistic sets do _not_ correspond to character variants.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_ssXX_2.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_stylistic_set.1.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * [FontFeature.characterVariant], which allows for individual character
  ///    variants to be selected, as opposed to entire sets.
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#ssxx>
  factory FontFeature.stylisticSet(int value) {
    assert(value >= 1);
    assert(value <= 20);
    return FontFeature('ss${value.toString().padLeft(2, "0")}');
  }

  /// Enable subscripts. (`subs`)
  ///
  /// This feature causes some fonts to change some glyphs to their subscripted form.
  ///
  /// It typically does not affect all glyphs, and so is not appropriate for generally causing
  /// all text to be subscripted.
  ///
  /// This may override other features that substitute glyphs.
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `subs` feature. It causes
  /// digits to be smaller and subscripted.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_subs.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_subscripts.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#subs>
  ///  * [FontFeature.scientificInferiors], which is similar but intended specifically for
  ///    subscripts used in scientific contexts.
  ///  * [FontFeature.superscripts], which is similar but for subscripting.
  const FontFeature.subscripts() : feature = 'subs', value = 1;

  /// Enable superscripts. (`sups`)
  ///
  /// This feature causes some fonts to change some glyphs to their
  /// superscripted form. This may be more than just changing their
  /// position. For example, digits might change to lining figures
  /// (see [FontFeature.liningFigures]) in addition to being raised
  /// and shrunk.
  ///
  /// It typically does not affect all glyphs, and so is not
  /// appropriate for generally causing all text to be superscripted.
  ///
  /// This may override other features that substitute glyphs.
  ///
  /// {@tool sample}
  /// The Sorts Mill Goudy font supports the `sups` feature. It causes
  /// digits to be smaller, superscripted, and changes them to lining
  /// figures (so they are all the same height).
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_sups.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_superscripts.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#sups>
  ///  * [FontFeature.subscripts], which is similar but for subscripting.
  const FontFeature.superscripts() : feature = 'sups', value = 1;

  /// Enable swash glyphs. (`swsh`)
  ///
  /// Some fonts have beautiful flourishes on some characters. These
  /// come in many forms, such as exaggerated serifs, long tails, long
  /// entry strokes, or other forms of decorative extensions to the
  /// base character.
  ///
  /// This feature enables the rendering of these flourishes. Some
  /// fonts have many swashes per character; the argument, if
  /// specified, selects which swash to use (0 disables them
  /// altogether).
  ///
  /// Some fonts have an absurd number of alternative swashes. For
  /// example, Adobe's Poetica famously has 63 different ampersand
  /// forms available through this feature!
  ///
  /// {@tool sample}
  /// The BioRhyme Expanded font supports the `swsh` feature specifically
  /// for the capital "Q" and "R" glyphs and the ampersand.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_swsh.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_swash.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#swsh>
  ///  * <https://en.wikipedia.org/wiki/Swash_(typography)>
  const FontFeature.swash([this.value = 1]) : feature = 'swsh', assert(value >= 0);

  /// Use tabular (monospace) figures. (`tnum`)
  ///
  /// For fonts that have both proportional (varying width) and tabular figures,
  /// this enables the tabular figures. Tabular figures are monospaced (all the
  /// same width), so that they align in tables of figures.
  ///
  /// This is mutually exclusive with [FontFeature.proportionalFigures].
  ///
  /// The default behavior varies from font to font.
  ///
  /// {@tool sample}
  /// The Piazzolla font supports the `tnum` feature. It causes the
  /// digits to become uniformly-sized, rather than having variable
  /// widths. In this font this is especially noticeable with the
  /// digit "1"; with tabular figures enabled, the "1" digit is more
  /// widely spaced.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_tnum.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_tabular_figures.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tnum>
  const FontFeature.tabularFigures() : feature = 'tnum', value = 1;

  /// Use the slashed zero. (`zero`)
  ///
  /// Some fonts contain both a circular zero and a zero with a slash. This
  /// enables the use of the latter form.
  ///
  /// This is overridden by [FontFeature.oldstyleFigures].
  ///
  /// {@tool sample}
  /// The Source Code Pro font supports the `zero` feature. It causes the
  /// zero digit to be drawn with a slash rather than the default rendering,
  /// which in this case has a dot through the zero rather than a slash.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/dart-ui/font_feature_zero.png)
  ///
  /// ** See code in examples/api/lib/ui/text/font_feature.font_feature_slashed_zero.0.dart **
  /// {@end-tool}
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_uz#zero>
  const FontFeature.slashedZero() : feature = 'zero', value = 1;

  // ------------------------------------------------------------------------
  // End of feature tags list.

  /// The tag that identifies the effect of this feature.  Must consist of 4
  /// ASCII characters (typically lowercase letters).
  ///
  /// These features are defined in a registry maintained by Microsoft:
  /// <https://docs.microsoft.com/en-us/typography/opentype/spec/featuretags>
  final String feature;

  /// The value assigned to this feature.
  ///
  /// Must be a positive integer. Many features are Boolean values that accept
  /// values of either 0 (feature is disabled) or 1 (feature is enabled). Other
  /// features have a bound range of values (which may be documented in these
  /// API docs for features that have dedicated constructors, and are generally
  /// documented in the official registry). In some cases the precise supported
  /// range depends on the font.
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/featurelist>
  final int value;

  static const int _kEncodedSize = 8;

  void _encode(ByteData byteData) {
    assert(feature.codeUnits.every((int c) => c >= 0x20 && c <= 0x7F));
    for (var i = 0; i < 4; i++) {
      byteData.setUint8(i, feature.codeUnitAt(i));
    }
    byteData.setInt32(4, value, _kFakeHostEndian);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FontFeature && other.feature == feature && other.value == value;
  }

  @override
  int get hashCode => Object.hash(feature, value);

  @override
  String toString() => "FontFeature('$feature', $value)";
}

/// An axis tag and value that can be used to customize variable fonts.
///
/// Some fonts are variable fonts that can generate a range of different
/// font faces by altering the values of the font's design axes.
///
/// For example:
///
/// ```dart
/// const TextStyle(fontVariations: <ui.FontVariation>[ui.FontVariation('slnt', -5.0)])
/// ```
///
/// Font variations are distinct from font features, as exposed by the
/// [FontFeature] class. Where features can be enabled or disabled in a discrete
/// manner, font variations provide a continuous axis of control.
///
/// See also:
///
///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg#registered-axis-tags>,
///    which lists registered axis tags.
///
///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/otvaroverview>,
///    an overview of the font variations technology.
class FontVariation {
  /// Creates a [FontVariation] object, which can be added to a [TextStyle] to
  /// change the variable attributes of a font.
  ///
  /// `axis` is the four-character tag that identifies the design axis.
  /// OpenType lists the [currently registered axis
  /// tags](https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxisreg).
  ///
  /// `value` is the value that the axis will be set to. The behavior
  /// depends on how the font implements the axis.
  const FontVariation(this.axis, this.value)
    : assert(axis.length == 4, 'Axis tag must be exactly four characters long.'),
      assert(
        value >= -32768.0 && value < 32768.0,
        'Value must be representable as a signed 16.16 fixed-point number, i.e. it must be in this range: -32768.0 ≤ value < 32768.0',
      );

  // Constructors below should be alphabetic by axis tag. This makes it easier
  // to determine when an axis is missing so that we avoid adding duplicates.

  // Start of axis tag list.
  // ------------------------------------------------------------------------

  /// Variable font style. (`ital`)
  ///
  /// Varies the style of glyphs in the font between normal and italic.
  ///
  /// Values must in the range 0.0 (meaning normal, or Roman, as in
  /// [FontStyle.normal]) to 1.0 (meaning fully italic, as in
  /// [FontStyle.italic]).
  ///
  /// This is distinct from [FontVariation.slant], which leans the characters
  /// without changing the font style.
  ///
  /// See also:
  ///
  ///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_ital>
  const FontVariation.italic(this.value)
    : assert(value >= 0.0),
      assert(value <= 1.0),
      axis = 'ital';

  /// Optical size optimization. (`opzs`)
  ///
  /// Changes the rendering of the font to be optimized for the given text size.
  /// Normally, the optical size of the font will be derived from the font size.
  ///
  /// This feature could be used when the text represents a particular physical
  /// font size, for example text in the representation of a hardcopy magazine,
  /// which does not correspond to the actual font size being used to render the
  /// text. By setting the optical size explicitly, font variations that might
  /// be applied as the text is zoomed will be fixed at the size being
  /// represented by the text.
  ///
  /// This feature could also be used to smooth animations. If a font varies its
  /// rendering as the font size is adjusted, it may appear to "quiver" (or, one
  /// might even say, "flutter") if the font size is animated. By setting a
  /// fixed optical size, the rendering can be fixed to one particular style as
  /// the text size animates.
  ///
  /// Values must be greater than zero, and are interpreted as points. A point
  /// is 1/72 of an inch, or 1.333 logical pixels (96/72).
  ///
  /// See also:
  ///
  ///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_opsz>
  const FontVariation.opticalSize(this.value) : assert(value > 0.0), axis = 'opsz';

  /// Variable font width. (`slnt`)
  ///
  /// Varies the slant of glyphs in the font.
  ///
  /// Values must be greater than -90.0 and less than +90.0, and represents the
  /// angle in _counter-clockwise_ degrees relative to "normal", at 0.0.
  ///
  /// For example, to lean the glyphs forward by 45 degrees, one would use
  /// `FontVariation.slant(-45.0)`.
  ///
  /// This is distinct from [FontVariation.italic], in that slant leans the
  /// characters without changing the font style.
  ///
  /// See also:
  ///
  ///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_slnt>
  const FontVariation.slant(this.value)
    : assert(value > -90.0),
      assert(value < 90.0),
      axis = 'slnt';

  /// Variable font width. (`wdth`)
  ///
  /// Varies the width of glyphs in the font.
  ///
  /// Values must be greater than zero, with no upper limit. 100.0 represents
  /// the "normal" width. Smaller values are "condensed", greater values are
  /// "extended".
  ///
  /// See also:
  ///
  ///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_wdth>
  const FontVariation.width(this.value) : assert(value >= 0.0), axis = 'wdth';

  /// Variable font weight. (`wght`)
  ///
  /// Applications should avoid using this and should instead declare font
  /// weight by specifying a [FontWeight], which will implicitly set this
  /// attribute. However, if a value is provided for this attribute, then it
  /// will override the [FontWeight].
  ///
  /// Varies the stroke thickness of the font.
  ///
  /// Values must be in the range 1..1000, and are to be interpreted in a manner
  /// consistent with the values of [FontWeight]. For instance, `400` is the
  /// "normal" weight, and `700` is "bold".
  ///
  /// See also:
  ///
  ///  * <https://learn.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_wght>
  const FontVariation.weight(this.value) : assert(value >= 1), assert(value <= 1000), axis = 'wght';

  // ------------------------------------------------------------------------
  // End of axis tags list.

  /// The tag that identifies the design axis.
  ///
  /// An axis tag must consist of 4 ASCII characters.
  final String axis;

  /// The value assigned to this design axis.
  ///
  /// The range of usable values depends on the specification of the axis.
  ///
  /// While this property is represented as a [double] in this API
  /// ([binary64](https://en.wikipedia.org/wiki/Double-precision_floating-point_format)),
  /// fonts use the fixed-point 16.16 format to represent the value of font
  /// variations. This means that the actual range is -32768.0 to approximately
  /// 32767.999985 and in principle the smallest increment between two values is
  /// approximately 0.000015 (1/65536).
  ///
  /// Unfortunately for technical reasons the value is first converted to the
  /// [binary32 floating point
  /// format](https://en.wikipedia.org/wiki/Single-precision_floating-point_format),
  /// which only has 24 bits of precision. This means that for values outside
  /// the range -256.0 to 256.0, the smallest increment is larger than what is
  /// technically supported by OpenType. At the extreme edge of the range, the
  /// smallest increment is only approximately ±0.002.
  final double value;

  static const int _kEncodedSize = 8;

  void _encode(ByteData byteData) {
    assert(axis.codeUnits.every((int c) => c >= 0x20 && c <= 0x7F));
    for (var i = 0; i < 4; i++) {
      byteData.setUint8(i, axis.codeUnitAt(i));
    }
    byteData.setFloat32(4, value, _kFakeHostEndian);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FontVariation && other.axis == axis && other.value == value;
  }

  @override
  int get hashCode => Object.hash(axis, value);

  /// Linearly interpolates between two font variations.
  ///
  /// If the two variations have different axis tags, the interpolation switches
  /// abruptly from one to the other at t=0.5. Otherwise, the value is
  /// interpolated (see [lerpDouble].
  ///
  /// The value is not clamped to the valid values of the axis tag, but it is
  /// clamped to the valid range of font variations values in general (the range
  /// of signed 16.16 fixed point numbers).
  ///
  /// The `t` argument represents position on the timeline, with 0.0 meaning
  /// that the interpolation has not started, returning `a` (or something
  /// equivalent to `a`), 1.0 meaning that the interpolation has finished,
  /// returning `b` (or something equivalent to `b`), and values in between
  /// meaning that the interpolation is at the relevant point on the timeline
  /// between `a` and `b`. The interpolation can be extrapolated beyond 0.0 and
  /// 1.0, so negative values and values greater than 1.0 are valid (and can
  /// easily be generated by curves such as [Curves.elasticInOut]).
  ///
  /// Values for `t` are usually obtained from an [Animation<double>], such as
  /// an [AnimationController].
  static FontVariation? lerp(FontVariation? a, FontVariation? b, double t) {
    if (a?.axis != b?.axis || (a == null && b == null)) {
      return t < 0.5 ? a : b;
    }
    return FontVariation(
      a!.axis,
      clampDouble(lerpDouble(a.value, b!.value, t)!, -32768.0, 32768.0 - 1.0 / 65536.0),
    );
  }

  @override
  String toString() => "FontVariation('$axis', $value)";
}

/// The measurements of a character (or a sequence of visually connected
/// characters) within a paragraph.
///
/// See also:
///
///  * [Paragraph.getGlyphInfoAt], which finds the [GlyphInfo] associated with
///    a code unit in the text.
///  * [Paragraph.getClosestGlyphInfoForOffset], which finds the [GlyphInfo] of
///    the glyph(s) onscreen that's closest to the given [Offset].
final class GlyphInfo {
  /// Creates a [GlyphInfo] with the specified values.
  GlyphInfo(
    this.graphemeClusterLayoutBounds,
    this.graphemeClusterCodeUnitRange,
    this.writingDirection,
  );

  GlyphInfo._(
    double left,
    double top,
    double right,
    double bottom,
    int graphemeStart,
    int graphemeEnd,
    bool isLTR,
  ) : graphemeClusterLayoutBounds = Rect.fromLTRB(left, top, right, bottom),
      graphemeClusterCodeUnitRange = TextRange(start: graphemeStart, end: graphemeEnd),
      writingDirection = isLTR ? TextDirection.ltr : TextDirection.rtl;

  /// The layout bounding rect of the associated character, in the paragraph's
  /// coordinates.
  ///
  /// This is **not** a tight bounding box that encloses the character's outline.
  /// The vertical extent reported is derived from the font metrics (instead of
  /// glyph metrics), and the horizontal extent is the horizontal advance of the
  /// character.
  final Rect graphemeClusterLayoutBounds;

  /// The UTF-16 range of the associated character in the text.
  final TextRange graphemeClusterCodeUnitRange;

  /// The writing direction within the [GlyphInfo].
  final TextDirection writingDirection;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    return other is GlyphInfo &&
        graphemeClusterLayoutBounds == other.graphemeClusterLayoutBounds &&
        graphemeClusterCodeUnitRange == other.graphemeClusterCodeUnitRange &&
        writingDirection == other.writingDirection;
  }

  @override
  int get hashCode =>
      Object.hash(graphemeClusterLayoutBounds, graphemeClusterCodeUnitRange, writingDirection);

  @override
  String toString() =>
      'Glyph($graphemeClusterLayoutBounds, textRange: $graphemeClusterCodeUnitRange, direction: $writingDirection)';
}

/// Whether and how to align text horizontally.
// The order of this enum must match the order of the values in RenderStyleConstants.h's ETextAlign.
enum TextAlign {
  /// Align the text on the left edge of the container.
  left,

  /// Align the text on the right edge of the container.
  right,

  /// Align the text in the center of the container.
  center,

  /// Stretch lines of text that end with a soft line break to fill the width of
  /// the container.
  ///
  /// Lines that end with hard line breaks are aligned towards the [start] edge.
  justify,

  /// Align the text on the leading edge of the container.
  ///
  /// For left-to-right text ([TextDirection.ltr]), this is the left edge.
  ///
  /// For right-to-left text ([TextDirection.rtl]), this is the right edge.
  start,

  /// Align the text on the trailing edge of the container.
  ///
  /// For left-to-right text ([TextDirection.ltr]), this is the right edge.
  ///
  /// For right-to-left text ([TextDirection.rtl]), this is the left edge.
  end,
}

/// A horizontal line used for aligning text.
enum TextBaseline {
  /// The horizontal line used to align the bottom of glyphs for alphabetic characters.
  ///
  /// This baseline is often used for alphabetical scripts like Latin, Greek,
  /// Cyrillic, etc.
  ///
  /// Characters with descenders (like 'p', 'g', or 'y') extend below this line.
  alphabetic,

  /// The horizontal line used to align ideographic characters.
  ///
  /// This baseline is often used for scripts with uniform square heights,
  /// like Chinese, Japanese, Korean, etc.
  ideographic,
}

/// A linear decoration to draw near the text.
final class TextDecoration {
  const TextDecoration._(this._mask);

  /// Creates a decoration that paints the union of all the given decorations.
  factory TextDecoration.combine(List<TextDecoration> decorations) {
    var mask = 0;
    for (final decoration in decorations) {
      mask |= decoration._mask;
    }
    return TextDecoration._(mask);
  }

  final int _mask;

  /// The bit mask value that represents this decoration.
  int get maskValue => _mask;

  /// Whether this decoration will paint at least as much decoration as the given decoration.
  bool contains(TextDecoration other) {
    return (_mask | other._mask) == _mask;
  }

  /// Do not draw a decoration
  static const TextDecoration none = TextDecoration._(0x0);

  /// Draw a line underneath each line of text
  static const TextDecoration underline = TextDecoration._(0x1);

  /// Draw a line above each line of text
  static const TextDecoration overline = TextDecoration._(0x2);

  /// Draw a line through each line of text
  static const TextDecoration lineThrough = TextDecoration._(0x4);

  @override
  bool operator ==(Object other) {
    return other is TextDecoration && other._mask == _mask;
  }

  @override
  int get hashCode => _mask.hashCode;

  @override
  String toString() {
    if (_mask == 0) {
      return 'TextDecoration.none';
    }
    final values = <String>[];
    if (_mask & underline._mask != 0) {
      values.add('underline');
    }
    if (_mask & overline._mask != 0) {
      values.add('overline');
    }
    if (_mask & lineThrough._mask != 0) {
      values.add('lineThrough');
    }
    if (values.length == 1) {
      return 'TextDecoration.${values[0]}';
    }
    return 'TextDecoration.combine([${values.join(", ")}])';
  }
}

/// The style in which to draw a text decoration
enum TextDecorationStyle {
  /// Draw a solid line
  solid,

  /// Draw two lines
  double,

  /// Draw a dotted line
  dotted,

  /// Draw a dashed line
  dashed,

  /// Draw a sinusoidal line
  wavy,
}

/// {@macro dart.ui.textLeadingDistribution}
enum TextLeadingDistribution {
  /// Distributes the [leading](https://en.wikipedia.org/wiki/Leading)
  /// of the text proportionally above and below the text, to the font's
  /// ascent/descent ratio.
  ///
  /// {@template dart.ui.leading}
  /// The leading of a text run is defined as
  /// `TextStyle.height * TextStyle.fontSize - TextStyle.fontSize`. When
  /// [TextStyle.height] is not set, the text run uses the leading specified by
  /// the font instead.
  /// {@endtemplate}
  proportional,

  /// Distributes the ["leading"](https://en.wikipedia.org/wiki/Leading)
  /// of the text evenly above and below the text (i.e. evenly above the
  /// font's ascender and below the descender).
  ///
  /// {@macro dart.ui.leading}
  ///
  /// The leading can become negative when [TextStyle.height] is smaller than
  /// 1.0.
  ///
  /// This is the default strategy used by CSS, known as
  /// ["half-leading"](https://www.w3.org/TR/css-inline-3/#half-leading).
  even,
}

/// {@template dart.ui.textHeightBehavior}
/// Defines how to apply [TextStyle.height] over and under text.
///
/// [TextHeightBehavior.applyHeightToFirstAscent] and
/// [TextHeightBehavior.applyHeightToLastDescent] represent whether the
/// [TextStyle.height] modifier will be applied to the corresponding metric. By
/// default both properties are true, and [TextStyle.height] is applied as
/// normal. When set to false, the font's default ascent will be used.
///
/// [TextHeightBehavior.leadingDistribution] determines how the
/// leading is distributed over and under text. This
/// property applies before [TextHeightBehavior.applyHeightToFirstAscent] and
/// [TextHeightBehavior.applyHeightToLastDescent].
///
/// {@endtemplate}
class TextHeightBehavior {
  /// Creates a new TextHeightBehavior object.
  ///
  ///  * applyHeightToFirstAscent: When true, the [TextStyle.height] modifier
  ///    will be applied to the ascent of the first line. When false, the font's
  ///    default ascent will be used.
  ///  * applyHeightToLastDescent: When true, the [TextStyle.height] modifier
  ///    will be applied to the descent of the last line. When false, the font's
  ///    default descent will be used.
  ///  * leadingDistribution: How the leading is distributed over and under
  ///    text.
  ///
  /// All properties default to true (height modifications applied as normal).
  const TextHeightBehavior({
    this.applyHeightToFirstAscent = true,
    this.applyHeightToLastDescent = true,
    this.leadingDistribution = TextLeadingDistribution.proportional,
  });

  /// Creates a new TextHeightBehavior object from an encoded form.
  ///
  /// See [_encode] for the creation of the encoded form.
  const TextHeightBehavior._fromEncoded(int encoded, this.leadingDistribution)
    : applyHeightToFirstAscent = (encoded & 0x1) == 0,
      applyHeightToLastDescent = (encoded & 0x2) == 0;

  /// Whether to apply the [TextStyle.height] modifier to the ascent of the first
  /// line in the paragraph.
  ///
  /// When true, the [TextStyle.height] modifier will be applied to the ascent
  /// of the first line. When false, the font's default ascent will be used and
  /// the [TextStyle.height] will have no effect on the ascent of the first line.
  ///
  /// This property only has effect if a non-null [TextStyle.height] is specified.
  ///
  /// Defaults to true (height modifications applied as normal).
  final bool applyHeightToFirstAscent;

  /// Whether to apply the [TextStyle.height] modifier to the descent of the last
  /// line in the paragraph.
  ///
  /// When true, the [TextStyle.height] modifier will be applied to the descent
  /// of the last line. When false, the font's default descent will be used and
  /// the [TextStyle.height] will have no effect on the descent of the last line.
  ///
  /// This property only has effect if a non-null [TextStyle.height] is specified.
  ///
  /// Defaults to true (height modifications applied as normal).
  final bool applyHeightToLastDescent;

  /// {@template dart.ui.textLeadingDistribution}
  /// How the ["leading"](https://en.wikipedia.org/wiki/Leading) is distributed
  /// over and under the text.
  ///
  /// Does not affect layout when [TextStyle.height] is not specified. The
  /// leading can become negative, for example, when [TextLeadingDistribution.even]
  /// is used with a [TextStyle.height] much smaller than 1.0.
  /// {@endtemplate}
  ///
  /// Defaults to [TextLeadingDistribution.proportional],
  final TextLeadingDistribution leadingDistribution;

  /// Returns an encoded int representation of this object (excluding
  /// [leadingDistribution]).
  int _encode() {
    return (applyHeightToFirstAscent ? 0 : 1 << 0) | (applyHeightToLastDescent ? 0 : 1 << 1);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is TextHeightBehavior &&
        other.applyHeightToFirstAscent == applyHeightToFirstAscent &&
        other.applyHeightToLastDescent == applyHeightToLastDescent &&
        other.leadingDistribution == leadingDistribution;
  }

  @override
  int get hashCode {
    return Object.hash(
      applyHeightToFirstAscent,
      applyHeightToLastDescent,
      leadingDistribution.index,
    );
  }

  @override
  String toString() {
    return 'TextHeightBehavior('
        'applyHeightToFirstAscent: $applyHeightToFirstAscent, '
        'applyHeightToLastDescent: $applyHeightToLastDescent, '
        'leadingDistribution: $leadingDistribution'
        ')';
  }
}

/// Determines if lists [a] and [b] are deep equivalent.
///
/// Returns true if the lists are both null, or if they are both non-null, have
/// the same length, and contain the same elements in the same order. Returns
/// false otherwise.
bool _listEquals<T>(List<T>? a, List<T>? b) {
  if (a == null) {
    return b == null;
  }
  if (b == null || a.length != b.length) {
    return false;
  }
  for (var index = 0; index < a.length; index += 1) {
    if (a[index] != b[index]) {
      return false;
    }
  }
  return true;
}

// This encoding must match the C++ version of ParagraphBuilder::pushStyle.
//
// The encoded array buffer has 8 elements.
//
//  - Element 0: A bit field where the ith bit indicates whether the ith element
//    has a non-null value. Bits 8 to 12 indicate whether |fontFamily|,
//    |fontSize|, |letterSpacing|, |wordSpacing|, and |height| are non-null,
//    respectively. Bit 0 indicates the [TextLeadingDistribution] of the text
//    style.
//
//  - Element 1: The |color| in ARGB with 8 bits per channel.
//
//  - Element 2: A bit field indicating which text decorations are present in
//    the |textDecoration| list. The ith bit is set if there's a TextDecoration
//    with enum index i in the list.
//
//  - Element 3: The |decorationColor| in ARGB with 8 bits per channel.
//
//  - Element 4: The bit field of the |decorationStyle|.
//
//  - Element 5: The index of the |fontWeight|.
//
//  - Element 6: The enum index of the |fontStyle|.
//
//  - Element 7: The enum index of the |textBaseline|.
//
Int32List _encodeTextStyle(
  Color? color,
  TextDecoration? decoration,
  Color? decorationColor,
  TextDecorationStyle? decorationStyle,
  double? decorationThickness,
  FontWeight? fontWeight,
  FontStyle? fontStyle,
  TextBaseline? textBaseline,
  String? fontFamily,
  List<String>? fontFamilyFallback,
  double? fontSize,
  double? letterSpacing,
  double? wordSpacing,
  double? height,
  Locale? locale,
  Paint? background,
  Paint? foreground,
  List<Shadow>? shadows,
  List<FontFeature>? fontFeatures,
  List<FontVariation>? fontVariations,
) {
  final result = Int32List(9);
  // The 0th bit of result[0] is reserved for leadingDistribution.

  if (color != null) {
    result[0] |= 1 << 1;
    result[1] = color.value;
  }
  if (decoration != null) {
    result[0] |= 1 << 2;
    result[2] = decoration._mask;
  }
  if (decorationColor != null) {
    result[0] |= 1 << 3;
    result[3] = decorationColor.value;
  }
  if (decorationStyle != null) {
    result[0] |= 1 << 4;
    result[4] = decorationStyle.index;
  }
  if (fontWeight != null) {
    result[0] |= 1 << 5;
    result[5] = fontWeight.value;
  }
  if (fontStyle != null) {
    result[0] |= 1 << 6;
    result[6] = fontStyle.index;
  }
  if (textBaseline != null) {
    result[0] |= 1 << 7;
    result[7] = textBaseline.index;
  }
  if (decorationThickness != null) {
    result[0] |= 1 << 8;
  }
  if (fontFamily != null || (fontFamilyFallback != null && fontFamilyFallback.isNotEmpty)) {
    result[0] |= 1 << 9;
    // Passed separately to native.
  }
  if (fontSize != null) {
    result[0] |= 1 << 10;
    // Passed separately to native.
  }
  if (letterSpacing != null) {
    result[0] |= 1 << 11;
    // Passed separately to native.
  }
  if (wordSpacing != null) {
    result[0] |= 1 << 12;
    // Passed separately to native.
  }
  if (height != null) {
    result[0] |= 1 << 13;
    // Passed separately to native.
  }
  if (locale != null) {
    result[0] |= 1 << 14;
    // Passed separately to native.
  }
  if (background != null) {
    result[0] |= 1 << 15;
    // Passed separately to native.
  }
  if (foreground != null) {
    result[0] |= 1 << 16;
    // Passed separately to native.
  }
  if (shadows != null) {
    result[0] |= 1 << 17;
    // Passed separately to native.
  }
  if (fontFeatures != null) {
    result[0] |= 1 << 18;
    // Passed separately to native.
  }
  if (fontVariations != null) {
    result[0] |= 1 << 19;
    // Passed separately to native.
  }

  return result;
}

/// An opaque object that determines the size, position, and rendering of text.
///
/// See also:
///
///  * [TextStyle](https://api.flutter.dev/flutter/painting/TextStyle-class.html), the class in the [painting] library.
///
class TextStyle {
  /// Creates a new TextStyle object.
  ///
  /// * `color`: The color to use when painting the text. If this is specified, `foreground` must be null.
  /// * `decoration`: The decorations to paint near the text (e.g., an underline).
  /// * `decorationColor`: The color in which to paint the text decorations.
  /// * `decorationStyle`: The style in which to paint the text decorations (e.g., dashed).
  /// * `decorationThickness`: The thickness of the decoration as a multiplier on the thickness specified by the font.
  /// * `fontWeight`: The typeface thickness to use when painting the text (e.g., bold).
  /// * `fontStyle`: The typeface variant to use when drawing the letters (e.g., italics).
  /// * `fontFamily`: The name of the font to use when painting the text (e.g., Roboto). If a `fontFamilyFallback` is
  ///   provided and `fontFamily` is not, then the first font family in `fontFamilyFallback` will take the position of
  ///   the preferred font family. When a higher priority font cannot be found or does not contain a glyph, a lower
  ///   priority font will be used.
  /// * `fontFamilyFallback`: An ordered list of the names of the fonts to fallback on when a glyph cannot
  ///   be found in a higher priority font. When the `fontFamily` is null, the first font family in this list
  ///   is used as the preferred font. Internally, the 'fontFamily` is concatenated to the front of this list.
  ///   When no font family is provided through 'fontFamilyFallback' (null or empty) or `fontFamily`, then the
  ///   platform default font will be used.
  /// * `fontSize`: The size of glyphs (in logical pixels) to use when painting the text.
  /// * `letterSpacing`: The amount of space (in logical pixels) to add between each letter.
  /// * `wordSpacing`: The amount of space (in logical pixels) to add at each sequence of white-space (i.e. between each word).
  /// * `textBaseline`: The common baseline that should be aligned between this text span and its parent text span, or, for the root text spans, with the line box.
  /// * `height`: The height of this text span, as a multiplier of the font size. Setting the `height` to `kTextHeightNone` will allow the line height
  ///   to take the height as defined by the font, which may not be exactly the height of the fontSize.
  /// * `leadingDistribution`: When `height` is set to a non-null that is not `kTextHeightNone`, how the extra vertical space should be distributed over and under the text.
  ///   Defaults to the paragraph's [TextHeightBehavior] if left unspecified.
  /// * `locale`: The locale used to select region-specific glyphs.
  /// * `background`: The paint drawn as a background for the text.
  /// * `foreground`: The paint used to draw the text. If this is specified, `color` must be null.
  /// * `fontFeatures`: The font features that should be applied to the text.
  /// * `fontVariations`: The font variations that should be applied to the text.
  TextStyle({
    Color? color,
    TextDecoration? decoration,
    Color? decorationColor,
    TextDecorationStyle? decorationStyle,
    double? decorationThickness,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    TextBaseline? textBaseline,
    String? fontFamily,
    List<String>? fontFamilyFallback,
    double? fontSize,
    double? letterSpacing,
    double? wordSpacing,
    double? height,
    TextLeadingDistribution? leadingDistribution,
    Locale? locale,
    Paint? background,
    Paint? foreground,
    List<Shadow>? shadows,
    List<FontFeature>? fontFeatures,
    List<FontVariation>? fontVariations,
  }) : assert(
         color == null || foreground == null,
         'Cannot provide both a color and a foreground\n'
         'The color argument is just a shorthand for "foreground: Paint()..color = color".',
       ),
       _encoded = _encodeTextStyle(
         color,
         decoration,
         decorationColor,
         decorationStyle,
         decorationThickness,
         fontWeight,
         fontStyle,
         textBaseline,
         fontFamily,
         fontFamilyFallback,
         fontSize,
         letterSpacing,
         wordSpacing,
         height,
         locale,
         background,
         foreground,
         shadows,
         fontFeatures,
         fontVariations,
       ),
       _leadingDistribution = leadingDistribution,
       _fontFamily = fontFamily ?? '',
       _fontFamilyFallback = fontFamilyFallback,
       _fontSize = fontSize,
       _letterSpacing = letterSpacing,
       _wordSpacing = wordSpacing,
       _height = height,
       _decorationThickness = decorationThickness,
       _locale = locale,
       _background = background,
       _foreground = foreground,
       _shadows = shadows,
       _fontFeatures = fontFeatures,
       _fontVariations = fontVariations;

  final Int32List _encoded;
  final String _fontFamily;
  final List<String>? _fontFamilyFallback;
  final double? _fontSize;
  final double? _letterSpacing;
  final double? _wordSpacing;
  final double? _height;
  final double? _decorationThickness;
  final Locale? _locale;
  final Paint? _background;
  final Paint? _foreground;
  final List<Shadow>? _shadows;
  final List<FontFeature>? _fontFeatures;
  final List<FontVariation>? _fontVariations;
  final TextLeadingDistribution? _leadingDistribution;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    return other is TextStyle &&
        other._leadingDistribution == _leadingDistribution &&
        other._fontFamily == _fontFamily &&
        other._fontSize == _fontSize &&
        other._letterSpacing == _letterSpacing &&
        other._wordSpacing == _wordSpacing &&
        other._height == _height &&
        other._decorationThickness == _decorationThickness &&
        other._locale == _locale &&
        other._background == _background &&
        other._foreground == _foreground &&
        _listEquals<int>(other._encoded, _encoded) &&
        _listEquals<Shadow>(other._shadows, _shadows) &&
        _listEquals<String>(other._fontFamilyFallback, _fontFamilyFallback) &&
        _listEquals<FontFeature>(other._fontFeatures, _fontFeatures) &&
        _listEquals<FontVariation>(other._fontVariations, _fontVariations);
  }

  @override
  int get hashCode {
    final List<Shadow>? shadows = _shadows;
    final List<FontFeature>? fontFeatures = _fontFeatures;
    final List<FontVariation>? fontVariations = _fontVariations;
    return Object.hash(
      Object.hashAll(_encoded),
      _leadingDistribution,
      _fontFamily,
      _fontFamilyFallback,
      _fontSize,
      _letterSpacing,
      _wordSpacing,
      _height,
      _locale,
      _background,
      _foreground,
      shadows == null ? null : Object.hashAll(shadows),
      _decorationThickness,
      fontFeatures == null ? null : Object.hashAll(fontFeatures),
      fontVariations == null ? null : Object.hashAll(fontVariations),
    );
  }

  @override
  String toString() {
    final List<String>? fontFamilyFallback = _fontFamilyFallback;
    final heightText = _encoded[0] & 0x02000 == 0x02000
        ? (_height == kTextHeightNone ? 'kTextHeightNone' : '${_height}x')
        : 'unspecified';
    return 'TextStyle('
        'color: ${_encoded[0] & 0x00002 == 0x00002 ? Color(_encoded[1]) : "unspecified"}, '
        'decoration: ${_encoded[0] & 0x00004 == 0x00004 ? TextDecoration._(_encoded[2]) : "unspecified"}, '
        'decorationColor: ${_encoded[0] & 0x00008 == 0x00008 ? Color(_encoded[3]) : "unspecified"}, '
        'decorationStyle: ${_encoded[0] & 0x00010 == 0x00010 ? TextDecorationStyle.values[_encoded[4]] : "unspecified"}, '
        // The decorationThickness is not in encoded order in order to keep it near the other decoration properties.
        'decorationThickness: ${_encoded[0] & 0x00100 == 0x00100 ? _decorationThickness : "unspecified"}, '
        'fontWeight: ${_encoded[0] & 0x00020 == 0x00020 ? FontWeight(_encoded[5]) : "unspecified"}, '
        'fontStyle: ${_encoded[0] & 0x00040 == 0x00040 ? FontStyle.values[_encoded[6]] : "unspecified"}, '
        'textBaseline: ${_encoded[0] & 0x00080 == 0x00080 ? TextBaseline.values[_encoded[7]] : "unspecified"}, '
        'fontFamily: ${_encoded[0] & 0x00200 == 0x00200 && _fontFamily != '' ? _fontFamily : "unspecified"}, '
        'fontFamilyFallback: ${_encoded[0] & 0x00200 == 0x00200 && fontFamilyFallback != null && fontFamilyFallback.isNotEmpty ? fontFamilyFallback : "unspecified"}, '
        'fontSize: ${_encoded[0] & 0x00400 == 0x00400 ? _fontSize : "unspecified"}, '
        'letterSpacing: ${_encoded[0] & 0x00800 == 0x00800 ? "${_letterSpacing}x" : "unspecified"}, '
        'wordSpacing: ${_encoded[0] & 0x01000 == 0x01000 ? "${_wordSpacing}x" : "unspecified"}, '
        'height: $heightText, '
        'leadingDistribution: ${_leadingDistribution ?? "unspecified"}, '
        'locale: ${_encoded[0] & 0x04000 == 0x04000 ? _locale : "unspecified"}, '
        'background: ${_encoded[0] & 0x08000 == 0x08000 ? _background : "unspecified"}, '
        'foreground: ${_encoded[0] & 0x10000 == 0x10000 ? _foreground : "unspecified"}, '
        'shadows: ${_encoded[0] & 0x20000 == 0x20000 ? _shadows : "unspecified"}, '
        'fontFeatures: ${_encoded[0] & 0x40000 == 0x40000 ? _fontFeatures : "unspecified"}, '
        'fontVariations: ${_encoded[0] & 0x80000 == 0x80000 ? _fontVariations : "unspecified"}'
        ')';
  }
}

// This encoding must match the C++ version ParagraphBuilder::build.
//
// The encoded array buffer has 6 elements.
//
//  - Element 0: A bit mask indicating which fields are non-null.
//    Bit 0 is unused. Bits 1-n are set if the corresponding index in the
//    encoded array is non-null.  The remaining bits represent fields that
//    are passed separately from the array.
//
//  - Element 1: The enum index of the |textAlign|.
//
//  - Element 2: The enum index of the |textDirection|.
//
//  - Element 3: The index of the |fontWeight|.
//
//  - Element 4: The enum index of the |fontStyle|.
//
//  - Element 5: The value of |maxLines|.
//
//  - Element 6: The encoded value of |textHeightBehavior|, except its leading
//    distribution.
Int32List _encodeParagraphStyle(
  TextAlign? textAlign,
  TextDirection? textDirection,
  int? maxLines,
  String? fontFamily,
  double? fontSize,
  double? height,
  TextHeightBehavior? textHeightBehavior,
  FontWeight? fontWeight,
  FontStyle? fontStyle,
  StrutStyle? strutStyle,
  String? ellipsis,
  Locale? locale,
) {
  final result = Int32List(7); // also update paragraph_builder.cc
  if (textAlign != null) {
    result[0] |= 1 << 1;
    result[1] = textAlign.index;
  }
  if (textDirection != null) {
    result[0] |= 1 << 2;
    result[2] = textDirection.index;
  }
  if (fontWeight != null) {
    result[0] |= 1 << 3;
    result[3] = fontWeight.value;
  }
  if (fontStyle != null) {
    result[0] |= 1 << 4;
    result[4] = fontStyle.index;
  }
  if (maxLines != null) {
    result[0] |= 1 << 5;
    result[5] = maxLines;
  }
  if (textHeightBehavior != null) {
    result[0] |= 1 << 6;
    result[6] = textHeightBehavior._encode();
  }
  if (fontFamily != null) {
    result[0] |= 1 << 7;
    // Passed separately to native.
  }
  if (fontSize != null) {
    result[0] |= 1 << 8;
    // Passed separately to native.
  }
  // Paragraph styles are unique in a paragraph, there is no inheriting so
  // height == null and height == kTextHeightNone are semantically equivalent.
  if (height != null && height != kTextHeightNone) {
    result[0] |= 1 << 9;
    // Passed separately to native.
  }
  if (strutStyle != null) {
    result[0] |= 1 << 10;
    // Passed separately to native.
  }
  if (ellipsis != null) {
    result[0] |= 1 << 11;
    // Passed separately to native.
  }
  if (locale != null) {
    result[0] |= 1 << 12;
    // Passed separately to native.
  }
  return result;
}

/// An opaque object that determines the configuration used by
/// [ParagraphBuilder] to position lines within a [Paragraph] of text.
class ParagraphStyle {
  /// Creates a new ParagraphStyle object.
  ///
  /// * `textAlign`: The alignment of the text within the lines of the
  ///   paragraph. If the last line is ellipsized (see `ellipsis` below), the
  ///   alignment is applied to that line after it has been truncated but before
  ///   the ellipsis has been added.
  ///   See: https://github.com/flutter/flutter/issues/9819
  ///
  /// * `textDirection`: The directionality of the text, left-to-right (e.g.
  ///   Norwegian) or right-to-left (e.g. Hebrew). This controls the overall
  ///   directionality of the paragraph, as well as the meaning of
  ///   [TextAlign.start] and [TextAlign.end] in the `textAlign` field.
  ///
  /// * `maxLines`: The maximum number of lines painted. Lines beyond this
  ///   number are silently dropped. For example, if `maxLines` is 1, then only
  ///   one line is rendered. If `maxLines` is null, but `ellipsis` is not null,
  ///   then lines after the first one that overflows the width constraints are
  ///   dropped. The width constraints are those set in the
  ///   [ParagraphConstraints] object passed to the [Paragraph.layout] method.
  ///
  /// * `fontFamily`: The name of the font family to apply when painting the text,
  ///   in the absence of a `textStyle` being attached to the span.
  ///
  /// * `fontSize`: The fallback size of glyphs (in logical pixels) to
  ///   use when painting the text. This is used when there is no [TextStyle].
  ///
  /// * `height`: The fallback height of the spans as a multiplier of the font
  ///   size. The fallback height is used when no height is provided through
  ///   [TextStyle.height]. Omitting `height` here (or setting it to
  ///   [kTextHeightNone]) and in [TextStyle] will allow the line height to take
  ///   the height as defined by the font, which may not be exactly the height of
  ///   the `fontSize`.
  ///
  /// * `textHeightBehavior`: Specifies how the `height` multiplier is
  ///   applied to ascent of the first line and the descent of the last line.
  ///
  /// * `leadingDistribution`: Specifies how the extra vertical space added by
  ///   the `height` multiplier should be distributed over and under the text.
  ///   Defaults to [TextLeadingDistribution.proportional].
  ///
  /// * `fontWeight`: The typeface thickness to use when painting the text
  ///   (e.g., bold).
  ///
  /// * `fontStyle`: The typeface variant to use when drawing the letters (e.g.,
  ///   italics).
  ///
  /// * `strutStyle`: The properties of the strut. Strut defines a set of minimum
  ///   vertical line height related metrics and can be used to obtain more
  ///   advanced line spacing behavior.
  ///
  /// * `ellipsis`: String used to ellipsize overflowing text. If `maxLines` is
  ///   not null, then the `ellipsis`, if any, is applied to the last rendered
  ///   line, if that line overflows the width constraints. If `maxLines` is
  ///   null, then the `ellipsis` is applied to the first line that overflows
  ///   the width constraints, and subsequent lines are dropped. The width
  ///   constraints are those set in the [ParagraphConstraints] object passed to
  ///   the [Paragraph.layout] method. The empty string and the null value are
  ///   considered equivalent and turn off this behavior.
  ///
  /// * `locale`: The locale used to select region-specific glyphs.
  ParagraphStyle({
    TextAlign? textAlign,
    TextDirection? textDirection,
    int? maxLines,
    String? fontFamily,
    double? fontSize,
    double? height,
    TextHeightBehavior? textHeightBehavior,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    StrutStyle? strutStyle,
    String? ellipsis,
    Locale? locale,
  }) : _encoded = _encodeParagraphStyle(
         textAlign,
         textDirection,
         maxLines,
         fontFamily,
         fontSize,
         height,
         textHeightBehavior,
         fontWeight,
         fontStyle,
         strutStyle,
         ellipsis,
         locale,
       ),
       _fontFamily = fontFamily,
       _fontSize = fontSize,
       _height = height,
       _strutStyle = strutStyle,
       _ellipsis = ellipsis,
       _locale = locale,
       _leadingDistribution =
           textHeightBehavior?.leadingDistribution ?? TextLeadingDistribution.proportional;

  final Int32List _encoded;
  final String? _fontFamily;
  final double? _fontSize;
  final double? _height;
  final StrutStyle? _strutStyle;
  final String? _ellipsis;
  final Locale? _locale;
  final TextLeadingDistribution _leadingDistribution;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is ParagraphStyle &&
        other._fontFamily == _fontFamily &&
        other._fontSize == _fontSize &&
        other._height == _height &&
        other._strutStyle == _strutStyle &&
        other._ellipsis == _ellipsis &&
        other._locale == _locale &&
        other._leadingDistribution == _leadingDistribution &&
        _listEquals<int>(other._encoded, _encoded);
  }

  @override
  int get hashCode => Object.hash(
    Object.hashAll(_encoded),
    _fontFamily,
    _fontSize,
    _height,
    _ellipsis,
    _locale,
    _leadingDistribution,
  );

  @override
  String toString() {
    return 'ParagraphStyle('
        'textAlign: ${_encoded[0] & 0x002 == 0x002 ? TextAlign.values[_encoded[1]] : "unspecified"}, '
        'textDirection: ${_encoded[0] & 0x004 == 0x004 ? TextDirection.values[_encoded[2]] : "unspecified"}, '
        'fontWeight: ${_encoded[0] & 0x008 == 0x008 ? FontWeight(_encoded[3]) : "unspecified"}, '
        'fontStyle: ${_encoded[0] & 0x010 == 0x010 ? FontStyle.values[_encoded[4]] : "unspecified"}, '
        'maxLines: ${_encoded[0] & 0x020 == 0x020 ? _encoded[5] : "unspecified"}, '
        'textHeightBehavior: ${_encoded[0] & 0x040 == 0x040 ? TextHeightBehavior._fromEncoded(_encoded[6], _leadingDistribution).toString() : "unspecified"}, '
        'fontFamily: ${_encoded[0] & 0x080 == 0x080 ? _fontFamily : "unspecified"}, '
        'fontSize: ${_encoded[0] & 0x100 == 0x100 ? _fontSize : "unspecified"}, '
        'height: ${_encoded[0] & 0x200 == 0x200 ? "${_height}x" : "unspecified"}, '
        'strutStyle: ${_encoded[0] & 0x400 == 0x400 ? _strutStyle : "unspecified"}, '
        'ellipsis: ${_encoded[0] & 0x800 == 0x800 ? '"$_ellipsis"' : "unspecified"}, '
        'locale: ${_encoded[0] & 0x1000 == 0x1000 ? _locale : "unspecified"}'
        ')';
  }
}

// Serialize strut properties into ByteData. This encoding errs towards
// compactness. The first 8 bits is a bitmask that records which properties are
// null. The rest of the values are encoded in the same order encountered in the
// bitmask. The final returned value truncates any unused bytes at the end. For
// ease of decoding, all 8 bit integers are stored before any 32 bit integers.
//
// We serialize this more thoroughly than ParagraphStyle because it is
// much more likely that the strut is empty/null and we wish to add
// minimal overhead for non-strut cases.
ByteData _encodeStrut(
  String? fontFamily,
  List<String>? fontFamilyFallback,
  double? fontSize,
  double? height,
  TextLeadingDistribution? leadingDistribution,
  double? leading,
  FontWeight? fontWeight,
  FontStyle? fontStyle,
  bool? forceStrutHeight,
) {
  // Strut styles are unique in a paragraph, there is no inheriting so
  // height == null and height == kTextHeightNone are semantically equivalent.
  final bool hasHeightOverride = height != null && height != kTextHeightNone;
  if (fontFamily == null &&
      fontSize == null &&
      !hasHeightOverride &&
      leadingDistribution == null &&
      leading == null &&
      fontWeight == null &&
      fontStyle == null &&
      forceStrutHeight == null) {
    return ByteData(0);
  }

  final data = ByteData(24); // Max size is 24 bytes
  var bitmask = 0;
  var byteCount = 4;
  if (fontWeight != null) {
    bitmask |= 1 << 0;
    data.setInt32(byteCount, fontWeight.value, _kFakeHostEndian);
    byteCount += 4;
  }
  if (fontStyle != null) {
    bitmask |= 1 << 1;
    data.setInt32(byteCount, fontStyle.index, _kFakeHostEndian);
    byteCount += 4;
  }
  if (fontFamily != null || (fontFamilyFallback != null && fontFamilyFallback.isNotEmpty)) {
    bitmask |= 1 << 2;
    // passed separately to native
  }

  // The 3rd bit (0-indexed) is reserved for leadingDistribution.

  if (fontSize != null) {
    bitmask |= 1 << 4;
    data.setFloat32(byteCount, fontSize, _kFakeHostEndian);
    byteCount += 4;
  }
  if (hasHeightOverride) {
    bitmask |= 1 << 5;
    data.setFloat32(byteCount, height, _kFakeHostEndian);
    byteCount += 4;
  }
  if (leading != null) {
    bitmask |= 1 << 6;
    data.setFloat32(byteCount, leading, _kFakeHostEndian);
    byteCount += 4;
  }
  if (forceStrutHeight ?? false) {
    bitmask |= 1 << 7;
  }

  data.setInt32(0, bitmask, _kFakeHostEndian);

  assert(byteCount <= 24);
  assert(bitmask >> 32 == 0, 'strut bitmask overflow: $bitmask');
  return ByteData.view(data.buffer, 0, byteCount);
}

/// See also:
///
///  * [StrutStyle](https://api.flutter.dev/flutter/painting/StrutStyle-class.html), the class in the [painting] library.
///
class StrutStyle {
  /// Creates a new StrutStyle object.
  ///
  /// * `fontFamily`: The name of the font to use when painting the text (e.g.,
  ///   Roboto).
  ///
  /// * `fontFamilyFallback`: An ordered list of font family names that will be
  ///    searched for when the font in `fontFamily` cannot be found.
  ///
  /// * `fontSize`: The size of glyphs (in logical pixels) to use when painting
  ///   the text.
  ///
  /// * `height`: The minimum height of the line boxes, as a multiplier of the
  ///   font size. The lines of the paragraph will be at least
  ///   `(height + leading) * fontSize` tall when `fontSize` is not null. Omitting
  ///   `height` (or setting it to [kTextHeightNone]) will allow the minimum line
  ///   height to take the height as defined by the font, which may not be exactly
  ///   the height of the `fontSize`. When `fontSize` is null, there is no minimum
  ///   line height. Tall glyphs due to baseline alignment or large
  ///   [TextStyle.fontSize] may cause the actual line height after layout to be
  ///   taller than specified here. The `fontSize` must be provided for
  ///   this property to take effect.
  ///
  /// * `leading`: The minimum amount of leading between lines as a multiple of
  ///   the font size. `fontSize` must be provided for this property to take
  ///   effect. The leading added by this property is distributed evenly over
  ///   and under the text, regardless of `leadingDistribution`.
  ///
  /// * `leadingDistribution`: how the extra vertical space added by the
  ///   `height` multiplier should be distributed over and under the text,
  ///   independent of `leading` (which is always distributed evenly over and
  ///   under text). Defaults to the paragraph's [TextHeightBehavior]'s leading
  ///   distribution.
  ///
  /// * `fontWeight`: The typeface thickness to use when painting the text
  ///   (e.g., bold).
  ///
  /// * `fontStyle`: The typeface variant to use when drawing the letters (e.g.,
  ///   italics).
  ///
  /// * `forceStrutHeight`: When true, the paragraph will force all lines to be exactly
  ///   `(height + leading) * fontSize` tall from baseline to baseline.
  ///   [TextStyle] is no longer able to influence the line height, and any tall
  ///   glyphs may overlap with lines above. If a `fontFamily` is specified, the
  ///   total ascent of the first line will be the min of the `Ascent + half-leading`
  ///   of the `fontFamily` and `(height + leading) * fontSize`. Otherwise, it
  ///   will be determined by the Ascent + half-leading of the first text.
  StrutStyle({
    String? fontFamily,
    List<String>? fontFamilyFallback,
    double? fontSize,
    double? height,
    TextLeadingDistribution? leadingDistribution,
    double? leading,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    bool? forceStrutHeight,
  }) : _encoded = _encodeStrut(
         fontFamily,
         fontFamilyFallback,
         fontSize,
         height,
         leadingDistribution,
         leading,
         fontWeight,
         fontStyle,
         forceStrutHeight,
       ),
       _leadingDistribution = leadingDistribution,
       _fontFamily = fontFamily,
       _fontFamilyFallback = fontFamilyFallback;

  final ByteData _encoded; // Most of the data for strut is encoded.
  final String? _fontFamily;
  final List<String>? _fontFamilyFallback;
  final TextLeadingDistribution? _leadingDistribution;

  bool get _enabled => _encoded.lengthInBytes > 0;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is StrutStyle &&
        other._fontFamily == _fontFamily &&
        other._leadingDistribution == _leadingDistribution &&
        _listEquals<String>(other._fontFamilyFallback, _fontFamilyFallback) &&
        _listEquals<int>(other._encoded.buffer.asInt8List(), _encoded.buffer.asInt8List());
  }

  @override
  int get hashCode =>
      Object.hash(Object.hashAll(_encoded.buffer.asInt8List()), _fontFamily, _leadingDistribution);
}

/// A direction in which text flows.
///
/// Some languages are written from the left to the right (for example, English,
/// Tamil, or Chinese), while others are written from the right to the left (for
/// example Aramaic, Hebrew, or Urdu). Some are also written in a mixture, for
/// example Arabic is mostly written right-to-left, with numerals written
/// left-to-right.
///
/// The text direction must be provided to APIs that render text or lay out
/// boxes horizontally, so that they can determine which direction to start in:
/// either right-to-left, [TextDirection.rtl]; or left-to-right,
/// [TextDirection.ltr].
///
/// ## Design discussion
///
/// Flutter is designed to address the needs of applications written in any of
/// the world's currently-used languages, whether they use a right-to-left or
/// left-to-right writing direction. Flutter does not support other writing
/// modes, such as vertical text or boustrophedon text, as these are rarely used
/// in computer programs.
///
/// It is common when developing user interface frameworks to pick a default
/// text direction — typically left-to-right, the direction most familiar to the
/// engineers working on the framework — because this simplifies the development
/// of applications on the platform. Unfortunately, this frequently results in
/// the platform having unexpected left-to-right biases or assumptions, as
/// engineers will typically miss places where they need to support
/// right-to-left text. This then results in bugs that only manifest in
/// right-to-left environments.
///
/// In an effort to minimize the extent to which Flutter experiences this
/// category of issues, the lowest levels of the Flutter framework do not have a
/// default text reading direction. Any time a reading direction is necessary,
/// for example when text is to be displayed, or when a
/// writing-direction-dependent value is to be interpreted, the reading
/// direction must be explicitly specified. Where possible, such as in `switch`
/// statements, the right-to-left case is listed first, to avoid the impression
/// that it is an afterthought.
///
/// At the higher levels (specifically starting at the widgets library), an
/// ambient [Directionality] is introduced, which provides a default. Thus, for
/// instance, a [widgets.Text] widget in the scope of a [MaterialApp] widget
/// does not need to be given an explicit writing direction. The
/// [Directionality.of] static method can be used to obtain the ambient text
/// direction for a particular [BuildContext].
///
/// ### Known left-to-right biases in Flutter
///
/// Despite the design intent described above, certain left-to-right biases have
/// nonetheless crept into Flutter's design. These include:
///
///  * The [Canvas] origin is at the top left, and the x-axis increases in a
///    left-to-right direction.
///
///  * The default localization in the widgets and material libraries is
///    American English, which is left-to-right.
///
/// ### Visual properties vs directional properties
///
/// Many classes in the Flutter framework are offered in two versions, a
/// visually-oriented variant, and a text-direction-dependent variant. For
/// example, [EdgeInsets] is described in terms of top, left, right, and bottom,
/// while [EdgeInsetsDirectional] is described in terms of top, start, end, and
/// bottom, where start and end correspond to right and left in right-to-left
/// text and left and right in left-to-right text.
///
/// There are distinct use cases for each of these variants.
///
/// Text-direction-dependent variants are useful when developing user interfaces
/// that should "flip" with the text direction. For example, a paragraph of text
/// in English will typically be left-aligned and a quote will be indented from
/// the left, while in Arabic it will be right-aligned and indented from the
/// right. Both of these cases are described by the direction-dependent
/// [TextAlign.start] and [EdgeInsetsDirectional.start].
///
/// In contrast, the visual variants are useful when the text direction is known
/// and not affected by the reading direction. For example, an application
/// giving driving directions might show a "turn left" arrow on the left and a
/// "turn right" arrow on the right — and would do so whether the application
/// was localized to French (left-to-right) or Hebrew (right-to-left).
///
/// In practice, it is also expected that many developers will only be
/// targeting one language, and in that case it may be simpler to think in
/// visual terms.
// The order of this enum must match the order of the values in TextDirection.h's TextDirection.
enum TextDirection {
  /// The text flows from right to left (e.g. Arabic, Hebrew).
  rtl,

  /// The text flows from left to right (e.g., English, French).
  ltr,
}

/// A rectangle enclosing a run of text.
///
/// This is similar to [Rect] but includes an inherent [TextDirection].
class TextBox {
  /// Creates an object that describes a box containing text.
  const TextBox.fromLTRBD(this.left, this.top, this.right, this.bottom, this.direction);

  /// The left edge of the text box, irrespective of direction.
  ///
  /// To get the leading edge (which may depend on the [direction]), consider [start].
  final double left;

  /// The top edge of the text box.
  final double top;

  /// The right edge of the text box, irrespective of direction.
  ///
  /// To get the trailing edge (which may depend on the [direction]), consider [end].
  final double right;

  /// The bottom edge of the text box.
  final double bottom;

  /// The direction in which text inside this box flows.
  final TextDirection direction;

  /// Returns a rect of the same size as this box.
  Rect toRect() => Rect.fromLTRB(left, top, right, bottom);

  /// The [left] edge of the box for left-to-right text; the [right] edge of the box for right-to-left text.
  ///
  /// See also:
  ///
  ///  * [direction], which specifies the text direction.
  double get start {
    return (direction == TextDirection.ltr) ? left : right;
  }

  /// The [right] edge of the box for left-to-right text; the [left] edge of the box for right-to-left text.
  ///
  /// See also:
  ///
  ///  * [direction], which specifies the text direction.
  double get end {
    return (direction == TextDirection.ltr) ? right : left;
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is TextBox &&
        other.left == left &&
        other.top == top &&
        other.right == right &&
        other.bottom == bottom &&
        other.direction == direction;
  }

  @override
  int get hashCode => Object.hash(left, top, right, bottom, direction);

  @override
  String toString() =>
      'TextBox.fromLTRBD(${left.toStringAsFixed(1)}, ${top.toStringAsFixed(1)}, ${right.toStringAsFixed(1)}, ${bottom.toStringAsFixed(1)}, $direction)';
}

/// A way to disambiguate a [TextPosition] when its offset could match two
/// different locations in the rendered string.
///
/// For example, at an offset where the rendered text wraps, there are two
/// visual positions that the offset could represent: one prior to the line
/// break (at the end of the first line) and one after the line break (at the
/// start of the second line). A text affinity disambiguates between these two
/// cases.
///
/// This affects only line breaks caused by wrapping, not explicit newline
/// characters. For newline characters, the position is fully specified by the
/// offset alone, and there is no ambiguity.
///
/// [TextAffinity] also affects bidirectional text at the interface between LTR
/// and RTL text. Consider the following string, where the lowercase letters
/// will be displayed as LTR and the uppercase letters RTL: "helloHELLO".  When
/// rendered, the string would appear visually as "helloOLLEH".  An offset of 5
/// would be ambiguous without a corresponding [TextAffinity].  Looking at the
/// string in code, the offset represents the position just after the "o" and
/// just before the "H".  When rendered, this offset could be either in the
/// middle of the string to the right of the "o" or at the end of the string to
/// the right of the "H".
enum TextAffinity {
  /// The position has affinity for the upstream side of the text position, i.e.
  /// in the direction of the beginning of the string.
  ///
  /// In the example of an offset at the place where text is wrapping, upstream
  /// indicates the end of the first line.
  ///
  /// In the bidirectional text example "helloHELLO", an offset of 5 with
  /// [TextAffinity] upstream would appear in the middle of the rendered text,
  /// just to the right of the "o". See the definition of [TextAffinity] for the
  /// full example.
  upstream,

  /// The position has affinity for the downstream side of the text position,
  /// i.e. in the direction of the end of the string.
  ///
  /// In the example of an offset at the place where text is wrapping,
  /// downstream indicates the beginning of the second line.
  ///
  /// In the bidirectional text example "helloHELLO", an offset of 5 with
  /// [TextAffinity] downstream would appear at the end of the rendered text,
  /// just to the right of the "H". See the definition of [TextAffinity] for the
  /// full example.
  downstream,
}

/// A position in a string of text.
///
/// A TextPosition can be used to describe a caret position in between
/// characters. The [offset] points to the position between `offset - 1` and
/// `offset` characters of the string, and the [affinity] is used to describe
/// which character this position affiliates with.
///
/// One use case is when rendered text is forced to wrap. In this case, the offset
/// where the wrap occurs could visually appear either at the end of the first
/// line or the beginning of the second line. The second way is with
/// bidirectional text.  An offset at the interface between two different text
/// directions could have one of two locations in the rendered text.
///
/// See the documentation for [TextAffinity] for more information on how
/// TextAffinity disambiguates situations like these.
class TextPosition {
  /// Creates an object representing a particular position in a string.
  ///
  /// The arguments must not be null (so the [offset] argument is required).
  const TextPosition({required this.offset, this.affinity = TextAffinity.downstream});

  /// The index of the character that immediately follows the position in the
  /// string representation of the text.
  ///
  /// For example, given the string `'Hello'`, offset 0 represents the cursor
  /// being before the `H`, while offset 5 represents the cursor being just
  /// after the `o`.
  final int offset;

  /// Disambiguates cases where the position in the string given by [offset]
  /// could represent two different visual positions in the rendered text. For
  /// example, this can happen when text is forced to wrap, or when one string
  /// of text is rendered with multiple text directions.
  ///
  /// See the documentation for [TextAffinity] for more information on how
  /// TextAffinity disambiguates situations like these.
  final TextAffinity affinity;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is TextPosition && other.offset == offset && other.affinity == affinity;
  }

  @override
  int get hashCode => Object.hash(offset, affinity);

  @override
  String toString() {
    return 'TextPosition(offset: $offset, affinity: $affinity)';
  }
}

/// A range of characters in a string of text.
class TextRange {
  /// Creates a text range.
  ///
  /// The [start] and [end] arguments must not be null. Both the [start] and
  /// [end] must either be greater than or equal to zero or both exactly -1.
  ///
  /// The text included in the range includes the character at [start], but not
  /// the one at [end].
  ///
  /// Instead of creating an empty text range, consider using the [empty]
  /// constant.
  const TextRange({required this.start, required this.end})
    : assert(start >= -1),
      assert(end >= -1);

  /// A text range that starts and ends at offset.
  ///
  /// The [offset] argument must be non-null and greater than or equal to -1.
  const TextRange.collapsed(int offset) : assert(offset >= -1), start = offset, end = offset;

  /// A text range that contains nothing and is not in the text.
  static const TextRange empty = TextRange(start: -1, end: -1);

  /// The index of the first character in the range.
  ///
  /// If [start] and [end] are both -1, the text range is empty.
  final int start;

  /// The next index after the characters in this range.
  ///
  /// If [start] and [end] are both -1, the text range is empty.
  final int end;

  /// Whether this range represents a valid position in the text.
  bool get isValid => start >= 0 && end >= 0;

  /// Whether this range is empty (but still potentially placed inside the text).
  bool get isCollapsed => start == end;

  /// Whether the start of this range precedes the end.
  bool get isNormalized => end >= start;

  /// The text before this range.
  String textBefore(String text) {
    assert(isNormalized);
    return text.substring(0, start);
  }

  /// The text after this range.
  String textAfter(String text) {
    assert(isNormalized);
    return text.substring(end);
  }

  /// The text inside this range.
  String textInside(String text) {
    assert(isNormalized);
    return text.substring(start, end);
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    return other is TextRange && other.start == start && other.end == end;
  }

  @override
  int get hashCode => Object.hash(start.hashCode, end.hashCode);

  @override
  String toString() => 'TextRange(start: $start, end: $end)';
}

/// Layout constraints for [Paragraph] objects.
///
/// Instances of this class are typically used with [Paragraph.layout].
///
/// The only constraint that can be specified is the [width]. See the discussion
/// at [width] for more details.
class ParagraphConstraints {
  /// Creates constraints for laying out a paragraph.
  ///
  /// The [width] argument must not be null.
  const ParagraphConstraints({required this.width});

  /// The width the paragraph should use whey computing the positions of glyphs.
  ///
  /// If possible, the paragraph will select a soft line break prior to reaching
  /// this width. If no soft line break is available, the paragraph will select
  /// a hard line break prior to reaching this width. If that would force a line
  /// break without any characters having been placed (i.e. if the next
  /// character to be laid out does not fit within the given width constraint)
  /// then the next character is allowed to overflow the width constraint and a
  /// forced line break is placed after it (even if an explicit line break
  /// follows).
  ///
  /// The width influences how ellipses are applied. See the discussion at
  /// [ParagraphStyle.new] for more details.
  ///
  /// This width is also used to position glyphs according to the [TextAlign]
  /// alignment described in the [ParagraphStyle] used when building the
  /// [Paragraph] with a [ParagraphBuilder].
  final double width;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is ParagraphConstraints && other.width == width;
  }

  @override
  int get hashCode => width.hashCode;

  @override
  String toString() => 'ParagraphConstraints(width: $width)';
}

/// Defines various ways to vertically bound the boxes returned by
/// [Paragraph.getBoxesForRange].
///
/// See [BoxWidthStyle] for a similar property to control width.
enum BoxHeightStyle {
  /// Provide tight bounding boxes that fit heights per run. This style may result
  /// in uneven bounding boxes that do not nicely connect with adjacent boxes.
  tight,

  /// The height of the boxes will be the maximum height of all runs in the
  /// line. All boxes in the same line will be the same height.
  ///
  /// This does not guarantee that the boxes will cover the entire vertical height of the line
  /// when there is additional line spacing.
  ///
  /// See [BoxHeightStyle.includeLineSpacingTop], [BoxHeightStyle.includeLineSpacingMiddle],
  /// and [BoxHeightStyle.includeLineSpacingBottom] for styles that will cover
  /// the entire line.
  max,

  /// Extends the top and bottom edge of the bounds to fully cover any line
  /// spacing.
  ///
  /// The top and bottom of each box will cover half of the
  /// space above and half of the space below the line.
  ///
  /// {@template dart.ui.boxHeightStyle.includeLineSpacing}
  /// The top edge of each line should be the same as the bottom edge
  /// of the line above. There should be no gaps in vertical coverage given any
  /// amount of line spacing. Line spacing is not included above the first line
  /// and below the last line due to no additional space present there.
  /// {@endtemplate}
  includeLineSpacingMiddle,

  /// Extends the top edge of the bounds to fully cover any line spacing.
  ///
  /// The line spacing will be added to the top of the box.
  ///
  /// {@macro dart.ui.boxHeightStyle.includeLineSpacing}
  includeLineSpacingTop,

  /// Extends the bottom edge of the bounds to fully cover any line spacing.
  ///
  /// The line spacing will be added to the bottom of the box.
  ///
  /// {@macro dart.ui.boxHeightStyle.includeLineSpacing}
  includeLineSpacingBottom,

  /// Calculate box heights based on the metrics of this paragraph's [StrutStyle].
  ///
  /// Boxes based on the strut will have consistent heights throughout the
  /// entire paragraph.  The top edge of each line will align with the bottom
  /// edge of the previous line.  It is possible for glyphs to extend outside
  /// these boxes.
  strut,
}

/// Defines various ways to horizontally bound the boxes returned by
/// [Paragraph.getBoxesForRange].
///
/// See [BoxHeightStyle] for a similar property to control height.
enum BoxWidthStyle {
  /// Provide tight bounding boxes that fit widths to the runs of each line
  /// independently.
  tight,

  /// Adds up to two additional boxes as needed at the beginning and/or end
  /// of each line so that the widths of the boxes in line are the same width
  /// as the widest line in the paragraph.
  ///
  /// The additional boxes on each line are only added when the relevant box
  /// at the relevant edge of that line does not span the maximum width of
  /// the paragraph.
  max,
}

/// Where to vertically align the placeholder relative to the surrounding text.
///
/// Used by [ParagraphBuilder.addPlaceholder].
enum PlaceholderAlignment {
  /// Match the baseline of the placeholder with the baseline.
  ///
  /// The [TextBaseline] to use must be specified and non-null when using this
  /// alignment mode.
  baseline,

  /// Align the bottom edge of the placeholder with the baseline such that the
  /// placeholder sits on top of the baseline.
  ///
  /// The [TextBaseline] to use must be specified and non-null when using this
  /// alignment mode.
  aboveBaseline,

  /// Align the top edge of the placeholder with the baseline specified
  /// such that the placeholder hangs below the baseline.
  ///
  /// The [TextBaseline] to use must be specified and non-null when using this
  /// alignment mode.
  belowBaseline,

  /// Align the top edge of the placeholder with the top edge of the text.
  ///
  /// When the placeholder is very tall, the extra space will hang from
  /// the top and extend through the bottom of the line.
  top,

  /// Align the bottom edge of the placeholder with the bottom edge of the text.
  ///
  /// When the placeholder is very tall, the extra space will rise from the
  /// bottom and extend through the top of the line.
  bottom,

  /// Align the middle of the placeholder with the middle of the text.
  ///
  /// When the placeholder is very tall, the extra space will grow equally
  /// from the top and bottom of the line.
  middle,
}

/// [LineMetrics] stores the measurements and statistics of a single line in the
/// paragraph.
///
/// The measurements here are for the line as a whole, and represent the maximum
/// extent of the line instead of per-run or per-glyph metrics. For more detailed
/// metrics, see [TextBox] and [Paragraph.getBoxesForRange].
///
/// [LineMetrics] should be obtained directly from the [Paragraph.computeLineMetrics]
/// method.
class LineMetrics {
  /// Creates a [LineMetrics] object with only the specified values.
  LineMetrics({
    required this.hardBreak,
    required this.ascent,
    required this.descent,
    required this.unscaledAscent,
    required this.height,
    required this.width,
    required this.left,
    required this.baseline,
    required this.lineNumber,
  });

  LineMetrics._(
    this.hardBreak,
    this.ascent,
    this.descent,
    this.unscaledAscent,
    this.height,
    this.width,
    this.left,
    this.baseline,
    this.lineNumber,
  );

  /// True if this line ends with an explicit line break (e.g. '\n') or is the end
  /// of the paragraph. False otherwise.
  final bool hardBreak;

  /// The rise from the [baseline] as calculated from the font and style for this line.
  ///
  /// This is the final computed ascent and can be impacted by the strut, height, scaling,
  /// as well as outlying runs that are very tall.
  ///
  /// The [ascent] is provided as a positive value, even though it is typically defined
  /// in fonts as negative. This is to ensure the signage of operations with these
  /// metrics directly reflects the intended signage of the value. For example,
  /// the y coordinate of the top edge of the line is `baseline - ascent`.
  final double ascent;

  /// The drop from the [baseline] as calculated from the font and style for this line.
  ///
  /// This is the final computed ascent and can be impacted by the strut, height, scaling,
  /// as well as outlying runs that are very tall.
  ///
  /// The y coordinate of the bottom edge of the line is `baseline + descent`.
  final double descent;

  /// The rise from the [baseline] as calculated from the font and style for this line
  /// ignoring the [TextStyle.height].
  ///
  /// The [unscaledAscent] is provided as a positive value, even though it is typically
  /// defined in fonts as negative. This is to ensure the signage of operations with
  /// these metrics directly reflects the intended signage of the value.
  final double unscaledAscent;

  /// Total height of the line from the top edge to the bottom edge.
  ///
  /// This is equivalent to `round(ascent + descent)`. This value is provided
  /// separately due to rounding causing sub-pixel differences from the unrounded
  /// values.
  final double height;

  /// Width of the line from the left edge of the leftmost glyph to the right
  /// edge of the rightmost glyph.
  ///
  /// This is not the same as the width of the pargraph.
  ///
  /// See also:
  ///
  ///  * [Paragraph.width], the max width passed in during layout.
  ///  * [Paragraph.longestLine], the width of the longest line in the paragraph.
  final double width;

  /// The x coordinate of left edge of the line.
  ///
  /// The right edge can be obtained with `left + width`.
  final double left;

  /// The y coordinate of the baseline for this line from the top of the paragraph.
  ///
  /// The bottom edge of the paragraph up to and including this line may be obtained
  /// through `baseline + descent`.
  final double baseline;

  /// The number of this line in the overall paragraph, with the first line being
  /// index zero.
  ///
  /// For example, the first line is line 0, second line is line 1.
  final int lineNumber;

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is LineMetrics &&
        other.hardBreak == hardBreak &&
        other.ascent == ascent &&
        other.descent == descent &&
        other.unscaledAscent == unscaledAscent &&
        other.height == height &&
        other.width == width &&
        other.left == left &&
        other.baseline == baseline &&
        other.lineNumber == lineNumber;
  }

  @override
  int get hashCode => Object.hash(
    hardBreak,
    ascent,
    descent,
    unscaledAscent,
    height,
    width,
    left,
    baseline,
    lineNumber,
  );

  @override
  String toString() {
    return 'LineMetrics(hardBreak: $hardBreak, '
        'ascent: $ascent, '
        'descent: $descent, '
        'unscaledAscent: $unscaledAscent, '
        'height: $height, '
        'width: $width, '
        'left: $left, '
        'baseline: $baseline, '
        'lineNumber: $lineNumber)';
  }
}

/// A paragraph of text.
///
/// A paragraph retains the size and position of each glyph in the text and can
/// be efficiently resized and painted.
///
/// To create a [Paragraph] object, use a [ParagraphBuilder].
///
/// Paragraphs can be displayed on a [Canvas] using the [Canvas.drawParagraph]
/// method.
abstract class Paragraph {
  /// The amount of horizontal space this paragraph occupies.
  ///
  /// Valid only after [layout] has been called.
  double get width;

  /// The amount of vertical space this paragraph occupies.
  ///
  /// Valid only after [layout] has been called.
  double get height;

  /// The distance from the left edge of the leftmost glyph to the right edge of
  /// the rightmost glyph in the paragraph.
  ///
  /// Valid only after [layout] has been called.
  double get longestLine;

  /// The minimum width that this paragraph could be without failing to paint
  /// its contents within itself.
  ///
  /// Valid only after [layout] has been called.
  double get minIntrinsicWidth;

  /// Returns the smallest width beyond which increasing the width never
  /// decreases the height.
  ///
  /// Valid only after [layout] has been called.
  double get maxIntrinsicWidth;

  /// The distance from the top of the paragraph to the alphabetic
  /// baseline of the first line, in logical pixels.
  double get alphabeticBaseline;

  /// The distance from the top of the paragraph to the ideographic
  /// baseline of the first line, in logical pixels.
  double get ideographicBaseline;

  /// True if there is more vertical content, but the text was truncated, either
  /// because we reached `maxLines` lines of text or because the `maxLines` was
  /// null, `ellipsis` was not null, and one of the lines exceeded the width
  /// constraint.
  ///
  /// See the discussion of the `maxLines` and `ellipsis` arguments at
  /// [ParagraphStyle.new].
  bool get didExceedMaxLines;

  /// Computes the size and position of each glyph in the paragraph.
  ///
  /// The [ParagraphConstraints] control how wide the text is allowed to be.
  void layout(ParagraphConstraints constraints);

  /// Returns a list of text boxes that enclose the given text range.
  ///
  /// The [boxHeightStyle] and [boxWidthStyle] parameters allow customization
  /// of how the boxes are bound vertically and horizontally. Both style
  /// parameters default to the tight option, which will provide close-fitting
  /// boxes and will not account for any line spacing.
  ///
  /// Coordinates of the TextBox are relative to the upper-left corner of the paragraph,
  /// where positive y values indicate down.
  ///
  /// The [boxHeightStyle] and [boxWidthStyle] parameters must not be null.
  ///
  /// See [BoxHeightStyle] and [BoxWidthStyle] for full descriptions of each option.
  List<TextBox> getBoxesForRange(
    int start,
    int end, {
    BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight,
    BoxWidthStyle boxWidthStyle = BoxWidthStyle.tight,
  });

  /// Returns a list of text boxes that enclose all placeholders in the paragraph.
  ///
  /// The order of the boxes are in the same order as passed in through
  /// [ParagraphBuilder.addPlaceholder].
  ///
  /// Coordinates of the [TextBox] are relative to the upper-left corner of the paragraph,
  /// where positive y values indicate down.
  List<TextBox> getBoxesForPlaceholders();

  /// Returns the text position closest to the given offset.
  ///
  /// This method always returns a [TextPosition] for any given [offset], even
  /// when the [offset] is not close to any text, or when the paragraph is empty.
  /// This is useful for determining the text to select when the user drags the
  /// text selection handle.
  ///
  /// See also:
  ///
  ///  * [getClosestGlyphInfoForOffset], which returns more information about
  ///    the closest character to an [Offset].
  TextPosition getPositionForOffset(Offset offset);

  /// Returns the [GlyphInfo] of the glyph closest to the given `offset` in the
  /// paragraph coordinate system, or null if if the text is empty, or is
  /// entirely clipped or ellipsized away.
  ///
  /// This method first finds the line closest to `offset.dy`, and then returns
  /// the [GlyphInfo] of the closest glyph(s) within that line.
  GlyphInfo? getClosestGlyphInfoForOffset(Offset offset);

  /// Returns the [GlyphInfo] located at the given UTF-16 `codeUnitOffset` in
  /// the paragraph, or null if the given `codeUnitOffset` is out of the visible
  /// lines or is ellipsized.
  GlyphInfo? getGlyphInfoAt(int codeUnitOffset);

  /// Returns the [TextRange] of the word at the given [TextPosition].
  ///
  /// Characters not part of a word, such as spaces, symbols, and punctuation,
  /// have word breaks on both sides. In such cases, this method will return
  /// (offset, offset+1). Word boundaries are defined more precisely in Unicode
  /// Standard Annex #29 http://www.unicode.org/reports/tr29/#Word_Boundaries
  ///
  /// The [TextPosition] is treated as caret position, its [TextPosition.affinity]
  /// is used to determine which character this position points to. For example,
  /// the word boundary at `TextPosition(offset: 5, affinity: TextPosition.upstream)`
  /// of the `string = 'Hello word'` will return range (0, 5) because the position
  /// points to the character 'o' instead of the space.
  TextRange getWordBoundary(TextPosition position);

  /// Returns the [TextRange] of the line at the given [TextPosition].
  ///
  /// The newline (if any) is returned as part of the range.
  ///
  /// Not valid until after layout.
  ///
  /// This can potentially be expensive, since it needs to compute the line
  /// metrics, so use it sparingly.
  TextRange getLineBoundary(TextPosition position);

  /// Returns the full list of [LineMetrics] that describe in detail the various
  /// metrics of each laid out line.
  ///
  /// Not valid until after layout.
  ///
  /// This can potentially return a large amount of data, so it is not recommended
  /// to repeatedly call this. Instead, cache the results.
  List<LineMetrics> computeLineMetrics();

  /// Returns the [LineMetrics] for the line at `lineNumber`, or null if the
  /// given `lineNumber` is greater than or equal to [numberOfLines].
  LineMetrics? getLineMetricsAt(int lineNumber);

  /// The total number of visible lines in the paragraph.
  ///
  /// Returns a non-negative number. If `maxLines` is non-null, the value of
  /// [numberOfLines] never exceeds `maxLines`.
  int get numberOfLines;

  /// Returns the line number of the line that contains the code unit that
  /// `codeUnitOffset` points to.
  ///
  /// This method returns null if the given `codeUnitOffset` is out of bounds, or
  /// is logically after the last visible codepoint. This includes the case where
  /// its codepoint belongs to a visible line, but the text layout library
  /// replaced it with an ellipsis.
  ///
  /// If the target code unit points to a control character that introduces
  /// mandatory line breaks (most notably the line feed character `LF`, typically
  /// represented in strings as the escape sequence "\n"), to conform to
  /// [the unicode rules](https://unicode.org/reports/tr14/#LB4), the control
  /// character itself is always considered to be at the end of "current" line
  /// rather than the beginning of the new line.
  int? getLineNumberAt(int codeUnitOffset);

  /// Release the resources used by this object. The object is no longer usable
  /// after this method is called.
  void dispose();

  /// Whether this reference to the underlying picture is [dispose]d.
  ///
  /// This only returns a valid value if asserts are enabled, and must not be
  /// used otherwise.
  bool get debugDisposed;
}

base class _NativeParagraph extends NativeFieldWrapperClass1 implements Paragraph {
  /// This class is created by the engine, and should not be instantiated
  /// or extended directly.
  ///
  /// To create a [Paragraph] object, use a [ParagraphBuilder].
  _NativeParagraph._();

  bool _needsLayout = true;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::width', isLeaf: true)
  external double get width;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::height', isLeaf: true)
  external double get height;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::longestLine', isLeaf: true)
  external double get longestLine;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::minIntrinsicWidth', isLeaf: true)
  external double get minIntrinsicWidth;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::maxIntrinsicWidth', isLeaf: true)
  external double get maxIntrinsicWidth;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::alphabeticBaseline', isLeaf: true)
  external double get alphabeticBaseline;

  @override
  @Native<Double Function(Pointer<Void>)>(symbol: 'Paragraph::ideographicBaseline', isLeaf: true)
  external double get ideographicBaseline;

  @override
  @Native<Bool Function(Pointer<Void>)>(symbol: 'Paragraph::didExceedMaxLines', isLeaf: true)
  external bool get didExceedMaxLines;

  @override
  void layout(ParagraphConstraints constraints) {
    _layout(constraints.width);
    assert(() {
      _needsLayout = false;
      return true;
    }());
  }

  @Native<Void Function(Pointer<Void>, Double)>(symbol: 'Paragraph::layout', isLeaf: true)
  external void _layout(double width);

  List<TextBox> _decodeTextBoxes(Float32List encoded) {
    final int count = encoded.length ~/ 5;
    final boxes = <TextBox>[];
    var position = 0;
    for (var index = 0; index < count; index += 1) {
      boxes.add(
        TextBox.fromLTRBD(
          encoded[position++],
          encoded[position++],
          encoded[position++],
          encoded[position++],
          TextDirection.values[encoded[position++].toInt()],
        ),
      );
    }
    return boxes;
  }

  @override
  List<TextBox> getBoxesForRange(
    int start,
    int end, {
    BoxHeightStyle boxHeightStyle = BoxHeightStyle.tight,
    BoxWidthStyle boxWidthStyle = BoxWidthStyle.tight,
  }) {
    return _decodeTextBoxes(
      _getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index),
    );
  }

  // See paragraph.cc for the layout of this return value.
  @Native<Handle Function(Pointer<Void>, Uint32, Uint32, Uint32, Uint32)>(
    symbol: 'Paragraph::getRectsForRange',
  )
  external Float32List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle);

  @override
  List<TextBox> getBoxesForPlaceholders() {
    return _decodeTextBoxes(_getBoxesForPlaceholders());
  }

  @Native<Handle Function(Pointer<Void>)>(symbol: 'Paragraph::getRectsForPlaceholders')
  external Float32List _getBoxesForPlaceholders();

  @override
  TextPosition getPositionForOffset(Offset offset) {
    final List<int> encoded = _getPositionForOffset(offset.dx, offset.dy);
    return TextPosition(offset: encoded[0], affinity: TextAffinity.values[encoded[1]]);
  }

  @Native<Handle Function(Pointer<Void>, Double, Double)>(symbol: 'Paragraph::getPositionForOffset')
  external List<int> _getPositionForOffset(double dx, double dy);

  @override
  GlyphInfo? getGlyphInfoAt(int codeUnitOffset) => _getGlyphInfoAt(codeUnitOffset, GlyphInfo._);
  @Native<Handle Function(Pointer<Void>, Uint32, Handle)>(symbol: 'Paragraph::getGlyphInfoAt')
  external GlyphInfo? _getGlyphInfoAt(int codeUnitOffset, Function constructor);

  @override
  GlyphInfo? getClosestGlyphInfoForOffset(Offset offset) =>
      _getClosestGlyphInfoForOffset(offset.dx, offset.dy, GlyphInfo._);
  @Native<Handle Function(Pointer<Void>, Double, Double, Handle)>(
    symbol: 'Paragraph::getClosestGlyphInfo',
  )
  external GlyphInfo? _getClosestGlyphInfoForOffset(double dx, double dy, Function constructor);

  @override
  TextRange getWordBoundary(TextPosition position) {
    final int characterPosition;
    switch (position.affinity) {
      case TextAffinity.upstream:
        characterPosition = position.offset - 1;
      case TextAffinity.downstream:
        characterPosition = position.offset;
    }
    final List<int> boundary = _getWordBoundary(characterPosition);
    return TextRange(start: boundary[0], end: boundary[1]);
  }

  @Native<Handle Function(Pointer<Void>, Uint32)>(symbol: 'Paragraph::getWordBoundary')
  external List<int> _getWordBoundary(int offset);

  @override
  TextRange getLineBoundary(TextPosition position) {
    final List<int> boundary = _getLineBoundary(position.offset);
    final line = TextRange(start: boundary[0], end: boundary[1]);

    final List<int> nextBoundary = _getLineBoundary(position.offset + 1);
    final nextLine = TextRange(start: nextBoundary[0], end: nextBoundary[1]);
    // If there is no next line, because we're at the end of the field, return line.
    if (!nextLine.isValid) {
      return line;
    }

    // _getLineBoundary only considers the offset and assumes that the
    // TextAffinity is upstream. In the case that TextPosition is just after a
    // word wrap (downstream), we need to return the line for the next offset.
    if (position.affinity == TextAffinity.downstream &&
        line != nextLine &&
        position.offset == line.end &&
        line.end == nextLine.start) {
      return TextRange(start: nextBoundary[0], end: nextBoundary[1]);
    }
    return line;
  }

  @Native<Handle Function(Pointer<Void>, Uint32)>(symbol: 'Paragraph::getLineBoundary')
  external List<int> _getLineBoundary(int offset);

  // Redirecting the paint function in this way solves some dependency problems
  // in the C++ code. If we straighten out the C++ dependencies, we can remove
  // this indirection.
  @Native<Void Function(Pointer<Void>, Pointer<Void>, Double, Double)>(symbol: 'Paragraph::paint')
  external void _paint(_NativeCanvas canvas, double x, double y);

  @override
  List<LineMetrics> computeLineMetrics() {
    final Float64List encoded = _computeLineMetrics();
    final int count = encoded.length ~/ 9;
    var position = 0;
    final metrics = <LineMetrics>[
      for (int index = 0; index < count; index += 1)
        LineMetrics(
          hardBreak: encoded[position++] != 0,
          ascent: encoded[position++],
          descent: encoded[position++],
          unscaledAscent: encoded[position++],
          height: encoded[position++],
          width: encoded[position++],
          left: encoded[position++],
          baseline: encoded[position++],
          lineNumber: encoded[position++].toInt(),
        ),
    ];
    return metrics;
  }

  @Native<Handle Function(Pointer<Void>)>(symbol: 'Paragraph::computeLineMetrics')
  external Float64List _computeLineMetrics();

  @override
  LineMetrics? getLineMetricsAt(int lineNumber) => _getLineMetricsAt(lineNumber, LineMetrics._);
  @Native<Handle Function(Pointer<Void>, Uint32, Handle)>(symbol: 'Paragraph::getLineMetricsAt')
  external LineMetrics? _getLineMetricsAt(int lineNumber, Function constructor);

  @override
  @Native<Uint32 Function(Pointer<Void>)>(symbol: 'Paragraph::getNumberOfLines')
  external int get numberOfLines;

  @override
  int? getLineNumberAt(int codeUnitOffset) {
    final int lineNumber = _getLineNumber(codeUnitOffset);
    return lineNumber < 0 ? null : lineNumber;
  }

  @Native<Int32 Function(Pointer<Void>, Uint32)>(symbol: 'Paragraph::getLineNumberAt')
  external int _getLineNumber(int codeUnitOffset);

  @override
  void dispose() {
    assert(!_disposed);
    assert(() {
      _disposed = true;
      return true;
    }());
    _dispose();
  }

  /// This can't be a leaf call because the native function calls Dart API
  /// (Dart_SetNativeInstanceField).
  @Native<Void Function(Pointer<Void>)>(symbol: 'Paragraph::dispose')
  external void _dispose();

  bool _disposed = false;

  @override
  bool get debugDisposed {
    bool? disposed;
    assert(() {
      disposed = _disposed;
      return true;
    }());
    return disposed ??
        (throw StateError(
          '$runtimeType.debugDisposed is only available when asserts are enabled.',
        ));
  }

  @override
  String toString() {
    String? result;
    assert(() {
      if (_disposed && _needsLayout) {
        result = 'Paragraph(DISPOSED while dirty)';
      }
      if (_disposed && !_needsLayout) {
        result = 'Paragraph(DISPOSED)';
      }
      return true;
    }());
    if (result != null) {
      return result!;
    }
    if (_needsLayout) {
      return 'Paragraph(dirty)';
    }
    return 'Paragraph()';
  }
}

/// Builds a [Paragraph] containing text with the given styling information.
///
/// To set the paragraph's alignment, truncation, and ellipsizing behavior, pass
/// an appropriately-configured [ParagraphStyle] object to the
/// [ParagraphBuilder.new] constructor.
///
/// Then, call combinations of [pushStyle], [addText], and [pop] to add styled
/// text to the object.
///
/// Finally, call [build] to obtain the constructed [Paragraph] object. After
/// this point, the builder is no longer usable.
///
/// After constructing a [Paragraph], call [Paragraph.layout] on it and then
/// paint it with [Canvas.drawParagraph].
abstract class ParagraphBuilder {
  /// Creates a new [ParagraphBuilder] object, which is used to create a
  /// [Paragraph].
  factory ParagraphBuilder(ParagraphStyle style) = _NativeParagraphBuilder;

  /// The number of placeholders currently in the paragraph.
  int get placeholderCount;

  /// The scales of the placeholders in the paragraph.
  List<double> get placeholderScales;

  /// Applies the given style to the added text until [pop] is called.
  ///
  /// See [pop] for details.
  void pushStyle(TextStyle style);

  /// Ends the effect of the most recent call to [pushStyle].
  ///
  /// Internally, the paragraph builder maintains a stack of text styles. Text
  /// added to the paragraph is affected by all the styles in the stack. Calling
  /// [pop] removes the topmost style in the stack, leaving the remaining styles
  /// in effect.
  void pop();

  /// Adds the given text to the paragraph.
  ///
  /// The text will be styled according to the current stack of text styles.
  void addText(String text);

  /// Adds an inline placeholder space to the paragraph.
  ///
  /// The paragraph will contain a rectangular space with no text of the dimensions
  /// specified.
  ///
  /// The `width` and `height` parameters specify the size of the placeholder rectangle.
  ///
  /// The `alignment` parameter specifies how the placeholder rectangle will be vertically
  /// aligned with the surrounding text. When [PlaceholderAlignment.baseline],
  /// [PlaceholderAlignment.aboveBaseline], and [PlaceholderAlignment.belowBaseline]
  /// alignment modes are used, the baseline needs to be set with the `baseline`.
  /// When using [PlaceholderAlignment.baseline], `baselineOffset` indicates the distance
  /// of the baseline down from the top of the rectangle. The default `baselineOffset`
  /// is the `height`.
  ///
  /// Examples:
  ///
  /// * For a 30x50 placeholder with the bottom edge aligned with the bottom of the text, use:
  /// `addPlaceholder(30, 50, PlaceholderAlignment.bottom);`
  /// * For a 30x50 placeholder that is vertically centered around the text, use:
  /// `addPlaceholder(30, 50, PlaceholderAlignment.middle);`.
  /// * For a 30x50 placeholder that sits completely on top of the alphabetic baseline, use:
  /// `addPlaceholder(30, 50, PlaceholderAlignment.aboveBaseline, baseline: TextBaseline.alphabetic)`.
  /// * For a 30x50 placeholder with 40 pixels above and 10 pixels below the alphabetic baseline, use:
  /// `addPlaceholder(30, 50, PlaceholderAlignment.baseline, baseline: TextBaseline.alphabetic, baselineOffset: 40)`.
  ///
  /// Lines are permitted to break around each placeholder.
  ///
  /// Decorations will be drawn based on the font defined in the most recently
  /// pushed [TextStyle]. The decorations are drawn as if unicode text were present
  /// in the placeholder space, and will draw the same regardless of the height and
  /// alignment of the placeholder. To hide or manually adjust decorations to fit,
  /// a text style with the desired decoration behavior should be pushed before
  /// adding a placeholder.
  ///
  /// Any decorations drawn through a placeholder will exist on the same canvas/layer
  /// as the text. This means any content drawn on top of the space reserved by
  /// the placeholder will be drawn over the decoration, possibly obscuring the
  /// decoration.
  ///
  /// Placeholders are represented by a unicode 0xFFFC "object replacement character"
  /// in the text buffer. For each placeholder, one object replacement character is
  /// added on to the text buffer.
  ///
  /// The `scale` parameter will scale the `width` and `height` by the specified amount,
  /// and keep track of the scale. The scales of placeholders added can be accessed
  /// through [placeholderScales]. This is primarily used for accessibility scaling.
  void addPlaceholder(
    double width,
    double height,
    PlaceholderAlignment alignment, {
    double scale = 1.0,
    double? baselineOffset,
    TextBaseline? baseline,
  });

  /// Applies the given paragraph style and returns a [Paragraph] containing the
  /// added text and associated styling.
  ///
  /// After calling this function, the paragraph builder object is invalid and
  /// cannot be used further.
  Paragraph build();
}

base class _NativeParagraphBuilder extends NativeFieldWrapperClass1 implements ParagraphBuilder {
  _NativeParagraphBuilder(ParagraphStyle style)
    : _defaultLeadingDistribution = style._leadingDistribution {
    List<String>? strutFontFamilies;
    final StrutStyle? strutStyle = style._strutStyle;
    final ByteData? encodedStrutStyle;
    if (strutStyle != null && strutStyle._enabled) {
      final String? fontFamily = strutStyle._fontFamily;
      strutFontFamilies = <String>[?fontFamily, ...?strutStyle._fontFamilyFallback];

      assert(TextLeadingDistribution.values.length <= 2);
      final TextLeadingDistribution leadingDistribution =
          strutStyle._leadingDistribution ?? style._leadingDistribution;
      encodedStrutStyle = strutStyle._encoded;
      int bitmask = encodedStrutStyle.getInt32(0, _kFakeHostEndian);
      bitmask |= (leadingDistribution.index) << 3;
      encodedStrutStyle.setInt32(0, bitmask, _kFakeHostEndian);
    } else {
      encodedStrutStyle = null;
    }
    _constructor(
      style._encoded,
      encodedStrutStyle,
      style._fontFamily ?? '',
      strutFontFamilies,
      style._fontSize ?? 0,
      style._height ?? 0,
      style._ellipsis ?? '',
      _encodeLocale(style._locale),
    );
  }

  @Native<Void Function(Handle, Handle, Handle, Handle, Handle, Double, Double, Handle, Handle)>(
    symbol: 'ParagraphBuilder::Create',
  )
  external void _constructor(
    Int32List encoded,
    ByteData? strutData,
    String fontFamily,
    List<Object?>? strutFontFamily,
    double fontSize,
    double height,
    String ellipsis,
    String locale,
  );

  @override
  int get placeholderCount => _placeholderCount;
  int _placeholderCount = 0;

  @override
  List<double> get placeholderScales => _placeholderScales;
  final List<double> _placeholderScales = <double>[];

  final TextLeadingDistribution _defaultLeadingDistribution;

  @override
  void pushStyle(TextStyle style) {
    final fullFontFamilies = <String>[];
    fullFontFamilies.add(style._fontFamily);
    final List<String>? fontFamilyFallback = style._fontFamilyFallback;
    if (fontFamilyFallback != null) {
      fullFontFamilies.addAll(fontFamilyFallback);
    }

    final Int32List encoded = style._encoded;
    final TextLeadingDistribution finalLeadingDistribution =
        style._leadingDistribution ?? _defaultLeadingDistribution;
    // ensure the enum can be represented using 1 bit.
    assert(TextLeadingDistribution.values.length <= 2);

    // Use the leading distribution from the paragraph's style if it's not
    // explicitly set in `style`.
    encoded[0] |= finalLeadingDistribution.index << 0;

    ByteData? encodedFontFeatures;
    final List<FontFeature>? fontFeatures = style._fontFeatures;
    if (fontFeatures != null) {
      encodedFontFeatures = ByteData(fontFeatures.length * FontFeature._kEncodedSize);
      var byteOffset = 0;
      for (final FontFeature feature in fontFeatures) {
        feature._encode(
          ByteData.view(encodedFontFeatures.buffer, byteOffset, FontFeature._kEncodedSize),
        );
        byteOffset += FontFeature._kEncodedSize;
      }
    }

    ByteData? encodedFontVariations;
    final List<FontVariation>? fontVariations = style._fontVariations;
    if (fontVariations != null) {
      encodedFontVariations = ByteData(fontVariations.length * FontVariation._kEncodedSize);
      var byteOffset = 0;
      for (final FontVariation variation in fontVariations) {
        variation._encode(
          ByteData.view(encodedFontVariations.buffer, byteOffset, FontVariation._kEncodedSize),
        );
        byteOffset += FontVariation._kEncodedSize;
      }
    }

    _pushStyle(
      encoded,
      fullFontFamilies,
      style._fontSize ?? 0,
      style._letterSpacing ?? 0,
      style._wordSpacing ?? 0,
      style._height ?? 0,
      style._decorationThickness ?? 0,
      _encodeLocale(style._locale),
      style._background?._objects,
      style._background?._data,
      style._foreground?._objects,
      style._foreground?._data,
      Shadow._encodeShadows(style._shadows),
      encodedFontFeatures,
      encodedFontVariations,
    );
  }

  @Native<
    Void Function(
      Pointer<Void>,
      Handle,
      Handle,
      Double,
      Double,
      Double,
      Double,
      Double,
      Handle,
      Handle,
      Handle,
      Handle,
      Handle,
      Handle,
      Handle,
      Handle,
    )
  >(symbol: 'ParagraphBuilder::pushStyle')
  external void _pushStyle(
    Int32List encoded,
    List<Object?> fontFamilies,
    double fontSize,
    double letterSpacing,
    double wordSpacing,
    double height,
    double decorationThickness,
    String locale,
    List<Object?>? backgroundObjects,
    ByteData? backgroundData,
    List<Object?>? foregroundObjects,
    ByteData? foregroundData,
    ByteData shadowsData,
    ByteData? fontFeaturesData,
    ByteData? fontVariationsData,
  );

  static String _encodeLocale(Locale? locale) => locale?.toString() ?? '';

  @override
  @Native<Void Function(Pointer<Void>)>(symbol: 'ParagraphBuilder::pop', isLeaf: true)
  external void pop();

  @override
  void addText(String text) {
    final String? error = _addText(text);
    if (error != null) {
      throw ArgumentError(error);
    }
  }

  @Native<Handle Function(Pointer<Void>, Handle)>(symbol: 'ParagraphBuilder::addText')
  external String? _addText(String text);

  @override
  void addPlaceholder(
    double width,
    double height,
    PlaceholderAlignment alignment, {
    double scale = 1.0,
    double? baselineOffset,
    TextBaseline? baseline,
  }) {
    // Require a baseline to be specified if using a baseline-based alignment.
    assert(
      !(alignment == PlaceholderAlignment.aboveBaseline ||
              alignment == PlaceholderAlignment.belowBaseline ||
              alignment == PlaceholderAlignment.baseline) ||
          baseline != null,
    );
    // Default the baselineOffset to height if null. This will place the placeholder
    // fully above the baseline, similar to [PlaceholderAlignment.aboveBaseline].
    baselineOffset = baselineOffset ?? height;
    _addPlaceholder(
      width * scale,
      height * scale,
      alignment.index,
      baselineOffset * scale,
      (baseline ?? TextBaseline.alphabetic).index,
    );
    _placeholderCount++;
    _placeholderScales.add(scale);
  }

  @Native<Void Function(Pointer<Void>, Double, Double, Uint32, Double, Uint32)>(
    symbol: 'ParagraphBuilder::addPlaceholder',
  )
  external void _addPlaceholder(
    double width,
    double height,
    int alignment,
    double baselineOffset,
    int baseline,
  );

  @override
  Paragraph build() {
    final paragraph = _NativeParagraph._();
    _build(paragraph);
    return paragraph;
  }

  @Native<Void Function(Pointer<Void>, Handle)>(symbol: 'ParagraphBuilder::build')
  external void _build(_NativeParagraph outParagraph);

  @override
  String toString() => 'ParagraphBuilder';
}

/// Loads a font from a buffer and makes it available for rendering text.
///
/// * `list`: A list of bytes containing the font file.
/// * `fontFamily`: The family name used to identify the font in text styles.
///  If this is not provided, then the family name will be extracted from the font file.
Future<void> loadFontFromList(Uint8List list, {String? fontFamily}) {
  return _futurize((_Callback<void> callback) {
    _loadFontFromList(list, callback, fontFamily ?? '');
    return null;
  }).then((_) => _sendFontChangeMessage());
}

final ByteData _fontChangeMessage = utf8
    .encode(json.encode(<String, Object?>{'type': 'fontsChange'}))
    .buffer
    .asByteData();

FutureOr<void> _sendFontChangeMessage() async {
  const kSystemChannelName = 'flutter/system';
  if (PlatformDispatcher.instance.onPlatformMessage != null) {
    _invoke3<String, ByteData?, PlatformMessageResponseCallback>(
      PlatformDispatcher.instance.onPlatformMessage,
      PlatformDispatcher.instance._onPlatformMessageZone,
      kSystemChannelName,
      _fontChangeMessage,
      (ByteData? responseData) {},
    );
  } else {
    channelBuffers.push(kSystemChannelName, _fontChangeMessage, (ByteData? responseData) {});
  }
}

@Native<Void Function(Handle, Handle, Handle)>(symbol: 'FontCollection::LoadFontFromList')
external void _loadFontFromList(Uint8List list, _Callback<void> callback, String fontFamily);
