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 305469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* 315469607a00d84a07dc638eda46a87fc90142d64breed@android.com tibetan syllables are of the form: 325469607a00d84a07dc638eda46a87fc90142d64breed@android.com head position consonant 335469607a00d84a07dc638eda46a87fc90142d64breed@android.com first sub-joined consonant 345469607a00d84a07dc638eda46a87fc90142d64breed@android.com ....intermediate sub-joined consonants (if any) 355469607a00d84a07dc638eda46a87fc90142d64breed@android.com last sub-joined consonant 365469607a00d84a07dc638eda46a87fc90142d64breed@android.com sub-joined vowel (a-chung U+0F71) 375469607a00d84a07dc638eda46a87fc90142d64breed@android.com standard or compound vowel sign (or 'virama' for devanagari transliteration) 385469607a00d84a07dc638eda46a87fc90142d64breed@android.com*/ 395469607a00d84a07dc638eda46a87fc90142d64breed@android.com 405469607a00d84a07dc638eda46a87fc90142d64breed@android.comtypedef enum { 415469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanOther, 425469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, 435469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, 445469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedVowel, 455469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel 465469607a00d84a07dc638eda46a87fc90142d64breed@android.com} TibetanForm; 475469607a00d84a07dc638eda46a87fc90142d64breed@android.com 485469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* this table starts at U+0f40 */ 495469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const unsigned char tibetanForm[0x80] = { 505469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 515469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 525469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 535469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 545469607a00d84a07dc638eda46a87fc90142d64breed@android.com 555469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 565469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 575469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 585469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 595469607a00d84a07dc638eda46a87fc90142d64breed@android.com 605469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 615469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 625469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, 635469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanOther, TibetanOther, TibetanOther, TibetanOther, 645469607a00d84a07dc638eda46a87fc90142d64breed@android.com 655469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel, 665469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 675469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 685469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 695469607a00d84a07dc638eda46a87fc90142d64breed@android.com 705469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 715469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel, 725469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanOther, TibetanOther, TibetanOther, TibetanOther, 735469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanOther, TibetanOther, TibetanOther, TibetanOther, 745469607a00d84a07dc638eda46a87fc90142d64breed@android.com 755469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 765469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 775469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 785469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 795469607a00d84a07dc638eda46a87fc90142d64breed@android.com 805469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 815469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 825469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 835469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 845469607a00d84a07dc638eda46a87fc90142d64breed@android.com 855469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 865469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 875469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, 885469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther 895469607a00d84a07dc638eda46a87fc90142d64breed@android.com}; 905469607a00d84a07dc638eda46a87fc90142d64breed@android.com 915469607a00d84a07dc638eda46a87fc90142d64breed@android.com 925469607a00d84a07dc638eda46a87fc90142d64breed@android.com#define tibetan_form(c) \ 935469607a00d84a07dc638eda46a87fc90142d64breed@android.com (TibetanForm)tibetanForm[c - 0x0f40] 945469607a00d84a07dc638eda46a87fc90142d64breed@android.com 955469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic const HB_OpenTypeFeature tibetan_features[] = { 965469607a00d84a07dc638eda46a87fc90142d64breed@android.com { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, 975469607a00d84a07dc638eda46a87fc90142d64breed@android.com { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty }, 985469607a00d84a07dc638eda46a87fc90142d64breed@android.com { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty }, 995469607a00d84a07dc638eda46a87fc90142d64breed@android.com { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, 1005469607a00d84a07dc638eda46a87fc90142d64breed@android.com {0, 0} 1015469607a00d84a07dc638eda46a87fc90142d64breed@android.com}; 1025469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1035469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid) 1045469607a00d84a07dc638eda46a87fc90142d64breed@android.com{ 1055469607a00d84a07dc638eda46a87fc90142d64breed@android.com hb_uint32 i; 1065469607a00d84a07dc638eda46a87fc90142d64breed@android.com const HB_UChar16 *str = item->string + item->item.pos; 1075469607a00d84a07dc638eda46a87fc90142d64breed@android.com int len = item->item.length; 1085469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE 1095469607a00d84a07dc638eda46a87fc90142d64breed@android.com const int availableGlyphs = item->num_glyphs; 1105469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif 1115469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_Bool haveGlyphs; 1125469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_STACKARRAY(HB_UChar16, reordered, len + 4); 1135469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1145469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (item->num_glyphs < item->item.length + 4) { 1155469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->num_glyphs = item->item.length + 4; 1165469607a00d84a07dc638eda46a87fc90142d64breed@android.com return FALSE; 1175469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1185469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1195469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (invalid) { 1205469607a00d84a07dc638eda46a87fc90142d64breed@android.com *reordered = 0x25cc; 1215469607a00d84a07dc638eda46a87fc90142d64breed@android.com memcpy(reordered+1, str, len*sizeof(HB_UChar16)); 1225469607a00d84a07dc638eda46a87fc90142d64breed@android.com len++; 1235469607a00d84a07dc638eda46a87fc90142d64breed@android.com str = reordered; 1245469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1255469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1265469607a00d84a07dc638eda46a87fc90142d64breed@android.com haveGlyphs = item->font->klass->convertStringToGlyphIndices(item->font, 1275469607a00d84a07dc638eda46a87fc90142d64breed@android.com str, len, 1285469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->glyphs, &item->num_glyphs, 1295469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->item.bidiLevel % 2); 1305469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1315469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_FREE_STACKARRAY(reordered); 1325469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1335469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (!haveGlyphs) 1345469607a00d84a07dc638eda46a87fc90142d64breed@android.com return FALSE; 1355469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1365469607a00d84a07dc638eda46a87fc90142d64breed@android.com for (i = 0; i < item->item.length; i++) { 1375469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->attributes[i].mark = FALSE; 1385469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->attributes[i].clusterStart = FALSE; 1395469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->attributes[i].justification = 0; 1405469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->attributes[i].zeroWidth = FALSE; 1415469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* IDEBUG(" %d: %4x", i, str[i]); */ 1425469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1435469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1445469607a00d84a07dc638eda46a87fc90142d64breed@android.com /* now we have the syllable in the right order, and can start running it through open type. */ 1455469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1465469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef NO_OPENTYPE 1475469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (openType) { 1485469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_OpenTypeShape(item, /*properties*/0); 1495469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (!HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE)) 1505469607a00d84a07dc638eda46a87fc90142d64breed@android.com return FALSE; 1515469607a00d84a07dc638eda46a87fc90142d64breed@android.com } else { 1525469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_HeuristicPosition(item); 1535469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1545469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif 1555469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1565469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->attributes[0].clusterStart = TRUE; 1575469607a00d84a07dc638eda46a87fc90142d64breed@android.com return TRUE; 1585469607a00d84a07dc638eda46a87fc90142d64breed@android.com} 1595469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1605469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1615469607a00d84a07dc638eda46a87fc90142d64breed@android.comstatic int tibetan_nextSyllableBoundary(const HB_UChar16 *s, int start, int end, HB_Bool *invalid) 1625469607a00d84a07dc638eda46a87fc90142d64breed@android.com{ 1635469607a00d84a07dc638eda46a87fc90142d64breed@android.com const HB_UChar16 *uc = s + start; 1645469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1655469607a00d84a07dc638eda46a87fc90142d64breed@android.com int pos = 0; 1665469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanForm state = tibetan_form(*uc); 1675469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1685469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos]);*/ 1695469607a00d84a07dc638eda46a87fc90142d64breed@android.com pos++; 1705469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1715469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (state != TibetanHeadConsonant) { 1725469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (state != TibetanOther) 1735469607a00d84a07dc638eda46a87fc90142d64breed@android.com *invalid = TRUE; 1745469607a00d84a07dc638eda46a87fc90142d64breed@android.com goto finish; 1755469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1765469607a00d84a07dc638eda46a87fc90142d64breed@android.com 1775469607a00d84a07dc638eda46a87fc90142d64breed@android.com while (pos < end - start) { 1785469607a00d84a07dc638eda46a87fc90142d64breed@android.com TibetanForm newState = tibetan_form(uc[pos]); 1795469607a00d84a07dc638eda46a87fc90142d64breed@android.com switch(newState) { 1805469607a00d84a07dc638eda46a87fc90142d64breed@android.com case TibetanSubjoinedConsonant: 1815469607a00d84a07dc638eda46a87fc90142d64breed@android.com case TibetanSubjoinedVowel: 1825469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (state != TibetanHeadConsonant && 1835469607a00d84a07dc638eda46a87fc90142d64breed@android.com state != TibetanSubjoinedConsonant) 1845469607a00d84a07dc638eda46a87fc90142d64breed@android.com goto finish; 1855469607a00d84a07dc638eda46a87fc90142d64breed@android.com state = newState; 1865469607a00d84a07dc638eda46a87fc90142d64breed@android.com break; 1875469607a00d84a07dc638eda46a87fc90142d64breed@android.com case TibetanVowel: 1885469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (state != TibetanHeadConsonant && 1895469607a00d84a07dc638eda46a87fc90142d64breed@android.com state != TibetanSubjoinedConsonant && 1905469607a00d84a07dc638eda46a87fc90142d64breed@android.com state != TibetanSubjoinedVowel) 1915469607a00d84a07dc638eda46a87fc90142d64breed@android.com goto finish; 1925469607a00d84a07dc638eda46a87fc90142d64breed@android.com break; 1935469607a00d84a07dc638eda46a87fc90142d64breed@android.com case TibetanOther: 1945469607a00d84a07dc638eda46a87fc90142d64breed@android.com case TibetanHeadConsonant: 1955469607a00d84a07dc638eda46a87fc90142d64breed@android.com goto finish; 1965469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1975469607a00d84a07dc638eda46a87fc90142d64breed@android.com pos++; 1985469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 1995469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2005469607a00d84a07dc638eda46a87fc90142d64breed@android.comfinish: 2015469607a00d84a07dc638eda46a87fc90142d64breed@android.com *invalid = FALSE; 2025469607a00d84a07dc638eda46a87fc90142d64breed@android.com return start+pos; 2035469607a00d84a07dc638eda46a87fc90142d64breed@android.com} 2045469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2055469607a00d84a07dc638eda46a87fc90142d64breed@android.comHB_Bool HB_TibetanShape(HB_ShaperItem *item) 2065469607a00d84a07dc638eda46a87fc90142d64breed@android.com{ 2075469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2085469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_Bool openType = FALSE; 2095469607a00d84a07dc638eda46a87fc90142d64breed@android.com unsigned short *logClusters = item->log_clusters; 2105469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2115469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_ShaperItem syllable = *item; 2125469607a00d84a07dc638eda46a87fc90142d64breed@android.com int first_glyph = 0; 2135469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2145469607a00d84a07dc638eda46a87fc90142d64breed@android.com int sstart = item->item.pos; 2155469607a00d84a07dc638eda46a87fc90142d64breed@android.com int end = sstart + item->item.length; 2165469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2175469607a00d84a07dc638eda46a87fc90142d64breed@android.com assert(item->item.script == HB_Script_Tibetan); 2185469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2195469607a00d84a07dc638eda46a87fc90142d64breed@android.com#ifndef QT_NO_OPENTYPE 2205469607a00d84a07dc638eda46a87fc90142d64breed@android.com openType = HB_SelectScript(item, tibetan_features); 2215469607a00d84a07dc638eda46a87fc90142d64breed@android.com#endif 2225469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2235469607a00d84a07dc638eda46a87fc90142d64breed@android.com while (sstart < end) { 2245469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_Bool invalid; 2255469607a00d84a07dc638eda46a87fc90142d64breed@android.com int i; 2265469607a00d84a07dc638eda46a87fc90142d64breed@android.com int send = tibetan_nextSyllableBoundary(item->string, sstart, end, &invalid); 2275469607a00d84a07dc638eda46a87fc90142d64breed@android.com/* IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart, 2285469607a00d84a07dc638eda46a87fc90142d64breed@android.com invalid ? "TRUE" : "FALSE"); */ 2295469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.item.pos = sstart; 2305469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.item.length = send-sstart; 2315469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.glyphs = item->glyphs + first_glyph; 2325469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.attributes = item->attributes + first_glyph; 2335469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.offsets = item->offsets + first_glyph; 2345469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.advances = item->advances + first_glyph; 2355469607a00d84a07dc638eda46a87fc90142d64breed@android.com syllable.num_glyphs = item->num_glyphs - first_glyph; 2365469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (!tibetan_shape_syllable(openType, &syllable, invalid)) { 2375469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->num_glyphs += syllable.num_glyphs; 2385469607a00d84a07dc638eda46a87fc90142d64breed@android.com return FALSE; 2395469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 2405469607a00d84a07dc638eda46a87fc90142d64breed@android.com /* fix logcluster array */ 2415469607a00d84a07dc638eda46a87fc90142d64breed@android.com for (i = sstart; i < send; ++i) 2425469607a00d84a07dc638eda46a87fc90142d64breed@android.com logClusters[i-item->item.pos] = first_glyph; 2435469607a00d84a07dc638eda46a87fc90142d64breed@android.com sstart = send; 2445469607a00d84a07dc638eda46a87fc90142d64breed@android.com first_glyph += syllable.num_glyphs; 2455469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 2465469607a00d84a07dc638eda46a87fc90142d64breed@android.com item->num_glyphs = first_glyph; 2475469607a00d84a07dc638eda46a87fc90142d64breed@android.com return TRUE; 2485469607a00d84a07dc638eda46a87fc90142d64breed@android.com} 2495469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2505469607a00d84a07dc638eda46a87fc90142d64breed@android.comvoid HB_TibetanAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes) 2515469607a00d84a07dc638eda46a87fc90142d64breed@android.com{ 2525469607a00d84a07dc638eda46a87fc90142d64breed@android.com int end = from + len; 2535469607a00d84a07dc638eda46a87fc90142d64breed@android.com const HB_UChar16 *uc = text + from; 2545469607a00d84a07dc638eda46a87fc90142d64breed@android.com hb_uint32 i = 0; 2555469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_UNUSED(script); 2565469607a00d84a07dc638eda46a87fc90142d64breed@android.com attributes += from; 2575469607a00d84a07dc638eda46a87fc90142d64breed@android.com while (i < len) { 2585469607a00d84a07dc638eda46a87fc90142d64breed@android.com HB_Bool invalid; 2595469607a00d84a07dc638eda46a87fc90142d64breed@android.com hb_uint32 boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from; 2605469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2615469607a00d84a07dc638eda46a87fc90142d64breed@android.com attributes[i].charStop = TRUE; 2625469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2635469607a00d84a07dc638eda46a87fc90142d64breed@android.com if (boundary > len-1) boundary = len; 2645469607a00d84a07dc638eda46a87fc90142d64breed@android.com i++; 2655469607a00d84a07dc638eda46a87fc90142d64breed@android.com while (i < boundary) { 2665469607a00d84a07dc638eda46a87fc90142d64breed@android.com attributes[i].charStop = FALSE; 2675469607a00d84a07dc638eda46a87fc90142d64breed@android.com ++uc; 2685469607a00d84a07dc638eda46a87fc90142d64breed@android.com ++i; 2695469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 2705469607a00d84a07dc638eda46a87fc90142d64breed@android.com assert(i == boundary); 2715469607a00d84a07dc638eda46a87fc90142d64breed@android.com } 2725469607a00d84a07dc638eda46a87fc90142d64breed@android.com} 2735469607a00d84a07dc638eda46a87fc90142d64breed@android.com 2745469607a00d84a07dc638eda46a87fc90142d64breed@android.com 275