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