Пример #1
0
cluster_t *GraphiteLayoutShaper::getCluster(gr_segment *segment, size_t numCodePoints) {
    const gr_slot *is;
    int ic, ci = 0;

    cluster_t *clusters = (cluster_t *) malloc(numCodePoints * sizeof(cluster_t));
    memset(clusters, 0, numCodePoints * sizeof(cluster_t));
    for (is = gr_seg_first_slot(segment), ic = 0; is; is = gr_slot_next_in_segment(is), ic++) {
        unsigned int before = gr_slot_before(is);
        unsigned int after = gr_slot_after(is);

        while (clusters[ci].base_char > before && ci) {
            clusters[ci - 1].num_chars += clusters[ci].num_chars;
            clusters[ci - 1].num_glyphs += clusters[ci].num_glyphs;
            --ci;
        }

        if (gr_slot_can_insert_before(is) && clusters[ci].num_chars
                && before >= clusters[ci].base_char + clusters[ci].num_chars) {
            cluster_t *c = clusters + ci + 1;
            c->base_char = clusters[ci].base_char + clusters[ci].num_chars;
            c->num_chars = before - c->base_char;
            c->base_glyph = ic;
            c->num_glyphs = 0;
            ++ci;
        }
        ++clusters[ci].num_glyphs;

        if (clusters[ci].base_char + clusters[ci].num_chars < after + 1) {
            clusters[ci].num_chars = after + 1 - clusters[ci].base_char;
        }
    }
    return clusters;
}
Пример #2
0
bool
initGraphiteBreaking(XeTeXLayoutEngine engine, const uint16_t* txtPtr, int txtLen)
{
    hb_face_t* hbFace = hb_font_get_face(engine->font->getHbFont());
    gr_face* grFace = hb_graphite2_face_get_gr_face(hbFace);
    gr_font* grFont = hb_graphite2_font_get_gr_font(engine->font->getHbFont());
    if (grFace != NULL && grFont != NULL) {
        if (grSegment != NULL) {
            gr_seg_destroy(grSegment);
            grSegment = NULL;
            grPrevSlot = NULL;
        }

        gr_feature_val *grFeatureValues = gr_face_featureval_for_lang (grFace, tag_from_lang(engine->language));

        int nFeatures = engine->nFeatures;
        hb_feature_t *features =  engine->features;
        while (nFeatures--) {
            const gr_feature_ref *fref = gr_face_find_fref (grFace, features->tag);
            if (fref)
                gr_fref_set_feature_value (fref, features->value, grFeatureValues);
            features++;
        }

        grSegment = gr_make_seg(grFont, grFace, engine->script, grFeatureValues, gr_utf16, txtPtr, txtLen, 0);
        grPrevSlot = gr_seg_first_slot(grSegment);
        grTextLen = txtLen;

        return true;
    }

    return false;
}
Пример #3
0
jfloat GraphiteLayoutShaper::shapeScriptRun(const SkPaint* paint, const UChar* chars,
        size_t count, bool isRTL, Vector<jfloat>* const outAdvances,
        Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos,
        jfloat startXPosition, uint32_t startScriptRun, size_t glyphBaseCount) {
    ALOGD("Shape Scrit Run with Graphite");
    SkTypeface *typeface = paint->getTypeface();
    mShapingGrFace = getCachedGrFace(typeface);

    unsigned int x_ppem;
    unsigned int y_ppem;
    int x_scale;
    int y_scale;
    getConversionFactor(x_ppem, y_ppem, x_scale, y_scale, paint);

    mShapingGrFont = gr_make_font_with_ops(x_ppem, paint, &GraphiteFontOps, mShapingGrFace);

    const uint16_t *charsScriptStart = chars ;
    const uint16_t *charsScriptEnd = chars + count;

    size_t numCP;
    char *pError;

    numCP = gr_count_unicode_characters(gr_utf16, charsScriptStart, charsScriptEnd, (const void **)(&pError));

#if DEBUG_GLYPHS
    ALOGD("Myanmar shape with Graphite, numCP = %d, grFont = %p, grFace = %p, pError = %p",
            numCP, mShapingGrFont, mShapingGrFace, pError);
#endif

    if(!mShapingGrFont || !mShapingGrFace || pError) {
        ALOGD("Invalid grFont is NULL, grFace is NULL or parse string error.");
        return 0.0;
    }

    mShapingSegment = gr_make_seg(mShapingGrFont, mShapingGrFace, 0, 0,
            gr_utf16, charsScriptStart, numCP, isRTL);
    cluster_t *clusters = getCluster(mShapingSegment, numCP);

#if DEBUG_GLYPHS
        ALOGD("Got from Graphite");
#endif

    const gr_slot *slot;
    size_t glyphIndex, clusterIndex = 0;
    jfloat totalFontRunAdvance = 0;
    for (slot = gr_seg_first_slot(mShapingSegment), glyphIndex = 0; slot;
            slot = gr_slot_next_in_segment(slot), ++ glyphIndex) {
#if DEBUG_GLYPHS
        ALOGD("         -- Glyph = %d, origin = (%f, %f), advance = (%f, %f)\n",
                gr_slot_gid(slot), gr_slot_origin_X(slot),
                gr_slot_origin_Y(slot),
                gr_slot_advance_X(slot, mShapingGrFace, mShapingGrFont),
                gr_slot_advance_Y(slot, mShapingGrFace, mShapingGrFont));
#endif
        if(glyphIndex == clusters[clusterIndex].base_glyph + clusters[clusterIndex].num_glyphs) {
            uint32_t clusterStart = clusters[clusterIndex].base_char + startScriptRun;
            jfloat startOrigin = outAdvances->itemAt(clusterStart);
            jfloat advance = gr_slot_origin_X(slot) - startOrigin;
            outAdvances->replaceAt(advance, clusterStart);

            ++ clusterIndex;
            clusterStart = clusters[clusterIndex].base_char + startScriptRun;
            outAdvances->replaceAt(gr_slot_origin_X(slot), clusterStart);
        }

        jfloat charRight = gr_slot_origin_X(slot) + gr_slot_advance_X(slot, mShapingGrFace, mShapingGrFont);
        if (charRight > totalFontRunAdvance) {
            totalFontRunAdvance = charRight;
        }

        jchar glyph = glyphBaseCount + gr_slot_gid(slot);
        outGlyphs->add(glyph);

        outPos->add(startXPosition + gr_slot_origin_X(slot));
        outPos->add(gr_slot_origin_Y(slot));
    }

    uint32_t clusterStart = clusters[clusterIndex].base_char + startScriptRun;
    jfloat startOrigin = outAdvances->itemAt(clusterStart);
    jfloat advance = totalFontRunAdvance - startOrigin;
    outAdvances->replaceAt(advance, clusterStart);

    if(mShapingSegment) {
        gr_seg_destroy(mShapingSegment);
        mShapingSegment = NULL;
    }

    if(mShapingGrFont) {
        gr_font_destroy(mShapingGrFont);
        mShapingGrFont = NULL;
    }
#if DEBUG_GLYPHS
    ALOGD("         -- totalFontRunAdvance = %f", totalFontRunAdvance);
#endif
    return totalFontRunAdvance;
}