11512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*
21512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 2010 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#include <assert.h>
281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifndef NO_OPENTYPE
301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const HB_OpenTypeFeature greek_features[] = {
311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },
331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },
341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {0, 0}
351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif
371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*
391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Greek decompositions
401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod*/
411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodtypedef struct _hb_greek_decomposition {
441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_UChar16 composed;
451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_UChar16 base;
461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod} hb_greek_decomposition;
471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x300[] = {
491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FBA, 0x0391 },
501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC8, 0x0395 },
511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FCA, 0x0397 },
521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FDA, 0x0399 },
531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF8, 0x039F },
541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FEA, 0x03A5 },
551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FFA, 0x03A9 },
561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F70, 0x03B1 },
571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F72, 0x03B5 },
581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F74, 0x03B7 },
591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F76, 0x03B9 },
601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F78, 0x03BF },
611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F7A, 0x03C5 },
621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F7C, 0x03C9 },
631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD2, 0x03CA },
641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE2, 0x03CB },
651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F02, 0x1F00 },
661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x300(HB_UChar16 base)
701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ((base ^ 0x1f00) < 0x100) {
721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base <= 0x1f69 && !(base & 0x6))
731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return base + 2;
741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base == 0x1fbf)
751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return 0x1fcd;
761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base == 0x1ffe)
771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return 0x1fdd;
781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        return 0;
791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        const hb_greek_decomposition *d = decompose_0x300;
821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        while (d->base && d->base != base)
831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            ++d;
841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        return d->composed;
851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x301[] = {
891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x0386, 0x0391 },
901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x0388, 0x0395 },
911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x0389, 0x0397 },
921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x038A, 0x0399 },
931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x038C, 0x039F },
941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x038E, 0x03A5 },
951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x038F, 0x03A9 },
961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AC, 0x03B1 },
971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AD, 0x03B5 },
981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AE, 0x03B7 },
991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AF, 0x03B9 },
1001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03CC, 0x03BF },
1011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03CD, 0x03C5 },
1021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03CE, 0x03C9 },
1031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x0390, 0x03CA },
1041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03B0, 0x03CB },
1051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03D3, 0x03D2 },
1061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
1071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
1081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x301(HB_UChar16 base)
1111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
1121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ((base ^ 0x1f00) < 0x100) {
1131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base <= 0x1f69 && !(base & 0x6))
1141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return base + 4;
1151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base == 0x1fbf)
1161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return 0x1fce;
1171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (base == 0x1ffe)
1181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            return 0x1fde;
1191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
1201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
1211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        const hb_greek_decomposition *d = decompose_0x301;
1221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        while (d->base && d->base != base)
1231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            ++d;
1241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        return d->composed;
1251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
1261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
1271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x304[] = {
1291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB9, 0x0391 },
1301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD9, 0x0399 },
1311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE9, 0x03A5 },
1321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB1, 0x03B1 },
1331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD1, 0x03B9 },
1341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE1, 0x03C5 },
1351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
1361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
1371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x304(HB_UChar16 base)
1391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
1401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x304;
1411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
1421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
1431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
1441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
1451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x306[] = {
1471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB8, 0x0391 },
1481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD8, 0x0399 },
1491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE8, 0x03A5 },
1501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB0, 0x03B1 },
1511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD0, 0x03B9 },
1521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE0, 0x03C5 },
1531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
1541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
1551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x306(HB_UChar16 base)
1571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
1581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x306;
1591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
1601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
1611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
1621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
1631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x308[] = {
1651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AA, 0x0399  },
1661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03AB, 0x03A5  },
1671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03CA, 0x03B9  },
1681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03CB, 0x03C5  },
1691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x03D4, 0x03D2  },
1701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
1711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
1721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x308(HB_UChar16 base)
1741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
1751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x308;
1761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
1771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
1781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
1791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
1801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x313[] = {
1831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F08, 0x0391 },
1841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F18, 0x0395 },
1851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F28, 0x0397 },
1861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F38, 0x0399 },
1871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F48, 0x039F },
1881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F68, 0x03A9 },
1891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F00, 0x03B1 },
1901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F10, 0x03B5 },
1911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F20, 0x03B7 },
1921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F30, 0x03B9 },
1931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F40, 0x03BF },
1941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE4, 0x03C1 },
1951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F50, 0x03C5 },
1961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F60, 0x03C9 },
1971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
1981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
1991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x313(HB_UChar16 base)
2011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x313;
2031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
2041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
2051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
2061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x314[] = {
2091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F09, 0x0391 },
2101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F19, 0x0395 },
2111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F29, 0x0397 },
2121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F39, 0x0399 },
2131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F49, 0x039F },
2141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FEC, 0x03A1 },
2151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F59, 0x03A5 },
2161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F69, 0x03A9 },
2171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F01, 0x03B1 },
2181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F11, 0x03B5 },
2191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F21, 0x03B7 },
2201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F31, 0x03B9 },
2211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F41, 0x03BF },
2221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE5, 0x03C1 },
2231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F51, 0x03C5 },
2241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F61, 0x03C9 },
2251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
2261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
2271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x314(HB_UChar16 base)
2291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x314;
2311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
2321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
2331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
2341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x342[] = {
2371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB6, 0x03B1 },
2381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC6, 0x03B7 },
2391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD6, 0x03B9 },
2401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE6, 0x03C5 },
2411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF6, 0x03C9 },
2421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FD7, 0x03CA },
2431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FE7, 0x03CB },
2441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F06, 0x1F00 },
2451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F07, 0x1F01 },
2461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F0E, 0x1F08 },
2471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F0F, 0x1F09 },
2481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F26, 0x1F20 },
2491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F27, 0x1F21 },
2501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F2E, 0x1F28 },
2511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F2F, 0x1F29 },
2521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F36, 0x1F30 },
2531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F37, 0x1F31 },
2541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F3E, 0x1F38 },
2551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F3F, 0x1F39 },
2561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F56, 0x1F50 },
2571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F57, 0x1F51 },
2581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F5F, 0x1F59 },
2591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F66, 0x1F60 },
2601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F67, 0x1F61 },
2611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F6E, 0x1F68 },
2621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F6F, 0x1F69 },
2631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FCF, 0x1FBF },
2641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FDF, 0x1FFE },
2651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
2661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
2671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x342(HB_UChar16 base)
2691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x342;
2711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
2721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
2731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
2741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic const hb_greek_decomposition decompose_0x345[] = {
2771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FBC, 0x0391 },
2781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FCC, 0x0397 },
2791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FFC, 0x03A9 },
2801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB4, 0x03AC },
2811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC4, 0x03AE },
2821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB3, 0x03B1 },
2831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC3, 0x03B7 },
2841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF3, 0x03C9 },
2851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF4, 0x03CE },
2861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F80, 0x1F00 },
2871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F81, 0x1F01 },
2881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F82, 0x1F02 },
2891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F83, 0x1F03 },
2901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F84, 0x1F04 },
2911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F85, 0x1F05 },
2921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F86, 0x1F06 },
2931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F87, 0x1F07 },
2941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F88, 0x1F08 },
2951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F89, 0x1F09 },
2961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8A, 0x1F0A },
2971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8B, 0x1F0B },
2981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8C, 0x1F0C },
2991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8D, 0x1F0D },
3001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8E, 0x1F0E },
3011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F8F, 0x1F0F },
3021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F90, 0x1F20 },
3031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F91, 0x1F21 },
3041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F92, 0x1F22 },
3051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F93, 0x1F23 },
3061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F94, 0x1F24 },
3071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F95, 0x1F25 },
3081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F96, 0x1F26 },
3091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F97, 0x1F27 },
3101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F98, 0x1F28 },
3111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F99, 0x1F29 },
3121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9A, 0x1F2A },
3131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9B, 0x1F2B },
3141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9C, 0x1F2C },
3151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9D, 0x1F2D },
3161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9E, 0x1F2E },
3171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1F9F, 0x1F2F },
3181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA0, 0x1F60 },
3191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA1, 0x1F61 },
3201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA2, 0x1F62 },
3211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA3, 0x1F63 },
3221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA4, 0x1F64 },
3231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA5, 0x1F65 },
3241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA6, 0x1F66 },
3251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA7, 0x1F67 },
3261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA8, 0x1F68 },
3271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FA9, 0x1F69 },
3281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAA, 0x1F6A },
3291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAB, 0x1F6B },
3301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAC, 0x1F6C },
3311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAD, 0x1F6D },
3321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAE, 0x1F6E },
3331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FAF, 0x1F6F },
3341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB2, 0x1F70 },
3351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC2, 0x1F74 },
3361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF2, 0x1F7C },
3371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FB7, 0x1FB6 },
3381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FC7, 0x1FC6 },
3391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0x1FF7, 0x1FF6 },
3401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    { 0, 0 }
3411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod};
3421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UChar16 compose_0x345(HB_UChar16 base)
3441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
3451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const hb_greek_decomposition *d = decompose_0x345;
3461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    while (d->base && d->base != base)
3471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ++d;
3481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return d->composed;
3491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
3501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*
3521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Greek shaping. Heuristic positioning can't render polytonic greek correctly. We're a lot
3531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  better off mapping greek chars with diacritics to the characters in the extended greek
3541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  region in Unicode if possible.
3551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod*/
3561512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Bool HB_GreekShape(HB_ShaperItem *shaper_item)
3571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
3581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const int availableGlyphs = shaper_item->num_glyphs;
3591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    const HB_UChar16 *uc = shaper_item->string + shaper_item->item.pos;
3601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    unsigned short *logClusters = shaper_item->log_clusters;
3611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_GlyphAttributes *attributes = shaper_item->attributes;
3621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_Bool haveGlyphs;
3641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    int slen = 1;
3651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    int cluster_start = 0;
3661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    hb_uint32 i;
3671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_STACKARRAY(HB_UChar16, shapedChars, 2 * shaper_item->item.length);
3691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    assert(shaper_item->item.script == HB_Script_Greek);
3711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *shapedChars = *uc;
3731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    logClusters[0] = 0;
3741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for (i = 1; i < shaper_item->item.length; ++i) {
3761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        hb_uint16 base = shapedChars[slen-1];
3771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        hb_uint16 shaped = 0;
3781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (uc[i] == 0x300)
3791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x300(base);
3801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x301)
3811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x301(base);
3821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x304)
3831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x304(base);
3841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x306)
3851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x306(base);
3861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x308)
3871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x308(base);
3881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x313)
3891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x313(base);
3901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x314)
3911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x314(base);
3921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x342)
3931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x342(base);
3941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        else if (uc[i] == 0x345)
3951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shaped = compose_0x345(base);
3961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (shaped) {
3981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            if (shaper_item->font->klass->canRender(shaper_item->font, (HB_UChar16 *)&shaped, 1)) {
3991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                shapedChars[slen-1] = shaped;
4001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            } else {
4011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                shaped = 0;
4021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            }
4031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        }
4041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        if (!shaped) {
4061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            HB_CharCategory category;
4071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            int cmb;
4081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            shapedChars[slen] = uc[i];
4091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            HB_GetUnicodeCharProperties(uc[i], &category, &cmb);
4101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            if (category != HB_Mark_NonSpacing) {
4111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].clusterStart = TRUE;
4121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].mark = FALSE;
4131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].combiningClass = 0;
4141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].dontPrint = HB_IsControlChar(uc[i]);
4151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                cluster_start = slen;
4161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            } else {
4171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].clusterStart = FALSE;
4181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].mark = TRUE;
4191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                attributes[slen].combiningClass = cmb;
4201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            }
4211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod            ++slen;
4221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        }
4231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        logClusters[i] = cluster_start;
4241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
4251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    haveGlyphs = shaper_item->font->klass
4271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        ->convertStringToGlyphIndices(shaper_item->font,
4281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                                      shapedChars, slen,
4291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                                      shaper_item->glyphs, &shaper_item->num_glyphs,
4301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod                                      shaper_item->item.bidiLevel % 2);
4311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_FREE_STACKARRAY(shapedChars);
4331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if (!haveGlyphs)
4351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        return FALSE;
4361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifndef NO_OPENTYPE
4381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if (HB_SelectScript(shaper_item, greek_features)) {
4391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        HB_OpenTypeShape(shaper_item, /*properties*/0);
4401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod        return HB_OpenTypePosition(shaper_item, availableGlyphs, /*doLogClusters*/TRUE);
4411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
4421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif
4431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_HeuristicPosition(shaper_item);
4441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return TRUE;
4461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
4471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
448