// 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;

/// 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.
///
/// 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.
/// See [FontVariation.weight] for details.
class FontWeight {
  const FontWeight._(this.index, this.value);

  /// The encoded integer value of this font weight.
  final int index;

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

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

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

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

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

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

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

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

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

  /// Black, the most thick.
  static const FontWeight w900 = FontWeight._(8, 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
  ];

  /// Linearly interpolates between two font weights.
  ///
  /// Rather than using fractional weights, the interpolation rounds to the
  /// nearest weight.
  ///
  /// For a smoother animation of font weight, consider using
  /// [FontVariation.weight] if the font in question supports it.
  ///
  /// 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 values[_lerpInt((a ?? normal).index, (b ?? normal).index, t).round().clamp(0, 8)];
  }

  @override
  String toString() {
    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 (int 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('wght', 800.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`)
  ///
  /// Varies the stroke thickness of the font, similar to [FontWeight] but on a
  /// continuous axis.
  ///
  /// 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 (int 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.
  alphabetic,

  /// The horizontal line used to align ideographic characters.
  ideographic,
}

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

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

  final int _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 List<String> 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 (int 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 Int32List 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.index;
  }
  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. Omitting `height` 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 specified, 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;
    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.values[_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: ${             _encoded[0] & 0x02000 == 0x02000  ? "${_height}x"                                : "unspecified"}, '
             '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 Int32List 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.index;
  }
  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.
  }
  if (height != null) {
    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 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.values[_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) {
  if (fontFamily == null &&
    fontSize == null &&
    height == null &&
    leadingDistribution == null &&
    leading == null &&
    fontWeight == null &&
    fontStyle == null &&
    forceStrutHeight == null) {
    return ByteData(0);
  }

  final ByteData data = ByteData(16); // Max size is 16 bytes
  int bitmask = 0; // 8 bit mask
  int byteCount = 1;
  if (fontWeight != null) {
    bitmask |= 1 << 0;
    data.setInt8(byteCount, fontWeight.index);
    byteCount += 1;
  }
  if (fontStyle != null) {
    bitmask |= 1 << 1;
    data.setInt8(byteCount, fontStyle.index);
    byteCount += 1;
  }
  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 (height != null) {
    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.setInt8(0, bitmask);

  assert(byteCount <= 16);
  assert(bitmask >> 8 == 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` 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 List<TextBox> boxes = <TextBox>[];
    int position = 0;
    for (int 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 TextRange line = TextRange(start: boundary[0], end: boundary[1]);

    final List<int> nextBoundary = _getLineBoundary(position.offset + 1);
    final TextRange 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;
    int position = 0;
    final List<LineMetrics> 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>[
          if (fontFamily != null) fontFamily,
          ...?strutStyle._fontFamilyFallback,
        ];

        assert(TextLeadingDistribution.values.length <= 2);
        final TextLeadingDistribution leadingDistribution = strutStyle._leadingDistribution
          ?? style._leadingDistribution;
        encodedStrutStyle = strutStyle._encoded;
        int bitmask = encodedStrutStyle.getInt8(0);
        bitmask |= (leadingDistribution.index) << 3;
        encodedStrutStyle.setInt8(0, bitmask);
      } 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 List<String> 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);
      int 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);
      int 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 _NativeParagraph 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 String 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);
