static int substituteWithVerticalGlyphs(const SimpleFontData* fontData, uint16_t* glyphs, unsigned bufferLength)
{
    HB_FaceRec_* hbFace = fontData->platformData().harfbuzzFace()->face();
    if (!hbFace->gsub) {
        // if there is no GSUB table, treat it as not covered
        return 0Xffff;
    }

    HB_Buffer buffer;
    hb_buffer_new(&buffer);
    for (unsigned i = 0; i < bufferLength; ++i)
        hb_buffer_add_glyph(buffer, glyphs[i], 0, i);

    HB_UShort scriptIndex;
    HB_UShort featureIndex;

    HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex);
    HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'e', 'r', 't'), scriptIndex, 0xffff, &featureIndex);
    HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1);
    HB_GSUB_Select_Feature(hbFace->gsub, HB_MAKE_TAG('v', 'r', 't', '2'), scriptIndex, 0xffff, &featureIndex);
    HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, 1);

    int error = HB_GSUB_Apply_String(hbFace->gsub, buffer);
    if (!error) {
        for (unsigned i = 0; i < bufferLength; ++i)
            glyphs[i] = static_cast<Glyph>(buffer->out_string[i].gindex);
    }
    return error;
}
Exemple #2
0
static void setupFontFeatures(const FontFeatureSettings* settings, HB_FaceRec_* hbFace)
{
    if (!settings)
        return;

    if (hbFace->gsub)
        HB_GSUB_Clear_Features(hbFace->gsub);
    if (hbFace->gpos)
        HB_GPOS_Clear_Features(hbFace->gpos);

    HB_UShort scriptIndex = 0;
    HB_GSUB_Select_Script(hbFace->gsub, HB_MAKE_TAG('D', 'F', 'L', 'T'), &scriptIndex);
    size_t numFeatures = settings->size();
    for (size_t i = 0; i < numFeatures; ++i) {
        if (!settings->at(i).value())
            continue;
        HB_UShort featureIndex = 0;
        const UChar* tag = settings->at(i).tag().characters();
        HB_UInt feature = HB_MAKE_TAG(tag[0], tag[1], tag[2], tag[3]);
        if (hbFace->gsub && HB_GSUB_Select_Feature(hbFace->gsub, feature, scriptIndex, 0xffff, &featureIndex) == HB_Err_Ok)
            HB_GSUB_Add_Feature(hbFace->gsub, featureIndex, settings->at(i).value());
        else if (hbFace->gpos && HB_GPOS_Select_Feature(hbFace->gpos, feature, scriptIndex, 0xffff, &featureIndex) == HB_Err_Ok)
            HB_GPOS_Add_Feature(hbFace->gpos, featureIndex, settings->at(i).value());
    }
}
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */

#include "harfbuzz-shaper.h"
#include "harfbuzz-shaper-private.h"
#include <assert.h>

/*
// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
*/
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature hebrew_features[] = {
    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
    {0, 0}
};
#endif

/* Hebrew shaping. In the non opentype case we try to use the
   presentation forms specified for Hebrew. Especially for the
   ligatures with Dagesh this gives much better results than we could
   achieve manually.
*/
HB_Bool HB_HebrewShape(HB_ShaperItem *shaper_item)
{
    enum {
        Dagesh = 0x5bc,
        ShinDot = 0x5c1,
        SinDot = 0x5c2,
        if (state < 0) {
            if (state < -1)
                --pos;
            break;
        }
        ++uc;
        ++pos;
    }
    return pos;
}

#ifndef NO_OPENTYPE
/* ###### might have to change order of above and below forms and substitutions,
   but according to Unicode below comes before above */
static const HB_OpenTypeFeature myanmar_features[] = {
    { HB_MAKE_TAG('p', 'r', 'e', 'f'), PreFormProperty },
    { HB_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
    { HB_MAKE_TAG('a', 'b', 'v', 'f'), AboveFormProperty },
    { HB_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
    { HB_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
    { HB_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
    { HB_MAKE_TAG('r', 'l', 'i', 'g'), CligProperty }, /* Myanmar1 uses this instead of the other features */
    { 0, 0 }
};
#endif


/*
// Visual order before shaping should be:
Exemple #5
0
        KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state,
                charClass, *uc );

        if (state < 0) {
            break;
        }
        ++uc;
        ++pos;
    }
    return pos;
}

#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature khmer_features[] = {
    { HB_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
    { HB_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
    { HB_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
    { HB_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
    { HB_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
    { HB_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
    { HB_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
    { HB_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
    { HB_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty },
    { 0, 0 }
};
#endif


static HB_Bool khmer_shape_syllable(HB_Bool openType, HB_ShaperItem *item)
{
Exemple #6
0
    result[len] = 0;
}

/*
 * ---------------------------------------------------------------------------
 * Thai Shaper / Attributes
 * ---------------------------------------------------------------------------
 */

/*
 * USe basic_features prepare for future adding.
 */
#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature thai_features[] = {
    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
    { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },
    { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },
    {0, 0}
};
#endif

/* TIS-to-Unicode glyph maps for characters 0x80-0xff */
static int tis620_0[128] = {
    /**/ 0,      0,      0,      0,      0,      0,      0,      0,
    /**/ 0,      0,      0,      0,      0,      0,      0,      0,
    /**/ 0,      0,      0,      0,      0,      0,      0,      0,
    /**/ 0,      0,      0,      0,      0,      0,      0,      0,
    0x0020, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,
    0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
    0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,
            break;
        case LVT:
            if (state > L)
                goto finish;
            state = T;
        }
        ++pos;
    }

 finish:
    return start+pos;
}

#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature hangul_features [] = {
    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
    { HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty },
    { HB_MAKE_TAG('v', 'j', 'm', 'o'), CcmpProperty },
    { HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
    { 0, 0 }
};
#endif

static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType)
{
    const HB_UChar16 *ch = item->string + item->item.pos;
    int len = item->item.length;
#ifndef NO_OPENTYPE
    const int availableGlyphs = item->num_glyphs;
#endif
    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,

    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
    TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
    TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther
};


#define tibetan_form(c) \
    ((c) >= 0x0f40 && (c) < 0x0fc0 ? (TibetanForm)tibetanForm[(c) - 0x0f40] : TibetanOther)

#ifndef NO_OPENTYPE
static const HB_OpenTypeFeature tibetan_features[] = {
    { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
    { HB_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
    { HB_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
    { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
    {0, 0}
};
#endif

static HB_Bool tibetan_shape_syllable(HB_Bool openType, HB_ShaperItem *item, HB_Bool invalid)
{
    hb_uint32 i;
    const HB_UChar16 *str = item->string + item->item.pos;
    int len = item->item.length;
#ifndef NO_OPENTYPE
    const int availableGlyphs = item->num_glyphs;
#endif