示例#1
0
/*
 * Function    : libaroma_font
 * Return Value: byte
 * Descriptions: load new font
 */
byte libaroma_font(
    byte fontid,
    LIBAROMA_STREAMP stream) {
  if (!stream) {
    ALOGW("libaroma_font stream not found");
    return 0;
  }
  
  if (fontid >= _LIBAROMA_FONT_MAX_FACE) {
    ALOGW("libaroma_font fontid(%i)>=%i",
      fontid, _LIBAROMA_FONT_MAX_FACE);
    return 0;
  }
  
  /* thread safe */
  _libaroma_font_lock(1);
  
  /* load face */
  FT_Face tmp_face;
  if (FT_New_Memory_Face(_libaroma_font_instance, 
      stream->data,
      stream->size,
      0,
      &tmp_face) == 0) {
    /* set default face size */
    int def_size = libaroma_font_size_px(2);
    
    if (FT_Set_Pixel_Sizes(tmp_face, 0, def_size) == 0) {
      /* save it */
      libaroma_font_free(fontid);
      _libaroma_font_faces[fontid].size   = def_size;
      _libaroma_font_faces[fontid].id     = fontid;
      _libaroma_font_faces[fontid].face   = tmp_face;
      _libaroma_font_faces[fontid].stream = stream;
      _libaroma_font_faces[fontid].cache  =
        libaroma_iarray(libaroma_font_freecache_cb);
      
      /* force ucs2 */
      libaroma_font_set_ucs2(_libaroma_font_faces[fontid].face);
      
      /* init harfbuzz */
      _libaroma_font_hb_init(fontid);
      
      /* unlock */
      _libaroma_font_lock(0);
      ALOGV("font loaded %ibytes (%s)", stream->size, stream->uri);
      return 1;
    }
    else {
      ALOGW("libaroma_font libaroma_font_set_size error");
      FT_Done_Face(tmp_face);
    }
  }
  else {
    ALOGW("libaroma_font FT_New_Memory_Face Error");
    libaroma_stream_close(stream);
  }
  _libaroma_font_lock(0);
  return 0;
} /* End of libaroma_font */
示例#2
0
/*
 * 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 */
示例#3
0
/*
 * 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;
	}