コード例 #1
1
ファイル: dao_font.c プロジェクト: dreamsxin/DaoGraphics-1
DaoxGlyph* DaoxFont_LoadGlyph( DaoxFont *self, size_t codepoint )
{
	DaoxGlyph *glyph = DaoxGlyph_New();
	stbtt_vertex *vertices = NULL;
	int id = stbtt_FindGlyphIndex( & self->info, codepoint );
	int i, num_verts = stbtt_GetGlyphShape( & self->info, id, & vertices );

	stbtt_GetGlyphHMetrics( & self->info, id, & glyph->advanceWidth, & glyph->leftSideBearing );

	DMap_Insert( self->glyphs, (void*) codepoint, glyph );
	DaoxPath_SetRelativeMode( glyph->shape, 0 );
	for(i=0; i<num_verts; ++i){
		stbtt_vertex_type x = vertices[i].x;
		stbtt_vertex_type y = vertices[i].y;
		stbtt_vertex_type cx = vertices[i].cx;
		stbtt_vertex_type cy = vertices[i].cy;
		switch( vertices[i].type ){
		case STBTT_vmove :
			if( i ) DaoxPath_Close( glyph->shape );
			DaoxPath_MoveTo( glyph->shape, x, y );
			break;
		case STBTT_vline :
			DaoxPath_LineTo( glyph->shape, x, y );
			break;
		case STBTT_vcurve :
			DaoxPath_QuadTo( glyph->shape, cx, cy, x, y );
			break;
		}
	}
	if( i ) DaoxPath_Close( glyph->shape );
	stbtt_FreeShape( & self->info, vertices );

	return glyph;
}
コード例 #2
0
 // Bake a given set of ranges of chars
 int TTFFontAsset::BakeFontBitmap(const unsigned char *data, int offset,  // font location (use offset=0 for plain .ttf)
                                  float pixel_height,                     // height of font in pixels
                                  unsigned char *pixels, int pw, int ph,  // bitmap to be filled in
                                  const GlyphRanges& ranges,              // characters to bake
                                  BakedChar *chardata)
 {
     stbtt_fontinfo f;
     stbtt_InitFont(&f, data, offset);
     STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
     
     int x = 1, y = 1;
     int bottom_y = 1;
     
     glyphMap.clear();
     
     float scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
     
     int bakedIdx = 0;
     for (GlyphRanges::const_iterator iter = ranges.begin(); iter != ranges.end(); ++iter)
     {
         const Range<int>& range = *iter;
         int numItemsInRange = range.high - range.low;
         for (int i = 0; i <= numItemsInRange; i++, bakedIdx++)
         {
             int unicodeCodepoint = i + range.low;
             glyphMap.insert(std::make_pair(unicodeCodepoint, bakedIdx));
             
             int advance, lsb, x0,y0,x1,y1,gw,gh;
             int g = stbtt_FindGlyphIndex(&f, unicodeCodepoint);
             stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
             stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
             
             gw = x1-x0;
             gh = y1-y0;
             if (x + gw + 1 >= pw)
                 y = bottom_y, x = 1; // advance to next row
             if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row
                 return -i;
             
             STBTT_assert(x+gw < pw);
             STBTT_assert(y+gh < ph);
             
             stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g);
             
             chardata[bakedIdx].x0 = (stbtt_int16) x;
             chardata[bakedIdx].y0 = (stbtt_int16) y;
             chardata[bakedIdx].x1 = (stbtt_int16) (x + gw);
             chardata[bakedIdx].y1 = (stbtt_int16) (y + gh);
             chardata[bakedIdx].xadvance = scale * advance;
             chardata[bakedIdx].xoff     = (float) x0;
             chardata[bakedIdx].yoff     = (float) y0;
             
             x = x + gw + 2;
             if (y+gh+2 > bottom_y)
                 bottom_y = y+gh+2;
         }
     }
     return bottom_y;
 }
コード例 #3
0
ファイル: glfont.cpp プロジェクト: Aand1/Autoware
void GlFont::InitialiseFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w, int tex_h)
{
    font_height_px = pixel_height;
    this->tex_w = tex_w;
    this->tex_h = tex_h;
    font_bitmap = new unsigned char[tex_w*tex_h];
    const int offset = 0;

    stbtt_fontinfo f;
    if (!stbtt_InitFont(&f, ttf_buffer, offset)) {
       throw std::runtime_error("Unable to initialise font");
    }

    float scale = stbtt_ScaleForPixelHeight(&f, pixel_height);

    STBTT_memset(font_bitmap, 0, tex_w*tex_h);
    int x = 1;
    int y = 1;
    int bottom_y = 1;

    // Generate bitmap and char indices
    for (int i=0; i < NUM_CHARS; ++i) {
       int advance, lsb, x0,y0,x1,y1,gw,gh;
       int g = stbtt_FindGlyphIndex(&f, FIRST_CHAR + i);
       stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
       stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
       gw = x1-x0;
       gh = y1-y0;
       if (x + gw + 1 >= tex_w)
          y = bottom_y, x = 1; // advance to next row
       if (y + gh + 1 >= tex_h) // check if it fits vertically AFTER potentially moving to next row
          throw std::runtime_error("Unable to initialise font");
       STBTT_assert(x+gw < tex_w);
       STBTT_assert(y+gh < tex_h);
       stbtt_MakeGlyphBitmap(&f, font_bitmap+x+y*tex_w, gw,gh,tex_w, scale,scale, g);

       // Adjust offset for edges of pixels
       chardata[i] = GlChar(tex_w,tex_h, x, y, gw, gh, scale*advance, x0 -0.5, -y0 -0.5);

       x = x + gw + 1;
       if (y+gh+1 > bottom_y)
          bottom_y = y+gh+1;
    }

    // Generate kern table
    for (int i=0; i < NUM_CHARS; ++i) {
        for (int j=0; j < NUM_CHARS; ++j) {
            kern_table[i*NUM_CHARS+j] = scale * stbtt_GetCodepointKernAdvance(&f,i,j);
        }
    }
}
コード例 #4
0
ファイル: text.c プロジェクト: 0502758187/libdarnit
struct TEXT_FONT_GLYPH *textRenderGlyph(struct TEXT_FONT_CACHE *index, unsigned int glyph, int glyph_index, TEXT_FONT *font) {
	int pos_x, pos_y, w, h, x1, x2, y1, y2, ad, sb;
	unsigned char *data;
	struct TEXT_FONT_GLYPH *next, *alloc;
	float skipf;

	if ((alloc = malloc(sizeof(struct TEXT_FONT_GLYPH))) == NULL)
		return NULL;

	next = index->glyph;
	alloc->next = NULL;

	if (next == NULL)
		index->glyph = alloc;
	else {
		while (next->next != NULL)
			next = next->next;
		next->next = alloc;
	}

	x1 = y1 = x2 = y2 = 0;
	data = stbtt_GetGlyphBitmap(&font->face, 0, font->scale, glyph_index, &w, &h, 0, 0);
	textCacheGetCoordinates(index, w, h, &pos_x, &pos_y);
	stbtt_GetGlyphBox(&font->face, glyph_index, &x1, &y1, &x2, &y2);
	stbtt_GetGlyphHMetrics(&font->face, glyph_index, &ad, &sb);

	alloc->u1 = index->sheet_pwf * pos_x;
	alloc->v1 = index->sheet_phf * pos_y;
	alloc->u2 = index->sheet_pwf * pos_x + index->sheet_pwf * (w);
	alloc->v2 = index->sheet_phf * pos_y + index->sheet_phf * (h);
	alloc->wf = index->sheet_pwf * w;
	alloc->hf = index->sheet_phf * h;
	alloc->risei = y2 * font->scale;
	alloc->rise = index->ts->shgran * alloc->risei;

	alloc->cw = w;
	alloc->ch = h;
	alloc->adv = lrintf(font->scale * ad);
	alloc->advf = index->ts->swgran * alloc->adv;
	skipf = font->scale * sb;
	alloc->skip = skipf;
	alloc->skipf = index->ts->swgran * skipf;

	alloc->glyph = glyph;
	alloc->tex_cache = index;

	renderUpdateTilesheet(index->ts, pos_x, pos_y, data, w, h);
	stbtt_FreeBitmap(data, NULL);

	return alloc;
}
コード例 #5
0
JNIEXPORT void JNICALL Java_com_badlogic_gdx_graphics_g2d_stbtt_StbTrueType_getGlyphHMetrics(JNIEnv* env, jclass clazz, jlong info, jint glyphIndex, jintArray obj_metrics) {
	int* metrics = (int*)env->GetPrimitiveArrayCritical(obj_metrics, 0);


//@line:90

		int advanceWidth = 0;
		int leftSideBearing = 0;
		stbtt_GetGlyphHMetrics((stbtt_fontinfo*)info, glyphIndex, &advanceWidth, &leftSideBearing);

		metrics[0] = advanceWidth;
		metrics[1] = leftSideBearing;
	
	env->ReleasePrimitiveArrayCritical(obj_metrics, metrics, 0);

}
コード例 #6
0
ファイル: stb_unicode.c プロジェクト: diablodiab/RetroArch
static uint32_t font_renderer_stb_unicode_update_atlas(
      stb_unicode_font_renderer_t *self, uint32_t charcode)
{
   int advance_width, left_side_bearing;
   int id, glyph_index, offset_x, offset_y;
   struct font_glyph *glyph = NULL;
   uint8_t *dst             = NULL;
   int x0                   = 0;
   int y1                   = 0;

   if(charcode > 0xFFFF)
      return 0;

   if(self->uc_to_id[charcode])
      return self->uc_to_id[charcode];

   id                       = font_renderer_stb_unicode_get_slot(self);
   self->id_to_uc[id]       = charcode;
   self->uc_to_id[charcode] = id;
   self->atlas.dirty        = true;

   glyph                    = &self->glyphs[id];

   glyph_index              = stbtt_FindGlyphIndex(&self->info, charcode);

   offset_x                 = (id % 16) * self->max_glyph_width;
   offset_y                 = (id / 16) * self->max_glyph_height;

   dst                      = self->atlas.buffer + offset_x + offset_y 
      * self->atlas.width;

   stbtt_MakeGlyphBitmap(&self->info, dst, self->max_glyph_width, self->max_glyph_height,
         self->atlas.width, self->scale_factor, self->scale_factor, glyph_index);

   stbtt_GetGlyphHMetrics(&self->info, glyph_index, &advance_width, &left_side_bearing);
   stbtt_GetGlyphBox(&self->info, glyph_index, &x0, NULL, NULL, &y1);

   glyph->advance_x      = advance_width * self->scale_factor;
   glyph->atlas_offset_x = offset_x;
   glyph->atlas_offset_y = offset_y;
   glyph->draw_offset_x  = x0 * self->scale_factor;
   glyph->draw_offset_y  = - y1 * self->scale_factor;
   glyph->width          = self->max_glyph_width;
   glyph->height         = self->max_glyph_height;

   return id;
}
コード例 #7
0
ファイル: font.c プロジェクト: ccxvii/mio
static float font_width_imp(struct font *font, float scale, char *str)
{
	int ucs, gid;
	int advance, kern;
	float w = 0.0;
	int left = 0;

	while (*str) {
		str += chartorune(&ucs, str);
		gid = stbtt_FindGlyphIndex(&font->info, ucs);
		stbtt_GetGlyphHMetrics(&font->info, gid, &advance, NULL);
		kern = stbtt_GetGlyphKernAdvance(&font->info, left, gid);
		w += advance * scale;
		w += kern * scale;
		left = gid;
	}

	return w;
}
コード例 #8
0
ファイル: font.c プロジェクト: ccxvii/mio
static struct glyph *lookup_glyph(struct font *font, float scale, int gid, int subx, int suby)
{
	struct key key;
	unsigned int pos;
	unsigned char *data;
	float shift_x, shift_y;
	int w, h, x, y;
	int advance, lsb;

	/* Look it up in the table */

	memset(&key, 0, sizeof key);
	key.font = font;
	key.size = scale * 10000;
	key.gid = gid;
	key.subx = subx;
	key.suby = suby;

	pos = lookup_table(&key);
	if (table[pos].key.font)
		return &table[pos].glyph;

	/* Render the bitmap */

	shift_x = (float)subx / XPRECISION;
	shift_y = (float)suby / YPRECISION;

	stbtt_GetGlyphHMetrics(&font->info, gid, &advance, &lsb);
	data = stbtt_GetGlyphBitmapSubpixel(&font->info, scale, scale, shift_x, shift_y, gid, &w, &h, &x, &y);

	/* Find an empty slot in the texture */

	if (table_load == (MAXGLYPHS * 3) / 4) {
		puts("glyph cache table full, clearing cache");
		clear_glyph_cache();
		pos = lookup_table(&key);
	}

	if (h + PADDING > CACHESIZE || w + PADDING > CACHESIZE) {
		warn("error: rendered glyph exceeds cache dimensions");
		exit(1);
	}

	if (cache_row_x + w + PADDING > CACHESIZE) {
		cache_row_y += cache_row_h + PADDING;
		cache_row_x = PADDING;
		cache_row_h = 0;
	}
	if (cache_row_y + h + PADDING > CACHESIZE) {
		puts("glyph cache texture full, clearing cache");
		clear_glyph_cache();
		pos = lookup_table(&key);
	}

	/* Copy the bitmap into our texture */

	memcpy(&table[pos].key, &key, sizeof(struct key));
	table[pos].glyph.w = w;
	table[pos].glyph.h = h;
	table[pos].glyph.x = x;
	table[pos].glyph.y = y;
	table[pos].glyph.s = cache_row_x;
	table[pos].glyph.t = cache_row_y;
	table[pos].glyph.advance = advance * scale;
	table_load ++;

	if (data && w && h) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
		glTexSubImage2D(GL_TEXTURE_2D, 0,
				cache_row_x, cache_row_y, w, h,
				GL_RED, GL_UNSIGNED_BYTE, data);
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
	}

	free(data);

	cache_row_x += w + PADDING;
	if (cache_row_h < h + PADDING)
		cache_row_h = h + PADDING;

	return &table[pos].glyph;
}
コード例 #9
0
ファイル: stash.cpp プロジェクト: shammellee/moon9
    stash::sth_glyph* stash::sth_font::get_glyph(unsigned int codepoint, short isize)
    {
        // Find code point and size.
        std::pair<unsigned int,int> key(codepoint, isize);

        if (glyphs.find( key ) != glyphs.end() )
            return &glyphs.find( key )->second;

        // Could not find glyph, create it.
        int advance,lsb,x0,y0,x1,y1;
        int g = stbtt_FindGlyphIndex(&font, codepoint);
        float scale = stbtt_ScaleForPixelHeight(&font, isize/10.0f);
        stbtt_GetGlyphHMetrics(&font, g, &advance, &lsb);
        stbtt_GetGlyphBitmapBox(&font, g, scale,scale, &x0,&y0,&x1,&y1);

        int gw = x1-x0;
        int gh = y1-y0;

        // Find row where the glyph can be fit (vertically first, then horizontally)
        sth_row* br = 0;
        int rh = (gh+7) & ~7;
        for (size_t i = 0; i < rows->size() && !br; ++i)
        {
            if (rows->at(i).h == rh && rows->at(i).x+gw+1 <= tw)
                br = &rows->at(i);
        }

        // If no row found, add new.
        if (br == NULL)
        {
            short py = 0;
            // Check that there is enough space.
            if (rows->size())
            {
                py = rows->back().y + rows->back().h+1;
                if (py+rh > th)
                    return 0;
            }
            // Init and add row
            rows->push_back( sth_row(0,py,rh) );
            br = &rows->back();
        }

        // Init glyph.
        sth_glyph glyph;

        glyph.codepoint = codepoint;
        glyph.size = isize;
        glyph.x0 = br->x;
        glyph.y0 = br->y;
        glyph.x1 = glyph.x0+gw;
        glyph.y1 = glyph.y0+gh;
        glyph.xadv = scale * advance;
        glyph.xoff = (float)x0;
        glyph.yoff = (float)y0;

//                glyphs[ key ] = glyphs[ key ];
        glyphs[ key ] = glyph;

        // Advance row location.
        br->x += gw+1;

        // Rasterize
        std::vector< unsigned char > bmp(gw*gh);
        if( bmp.size() )
        {
            stbtt_MakeGlyphBitmap(&font, &bmp[0], gw,gh,gw, scale,scale, g);

            // Update texture
            glBindTexture(GL_TEXTURE_2D, tex);
            glPixelStorei(GL_UNPACK_ALIGNMENT,1);
            glTexSubImage2D(GL_TEXTURE_2D, 0, glyph.x0,glyph.y0, gw,gh, GL_ALPHA,GL_UNSIGNED_BYTE,&bmp[0]);
        }

        return &glyphs[ key ];
    }
コード例 #10
0
ファイル: Face.cpp プロジェクト: elmindreda/Nori
float Face::advance(int index, float scale) const
{
  int advance;
  stbtt_GetGlyphHMetrics(m_info, index, &advance, nullptr);
  return advance * scale;
}