static int gr_font_loadfrom( file * fp ) { char header[8]; int bpp; int types, i, id; uint32_t y; FONT * f; PALETTE * pal = NULL; struct { int width ; int height ; int yoffset ; int fileoffset ; } oldchardata[256]; _chardata chardata[256] ; if ( font_count == MAX_FONTS ) return -1 ; /* Read the file header */ if ( !file_read( fp, header, 8 ) ) return -1; if ( memcmp( header, FNT_MAGIC, 7 ) != 0 && memcmp( header, FNX_MAGIC, 7 ) != 0 ) { return -1; } bpp = header[7]; if ( bpp == 0 ) bpp = 8; /* Read or ignore the palette */ if ( bpp == 8 && !( pal = gr_read_pal_with_gamma( fp ) ) ) return -1 ; /* Read the character data (detect old format) */ if ( header[2] == 'x' ) { if ( !file_readSint32( fp, &types ) ) { pal_destroy( pal ); return -1 ; } if ( !file_read( fp, chardata, sizeof( chardata ) ) ) { pal_destroy( pal ); return -1 ; } for ( i = 0 ; i < 256 ; i++ ) { ARRANGE_DWORD( &chardata[i].width ); ARRANGE_DWORD( &chardata[i].height ); ARRANGE_DWORD( &chardata[i].xadvance ); ARRANGE_DWORD( &chardata[i].yadvance ); ARRANGE_DWORD( &chardata[i].xoffset ); ARRANGE_DWORD( &chardata[i].yoffset ); ARRANGE_DWORD( &chardata[i].fileoffset ); } } else { if ( !file_readSint32( fp, &types ) ) { pal_destroy( pal ); return -1 ; } if ( !file_read( fp, oldchardata, sizeof( oldchardata ) ) ) { pal_destroy( pal ); return -1 ; } for ( i = 0 ; i < 256 ; i++ ) { ARRANGE_DWORD( &oldchardata[i].width ); ARRANGE_DWORD( &oldchardata[i].height ); ARRANGE_DWORD( &oldchardata[i].yoffset ); ARRANGE_DWORD( &oldchardata[i].fileoffset ); chardata[i].width = oldchardata[i].width; chardata[i].height = oldchardata[i].height; chardata[i].xoffset = 0; chardata[i].yoffset = oldchardata[i].yoffset; chardata[i].xadvance = oldchardata[i].width; chardata[i].yadvance = oldchardata[i].height + oldchardata[i].yoffset; chardata[i].fileoffset = oldchardata[i].fileoffset; } } /* Create the font */ if ( header[2] == 'x' ) id = gr_font_new( types, header[7] ) ; else id = gr_font_new( CHARSET_CP850, 8 ) ; if ( id == -1 ) { pal_destroy( pal ); return -1 ; } f = fonts[id]; if ( !f ) { gr_font_destroy( id ); pal_destroy( pal ); return -1 ; } /* Load the character bitmaps */ for ( i = 0 ; i < 256 ; i++ ) { GRAPH * gr; uint8_t * ptr; f->glyph[i].xadvance = chardata[i].xadvance ; f->glyph[i].yadvance = chardata[i].yadvance ; if ( chardata[i].fileoffset == 0 || chardata[i].width == 0 || chardata[i].height == 0 ) continue ; f->glyph[i].xoffset = chardata[i].xoffset ; f->glyph[i].yoffset = chardata[i].yoffset ; file_seek( fp, chardata[i].fileoffset, SEEK_SET ) ; f->glyph[i].bitmap = gr = bitmap_new( i, chardata[i].width, chardata[i].height, f->bpp ) ; if ( !gr ) { gr_font_destroy( id ); pal_destroy( pal ); return -1 ; } bitmap_add_cpoint( gr, 0, 0 ) ; gr->format->palette = pal; pal_use( pal ); for ( y = 0, ptr = gr->data; y < gr->height; y++, ptr += gr->pitch ) { if ( !file_read( fp, ptr, gr->widthb ) ) break ; if ( gr->format->depth == 16 ) { ARRANGE_WORDS( ptr, ( int )gr->width ); } else if ( gr->format->depth == 32 ) { ARRANGE_DWORDS( ptr, ( int )gr->width ); } } f->glyph[i].yoffset = chardata[i].yoffset ; } if ( f->glyph[32].xadvance == 0 ) f->glyph[32].xadvance = f->glyph['j'].xadvance ; pal_destroy( pal ); // Elimino la instancia inicial return id ; }
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; }