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; }
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; }