15469607a00d84a07dc638eda46a87fc90142d64breed@android.com/*
25469607a00d84a07dc638eda46a87fc90142d64breed@android.com * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
35469607a00d84a07dc638eda46a87fc90142d64breed@android.com *
45469607a00d84a07dc638eda46a87fc90142d64breed@android.com * This is part of HarfBuzz, an OpenType Layout engine library.
55469607a00d84a07dc638eda46a87fc90142d64breed@android.com *
65469607a00d84a07dc638eda46a87fc90142d64breed@android.com * Permission is hereby granted, without written agreement and without
75469607a00d84a07dc638eda46a87fc90142d64breed@android.com * license or royalty fees, to use, copy, modify, and distribute this
85469607a00d84a07dc638eda46a87fc90142d64breed@android.com * software and its documentation for any purpose, provided that the
95469607a00d84a07dc638eda46a87fc90142d64breed@android.com * above copyright notice and the following two paragraphs appear in
105469607a00d84a07dc638eda46a87fc90142d64breed@android.com * all copies of this software.
115469607a00d84a07dc638eda46a87fc90142d64breed@android.com *
125469607a00d84a07dc638eda46a87fc90142d64breed@android.com * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
135469607a00d84a07dc638eda46a87fc90142d64breed@android.com * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
145469607a00d84a07dc638eda46a87fc90142d64breed@android.com * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
155469607a00d84a07dc638eda46a87fc90142d64breed@android.com * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
165469607a00d84a07dc638eda46a87fc90142d64breed@android.com * DAMAGE.
175469607a00d84a07dc638eda46a87fc90142d64breed@android.com *
185469607a00d84a07dc638eda46a87fc90142d64breed@android.com * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
195469607a00d84a07dc638eda46a87fc90142d64breed@android.com * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
205469607a00d84a07dc638eda46a87fc90142d64breed@android.com * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
215469607a00d84a07dc638eda46a87fc90142d64breed@android.com * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
225469607a00d84a07dc638eda46a87fc90142d64breed@android.com * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
235469607a00d84a07dc638eda46a87fc90142d64breed@android.com */
245469607a00d84a07dc638eda46a87fc90142d64breed@android.com
255469607a00d84a07dc638eda46a87fc90142d64breed@android.com#include "harfbuzz-shaper.h"
265469607a00d84a07dc638eda46a87fc90142d64breed@android.com#include "harfbuzz-shaper-private.h"
275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
285469607a00d84a07dc638eda46a87fc90142d64breed@android.com#include <assert.h>
295469607a00d84a07dc638eda46a87fc90142d64breed@android.com#include <stdio.h>
305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
315469607a00d84a07dc638eda46a87fc90142d64breed@android.com#define FLAG(x) (1 << (x))
325469607a00d84a07dc638eda46a87fc90142d64breed@android.com
335469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic HB_Bool isLetter(HB_UChar16 ucs)
345469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const int test = FLAG(HB_Letter_Uppercase) |
365469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Letter_Lowercase) |
375469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Letter_Titlecase) |
385469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Letter_Modifier) |
395469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Letter_Other);
405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return FLAG(HB_GetUnicodeCharCategory(ucs)) & test;
415469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
425469607a00d84a07dc638eda46a87fc90142d64breed@android.com
435469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic HB_Bool isMark(HB_UChar16 ucs)
445469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const int test = FLAG(HB_Mark_NonSpacing) |
465469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Mark_SpacingCombining) |
475469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     FLAG(HB_Mark_Enclosing);
485469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return FLAG(HB_GetUnicodeCharCategory(ucs)) & test;
495469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
505469607a00d84a07dc638eda46a87fc90142d64breed@android.com
515469607a00d84a07dc638eda46a87fc90142d64breed@android.comenum Form {
525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid = 0x0,
535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    UnknownForm = Invalid,
545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant,
555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta,
565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Halant,
575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra,
585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    VowelMark,
595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    StressMark,
605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel,
615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    LengthMark,
625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Control,
635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other
645469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
655469607a00d84a07dc638eda46a87fc90142d64breed@android.com
665469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const unsigned char indicForms[0xe00-0x900] = {
675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Devangari
685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
725469607a00d84a07dc638eda46a87fc90142d64breed@android.com
735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
775469607a00d84a07dc638eda46a87fc90142d64breed@android.com
785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
825469607a00d84a07dc638eda46a87fc90142d64breed@android.com
835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
875469607a00d84a07dc638eda46a87fc90142d64breed@android.com
885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
895469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, UnknownForm, UnknownForm,
925469607a00d84a07dc638eda46a87fc90142d64breed@android.com
935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, StressMark, StressMark, StressMark,
945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    StressMark, UnknownForm, UnknownForm, UnknownForm,
955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
975469607a00d84a07dc638eda46a87fc90142d64breed@android.com
985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Consonant,
1065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant /* ??? */, Consonant, Consonant,
1075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Bengali
1095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
1105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
1115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
1125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, Invalid, IndependentVowel,
1135469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, Invalid, IndependentVowel,
1155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
1165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1185469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
1225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1235469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Invalid,
1255469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Consonant, Consonant,
1265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
1275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
1285469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
1305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Invalid, Matra,
1315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Invalid, Matra,
1325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, Consonant, UnknownForm,
1335469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
1355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, VowelMark,
1365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
1375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Invalid, Consonant,
1385469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
1405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1435469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Other, Other,
1455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gurmukhi
1505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
1515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
1525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
1535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, IndependentVowel,
1545469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, Invalid, IndependentVowel,
1565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
1575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1595469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
1635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1645469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
1665469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Invalid,
1675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
1685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
1695469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Invalid,
1715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Matra,
1725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Invalid, Matra,
1735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, UnknownForm, UnknownForm,
1745469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
1765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, UnknownForm, UnknownForm, UnknownForm,
1775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Consonant,
1785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Invalid,
1795469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Invalid, Invalid,
1815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1845469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    StressMark, StressMark, Consonant, Consonant,
1865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
1895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gujarati
1915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
1925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
1935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
1945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
1955469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
1975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
1985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
1995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2005469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
2045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2055469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
2075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Consonant,
2085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
2095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
2105469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
2125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Invalid, Matra,
2135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Invalid, Matra,
2145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, UnknownForm, UnknownForm,
2155469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, UnknownForm, UnknownForm, UnknownForm,
2175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
2185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
2195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    UnknownForm, UnknownForm, UnknownForm, UnknownForm,
2205469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
2225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Oriya
2325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
2335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
2345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
2355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, Invalid, IndependentVowel,
2365469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, Invalid, IndependentVowel,
2385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
2395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2415469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
2455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2465469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
2485469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Consonant,
2495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
2505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
2515469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
2535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Matra,
2545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Invalid, Matra,
2555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, UnknownForm, UnknownForm,
2565469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Invalid, Invalid, Invalid,
2585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, UnknownForm, LengthMark, LengthMark,
2595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
2605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Invalid, Consonant,
2615469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, Invalid, Invalid,
2635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Other, Other,
2645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2665469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Consonant, Other, Other,
2685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
2715469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    //Tamil
2735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, VowelMark, Other,
2745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
2755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
2765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, IndependentVowel, IndependentVowel,
2775469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
2795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Invalid, Invalid,
2805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Invalid,
2815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
2825469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Consonant,
2845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Invalid, Invalid,
2855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Invalid,
2865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Consonant, Consonant,
2875469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2895469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
2905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
2915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
2925469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Invalid,
2945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
2955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
2965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, Invalid, Invalid,
2975469607a00d84a07dc638eda46a87fc90142d64breed@android.com
2985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
2995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, LengthMark,
3005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Other, Other,
3055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3125469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Telugu
3145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, VowelMark, VowelMark, VowelMark,
3155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
3165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
3175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
3185469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
3205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
3215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3235469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3255469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
3275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3285469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Consonant,
3315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
3325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
3335469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
3355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
3365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
3375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, Invalid, Invalid,
3385469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, LengthMark, Matra, Invalid,
3415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3435469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, Invalid, Invalid,
3455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Other, Other,
3465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3535469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Kannada
3555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, VowelMark, VowelMark,
3565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
3575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
3585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
3595469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
3615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
3625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3645469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3665469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
3685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3695469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
3715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Consonant, Consonant,
3725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
3735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Nukta, Other, Matra, Matra,
3745469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
3765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
3775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
3785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, Invalid, Invalid,
3795469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, LengthMark, LengthMark, Invalid,
3825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
3835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Consonant, Invalid,
3845469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, VowelMark, VowelMark,
3865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Other, Other,
3875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
3945469607a00d84a07dc638eda46a87fc90142d64breed@android.com
3955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Malayalam
3965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, VowelMark, VowelMark,
3975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
3985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
3995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
4005469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
4025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, Consonant, Consonant, Consonant,
4035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4055469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Invalid, Consonant, Consonant,
4095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4105469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, UnknownForm, UnknownForm,
4145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
4155469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
4175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
4185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Matra,
4195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Halant, Invalid, Invalid,
4205469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Matra,
4235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, Invalid, Invalid,
4275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Other, Other,
4285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4355469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Sinhala
4375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, VowelMark, VowelMark,
4385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
4395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
4405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
4415469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
4435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
4445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Consonant, Consonant,
4455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4465469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4485469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4515469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Invalid, Consonant,
4535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Consonant, Invalid, Invalid,
4565469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Consonant,
4585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Consonant, Consonant, Consonant, Invalid,
4595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Halant, Invalid,
4605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Matra,
4615469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
4635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Invalid, Matra, Invalid,
4645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
4655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Matra, Matra, Matra, Matra,
4665469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Invalid, Invalid,
4715469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Invalid, Invalid, Matra, Matra,
4735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Other, Other, Other, Other,
4765469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
4775469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4785469607a00d84a07dc638eda46a87fc90142d64breed@android.comenum Position {
4795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None,
4805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Pre,
4815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above,
4825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below,
4835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post,
4845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split,
4855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Base,
4865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Reph,
4875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Vattu,
4885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Inherit
4895469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
4905469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4915469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const unsigned char indicPosition[0xe00-0x900] = {
4925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Devanagari
4935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Above, Post,
4945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
4955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
4965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
4975469607a00d84a07dc638eda46a87fc90142d64breed@android.com
4985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
4995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
5095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Pre,
5125469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Below, Below, Below,
5145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Above, Above, Above,
5155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Post, Post, Post,
5165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, None, None, None,
5175469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Below, Above,
5195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, None, None, None,
5205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5225469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Below, Below,
5245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5255469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5325469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Bengali
5345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Post, Post,
5355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5385469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5435469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, Post,
5485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
5505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Post, Pre,
5535469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Below, Below, Below,
5555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, Pre,
5565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Pre, None, None, Split,
5575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, Below, None, None,
5585469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
5615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5635469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Below, Below,
5655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5665469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5685469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
5705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5735469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gurmukhi
5755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Above, Post,
5765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5795469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5845469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
5885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
5895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
5915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, None, None,
5925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, None, None,
5935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Post, Pre,
5945469607a00d84a07dc638eda46a87fc90142d64breed@android.com
5955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Below, Below, None,
5965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Above,
5975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, None, None, Above,
5985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, None, None, None,
5995469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6045469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6095469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Above, None, None,
6115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6145469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gujarati
6165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Above, Post,
6175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6205469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
6325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Pre,
6355469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Below, Below, Below,
6375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Above, None, Above,
6385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Post, None, Post,
6395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, None, None, None,
6405469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6455469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Below, Below,
6475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6485469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6505469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6555469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Oriya
6575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Post, Post,
6585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6615469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6665469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
6695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, None, None,
6705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Post,
6715469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Below, Below,
6735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Above,
6765469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Below, Below, Below,
6785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Pre,
6795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, None, None, Split,
6805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, None, None, None,
6815469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Above, Post,
6845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
6865469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6895469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6915469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, None, None,
6935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
6965469607a00d84a07dc638eda46a87fc90142d64breed@android.com
6975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Tamil
6985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Above, None,
6995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7125469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
7175469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Below, Below, None,
7195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Pre, Pre,
7205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Pre, None, Split, Split,
7215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, Halant, None, None,
7225469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
7255469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7325469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7375469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Telugu
7395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Post, Post, Post,
7405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7435469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, Below, Below,
7465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Below, Below,
7525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7535469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Below, Below,
7555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, Below, Below,
7565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, None, None,
7575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Above,
7585469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Post, Post, Post,
7605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, None, Above, Above,
7615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, None, Post, Above,
7625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Halant, None, None,
7635469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Above, Below, None,
7665469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7685469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7735469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7785469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Kannada
7805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
7815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7845469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
7865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, Below, Below,
7875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, Below, Below,
7945469607a00d84a07dc638eda46a87fc90142d64breed@android.com
7955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Below, Below,
7965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Below, Below, Below,
7975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, Below, None, None,
7985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Above,
7995469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, Post, Post, Post,
8015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, None, Above, Split,
8025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, None, Split, Split,
8035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Above, Halant, None, None,
8045469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Post, Post, None,
8075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Below, None,
8095469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Below, Below,
8115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8145469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8195469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Malayalam
8215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
8225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
8355469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, None, Below, None,
8375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, Post, None, None,
8385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
8405469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Post, Post, Post,
8425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Pre, Pre,
8435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Pre, None, Split, Split,
8445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, Halant, None, None,
8455469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8475469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
8485469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8505469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8555469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8605469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Sinhala
8625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
8635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8665469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8715469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8765469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8815469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, Post,
8865469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Post, Above, Above,
8885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Below, None, Below, None,
8895469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Post, Pre, Split, Pre,
8905469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Split, Split, Split, Post,
8915469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8965469607a00d84a07dc638eda46a87fc90142d64breed@android.com
8975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, Post, Post,
8985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
8995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None,
9005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    None, None, None, None
9015469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9035469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic inline Form form(unsigned short uc) {
9045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (uc < 0x900 || uc > 0xdff) {
9055469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (uc == 0x25cc)
9065469607a00d84a07dc638eda46a87fc90142d64breed@android.com            return Consonant;
9075469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (uc == 0x200c || uc == 0x200d)
9085469607a00d84a07dc638eda46a87fc90142d64breed@android.com            return Control;
9095469607a00d84a07dc638eda46a87fc90142d64breed@android.com        return Other;
9105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
9115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return (Form)indicForms[uc-0x900];
9125469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
9135469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9145469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic inline Position indic_position(unsigned short uc) {
9155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (uc < 0x900 || uc > 0xdff)
9165469607a00d84a07dc638eda46a87fc90142d64breed@android.com        return None;
9175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return (Position) indicPosition[uc-0x900];
9185469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
9195469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9205469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9215469607a00d84a07dc638eda46a87fc90142d64breed@android.comenum IndicScriptProperties {
9225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasReph = 0x01,
9235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit = 0x02
9245469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9265469607a00d84a07dc638eda46a87fc90142d64breed@android.comconst hb_uint8 scriptProperties[10] = {
9275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Devanagari,
9285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasReph,
9295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Bengali,
9305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasReph|HasSplit,
9315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gurmukhi,
9325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0,
9335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Gujarati,
9345469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasReph,
9355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Oriya,
9365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasReph|HasSplit,
9375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Tamil,
9385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit,
9395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Telugu,
9405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit,
9415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Kannada,
9425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit|HasReph,
9435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Malayalam,
9445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit,
9455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // Sinhala,
9465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HasSplit
9475469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9495469607a00d84a07dc638eda46a87fc90142d64breed@android.comstruct IndicOrdering {
9505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Form form;
9515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Position position;
9525469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9535469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9545469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering devanagari_order [] = {
9555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
9565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
9575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Below },
9585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { StressMark, Below },
9595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
9605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
9615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Reph },
9625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Above },
9635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { StressMark, Above },
9645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
9655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
9665469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9675469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9685469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering bengali_order [] = {
9695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
9705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
9715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
9725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Reph },
9735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Above },
9745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Post },
9755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
9765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
9775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
9785469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9795469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9805469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering gurmukhi_order [] = {
9815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
9825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
9835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
9845469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Post },
9855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
9865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Above },
9875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
9885469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9905469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering tamil_order [] = {
9915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
9925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
9935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
9945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
9955469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
9965469607a00d84a07dc638eda46a87fc90142d64breed@android.com
9975469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering telugu_order [] = {
9985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
9995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
10005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
10015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
10025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Post },
10035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
10045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
10055469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10065469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10075469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering kannada_order [] = {
10085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
10095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
10105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
10115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Post },
10125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { LengthMark, Post },
10135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Reph },
10145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
10155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
10165469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10175469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10185469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering malayalam_order [] = {
10195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Below },
10205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
10215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Reph },
10225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Consonant, Post },
10235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
10245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
10255469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
10265469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10285469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering sinhala_order [] = {
10295469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Below },
10305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Above },
10315469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { Matra, Post },
10325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { VowelMark, Post },
10335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { (Form)0, None }
10345469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10355469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10365469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const IndicOrdering * const indic_order[] = {
10375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    devanagari_order, // Devanagari
10385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    bengali_order, // Bengali
10395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    gurmukhi_order, // Gurmukhi
10405469607a00d84a07dc638eda46a87fc90142d64breed@android.com    devanagari_order, // Gujarati
10415469607a00d84a07dc638eda46a87fc90142d64breed@android.com    bengali_order, // Oriya
10425469607a00d84a07dc638eda46a87fc90142d64breed@android.com    tamil_order, // Tamil
10435469607a00d84a07dc638eda46a87fc90142d64breed@android.com    telugu_order, // Telugu
10445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    kannada_order, // Kannada
10455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    malayalam_order, // Malayalam
10465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    sinhala_order // Sinhala
10475469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10495469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10505469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10515469607a00d84a07dc638eda46a87fc90142d64breed@android.com// vowel matras that have to be split into two parts.
10525469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const unsigned short split_matras[]  = {
10535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    //  matra, split1, split2, split3
10545469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // bengalis
10565469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0x9cb, 0x9c7, 0x9be, 0x0,
10575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0x9cc, 0x9c7, 0x9d7, 0x0,
10585469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // oriya
10595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xb48, 0xb47, 0xb56, 0x0,
10605469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xb4b, 0xb47, 0xb3e, 0x0,
10615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xb4c, 0xb47, 0xb57, 0x0,
10625469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // tamil
10635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xbca, 0xbc6, 0xbbe, 0x0,
10645469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xbcb, 0xbc7, 0xbbe, 0x0,
10655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xbcc, 0xbc6, 0xbd7, 0x0,
10665469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // telugu
10675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xc48, 0xc46, 0xc56, 0x0,
10685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // kannada
10695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xcc0, 0xcbf, 0xcd5, 0x0,
10705469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xcc7, 0xcc6, 0xcd5, 0x0,
10715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xcc8, 0xcc6, 0xcd6, 0x0,
10725469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xcca, 0xcc6, 0xcc2, 0x0,
10735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xccb, 0xcc6, 0xcc2, 0xcd5,
10745469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // malayalam
10755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xd4a, 0xd46, 0xd3e, 0x0,
10765469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xd4b, 0xd47, 0xd3e, 0x0,
10775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xd4c, 0xd46, 0xd57, 0x0,
10785469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // sinhala
10795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xdda, 0xdd9, 0xdca, 0x0,
10805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xddc, 0xdd9, 0xdcf, 0x0,
10815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xddd, 0xdd9, 0xdcf, 0xdca,
10825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xdde, 0xdd9, 0xddf, 0x0,
10835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    0xffff
10845469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
10855469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10865469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic inline void splitMatra(unsigned short *reordered, int matra, int &len)
10875469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
10885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    unsigned short matra_uc = reordered[matra];
10895469607a00d84a07dc638eda46a87fc90142d64breed@android.com    //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]);
10905469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const unsigned short *split = split_matras;
10925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    while (split[0] < matra_uc)
10935469607a00d84a07dc638eda46a87fc90142d64breed@android.com        split += 4;
10945469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    assert(*split == matra_uc);
10965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    ++split;
10975469607a00d84a07dc638eda46a87fc90142d64breed@android.com
10985469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int added_chars = split[2] == 0x0 ? 1 : 2;
10995469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    memmove(reordered + matra + added_chars, reordered + matra, (len-matra)*sizeof(unsigned short));
11015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    reordered[matra] = split[0];
11025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    reordered[matra+1] = split[1];
11035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if(added_chars == 2)
11045469607a00d84a07dc638eda46a87fc90142d64breed@android.com        reordered[matra+2] = split[2];
11055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    len += added_chars;
11065469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
11075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11085469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE
11095469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const HB_OpenTypeFeature indic_features[] = {
11105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
11115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
11125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
11135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty },
11145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty },
11155469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
11165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
11175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
11185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
11195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
11205469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
11215469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
11225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
11235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { HB_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
11245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    { 0, 0 }
11255469607a00d84a07dc638eda46a87fc90142d64breed@android.com};
11265469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
11275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11285469607a00d84a07dc638eda46a87fc90142d64breed@android.com// #define INDIC_DEBUG
11295469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifdef INDIC_DEBUG
11305469607a00d84a07dc638eda46a87fc90142d64breed@android.com#define IDEBUG hb_debug
11315469607a00d84a07dc638eda46a87fc90142d64breed@android.com#include <stdarg.h>
11325469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11335469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic void hb_debug(const char *msg, ...)
11345469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
11355469607a00d84a07dc638eda46a87fc90142d64breed@android.com    va_list ap;
11365469607a00d84a07dc638eda46a87fc90142d64breed@android.com    va_start(ap, msg); // use variable arg list
11375469607a00d84a07dc638eda46a87fc90142d64breed@android.com    vfprintf(stderr, msg, ap);
11385469607a00d84a07dc638eda46a87fc90142d64breed@android.com    va_end(ap);
11395469607a00d84a07dc638eda46a87fc90142d64breed@android.com    fprintf(stderr, "\n");
11405469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
11415469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11425469607a00d84a07dc638eda46a87fc90142d64breed@android.com#else
11435469607a00d84a07dc638eda46a87fc90142d64breed@android.com#define IDEBUG if(0) printf
11445469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
11455469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11465469607a00d84a07dc638eda46a87fc90142d64breed@android.com#if 0 //def INDIC_DEBUG
11475469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic QString propertiesToString(int properties)
11485469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
11495469607a00d84a07dc638eda46a87fc90142d64breed@android.com    QString res;
11505469607a00d84a07dc638eda46a87fc90142d64breed@android.com    properties = ~properties;
11515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & CcmpProperty)
11525469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Ccmp ";
11535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & InitProperty)
11545469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Init ";
11555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & NuktaProperty)
11565469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Nukta ";
11575469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & AkhantProperty)
11585469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Akhant ";
11595469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & RephProperty)
11605469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Reph ";
11615469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & PreFormProperty)
11625469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "PreForm ";
11635469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & BelowFormProperty)
11645469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "BelowForm ";
11655469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & AboveFormProperty)
11665469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "AboveForm ";
11675469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & HalfFormProperty)
11685469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "HalfForm ";
11695469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & PostFormProperty)
11705469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "PostForm ";
11715469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & VattuProperty)
11725469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Vattu ";
11735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & PreSubstProperty)
11745469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "PreSubst ";
11755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & BelowSubstProperty)
11765469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "BelowSubst ";
11775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & AboveSubstProperty)
11785469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "AboveSubst ";
11795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & PostSubstProperty)
11805469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "PostSubst ";
11815469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & HalantProperty)
11825469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Halant ";
11835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (properties & CligProperty)
11845469607a00d84a07dc638eda46a87fc90142d64breed@android.com        res += "Clig ";
11855469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return res;
11865469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
11875469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
11885469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11895469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic bool indic_shape_syllable(HB_Bool openType, HB_ShaperItem *item, bool invalid)
11905469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
11915469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_Script script = item->item.script;
11925469607a00d84a07dc638eda46a87fc90142d64breed@android.com    assert(script >= HB_Script_Devanagari && script <= HB_Script_Sinhala);
11935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const unsigned short script_base = 0x0900 + 0x80*(script-HB_Script_Devanagari);
11945469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const unsigned short ra = script_base + 0x30;
11955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const unsigned short halant = script_base + 0x4d;
11965469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const unsigned short nukta = script_base + 0x3c;
11975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    bool control = false;
11985469607a00d84a07dc638eda46a87fc90142d64breed@android.com
11995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int len = (int)item->item.length;
12005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG(">>>>> indic shape: from=%d, len=%d invalid=%d", item->item.pos, item->item.length, invalid);
12015469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if ((int)item->num_glyphs < len+4) {
12035469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->num_glyphs = len+4;
12045469607a00d84a07dc638eda46a87fc90142d64breed@android.com        return false;
12055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
12065469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_STACKARRAY(HB_UChar16, reordered, len + 4);
12085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_STACKARRAY(hb_uint8, position, len + 4);
12095469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    unsigned char properties = scriptProperties[script-HB_Script_Devanagari];
12115469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (invalid) {
12135469607a00d84a07dc638eda46a87fc90142d64breed@android.com        *reordered = 0x25cc;
12145469607a00d84a07dc638eda46a87fc90142d64breed@android.com        memcpy(reordered+1, item->string + item->item.pos, len*sizeof(HB_UChar16));
12155469607a00d84a07dc638eda46a87fc90142d64breed@android.com        len++;
12165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    } else {
12175469607a00d84a07dc638eda46a87fc90142d64breed@android.com        memcpy(reordered, item->string + item->item.pos, len*sizeof(HB_UChar16));
12185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
12195469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (reordered[len-1] == 0x200c) // zero width non joiner
12205469607a00d84a07dc638eda46a87fc90142d64breed@android.com        len--;
12215469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12225469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int i;
12235469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int base = 0;
12245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int reph = -1;
12255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12265469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifdef INDIC_DEBUG
12275469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("original:");
12285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    for (i = 0; i < len; i++) {
12295469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("    %d: %4x", i, reordered[i]);
12305469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
12315469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
12325469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12335469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (len != 1) {
12345469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_UChar16 *uc = reordered;
12355469607a00d84a07dc638eda46a87fc90142d64breed@android.com        bool beginsWithRa = false;
12365469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12375469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Rule 1: find base consonant
12385469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //
12395469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // The shaping engine finds the base consonant of the
12405469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // syllable, using the following algorithm: starting from the
12415469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // end of the syllable, move backwards until a consonant is
12425469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // found that does not have a below-base or post-base form
12435469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // (post-base forms have to follow below-base forms), or
12445469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // arrive at the first consonant. The consonant stopped at
12455469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // will be the base.
12465469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //
12475469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //  * If the syllable starts with Ra + H (in a script that has
12485469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //    'Reph'), Ra is excluded from candidates for base
12495469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //    consonants.
12505469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //
12515469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // * In Kannada and Telugu, the base consonant cannot be
12525469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //   farther than 3 consonants from the end of the syllable.
12535469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // #### replace the HasReph property by testing if the feature exists in the font!
12545469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (form(*uc) == Consonant || (script == HB_Script_Bengali && form(*uc) == IndependentVowel)) {
12555469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if ((properties & HasReph) && (len > 2) &&
12565469607a00d84a07dc638eda46a87fc90142d64breed@android.com                (*uc == ra || *uc == 0x9f0) && *(uc+1) == halant)
12575469607a00d84a07dc638eda46a87fc90142d64breed@android.com                beginsWithRa = true;
12585469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12595469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (beginsWithRa && form(*(uc+2)) == Control)
12605469607a00d84a07dc638eda46a87fc90142d64breed@android.com                beginsWithRa = false;
12615469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12625469607a00d84a07dc638eda46a87fc90142d64breed@android.com            base = (beginsWithRa ? 2 : 0);
12635469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("    length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base);
12645469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12655469607a00d84a07dc638eda46a87fc90142d64breed@android.com            int lastConsonant = 0;
12665469607a00d84a07dc638eda46a87fc90142d64breed@android.com            int matra = -1;
12675469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // we remember:
12685469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // * the last consonant since we need it for rule 2
12695469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // * the matras position for rule 3 and 4
12705469607a00d84a07dc638eda46a87fc90142d64breed@android.com
12715469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // figure out possible base glyphs
12725469607a00d84a07dc638eda46a87fc90142d64breed@android.com            memset(position, 0, len);
12735469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
12745469607a00d84a07dc638eda46a87fc90142d64breed@android.com                bool vattu = false;
12755469607a00d84a07dc638eda46a87fc90142d64breed@android.com                for (i = base; i < len; ++i) {
12765469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    position[i] = form(uc[i]);
12775469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (position[i] == Consonant) {
12785469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        lastConsonant = i;
12795469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        vattu = (!vattu && uc[i] == ra);
12805469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        if (vattu) {
12815469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            IDEBUG("excluding vattu glyph at %d from base candidates", i);
12825469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            position[i] = Vattu;
12835469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        }
12845469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    } else if (position[i] == Matra) {
12855469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        matra = i;
12865469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    }
12875469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
12885469607a00d84a07dc638eda46a87fc90142d64breed@android.com            } else {
12895469607a00d84a07dc638eda46a87fc90142d64breed@android.com                for (i = base; i < len; ++i) {
12905469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    position[i] = form(uc[i]);
12915469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (position[i] == Consonant)
12925469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        lastConsonant = i;
12935469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    else if (matra < 0 && position[i] == Matra)
12945469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        matra = i;
12955469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
12965469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
12975469607a00d84a07dc638eda46a87fc90142d64breed@android.com            int skipped = 0;
12985469607a00d84a07dc638eda46a87fc90142d64breed@android.com            Position pos = Post;
12995469607a00d84a07dc638eda46a87fc90142d64breed@android.com            for (i = len-1; i > base; i--) {
13005469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (position[i] != Consonant && (position[i] != Control || script == HB_Script_Kannada))
13015469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    continue;
13025469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13035469607a00d84a07dc638eda46a87fc90142d64breed@android.com                Position charPosition = indic_position(uc[i]);
13045469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (pos == Post && charPosition == Post) {
13055469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    pos = Post;
13065469607a00d84a07dc638eda46a87fc90142d64breed@android.com                } else if ((pos == Post || pos == Below) && charPosition == Below) {
13075469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (script == HB_Script_Devanagari || script == HB_Script_Gujarati)
13085469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        base = i;
13095469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    pos = Below;
13105469607a00d84a07dc638eda46a87fc90142d64breed@android.com                } else {
13115469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    base = i;
13125469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    break;
13135469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
13145469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (skipped == 2 && (script == HB_Script_Kannada || script == HB_Script_Telugu)) {
13155469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    base = i;
13165469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    break;
13175469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
13185469607a00d84a07dc638eda46a87fc90142d64breed@android.com                ++skipped;
13195469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
13205469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13215469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("    base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant);
13225469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13235469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Rule 2:
13245469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //
13255469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // If the base consonant is not the last one, Uniscribe
13265469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // moves the halant from the base consonant to the last
13275469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // one.
13285469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (lastConsonant > base) {
13295469607a00d84a07dc638eda46a87fc90142d64breed@android.com                int halantPos = 0;
13305469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (uc[base+1] == halant)
13315469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    halantPos = base + 1;
13325469607a00d84a07dc638eda46a87fc90142d64breed@android.com                else if (uc[base+1] == nukta && uc[base+2] == halant)
13335469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    halantPos = base + 2;
13345469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (halantPos > 0) {
13355469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    IDEBUG("    moving halant from %d to %d!", base+1, lastConsonant);
13365469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    for (i = halantPos; i < lastConsonant; i++)
13375469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        uc[i] = uc[i+1];
13385469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    uc[lastConsonant] = halant;
13395469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
13405469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
13415469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13425469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Rule 3:
13435469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //
13445469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // If the syllable starts with Ra + H, Uniscribe moves
13455469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // this combination so that it follows either:
13465469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13475469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // * the post-base 'matra' (if any) or the base consonant
13485469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //   (in scripts that show similarity to Devanagari, i.e.,
13495469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //   Devanagari, Gujarati, Bengali)
13505469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // * the base consonant (other scripts)
13515469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // * the end of the syllable (Kannada)
13525469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13535469607a00d84a07dc638eda46a87fc90142d64breed@android.com            Position matra_position = None;
13545469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (matra > 0)
13555469607a00d84a07dc638eda46a87fc90142d64breed@android.com                matra_position = indic_position(uc[matra]);
13565469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("    matra at %d with form %d, base=%d", matra, matra_position, base);
13575469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13585469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (beginsWithRa && base != 0) {
13595469607a00d84a07dc638eda46a87fc90142d64breed@android.com                int toPos = base+1;
13605469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (toPos < len && uc[toPos] == nukta)
13615469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    toPos++;
13625469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (toPos < len && uc[toPos] == halant)
13635469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    toPos++;
13645469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (toPos < len && uc[toPos] == 0x200d)
13655469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    toPos++;
13665469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant)
13675469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    toPos += 2;
13685469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (script == HB_Script_Devanagari || script == HB_Script_Gujarati || script == HB_Script_Bengali) {
13695469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (matra_position == Post || matra_position == Split) {
13705469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        toPos = matra+1;
13715469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        matra -= 2;
13725469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    }
13735469607a00d84a07dc638eda46a87fc90142d64breed@android.com                } else if (script == HB_Script_Kannada) {
13745469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    toPos = len;
13755469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    matra -= 2;
13765469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
13775469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13785469607a00d84a07dc638eda46a87fc90142d64breed@android.com                IDEBUG("moving leading ra+halant to position %d", toPos);
13795469607a00d84a07dc638eda46a87fc90142d64breed@android.com                for (i = 2; i < toPos; i++)
13805469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    uc[i-2] = uc[i];
13815469607a00d84a07dc638eda46a87fc90142d64breed@android.com                uc[toPos-2] = ra;
13825469607a00d84a07dc638eda46a87fc90142d64breed@android.com                uc[toPos-1] = halant;
13835469607a00d84a07dc638eda46a87fc90142d64breed@android.com                base -= 2;
13845469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (properties & HasReph)
13855469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    reph = toPos-2;
13865469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
13875469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13885469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Rule 4:
13895469607a00d84a07dc638eda46a87fc90142d64breed@android.com
13905469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Uniscribe splits two- or three-part matras into their
13915469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // parts. This splitting is a character-to-character
13925469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // operation).
13935469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //
13945469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //      Uniscribe describes some moving operations for these
13955469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //      matras here. For shaping however all pre matras need
13965469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //      to be at the beginning of the syllable, so we just move
13975469607a00d84a07dc638eda46a87fc90142d64breed@android.com            //      them there now.
13985469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (matra_position == Split) {
13995469607a00d84a07dc638eda46a87fc90142d64breed@android.com                splitMatra(uc, matra, len);
14005469607a00d84a07dc638eda46a87fc90142d64breed@android.com                // Handle three-part matras (0xccb in Kannada)
14015469607a00d84a07dc638eda46a87fc90142d64breed@android.com                matra_position = indic_position(uc[matra]);
14025469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
14035469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14045469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (matra_position == Pre) {
14055469607a00d84a07dc638eda46a87fc90142d64breed@android.com                unsigned short m = uc[matra];
14065469607a00d84a07dc638eda46a87fc90142d64breed@android.com                while (matra--)
14075469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    uc[matra+1] = uc[matra];
14085469607a00d84a07dc638eda46a87fc90142d64breed@android.com                uc[0] = m;
14095469607a00d84a07dc638eda46a87fc90142d64breed@android.com                base++;
14105469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
14115469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
14125469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14135469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Rule 5:
14145469607a00d84a07dc638eda46a87fc90142d64breed@android.com        //
14155469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Uniscribe classifies consonants and 'matra' parts as
14165469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // pre-base, above-base (Reph), below-base or post-base. This
14175469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // classification exists on the character code level and is
14185469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // language-dependent, not font-dependent.
14195469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = 0; i < base; ++i)
14205469607a00d84a07dc638eda46a87fc90142d64breed@android.com            position[i] = Pre;
14215469607a00d84a07dc638eda46a87fc90142d64breed@android.com        position[base] = Base;
14225469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = base+1; i < len; ++i) {
14235469607a00d84a07dc638eda46a87fc90142d64breed@android.com            position[i] = indic_position(uc[i]);
14245469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // #### replace by adjusting table
14255469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (uc[i] == nukta || uc[i] == halant)
14265469607a00d84a07dc638eda46a87fc90142d64breed@android.com                position[i] = Inherit;
14275469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
14285469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (reph > 0) {
14295469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // recalculate reph, it might have changed.
14305469607a00d84a07dc638eda46a87fc90142d64breed@android.com            for (i = base+1; i < len; ++i)
14315469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (uc[i] == ra)
14325469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    reph = i;
14335469607a00d84a07dc638eda46a87fc90142d64breed@android.com            position[reph] = Reph;
14345469607a00d84a07dc638eda46a87fc90142d64breed@android.com            position[reph+1] = Inherit;
14355469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
14365469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14375469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // all reordering happens now to the chars after the base
14385469607a00d84a07dc638eda46a87fc90142d64breed@android.com        int fixed = base+1;
14395469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (fixed < len && uc[fixed] == nukta)
14405469607a00d84a07dc638eda46a87fc90142d64breed@android.com            fixed++;
14415469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (fixed < len && uc[fixed] == halant)
14425469607a00d84a07dc638eda46a87fc90142d64breed@android.com            fixed++;
14435469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (fixed < len && uc[fixed] == 0x200d)
14445469607a00d84a07dc638eda46a87fc90142d64breed@android.com            fixed++;
14455469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14465469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifdef INDIC_DEBUG
14475469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = fixed; i < len; ++i)
14485469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("position[%d] = %d, form=%d uc=%x", i, position[i], form(uc[i]), uc[i]);
14495469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
14505469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // we continuosly position the matras and vowel marks and increase the fixed
14515469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // until we reached the end.
14525469607a00d84a07dc638eda46a87fc90142d64breed@android.com        const IndicOrdering *finalOrder = indic_order[script-HB_Script_Devanagari];
14535469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14545469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("    reordering pass:");
14555469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("        base=%d fixed=%d", base, fixed);
14565469607a00d84a07dc638eda46a87fc90142d64breed@android.com        int toMove = 0;
14575469607a00d84a07dc638eda46a87fc90142d64breed@android.com        while (finalOrder[toMove].form && fixed < len-1) {
14585469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("        fixed = %d, toMove=%d, moving form %d with pos %d", fixed, toMove, finalOrder[toMove].form, finalOrder[toMove].position);
14595469607a00d84a07dc638eda46a87fc90142d64breed@android.com            for (i = fixed; i < len; i++) {
14605469607a00d84a07dc638eda46a87fc90142d64breed@android.com//                IDEBUG() << "           i=" << i << "uc=" << hex << uc[i] << "form=" << form(uc[i])
14615469607a00d84a07dc638eda46a87fc90142d64breed@android.com//                         << "position=" << position[i];
14625469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (form(uc[i]) == finalOrder[toMove].form &&
14635469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     position[i] == finalOrder[toMove].position) {
14645469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    // need to move this glyph
14655469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    int to = fixed;
14665469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (i < len-1 && position[i+1] == Inherit) {
14675469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        IDEBUG("         moving two chars from %d to %d", i, to);
14685469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        unsigned short ch = uc[i];
14695469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        unsigned short ch2 = uc[i+1];
14705469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        unsigned char pos = position[i];
14715469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        for (int j = i+1; j > to+1; j--) {
14725469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            uc[j] = uc[j-2];
14735469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            position[j] = position[j-2];
14745469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        }
14755469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        uc[to] = ch;
14765469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        uc[to+1] = ch2;
14775469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        position[to] = pos;
14785469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        position[to+1] = pos;
14795469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        fixed += 2;
14805469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    } else {
14815469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        IDEBUG("         moving one char from %d to %d", i, to);
14825469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        unsigned short ch = uc[i];
14835469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        unsigned char pos = position[i];
14845469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        for (int j = i; j > to; j--) {
14855469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            uc[j] = uc[j-1];
14865469607a00d84a07dc638eda46a87fc90142d64breed@android.com                            position[j] = position[j-1];
14875469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        }
14885469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        uc[to] = ch;
14895469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        position[to] = pos;
14905469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        fixed++;
14915469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    }
14925469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
14935469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
14945469607a00d84a07dc638eda46a87fc90142d64breed@android.com            toMove++;
14955469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
14965469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14975469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
14985469607a00d84a07dc638eda46a87fc90142d64breed@android.com
14995469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (reph > 0) {
15005469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // recalculate reph, it might have changed.
15015469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = base+1; i < len; ++i)
15025469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (reordered[i] == ra)
15035469607a00d84a07dc638eda46a87fc90142d64breed@android.com                reph = i;
15045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
15055469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15065469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE
15075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const int availableGlyphs = item->num_glyphs;
15085469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
15095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (!item->font->klass->convertStringToGlyphIndices(item->font,
15105469607a00d84a07dc638eda46a87fc90142d64breed@android.com                                                        reordered, len,
15115469607a00d84a07dc638eda46a87fc90142d64breed@android.com                                                        item->glyphs, &item->num_glyphs,
15125469607a00d84a07dc638eda46a87fc90142d64breed@android.com                                                        item->item.bidiLevel % 2))
15135469607a00d84a07dc638eda46a87fc90142d64breed@android.com        goto error;
15145469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15155469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("  base=%d, reph=%d", base, reph);
15175469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("reordered:");
15185469607a00d84a07dc638eda46a87fc90142d64breed@android.com    for (i = 0; i < len; i++) {
15195469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->attributes[i].mark = false;
15205469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->attributes[i].clusterStart = false;
15215469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->attributes[i].justification = 0;
15225469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->attributes[i].zeroWidth = false;
15235469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("    %d: %4x", i, reordered[i]);
15245469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
15255469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15265469607a00d84a07dc638eda46a87fc90142d64breed@android.com    // now we have the syllable in the right order, and can start running it through open type.
15275469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15285469607a00d84a07dc638eda46a87fc90142d64breed@android.com    for (i = 0; i < len; ++i)
15295469607a00d84a07dc638eda46a87fc90142d64breed@android.com        control |= (form(reordered[i]) == Control);
15305469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15315469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE
15325469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (openType) {
15335469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15345469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // we need to keep track of where the base glyph is for some
15355469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // scripts and use the cluster feature for this.  This
15365469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // also means we have to correct the logCluster output from
15375469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // the open type engine manually afterwards.  for indic this
15385469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // is rather simple, as all chars just point to the first
15395469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // glyph in the syllable.
15405469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_STACKARRAY(unsigned short, clusters, len);
15415469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_STACKARRAY(unsigned int, properties, len);
15425469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15435469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = 0; i < len; ++i)
15445469607a00d84a07dc638eda46a87fc90142d64breed@android.com            clusters[i] = i;
15455469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15465469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // features we should always apply
15475469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = 0; i < len; ++i)
15485469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[i] = ~(CcmpProperty
15495469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | NuktaProperty
15505469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | VattuProperty
15515469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | PreSubstProperty
15525469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | BelowSubstProperty
15535469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | AboveSubstProperty
15545469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | PostSubstProperty
15555469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | HalantProperty
15565469607a00d84a07dc638eda46a87fc90142d64breed@android.com                              | PositioningProperties);
15575469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15585469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Ccmp always applies
15595469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Init
15605469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (item->item.pos == 0
15615469607a00d84a07dc638eda46a87fc90142d64breed@android.com            || !(isLetter(item->string[item->item.pos-1]) || isMark(item->string[item->item.pos-1])))
15625469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[0] &= ~InitProperty;
15635469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15645469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Nukta always applies
15655469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Akhant
15665469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = 0; i <= base; ++i)
15675469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[i] &= ~AkhantProperty;
15685469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // Reph
15695469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (reph >= 0) {
15705469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[reph] &= ~RephProperty;
15715469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[reph+1] &= ~RephProperty;
15725469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
15735469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // BelowForm
15745469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = base+1; i < len; ++i)
15755469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[i] &= ~BelowFormProperty;
15765469607a00d84a07dc638eda46a87fc90142d64breed@android.com
15775469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (script == HB_Script_Devanagari || script == HB_Script_Gujarati) {
15785469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // vattu glyphs need this aswell
15795469607a00d84a07dc638eda46a87fc90142d64breed@android.com            bool vattu = false;
15805469607a00d84a07dc638eda46a87fc90142d64breed@android.com            for (i = base-2; i > 1; --i) {
15815469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (form(reordered[i]) == Consonant) {
15825469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    vattu = (!vattu && reordered[i] == ra);
15835469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (vattu) {
15845469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        IDEBUG("forming vattu ligature at %d", i);
15855469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        properties[i] &= ~BelowFormProperty;
15865469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        properties[i+1] &= ~BelowFormProperty;
15875469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    }
15885469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
15895469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
15905469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
15915469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // HalfFormProperty
15925469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = 0; i < base; ++i)
15935469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[i] &= ~HalfFormProperty;
15945469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (control) {
15955469607a00d84a07dc638eda46a87fc90142d64breed@android.com            for (i = 2; i < len; ++i) {
15965469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (reordered[i] == 0x200d /* ZWJ */) {
15975469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    properties[i-1] &= ~HalfFormProperty;
15985469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    properties[i-2] &= ~HalfFormProperty;
15995469607a00d84a07dc638eda46a87fc90142d64breed@android.com                } else if (reordered[i] == 0x200c /* ZWNJ */) {
16005469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    properties[i-1] &= ~HalfFormProperty;
16015469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    properties[i-2] &= ~HalfFormProperty;
16025469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
16035469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
16045469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
16055469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // PostFormProperty
16065469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = base+1; i < len; ++i)
16075469607a00d84a07dc638eda46a87fc90142d64breed@android.com            properties[i] &= ~PostFormProperty;
16085469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // vattu always applies
16095469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // pres always applies
16105469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // blws always applies
16115469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // abvs always applies
16125469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // psts always applies
16135469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // halant always applies
16145469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16155469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifdef INDIC_DEBUG
16165469607a00d84a07dc638eda46a87fc90142d64breed@android.com//        {
16175469607a00d84a07dc638eda46a87fc90142d64breed@android.com//            IDEBUG("OT properties:");
16185469607a00d84a07dc638eda46a87fc90142d64breed@android.com//            for (int i = 0; i < len; ++i)
16195469607a00d84a07dc638eda46a87fc90142d64breed@android.com//                qDebug("    i: %s", ::propertiesToString(properties[i]).toLatin1().data());
16205469607a00d84a07dc638eda46a87fc90142d64breed@android.com//        }
16215469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
16225469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16235469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // initialize
16245469607a00d84a07dc638eda46a87fc90142d64breed@android.com        item->log_clusters = clusters;
16255469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_OpenTypeShape(item, properties);
16265469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16275469607a00d84a07dc638eda46a87fc90142d64breed@android.com        int newLen = item->face->buffer->in_length;
16285469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_GlyphItem otl_glyphs = item->face->buffer->in_string;
16295469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16305469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // move the left matra back to its correct position in malayalam and tamil
16315469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if ((script == HB_Script_Malayalam || script == HB_Script_Tamil) && (form(reordered[0]) == Matra)) {
16325469607a00d84a07dc638eda46a87fc90142d64breed@android.com//             qDebug("reordering matra, len=%d", newLen);
16335469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // need to find the base in the shaped string and move the matra there
16345469607a00d84a07dc638eda46a87fc90142d64breed@android.com            int basePos = 0;
16355469607a00d84a07dc638eda46a87fc90142d64breed@android.com            while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base)
16365469607a00d84a07dc638eda46a87fc90142d64breed@android.com                basePos++;
16375469607a00d84a07dc638eda46a87fc90142d64breed@android.com            --basePos;
16385469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (basePos < newLen && basePos > 1) {
16395469607a00d84a07dc638eda46a87fc90142d64breed@android.com//                 qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen);
16405469607a00d84a07dc638eda46a87fc90142d64breed@android.com                HB_GlyphItemRec m = otl_glyphs[0];
16415469607a00d84a07dc638eda46a87fc90142d64breed@android.com                --basePos;
16425469607a00d84a07dc638eda46a87fc90142d64breed@android.com                for (i = 0; i < basePos; ++i)
16435469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    otl_glyphs[i] = otl_glyphs[i+1];
16445469607a00d84a07dc638eda46a87fc90142d64breed@android.com                otl_glyphs[basePos] = m;
16455469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
16465469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
16475469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16485469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_Bool positioned = HB_OpenTypePosition(item, availableGlyphs, false);
16495469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16505469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_FREE_STACKARRAY(clusters);
16515469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_FREE_STACKARRAY(properties);
16525469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16535469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (!positioned)
16545469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto error;
16555469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16565469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (control) {
16575469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("found a control char in the syllable");
16585469607a00d84a07dc638eda46a87fc90142d64breed@android.com            hb_uint32 i = 0, j = 0;
16595469607a00d84a07dc638eda46a87fc90142d64breed@android.com            while (i < item->num_glyphs) {
16605469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (form(reordered[otl_glyphs[i].cluster]) == Control) {
16615469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    ++i;
16625469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    if (i >= item->num_glyphs)
16635469607a00d84a07dc638eda46a87fc90142d64breed@android.com                        break;
16645469607a00d84a07dc638eda46a87fc90142d64breed@android.com                }
16655469607a00d84a07dc638eda46a87fc90142d64breed@android.com                item->glyphs[j] = item->glyphs[i];
16665469607a00d84a07dc638eda46a87fc90142d64breed@android.com                item->attributes[j] = item->attributes[i];
16675469607a00d84a07dc638eda46a87fc90142d64breed@android.com                ++i;
16685469607a00d84a07dc638eda46a87fc90142d64breed@android.com                ++j;
16695469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
16705469607a00d84a07dc638eda46a87fc90142d64breed@android.com            item->num_glyphs = j;
16715469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
16725469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16735469607a00d84a07dc638eda46a87fc90142d64breed@android.com    } else {
16745469607a00d84a07dc638eda46a87fc90142d64breed@android.com        HB_HeuristicPosition(item);
16755469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
16765469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif // NO_OPENTYPE
16775469607a00d84a07dc638eda46a87fc90142d64breed@android.com    item->attributes[0].clusterStart = true;
16785469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16795469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_FREE_STACKARRAY(reordered);
16805469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_FREE_STACKARRAY(position);
16815469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16825469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("<<<<<<");
16835469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return true;
16845469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16855469607a00d84a07dc638eda46a87fc90142d64breed@android.comerror:
16865469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_FREE_STACKARRAY(reordered);
16875469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_FREE_STACKARRAY(position);
16885469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return false;
16895469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
16905469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16915469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* syllables are of the form:
16925469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16935469607a00d84a07dc638eda46a87fc90142d64breed@android.com   (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark?
16945469607a00d84a07dc638eda46a87fc90142d64breed@android.com   (Consonant Nukta? Halant)* Consonant Halant
16955469607a00d84a07dc638eda46a87fc90142d64breed@android.com   IndependentVowel VowelMark? StressMark?
16965469607a00d84a07dc638eda46a87fc90142d64breed@android.com
16975469607a00d84a07dc638eda46a87fc90142d64breed@android.com   We return syllable boundaries on invalid combinations aswell
16985469607a00d84a07dc638eda46a87fc90142d64breed@android.com*/
16995469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic int indic_nextSyllableBoundary(HB_Script script, const HB_UChar16 *s, int start, int end, bool *invalid)
17005469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
17015469607a00d84a07dc638eda46a87fc90142d64breed@android.com    *invalid = false;
17025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end);
17035469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const HB_UChar16 *uc = s+start;
17045469607a00d84a07dc638eda46a87fc90142d64breed@android.com
17055469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int pos = 0;
17065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    Form state = form(uc[pos]);
17075469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);
17085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    pos++;
17095469607a00d84a07dc638eda46a87fc90142d64breed@android.com
17105469607a00d84a07dc638eda46a87fc90142d64breed@android.com    if (state != Consonant && state != IndependentVowel) {
17115469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (state != Other)
17125469607a00d84a07dc638eda46a87fc90142d64breed@android.com            *invalid = true;
17135469607a00d84a07dc638eda46a87fc90142d64breed@android.com        goto finish;
17145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
17155469607a00d84a07dc638eda46a87fc90142d64breed@android.com
17165469607a00d84a07dc638eda46a87fc90142d64breed@android.com    while (pos < end - start) {
17175469607a00d84a07dc638eda46a87fc90142d64breed@android.com        Form newState = form(uc[pos]);
17185469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos]);
17195469607a00d84a07dc638eda46a87fc90142d64breed@android.com        switch(newState) {
17205469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Control:
17215469607a00d84a07dc638eda46a87fc90142d64breed@android.com            newState = state;
17225469607a00d84a07dc638eda46a87fc90142d64breed@android.com 	    if (state == Halant && uc[pos] == 0x200d /* ZWJ */)
17235469607a00d84a07dc638eda46a87fc90142d64breed@android.com  		break;
17245469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // the control character should be the last char in the item
17255469607a00d84a07dc638eda46a87fc90142d64breed@android.com            ++pos;
17265469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17275469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Consonant:
17285469607a00d84a07dc638eda46a87fc90142d64breed@android.com	    if (state == Halant && (script != HB_Script_Sinhala || uc[pos-1] == 0x200d /* ZWJ */))
17295469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17305469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17315469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Halant:
17325469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Nukta || state == Consonant)
17335469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17345469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya
17355469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Bengali && pos == 1 &&
17365469607a00d84a07dc638eda46a87fc90142d64breed@android.com                 (uc[0] == 0x0985 || uc[0] == 0x098f))
17375469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17385469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // Sinhala uses the Halant as a component of certain matras. Allow these, but keep the state on Matra.
17395469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Sinhala && state == Matra) {
17405469607a00d84a07dc638eda46a87fc90142d64breed@android.com                ++pos;
17415469607a00d84a07dc638eda46a87fc90142d64breed@android.com                continue;
17425469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
17435469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Malayalam && state == Matra && uc[pos-1] == 0x0d41) {
17445469607a00d84a07dc638eda46a87fc90142d64breed@android.com                ++pos;
17455469607a00d84a07dc638eda46a87fc90142d64breed@android.com                continue;
17465469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
17475469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17485469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Nukta:
17495469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Consonant)
17505469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17515469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17525469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case StressMark:
17535469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == VowelMark)
17545469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17555469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // fall through
17565469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case VowelMark:
17575469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Matra || state == LengthMark || state == IndependentVowel)
17585469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17595469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // fall through
17605469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Matra:
17615469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Consonant || state == Nukta)
17625469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17635469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Matra) {
17645469607a00d84a07dc638eda46a87fc90142d64breed@android.com                // ### needs proper testing for correct two/three part matras
17655469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17665469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
17675469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // ### not sure if this is correct. If it is, does it apply only to Bengali or should
17685469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // it work for all Indic languages?
17695469607a00d84a07dc638eda46a87fc90142d64breed@android.com            // the combination Independent_A + Vowel Sign AA is allowed.
17705469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Bengali && uc[pos] == 0x9be && uc[pos-1] == 0x985)
17715469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17725469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (script == HB_Script_Tamil && state == Matra) {
17735469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (uc[pos-1] == 0x0bc6 &&
17745469607a00d84a07dc638eda46a87fc90142d64breed@android.com                     (uc[pos] == 0xbbe || uc[pos] == 0xbd7))
17755469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    break;
17765469607a00d84a07dc638eda46a87fc90142d64breed@android.com                if (uc[pos-1] == 0x0bc7 && uc[pos] == 0xbbe)
17775469607a00d84a07dc638eda46a87fc90142d64breed@android.com                    break;
17785469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
17795469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17805469607a00d84a07dc638eda46a87fc90142d64breed@android.com
17815469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case LengthMark:
17825469607a00d84a07dc638eda46a87fc90142d64breed@android.com            if (state == Matra) {
17835469607a00d84a07dc638eda46a87fc90142d64breed@android.com                // ### needs proper testing for correct two/three part matras
17845469607a00d84a07dc638eda46a87fc90142d64breed@android.com                break;
17855469607a00d84a07dc638eda46a87fc90142d64breed@android.com            }
17865469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case IndependentVowel:
17875469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Invalid:
17885469607a00d84a07dc638eda46a87fc90142d64breed@android.com        case Other:
17895469607a00d84a07dc638eda46a87fc90142d64breed@android.com            goto finish;
17905469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
17915469607a00d84a07dc638eda46a87fc90142d64breed@android.com        state = newState;
17925469607a00d84a07dc638eda46a87fc90142d64breed@android.com        pos++;
17935469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
17945469607a00d84a07dc638eda46a87fc90142d64breed@android.com finish:
17955469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return pos+start;
17965469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
17975469607a00d84a07dc638eda46a87fc90142d64breed@android.com
17985469607a00d84a07dc638eda46a87fc90142d64breed@android.comHB_Bool HB_IndicShape(HB_ShaperItem *item)
17995469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
18005469607a00d84a07dc638eda46a87fc90142d64breed@android.com    assert(item->item.script >= HB_Script_Devanagari && item->item.script <= HB_Script_Sinhala);
18015469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18025469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_Bool openType = false;
18035469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE
18045469607a00d84a07dc638eda46a87fc90142d64breed@android.com    openType = HB_SelectScript(item, indic_features);
18055469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif
18065469607a00d84a07dc638eda46a87fc90142d64breed@android.com    unsigned short *logClusters = item->log_clusters;
18075469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18085469607a00d84a07dc638eda46a87fc90142d64breed@android.com    HB_ShaperItem syllable = *item;
18095469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int first_glyph = 0;
18105469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18115469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int sstart = item->item.pos;
18125469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int end = sstart + item->item.length;
18135469607a00d84a07dc638eda46a87fc90142d64breed@android.com    IDEBUG("indic_shape: from %d length %d", item->item.pos, item->item.length);
18145469607a00d84a07dc638eda46a87fc90142d64breed@android.com    while (sstart < end) {
18155469607a00d84a07dc638eda46a87fc90142d64breed@android.com        bool invalid;
18165469607a00d84a07dc638eda46a87fc90142d64breed@android.com        int send = indic_nextSyllableBoundary(item->item.script, item->string, sstart, end, &invalid);
18175469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
18185469607a00d84a07dc638eda46a87fc90142d64breed@android.com               invalid ? "true" : "false");
18195469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.item.pos = sstart;
18205469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.item.length = send-sstart;
18215469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.glyphs = item->glyphs + first_glyph;
18225469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.attributes = item->attributes + first_glyph;
18235469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.offsets = item->offsets + first_glyph;
18245469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.advances = item->advances + first_glyph;
18255469607a00d84a07dc638eda46a87fc90142d64breed@android.com        syllable.num_glyphs = item->num_glyphs - first_glyph;
18265469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (!indic_shape_syllable(openType, &syllable, invalid)) {
18275469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
18285469607a00d84a07dc638eda46a87fc90142d64breed@android.com            item->num_glyphs += syllable.num_glyphs;
18295469607a00d84a07dc638eda46a87fc90142d64breed@android.com            return false;
18305469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
18315469607a00d84a07dc638eda46a87fc90142d64breed@android.com        // fix logcluster array
18325469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("syllable:");
18335469607a00d84a07dc638eda46a87fc90142d64breed@android.com        hb_uint32 g;
18345469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (g = first_glyph; g < first_glyph + syllable.num_glyphs; ++g)
18355469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("        %d -> glyph %x", g, item->glyphs[g]);
18365469607a00d84a07dc638eda46a87fc90142d64breed@android.com        IDEBUG("    logclusters:");
18375469607a00d84a07dc638eda46a87fc90142d64breed@android.com        int i;
18385469607a00d84a07dc638eda46a87fc90142d64breed@android.com        for (i = sstart; i < send; ++i) {
18395469607a00d84a07dc638eda46a87fc90142d64breed@android.com            IDEBUG("        %d -> glyph %d", i, first_glyph);
18405469607a00d84a07dc638eda46a87fc90142d64breed@android.com            logClusters[i-item->item.pos] = first_glyph;
18415469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
18425469607a00d84a07dc638eda46a87fc90142d64breed@android.com        sstart = send;
18435469607a00d84a07dc638eda46a87fc90142d64breed@android.com        first_glyph += syllable.num_glyphs;
18445469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
18455469607a00d84a07dc638eda46a87fc90142d64breed@android.com    item->num_glyphs = first_glyph;
18465469607a00d84a07dc638eda46a87fc90142d64breed@android.com    return true;
18475469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
18485469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18495469607a00d84a07dc638eda46a87fc90142d64breed@android.comvoid HB_IndicAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)
18505469607a00d84a07dc638eda46a87fc90142d64breed@android.com{
18515469607a00d84a07dc638eda46a87fc90142d64breed@android.com    int end = from + len;
18525469607a00d84a07dc638eda46a87fc90142d64breed@android.com    const HB_UChar16 *uc = text + from;
18535469607a00d84a07dc638eda46a87fc90142d64breed@android.com    attributes += from;
18545469607a00d84a07dc638eda46a87fc90142d64breed@android.com    hb_uint32 i = 0;
18555469607a00d84a07dc638eda46a87fc90142d64breed@android.com    while (i < len) {
18565469607a00d84a07dc638eda46a87fc90142d64breed@android.com        bool invalid;
18575469607a00d84a07dc638eda46a87fc90142d64breed@android.com        hb_uint32 boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from;
18585469607a00d84a07dc638eda46a87fc90142d64breed@android.com         attributes[i].charStop = true;
18595469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18605469607a00d84a07dc638eda46a87fc90142d64breed@android.com        if (boundary > len-1) boundary = len;
18615469607a00d84a07dc638eda46a87fc90142d64breed@android.com        i++;
18625469607a00d84a07dc638eda46a87fc90142d64breed@android.com        while (i < boundary) {
18635469607a00d84a07dc638eda46a87fc90142d64breed@android.com            attributes[i].charStop = false;
18645469607a00d84a07dc638eda46a87fc90142d64breed@android.com            ++uc;
18655469607a00d84a07dc638eda46a87fc90142d64breed@android.com            ++i;
18665469607a00d84a07dc638eda46a87fc90142d64breed@android.com        }
18675469607a00d84a07dc638eda46a87fc90142d64breed@android.com        assert(i == boundary);
18685469607a00d84a07dc638eda46a87fc90142d64breed@android.com    }
18695469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18705469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18715469607a00d84a07dc638eda46a87fc90142d64breed@android.com}
18725469607a00d84a07dc638eda46a87fc90142d64breed@android.com
18735469607a00d84a07dc638eda46a87fc90142d64breed@android.com
1874