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

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); // ignore: unnecessary_null_comparison
    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.
///
/// {@tool sample --template=freeform}
///
/// This example shows usage of several OpenType font features, including
/// Small Caps (smcp), old-style figures, fractional ligatures and stylistic
/// sets.
///
/// ```dart
///class TypePage extends StatelessWidget {
///  // The Cardo, Milonga and Raleway Dots fonts can be downloaded from
///  // Google Fonts (https://www.google.com/fonts).
///
///  final titleStyle = TextStyle(
///    fontSize: 18,
///    fontFeatures: [FontFeature.enable('smcp')],
///    color: Colors.blueGrey[600],
///  );
///
///  @override
///  Widget build(BuildContext context) {
///    return Scaffold(
///      body: Center(
///        child: Column(
///          mainAxisAlignment: MainAxisAlignment.center,
///          children: <Widget>[
///            Spacer(flex: 5),
///            Text('regular numbers have their place:', style: titleStyle),
///            Text('The 1972 cup final was a 1-1 draw.',
///                style: TextStyle(
///                  fontFamily: 'Cardo',
///                  fontSize: 24,
///                )),
///            Spacer(),
///            Text('but old-style figures blend well with lower case:',
///                style: titleStyle),
///            Text('The 1972 cup final was a 1-1 draw.',
///                style: TextStyle(
///                    fontFamily: 'Cardo',
///                    fontSize: 24,
///                    fontFeatures: [FontFeature.oldstyleFigures()])),
///            Spacer(),
///            Divider(),
///            Spacer(),
///            Text('fractions look better with a custom ligature:',
///                style: titleStyle),
///            Text('Add 1/2 tsp of flour and stir.',
///                style: TextStyle(
///                    fontFamily: 'Milonga',
///                    fontSize: 24,
///                    fontFeatures: [FontFeature.enable('frac')])),
///            Spacer(),
///            Divider(),
///            Spacer(),
///            Text('multiple stylistic sets in one font:', style: titleStyle),
///            Text('Raleway Dots',
///                style: TextStyle(fontFamily: 'Raleway Dots', fontSize: 48)),
///            Text('Raleway Dots',
///                style: TextStyle(
///                  fontFeatures: [FontFeature.stylisticSet(1)],
///                  fontFamily: 'Raleway Dots',
///                  fontSize: 48,
///                )),
///            Spacer(flex: 5),
///          ],
///        ),
///      ),
///    );
///  }
///}
/// ```
/// {@end-tool}
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>
  // ignore: unnecessary_null_comparison
  const FontFeature(this.feature, [ this.value = 1 ]) : assert(feature != null), assert(feature.length == 4), assert(value != null), assert(value >= 0);

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

  /// Randomize the alternate forms used in text.
  ///
  /// 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.
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#rand>
  const FontFeature.randomize() : feature = 'rand', value = 1;

  /// Select a stylistic set.
  ///
  /// Fonts may have up to 20 stylistic sets, numbered 1 through 20.
  ///
  /// See also:
  ///
  ///  * <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")}');
  }

  /// Use the slashed 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].
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_uz#zero>
  const FontFeature.slashedZero() : feature = 'zero', value = 1;

  /// Use oldstyle figures.
  ///
  /// 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.
  ///
  /// This overrides [FontFeature.slashedZero].
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_ko#onum>
  const FontFeature.oldstyleFigures() : feature = 'onum', value = 1;

  /// Use proportional (varying width) figures.
  ///
  /// 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.
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#pnum>
  const FontFeature.proportionalFigures() : feature = 'pnum', value = 1;

  /// Use tabular (monospace) figures.
  ///
  /// For fonts that have both proportional (varying width) and tabular figures,
  /// this enables the tabular figures.
  ///
  /// This is mutually exclusive with [FontFeature.proportionalFigures].
  ///
  /// The default behavior varies from font to font.
  ///
  /// See also:
  ///
  ///  * <https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tnum>
  const FontFeature.tabularFigures() : feature = 'tnum', value = 1;

  /// The tag that identifies the effect of this feature.  Must consist of 4
  /// ASCII characters (typically lowercase letters).
  ///
  /// See <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).
  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 (identical(this, other))
      return true;
    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 (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
}

/// {@template dart.ui.textHeightBehavior}
/// Defines how the paragraph will apply [TextStyle.height] to the ascent of the
/// first line and descent of the last line.
///
/// Each boolean value represents whether the [TextStyle.height] modifier will
/// be applied to the corresponding metric. By default, all properties are true,
/// and [TextStyle.height] is applied as normal. When set to false, the font's
/// default ascent will be used.
/// {@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.
  ///
  /// All properties default to true (height modifications applied as normal).
  const TextHeightBehavior({
    this.applyHeightToFirstAscent = true,
    this.applyHeightToLastDescent = true,
  });

  /// Creates a new TextHeightBehavior object from an encoded form.
  ///
  /// See [encode] for the creation of the encoded form.
  const TextHeightBehavior.fromEncoded(int encoded)
    : 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;

  /// Returns an encoded int representation of this object.
  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;
  }

  @override
  int get hashCode {
    return hashValues(
      applyHeightToFirstAscent,
      applyHeightToLastDescent,
    );
  }

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

/// 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 is unused.
//
//  - 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(8);
  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 muliplier 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.
  /// * `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,
    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,
       ),
       _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;

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    return other is TextStyle
        && 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), _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"}, '
             '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|.
//
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.
  ///
  /// * `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;

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

  @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
        && _listEquals<int>(other._encoded, _encoded);
  }

  @override
  int get hashCode => hashValues(hashList(_encoded), _fontFamily, _fontSize, _height, _ellipsis, _locale);

  @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]).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.
//
// 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,
  double? leading,
  FontWeight? fontWeight,
  FontStyle? fontStyle,
  bool? forceStrutHeight) {
  if (fontFamily == null &&
    fontSize == null &&
    height == null &&
    leading == null &&
    fontWeight == null &&
    fontStyle == null &&
    forceStrutHeight == null)
    return ByteData(0);

  final ByteData data = ByteData(15); // Max size is 15 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
  }
  if (fontSize != null) {
    bitmask |= 1 << 3;
    data.setFloat32(byteCount, fontSize, _kFakeHostEndian);
    byteCount += 4;
  }
  if (height != null) {
    bitmask |= 1 << 4;
    data.setFloat32(byteCount, height, _kFakeHostEndian);
    byteCount += 4;
  }
  if (leading != null) {
    bitmask |= 1 << 5;
    data.setFloat32(byteCount, leading, _kFakeHostEndian);
    byteCount += 4;
  }
  if (forceStrutHeight != null) {
    bitmask |= 1 << 6;
    // We store this boolean directly in the bitmask since there is
    // extra space in the 16 bit int.
    bitmask |= (forceStrutHeight ? 1 : 0) << 7;
  }

  data.setInt8(0, 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.
  ///
  /// * `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,
    double? leading,
    FontWeight? fontWeight,
    FontStyle? fontStyle,
    bool? forceStrutHeight,
  }) : _encoded = _encodeStrut(
         fontFamily,
         fontFamilyFallback,
         fontSize,
         height,
         leading,
         fontWeight,
         fontStyle,
         forceStrutHeight,
       ),
       _fontFamily = fontFamily,
       _fontFamilyFallback = fontFamilyFallback;

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


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

  @override
  int get hashCode => hashValues(hashList(_encoded.buffer.asInt8List()), _fontFamily);

}

/// 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), // ignore: unnecessary_null_comparison
       assert(affinity != null); // ignore: unnecessary_null_comparison

  /// 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), // ignore: unnecessary_null_comparison
        assert(end != null && end >= -1); // ignore: unnecessary_null_comparison

  /// 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), // ignore: unnecessary_null_comparison
        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); // ignore: unnecessary_null_comparison

  /// 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.
  ///
  /// Omitted values will remain null. [Paragraph.computeLineMetrics] produces
  /// fully defined [LineMetrics] with no null 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 NativeFieldWrapperClass2 {
  /// 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); // ignore: unnecessary_null_comparison
    assert(boxWidthStyle != null); // ignore: unnecessary_null_comparison
    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);
    return TextRange(start: boundary[0], end: boundary[1]);
  }
  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 NativeFieldWrapperClass2 {

  /// Creates a new [ParagraphBuilder] object, which is used to create a
  /// [Paragraph].
  @pragma('vm:entry-point')
  ParagraphBuilder(ParagraphStyle style) {
    List<String>? strutFontFamilies;
    final StrutStyle? strutStyle = style._strutStyle;
    if (strutStyle != null) {
      strutFontFamilies = <String>[];
      final String? fontFamily = strutStyle._fontFamily;
      if (fontFamily != null)
        strutFontFamilies.add(fontFamily);
      if (strutStyle._fontFamilyFallback != null)
        strutFontFamilies.addAll(strutStyle._fontFamilyFallback!);
    }
    _constructor(
      style._encoded,
      strutStyle?._encoded,
      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>[];

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

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

    _pushStyle(
      style._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 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 acessibility 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 : true);
    // 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 == null ? null : 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 {
  PlatformDispatcher.instance.onPlatformMessage?.call(
    'flutter/system',
    _fontChangeMessage,
    (_) {},
  );
}

// TODO(gspencergoog): remove this template block once the framework templates
// are renamed to not reference it.
/// {@template flutter.dart:ui.textHeightBehavior}
/// Defines how the paragraph will apply [TextStyle.height] to the ascent of the
/// first line and descent of the last line.
///
/// Each boolean value represents whether the [TextStyle.height] modifier will
/// be applied to the corresponding metric. By default, all properties are true,
/// and [TextStyle.height] is applied as normal. When set to false, the font's
/// default ascent will be used.
/// {@endtemplate}

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