/* * Function : libaroma_font_glyph * Return Value: LIBAROMA_GLYPH * Descriptions: get font glyph */ LIBAROMA_GLYPH libaroma_font_glyph( int c, byte fontid, byte size ) { /* UTF 8 Flag */ if (c == 0xfeff) { return NULL; } /* 0 - 9 */ if (fontid >= _LIBAROMA_FONT_MAX_FACE) { ALOGW("libaroma_font_glyph fontid(%i)>=%i", fontid, _LIBAROMA_FONT_MAX_FACE); return NULL; } /* cleanup last variables */ // _libaroma_font_faces[fontid].last_cache = NULL; // _libaroma_font_faces[fontid].last_slotid = 0; if (size == 0) { size = _libaroma_font_faces[fontid].size; } /* find in cache */ int cache_id = ((c & 0xfffff) | (size << 20)); _libaroma_font_lock(1); _LIBAROMA_FONT_SLOT_CACHEP tmp_glyph = (_LIBAROMA_FONT_SLOT_CACHEP) libaroma_iarray_get(_libaroma_font_faces[fontid].cache, cache_id); if (tmp_glyph != NULL) { /* cache is available */ // _libaroma_font_faces[fontid].last_cache = tmp_glyph; // _libaroma_font_faces[fontid].last_slotid = cache_id; _libaroma_font_lock(0); return (LIBAROMA_GLYPH) tmp_glyph; } /* get freetype face */ FT_Face face = _libaroma_font_faces[fontid].face; if (face == NULL) { ALOGW("libaroma_font_glyph fontid(%i) uninitialized", fontid); _libaroma_font_lock(0); return NULL; } /* set requested font size */ libaroma_font_set_size(fontid, libaroma_font_size_px(size), 0); /* load glyph from freetype face */ if (FT_Load_Glyph(face, c, _LIBAROMA_FONT_LOAD_GLYPH_FLAG) == 0) { _LIBAROMA_FONT_SLOT_CACHE slot={0}; FT_Get_Glyph(face->glyph, &slot.glyph); memcpy(&slot.metrics, &face->glyph->metrics, sizeof(FT_Glyph_Metrics)); slot.codepoint = c; slot.size = _libaroma_font_faces[fontid].size; /* ready to return */ libaroma_iarray_set( _libaroma_font_faces[fontid].cache, cache_id, (voidp) &slot, sizeof(_LIBAROMA_FONT_SLOT_CACHE), 1 ); // _libaroma_font_faces[fontid].last_cache tmp_glyph = libaroma_iarray_get( _libaroma_font_faces[fontid].cache, cache_id ); _libaroma_font_lock(0); // _libaroma_font_faces[fontid].last_slotid = cache_id; return (LIBAROMA_GLYPH) tmp_glyph; // _libaroma_font_faces[fontid].last_cache; } _libaroma_font_lock(0); return NULL; } /* End of libaroma_font_glyph */
/* * Function : libaroma_text_shaper * Return Value: _LIBAROMA_TEXTSHAPEDP * Descriptions: text shaper with harfbuzz-ng */ _LIBAROMA_TEXTSHAPEDP libaroma_text_shaper( _LIBAROMA_TEXTPRESHAPEDP span, _LIBAROMA_TEXTCHUNKP chunk) { /* get freetype font face */ FT_Face font = libaroma_font_get(span->fontid, 1); if (font == NULL) { return NULL; } _libaroma_text_lock(1); /* set size */ byte fontsize = _LIBAROMA_TEXTCHUNK_GETFONTSIZE(chunk->curr_state.font); libaroma_font_set_size(span->fontid, libaroma_font_size_px(fontsize), 0); /* init harfbuzz font */ _LIBAROMA_FONT_FACEP afont = libaroma_font_get_face(span->fontid); /* calculating */ dword i = 0; int sizer_x = 0; int sizer_y = 0; int max_x = INT_MIN; int min_x = INT_MAX; int max_y = INT_MIN; int min_y = INT_MAX; int x = 0; int y = 0; int u = 0; #ifdef LIBAROMA_CONFIG_TEXT_NOHARFBUZZ _LIBAROMA_TEXTSHAPEDP shaped = (_LIBAROMA_TEXTSHAPEDP) malloc(sizeof(_LIBAROMA_TEXTSHAPED)); shaped->coln = span->len; shaped->cols = (_LIBAROMA_TEXTCOLUMNP) malloc(sizeof(_LIBAROMA_TEXTCOLUMN) * shaped->coln); shaped->rtl = chunk->rtl; shaped->font = _LIBAROMA_TEXT_FONT(span->fontid, fontsize); shaped->next = NULL; FT_Bool use_kerning = FT_HAS_KERNING(afont->face); int previous=0; dword ii; for (ii=0;ii<shaped->coln;ii++) { if (shaped->rtl){ i=(shaped->coln-1)-ii; } else{ i=ii; } u=FT_Get_Char_Index(afont->face, span->text[i]); _LIBAROMA_FONT_SLOT_CACHEP glp=(_LIBAROMA_FONT_SLOT_CACHEP) libaroma_font_glyph(u,span->fontid,fontsize); int xa = glp->metrics.horiAdvance>>6; int xo = 0; if (use_kerning&&previous&&u){ FT_Vector delta; if (shaped->rtl){ FT_Get_Kerning(afont->face, u, previous,FT_KERNING_DEFAULT, &delta ); } else{ FT_Get_Kerning(afont->face, previous, u,FT_KERNING_DEFAULT, &delta ); } xo = delta.x>>6; } int gx = sizer_x + xo; if (min_x > gx) { min_x = gx; } if (max_x < gx) { max_x = gx; } if (min_y > sizer_y) { min_y = sizer_y; } if (max_y < sizer_y) { max_y = sizer_y; } shaped->cols[i].id = u; shaped->cols[i].x = x + xo; shaped->cols[i].y = y; shaped->cols[i].w = xa; xa+=xo; sizer_x += xa; x += xa; previous = u; }