projectText function

TextProjection projectText(
  1. String logicalText, {
  2. required TextPresentationPolicy policy,
})

Projects logicalText for display under policy.

Identity unless the policy authorizes lowering AND the text contains a joiner AND a cluster parses as an emoji ZWJ sequence — everything else, including shaping-significant non-emoji ZWJ text, passes through byte-identical (property gate 10 rides on the parser's strictness).

Implementation

TextProjection projectText(
  String logicalText, {
  required TextPresentationPolicy policy,
}) {
  if (policy.lowering != ClusterLowering.split) {
    return TextProjection.identity(logicalText);
  }
  // Zero-allocation reject for the overwhelmingly common case: U+200D is a
  // BMP code unit, so a plain code-unit scan is exact.
  var hasZwj = false;
  for (var i = 0; i < logicalText.length; i++) {
    if (logicalText.codeUnitAt(i) == _zwjCodeUnit) {
      hasZwj = true;
      break;
    }
  }
  if (!hasZwj) return TextProjection.identity(logicalText);

  final display = StringBuffer();
  final changed = <PreparedCluster>[];
  var sourceOffset = 0;
  for (final cluster in logicalText.characters) {
    final components = splitEmojiZwjSequence(cluster);
    if (components == null) {
      display.write(cluster);
    } else {
      final displayStart = display.length;
      final atoms = <TextRange>[];
      for (final component in components) {
        atoms.add(
          TextRange(
            start: display.length,
            end: display.length + component.length,
          ),
        );
        display.write(component);
      }
      changed.add(
        PreparedCluster(
          sourceRange: TextRange(
            start: sourceOffset,
            end: sourceOffset + cluster.length,
          ),
          displayRange: TextRange(start: displayStart, end: display.length),
          displayAtomRanges: List.unmodifiable(atoms),
        ),
      );
    }
    sourceOffset += cluster.length;
  }
  if (changed.isEmpty) {
    // Joiners were present but nothing parsed as an emoji sequence (Arabic,
    // Indic, malformed) — identity, same object, no mappings.
    return TextProjection.identity(logicalText);
  }
  return TextProjection._(display.toString(), List.unmodifiable(changed));
}