11512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* 21512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 31512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 41512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library. 51512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 61512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Permission is hereby granted, without written agreement and without 71512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 81512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * software and its documentation for any purpose, provided that the 91512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * all copies of this software. 111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DAMAGE. 171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * 181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */ 241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-shaper.h" 261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-shaper-private.h" 271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include <assert.h> 291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* 311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod tibetan syllables are of the form: 321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod head position consonant 331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod first sub-joined consonant 341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ....intermediate sub-joined consonants (if any) 351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod last sub-joined consonant 361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sub-joined vowel (a-chung U+0F71) 371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod standard or compound vowel sign (or 'virama' for devanagari transliteration) 381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod*/ 391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodtypedef enum { 411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanOther, 421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, 431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, 441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedVowel, 451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel 461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} TibetanForm; 471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* this table starts at U+0f40 */ 491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const unsigned char tibetanForm[0x80] = { 501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanOther, TibetanOther, TibetanOther, TibetanOther, 641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel, 661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanOther, TibetanOther, TibetanOther, TibetanOther, 731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanOther, TibetanOther, TibetanOther, TibetanOther, 741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther 891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}; 901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define tibetan_form(c) \ 931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ((c) >= 0x0f40 && (c) < 0x0fc0 ? (TibetanForm)tibetanForm[(c) - 0x0f40] : TibetanOther) 941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const HB_OpenTypeFeature tibetan_features[] = { 961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, 971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, 981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, 991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, 1001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod {0, 0} 1011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}; 1021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) 1041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod hb_uint32 i; 1061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod const HB_UChar16 *str = item->string + item->item.pos; 1071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int len = item->item.length; 1081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifndef NO_OPENTYPE 1091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod const int availableGlyphs = item->num_glyphs; 1101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif 1111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Bool haveGlyphs; 1121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_STACKARRAY(HB_UChar16, reordered, len + 4); 1131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (item->num_glyphs < item->item.length + 4) { 1151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->num_glyphs = item->item.length + 4; 116f2377155e35c15919af4d7db21b6edc6783146b6Behdad Esfahbod HB_FREE_STACKARRAY(reordered); 1171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return FALSE; 1181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (invalid) { 1211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *reordered = 0x25cc; 1221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod memcpy(reordered+1, str, len*sizeof(HB_UChar16)); 1231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod len++; 1241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod str = reordered; 1251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod haveGlyphs = item->font->klass->convertStringToGlyphIndices(item->font, 1281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod str, len, 1291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->glyphs, &item->num_glyphs, 1301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->item.bidiLevel % 2); 1311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_FREE_STACKARRAY(reordered); 1331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (!haveGlyphs) 1351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return FALSE; 1361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for (i = 0; i < item->item.length; i++) { 1381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->attributes[i].mark = FALSE; 1391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->attributes[i].clusterStart = FALSE; 1401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->attributes[i].justification = 0; 1411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->attributes[i].zeroWidth = FALSE; 1421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* IDEBUG(" %d: %4x", i, str[i]); */ 1431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* now we have the syllable in the right order, and can start running it through open type. */ 1461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifndef NO_OPENTYPE 1481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (openType) { 1491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_OpenTypeShape(item, /*properties*/0); 1501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) 1511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return FALSE; 1521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } else { 1531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_HeuristicPosition(item); 1541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif 1561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->attributes[0].clusterStart = TRUE; 1581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return TRUE; 1591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 1601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic int tibetan_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) 1631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 1641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod const HB_UChar16 *uc = s + start; 1651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int pos = 0; 1671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanForm state = tibetan_form(*uc); 1681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/ 1701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod pos++; 1711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (state != TibetanHeadConsonant) { 1731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (state != TibetanOther) 1741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *invalid = TRUE; 1751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto finish; 1761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 1781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod while (pos < end - start) { 1791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod TibetanForm newState = tibetan_form(uc[pos]); 1801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod switch(newState) { 1811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case TibetanSubjoinedConsonant: 1821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case TibetanSubjoinedVowel: 1831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (state != TibetanHeadConsonant && 1841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod state != TibetanSubjoinedConsonant) 1851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto finish; 1861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod state = newState; 1871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 1881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case TibetanVowel: 1891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (state != TibetanHeadConsonant && 1901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod state != TibetanSubjoinedConsonant && 1911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod state != TibetanSubjoinedVowel) 1921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto finish; 1931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod break; 1941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case TibetanOther: 1951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod case TibetanHeadConsonant: 1961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod goto finish; 1971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 1981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod pos++; 1991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodfinish: 2021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *invalid = FALSE; 2031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return start+pos; 2041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 2051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2061512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Bool HB_TibetanShape(HB_ShaperItem *item) 2071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{ 2081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Bool openType = FALSE; 2101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod unsigned short *logClusters = item->log_clusters; 2111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_ShaperItem syllable = *item; 2131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int first_glyph = 0; 2141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int sstart = item->item.pos; 2161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int end = sstart + item->item.length; 2171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod assert(item->item.script == HB_Script_Tibetan); 2191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifndef QT_NO_OPENTYPE 2211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod openType = HB_SelectScript(item, tibetan_features); 2221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif 2231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod 2241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod while (sstart < end) { 2251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod HB_Bool invalid; 2261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int i; 2271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod int send = tibetan_nextSyllableBoundary(item->string, sstart, end, &invalid); 2281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, 2291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod invalid ? "TRUE" : "FALSE"); */ 2301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.item.pos = sstart; 2311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.item.length = send-sstart; 2321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.glyphs = item->glyphs + first_glyph; 2331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.attributes = item->attributes + first_glyph; 2341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.offsets = item->offsets + first_glyph; 2351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.advances = item->advances + first_glyph; 2361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod syllable.num_glyphs = item->num_glyphs - first_glyph; 2371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod if (!tibetan_shape_syllable(openType, &syllable, invalid)) { 2381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->num_glyphs += syllable.num_glyphs; 2391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return FALSE; 2401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod /* fix logcluster array */ 2421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod for (i = sstart; i < send; ++i) 2431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod logClusters[i-item->item.pos] = first_glyph; 2441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod sstart = send; 2451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod first_glyph += syllable.num_glyphs; 2461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod } 2471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod item->num_glyphs = first_glyph; 2481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod return TRUE; 2491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} 250