예제 #1
0
bool Font::insertGlyph(Char character) {
	
	FT_Error error;
	FT_UInt glyphIndex = FT_Get_Char_Index(face, character);
	if(!glyphIndex) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Load_Glyph(face, glyphIndex, FT_LOAD_FORCE_AUTOHINT);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
	if(error) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	// Fill in info for this glyph.
	Glyph & glyph = glyphs[character];
	glyph.index = glyphIndex;
	glyph.size.x = face->glyph->bitmap.width;
	glyph.size.y = face->glyph->bitmap.rows;
	glyph.advance.x = face->glyph->linearHoriAdvance / 65536.0f;
	glyph.advance.y = face->glyph->linearVertAdvance / 65536.0f;
	glyph.lsb_delta = face->glyph->lsb_delta;
	glyph.rsb_delta = face->glyph->rsb_delta;
	glyph.draw_offset.x = face->glyph->bitmap_left;
	glyph.draw_offset.y = face->glyph->bitmap_top - face->glyph->bitmap.rows;
	glyph.uv_start = Vec2f_ZERO;
	glyph.uv_end = Vec2f_ZERO;
	glyph.texture = 0;
	
	// Some glyphs like spaces have a size of 0...
	if(glyph.size.x != 0 && glyph.size.y != 0) {
		
		Image imgGlyph;
		imgGlyph.Create(glyph.size.x, glyph.size.y, Image::Format_A8);
		
		FT_Bitmap * srcBitmap = &face->glyph->bitmap;
		arx_assert(srcBitmap->pitch >= 0);
		arx_assert(unsigned(srcBitmap->pitch) == unsigned(srcBitmap->width));
		
		// Copy pixels
		unsigned char * src = srcBitmap->buffer;
		unsigned char * dst = imgGlyph.GetData();
		memcpy(dst, src, glyph.size.x * glyph.size.y);
		
		Vec2i offset;
		if(!textures->insertImage(imgGlyph, glyph.texture, offset)) {
			LogWarning << "Could not upload glyph for character U+" << std::hex << character
			           << " (" << util::encode<util::UTF8>(character) << ") in font "
			           << info.name;
			insertPlaceholderGlyph(character);
			return false;
		}
		
		// Compute UV mapping for each glyph.
		const float textureSize = textures->getTextureSize();
		glyph.uv_start = Vec2f(offset) / Vec2f(textureSize);
		glyph.uv_end = Vec2f(offset + glyph.size) / Vec2f(textureSize);
	}
	
	return true;
}
예제 #2
0
bool Font::insertGlyph(Char character) {
	
	if(!m_size) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	FT_UInt glyphIndex = FT_Get_Char_Index(m_size->face, character);
	if(!glyphIndex) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	FT_Int32 flags = FT_LOAD_TARGET_LIGHT;
	if(m_info.weight != 0) {
		flags |= FT_LOAD_FORCE_AUTOHINT;
	}
	if(FT_Load_Glyph(m_size->face, glyphIndex, flags)) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	FT_GlyphSlot ftGlyph = m_size->face->glyph;
	
	if(m_info.weight != 0 && ftGlyph->format == FT_GLYPH_FORMAT_OUTLINE) {
		FT_Pos strength = FT_MulFix(m_size->face->units_per_EM, m_size->metrics.y_scale) / 24 * m_info.weight / 4;
		FT_Outline_Embolden(&ftGlyph->outline, strength);
	}
	
	if(FT_Render_Glyph(ftGlyph, FT_RENDER_MODE_NORMAL)) {
		insertPlaceholderGlyph(character);
		return false;
	}
	
	// Fill in info for this glyph.
	Glyph & glyph = m_glyphs[character];
	glyph.index = glyphIndex;
	glyph.size.x = ftGlyph->bitmap.width;
	glyph.size.y = ftGlyph->bitmap.rows;
	glyph.advance.x = float(ftGlyph->linearHoriAdvance) / 65536.f;
	glyph.advance.y = float(ftGlyph->linearVertAdvance) / 65536.f;
	glyph.lsb_delta = ftGlyph->lsb_delta;
	glyph.rsb_delta = ftGlyph->rsb_delta;
	glyph.draw_offset.x = ftGlyph->bitmap_left;
	glyph.draw_offset.y = ftGlyph->bitmap_top - ftGlyph->bitmap.rows;
	glyph.uv_start = Vec2f(0.f);
	glyph.uv_end = Vec2f(0.f);
	glyph.texture = 0;
	
	// Some glyphs like spaces have a size of 0...
	if(glyph.size.x != 0 && glyph.size.y != 0) {
		
		Image imgGlyph;
		imgGlyph.create(size_t(glyph.size.x), size_t(glyph.size.y), Image::Format_A8);
		
		FT_Bitmap & srcBitmap = ftGlyph->bitmap;
		arx_assert(srcBitmap.pitch >= 0);
		arx_assert(unsigned(srcBitmap.pitch) == unsigned(srcBitmap.width));
		
		// Copy pixels
		unsigned char * src = srcBitmap.buffer;
		unsigned char * dst = imgGlyph.getData();
		memcpy(dst, src, glyph.size.x * glyph.size.y);
		
		Vec2i offset;
		if(!m_textures->insertImage(imgGlyph, glyph.texture, offset)) {
			LogWarning << "Could not upload glyph for character U+" << std::hex << character
			           << " (" << util::encode<util::UTF8>(character) << ") in font "
			           << m_info.name;
			insertPlaceholderGlyph(character);
			return false;
		}
		
		// Compute UV mapping for each glyph.
		const float textureSize = float(m_textures->getTextureSize());
		glyph.uv_start = Vec2f(offset) / Vec2f(textureSize);
		glyph.uv_end = Vec2f(offset + glyph.size) / Vec2f(textureSize);
		
	}
	
	return true;
}