Matras and Ikar in the Wrong Position After Conversion: Full Fix

You convert a document and the Hindi comes out almost right. Most words are fine. Then you hit one where a vowel sign has landed against the wrong letter, or floats at the start of a word attached to nothing. It is always the same vowel sign causing it, and there is a specific reason why that one and no other.

One vowel sign behaves differently from all the others

Devanagari writes most vowel signs after, above, or below the consonant they modify. का puts the sign to the right. कु puts it underneath. के puts it on top. In every one of those, the order you read the characters on the page matches the order a computer stores them.

The short-i breaks that pattern. In कि the sign is drawn to the left of the क, but it is pronounced after it, and Unicode stores characters in pronunciation order. So the stored sequence runs consonant first, sign second, while the page shows sign first, consonant second.

WordOrder on the pageOrder in memory
काक then ाक then ा (same)
किि then कक then ि (reversed)

Legacy fonts like KrutiDev store what gets drawn, in the order it gets drawn. Unicode stores what gets said. For every vowel sign except the short-i those two orders agree, which is why a naive conversion gets most of a document right and then fails in exactly one place.

What that looks like in KrutiDev

KrutiDev writes the short-i as the letter f, sitting before the consonant it belongs to. Typing fd produces कि on screen: the f draws the hook, the d draws क.

A converter working one character at a time reads f, emits ि, reads d, emits क, and hands back ि क. Two correct characters in the wrong order, which renders as a broken word.

Getting it right means the converter has to look ahead: on seeing the marker, find the consonant that follows, emit that consonant first, and only then emit the vowel sign. This site's engine does that as a dedicated pass over the text rather than as part of the character mapping, because character mapping alone cannot express it.

The characters are never wrong. The order is. That is why the output looks like Hindi and reads like nonsense.

Conjuncts are where converters break

Single consonants are the easy case. The failure that survives into shipped converters involves consonant clusters.

Take स्थि, as in स्थिति. The cluster is स joined to थ, and the short-i belongs to the cluster as a whole. Stored correctly the sequence runs स, joiner, थ, ि: four characters with the vowel sign at the very end.

A converter that knows it must move the sign one position past the following consonant produces स, ि, joiner, थ instead. The sign has landed inside the cluster, between the joiner and its consonant, which is not a sequence Devanagari permits. Rendering engines respond by drawing a dotted circle or splitting the cluster apart.

The rule that holds is that the vowel sign clears the entire cluster, however long it runs. Handling that requires a second pass specifically for the case where a short-i ends up sitting before a joiner, moving it past everything the joiner binds together.

Checking your own output

Two searches catch nearly every instance of this. Look for the short-i character immediately after a joiner, and look for it at the beginning of a word. Neither is valid Devanagari, and both are what a reordering failure leaves behind.

For a manual spot check, read a handful of words that contain कि, नि, सि, or any conjunct carrying a short-i. Those exercise the exact code path that fails, and a converter that gets स्थिति right is very unlikely to be wrong elsewhere.

Reph moves too, in the opposite direction

The other reordering case is reph: an r-sound that attaches to a following consonant and is drawn as a small hook above it. In चर्म the hook sits over म, near the end of the syllable.

Legacy fonts put the marker where it is drawn, at the end. Unicode stores it where it is pronounced, at the start, as र followed by a joiner. So चर्म is stored च, र, joiner, म, and a converter has to walk backward from the marker to find where the syllable began, then insert the r-sound there.

Backward is the operative word, and it is why reph and short-i need separate handling. One moves forward past a cluster, the other moves backward to a syllable boundary. A converter can implement either and still get the other wrong, which is worth knowing when comparing tools.

Why some converters get this wrong

Legacy-to-Unicode conversion looks like a substitution table, and for perhaps ninety-five percent of characters it is one. Build the table, replace each character, ship it. The output will be right often enough to seem finished.

Reordering cannot live in a substitution table, because the correct output depends on what comes next rather than only on the character in hand. It needs its own logic, running after substitution, and it needs a case for clusters on top of the case for single consonants. Converters that skip that work do not fail loudly. They produce documents that are mostly fine, which is harder to notice than a total failure and worse if the document is going to a court or an examiner.

If you have text that came out with signs in the wrong places, our converter handles this, including the conjunct case. Running the original legacy text through again is more reliable than trying to repair broken output, because the ordering information is still intact in the source and mostly lost in the result.

Edge cases

The text was already converted by another tool

Go back to the legacy original if it exists. Repairing misordered Unicode means inferring which consonant each stray sign belonged to, and once several are wrong in the same word that inference stops being reliable.

Only conjunct words are affected

A converter that handles single consonants and not clusters. Simple words pass and स्थिति fails. Test with a few cluster words before trusting it on a long document.

A dotted circle appears next to the sign

That circle is the rendering engine reporting a vowel sign with nothing valid to attach to. It confirms the ordering is wrong rather than the characters being wrong.

The problem appeared after copying from a PDF rather than converting

Different cause, similar symptom. PDF extraction can read glyphs in the order they were painted on the page, which produces the same visual-order sequence for unrelated reasons. That case is covered on the page about copy-pasting Hindi from a PDF giving garbled text.

Half-forms are breaking as well as matras

Conjunct handling and matra reordering fail together often, since both depend on the converter understanding cluster boundaries. Broken half-forms and dropped joiners have their own walkthrough on the page about half characters and conjuncts breaking after conversion.

Reordering is one of two conversion faults worth knowing about, and both are indexed with the display problems in Hindi font resources.