isolateBidi function

String isolateBidi(
  1. String text,
  2. TextDirection direction, {
  3. bool wholeRun = true,
})

Implementation

String isolateBidi(
  String text,
  TextDirection direction, {
  bool wholeRun = true,
}) {
  if (direction != TextDirection.rtl) return text;
  if (text.contains(_lri)) return text;

  // A whole run whose own base direction opposes the paragraph's is isolated
  // entire, because the damage is not confined to digits. Measured on a real
  // screenshot from the owner's simulator: an English review body inside an
  // `ar` panel rendered `.Great lamp, sturdy base` — the trailing full stop
  // is bidi-NEUTRAL, so it takes the paragraph direction and lands at the
  // wrong end of the sentence. `x(Great)=14.0, x(.)=0.0` plain against
  // `x(Great)=0.0, x(.)=322.0` isolated.
  //
  // This subsumes nothing: a grouped-digit run has NO strong character at
  // all (digits are weak), so first-strong returns null for a phone number
  // and the per-run rule below still does that work. The two rules cover
  // disjoint cases and both are needed.
  // `wholeRun: false` is passed by the one caller that hands this a FRAGMENT
  // rather than a standalone value: `rich_entry_tile`'s `_span`, which is
  // invoked per mark leaf, so several calls compose a single paragraph.
  // Isolating each leaf on its own does not just fix punctuation there — it
  // changes how the paragraph lays out, because each isolate is positioned as
  // a unit. Measured: it moved a blockquote's quoted text flush against a
  // plain paragraph, losing the indent the RTL layout had given it. A whole
  // paragraph's direction is the bidi algorithm's job once it can see the
  // whole paragraph; a fragment must not pre-empt it.
  if (wholeRun && _firstStrongIsLtr(text) == true) return '$_lri$text$_pdi';

  return text.replaceAllMapped(
    _groupedDigits,
    (match) => '$_lri${match[0]}$_pdi',
  );
}