ApplyDevanagariReorder

Signature

function ApplyDevanagariReorder(const Wide: UnicodeString): UnicodeString;

Purpose

Applies the Devanagari reorder pre-pass to Wide and returns the reordered UnicodeString ready for cmap + GSUB consumption. Non-Devanagari content (Latin, digits, punctuation, other scripts) passes through byte-identical.

Reorder rules applied

  • R1 Repha: when a syllable starts with Ra (U+0930) + Halant (U+094D) + Consonant, the (Ra, Halant) pair moves to the syllable end.
  • R2 Pre-base matras: matras with MatraPos = 1 (e.g. U+093F I-matra, U+094E PRISHTHAMATRA E) move to the syllable start.
  • R3 Above-base matras: matras with MatraPos = 3 (e.g. U+0947U+0948 E/AI, U+0945U+0946 CANDRA E/SHORT E) emit after the base block.
  • R4 Below-base matras: matras with MatraPos = 4 (e.g. U+0941U+0944 U/UU/Vocalic R/RR) emit after above-base.
  • R5 Post-base matras: matras with MatraPos = 2 (e.g. U+093E AA, U+0940 II, U+0949U+094C CANDRA O/SHORT O/O/AU) emit after below-base.

Output layout per syllable: [pre-matras] + [base + halant + nukta + bindu/visarga/modifier — Repha and matras removed] + [above-matras] + [below-matras] + [post-matras] + [Repha: Ra Halant]?

Conjuncts (C + Halant + C) are preserved by keeping all non-matra content in the base block in original relative order. Reorder is single-pass and idempotent.

Example

var
  Wide: UnicodeString;
begin
  // Input: RA + HALANT + KA + I-matra
  Wide:= Doc.ApplyDevanagariReorder(#$0930#$094D#$0915#$093F);
  // Wide is now: I-matra + KA + RA + HALANT  (R1 + R2 applied)
end;

See also

  • ApplyIndicReorder — total dispatcher covering all registered Indic scripts (Devanagari plus future 8f.2–8f.10 scripts).
  • GetDevanagariCategory — pure Unicode codepoint → category lookup.

Standards

  • Unicode 16.0 §12.1 (Devanagari)
  • Unicode 16.0 IndicSyllabicCategory.txt and IndicPositionalCategory.txt
  • ISO 32000-1 §9.10 (extraction of text content)
  • OpenType Devanagari shaping spec

Version history

  • v2.119.55 — Initial Devanagari reorder pre-pass (Phase 8e Phase D); R1 Repha + R2 pre-base I-matra only.
  • v2.119.67 — Auto-applied inside BuildUnicode*FieldContent when sfIndicShaping is set (Phase 8e).
  • v2.119.69 — Internally routed via ApplyIndicReorder dispatcher; output unchanged (Phase 8f.0).
  • v2.119.70 — Complete shaper: R3 above-base + R4 below-base + R5 post-base matra repositioning added; reorder now covers all 4 MatraPos slots (Phase 8f.1).