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

// @dart = 2.12
part of dart.ui;

/// Whether to slant the glyphs in the font
enum FontStyle {
  /// Use the upright glyphs
  normal,

  /// Use glyphs designed for slanting
  italic,
}

/// The thickness of the glyphs used to draw the text
class FontWeight {
  const FontWeight._(this.index);

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

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

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

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

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

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

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

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

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

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

  /// 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.
  ///
  /// 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) {
    assert(t != null);
    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}
///
/// 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 != null),
      assert(feature.length == 4, 'Feature tag must be exactly four characters long.'),
      assert(value != null),
      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 [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.numerator] 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 => hashValues(feature, value);

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

/// 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 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 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 hashValues(
      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,
) {
  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.
  }

  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.
  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,
  }) : 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,
       ),
       _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;

  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 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);
  }

  @override
  int get hashCode => hashValues(hashList(_encoded), _leadingDistribution, _fontFamily, _fontFamilyFallback, _fontSize, _letterSpacing, _wordSpacing, _height, _locale, _background, _foreground, hashList(_shadows), _decorationThickness, hashList(_fontFeatures));

  @override
  String toString() {
    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"}'
           ')';
  }
}

// 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 => hashValues(hashList(_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"}, '
             'ellipsis: ${      _encoded[0] & 0x400 == 0x400 ? "\"$_ellipsis\""                  : "unspecified"}, '
             'locale: ${        _encoded[0] & 0x800 == 0x800 ? _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 => hashValues(hashList(_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 [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].
@pragma('vm:entry-point')
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 => hashValues(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 locate a position in a string in code (using
/// the [offset] property), and it can also be used to locate the same position
/// visually in a rendered string of text (using [offset] and, when needed to
/// resolve ambiguity, [affinity]).
///
/// The location of an offset in a rendered string is ambiguous in two cases.
/// One happens 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,
  }) : assert(offset != null),
       assert(affinity != null);

  /// 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 => hashValues(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 != null && start >= -1),
        assert(end != null && 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 != null && 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 => hashValues(
    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,
  }) : assert(width != null);

  /// 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
  /// [new ParagraphStyle] 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,
  });

  /// 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 => hashValues(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.
@pragma('vm:entry-point')
class Paragraph extends NativeFieldWrapperClass1 {
  /// This class is created by the engine, and should not be instantiated
  /// or extended directly.
  ///
  /// To create a [Paragraph] object, use a [ParagraphBuilder].
  @pragma('vm:entry-point')
  Paragraph._();

  /// The amount of horizontal space this paragraph occupies.
  ///
  /// Valid only after [layout] has been called.
  double get width native 'Paragraph_width';

  /// The amount of vertical space this paragraph occupies.
  ///
  /// Valid only after [layout] has been called.
  double get height native 'Paragraph_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 native 'Paragraph_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 native 'Paragraph_minIntrinsicWidth';

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

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

  /// The distance from the top of the paragraph to the ideographic
  /// baseline of the first line, in logical pixels.
  double get ideographicBaseline native 'Paragraph_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
  /// [new ParagraphStyle].
  bool get didExceedMaxLines native 'Paragraph_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) => _layout(constraints.width);
  void _layout(double width) native 'Paragraph_layout';

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

  /// 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}) {
    assert(boxHeightStyle != null);
    assert(boxWidthStyle != null);
    return _decodeTextBoxes(_getBoxesForRange(start, end, boxHeightStyle.index, boxWidthStyle.index));
  }
  // See paragraph.cc for the layout of this return value.
  Float32List _getBoxesForRange(int start, int end, int boxHeightStyle, int boxWidthStyle) native 'Paragraph_getRectsForRange';

  /// 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() {
    return _decodeTextBoxes(_getBoxesForPlaceholders());
  }
  Float32List _getBoxesForPlaceholders() native 'Paragraph_getRectsForPlaceholders';

  /// Returns the text position closest to the given offset.
  TextPosition getPositionForOffset(Offset offset) {
    final List<int> encoded = _getPositionForOffset(offset.dx, offset.dy);
    return TextPosition(offset: encoded[0], affinity: TextAffinity.values[encoded[1]]);
  }
  List<int> _getPositionForOffset(double dx, double dy) native 'Paragraph_getPositionForOffset';

  /// 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
  TextRange getWordBoundary(TextPosition position) {
    final List<int> boundary = _getWordBoundary(position.offset);
    return TextRange(start: boundary[0], end: boundary[1]);
  }
  List<int> _getWordBoundary(int offset) native 'Paragraph_getWordBoundary';

  /// 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) {
    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) {
      final List<int> nextBoundary = _getLineBoundary(position.offset + 1);
      return TextRange(start: nextBoundary[0], end: nextBoundary[1]);
    }
    return line;
  }
  List<int> _getLineBoundary(int offset) native 'Paragraph_getLineBoundary';

  // 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.
  void _paint(Canvas canvas, double x, double y) native 'Paragraph_paint';

  /// 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() {
    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;
  }
  Float64List _computeLineMetrics() native 'Paragraph_computeLineMetrics';
}

/// 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
/// [new ParagraphBuilder] 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].
class ParagraphBuilder extends NativeFieldWrapperClass1 {

  /// Creates a new [ParagraphBuilder] object, which is used to create a
  /// [Paragraph].
  @pragma('vm:entry-point')
  ParagraphBuilder(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,
        style._height,
        style._ellipsis,
        _encodeLocale(style._locale)
      );
  }

  void _constructor(
    Int32List encoded,
    ByteData? strutData,
    String? fontFamily,
    List<dynamic>? strutFontFamily,
    double? fontSize,
    double? height,
    String? ellipsis,
    String locale
  ) native 'ParagraphBuilder_constructor';

  /// The number of placeholders currently in the paragraph.
  int get placeholderCount => _placeholderCount;
  int _placeholderCount = 0;

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

  final TextLeadingDistribution _defaultLeadingDistribution;
  /// Applies the given style to the added text until [pop] is called.
  ///
  /// See [pop] for details.
  void pushStyle(TextStyle style) {
    final List<String> fullFontFamilies = <String>[];
    fullFontFamilies.add(style._fontFamily);
    if (style._fontFamilyFallback != null)
      fullFontFamilies.addAll(style._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;
      }
    }

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

  void _pushStyle(
    Int32List encoded,
    List<dynamic> fontFamilies,
    double? fontSize,
    double? letterSpacing,
    double? wordSpacing,
    double? height,
    double? decorationThickness,
    String locale,
    List<dynamic>? backgroundObjects,
    ByteData? backgroundData,
    List<dynamic>? foregroundObjects,
    ByteData? foregroundData,
    ByteData shadowsData,
    ByteData? fontFeaturesData,
  ) native 'ParagraphBuilder_pushStyle';

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

  /// 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() native 'ParagraphBuilder_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) {
    final String? error = _addText(text);
    if (error != null)
      throw ArgumentError(error);
  }
  String? _addText(String text) native 'ParagraphBuilder_addText';

  /// 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,
  }) {
    // 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?.index);
    _placeholderCount++;
    _placeholderScales.add(scale);
  }
  String? _addPlaceholder(double width, double height, int alignment, double baselineOffset, int? baseline) native 'ParagraphBuilder_addPlaceholder';

  /// 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() {
    final Paragraph paragraph = Paragraph._();
    _build(paragraph);
    return paragraph;
  }
  void _build(Paragraph outParagraph) native 'ParagraphBuilder_build';
}

/// 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);
    }
  ).then((_) => _sendFontChangeMessage());
}

final ByteData _fontChangeMessage = utf8.encoder.convert(
  json.encode(<String, dynamic>{'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) { });
  }
}

void _loadFontFromList(Uint8List list, _Callback<void> callback, String? fontFamily) native 'loadFontFromList';
