Example #1
0
Font::Font(const res::path & fontFile, unsigned int fontSize, FT_Face face) 
	: info(fontFile, fontSize)
	, referenceCount(0)
	, face(face)
	, textures(0) {
	
	// TODO-font: Compute optimal size using m_FTFace->bbox
	const unsigned int TEXTURE_SIZE = 512;
	
	// Insert all the glyphs into texture pages
	textures = new PackedTexture(TEXTURE_SIZE, Image::Format_A8);
	
	// Insert the replacement characters first as they may be needed if others are missing
	insertGlyph('?');
	insertGlyph(util::REPLACEMENT_CHAR);
	
	// Pre-load glyphs for displayable ASCII characters
	for(Char chr = 32; chr < FONT_PRELOAD_LIMIT; ++chr) {
		if(chr != '?') {
			insertGlyph(chr);
		}
	}
	
	textures->upload();
}
Example #2
0
Font::Font(const res::path & file, unsigned size, unsigned weight, FT_Face face)
	: m_info(file, size, weight)
	, m_referenceCount(0)
	, m_size(NULL)
	, m_textures(NULL) {
	
	FT_New_Size(face, &m_size);
	
	FT_Activate_Size(m_size);
	
	// Windows default is 96dpi
	// FreeType default is 72dpi
	FT_Set_Char_Size(m_size->face, 0, m_info.size * 64, 64, 64);
	
	// TODO Compute optimal size using m_FTFace->bbox
	const unsigned int TEXTURE_SIZE = 512;
	
	// Insert all the glyphs into texture pages
	m_textures = new PackedTexture(TEXTURE_SIZE, Image::Format_A8);
	
	// Insert the replacement characters first as they may be needed if others are missing
	insertGlyph('?');
	insertGlyph(util::REPLACEMENT_CHAR);
	
	// Pre-load glyphs for displayable ASCII characters
	for(Char chr = 32; chr < FONT_PRELOAD_LIMIT; ++chr) {
		if(chr != '?') {
			insertGlyph(chr);
		}
	}
	
	m_textures->upload();
	
}
Example #3
0
Font::glyph_iterator Font::getNextGlyph(text_iterator & it, text_iterator end) {
	
	Char chr = util::UTF8::read(it, end);
	if(chr == util::INVALID_CHAR) {
		return glyphs.end();
	}
	
	glyph_iterator glyph = glyphs.find(chr);
	if(glyph != glyphs.end()) {
		return glyph; // an existing glyph
	}
	
	if(chr < FONT_PRELOAD_LIMIT) {
		// We pre-load all glyphs for ASCII characters, so there is no point in checking again
		return glyphs.end();
	}
	
	if(!insertGlyph(chr)) {
		// No new glyph was inserted but the character was mapped to an existing one
		return glyphs.find(chr);
	}
	
	arx_assert(glyphs.find(chr) != glyphs.end());
	
	// As we need to re-upload the textures now, first check for more missing glyphs
	insertMissingGlyphs(it, end);
	
	// Re-upload the changed textures
	textures->upload();
	
	return glyphs.find(chr); // the newly inserted glyph
}
Example #4
0
/** Update the supported characters for this font if required.
 */
void FontWithFace::updateCharactersList()
{
    if (m_fallback_font != NULL)
        m_fallback_font->updateCharactersList();

    if (m_new_char_holder.empty()) return;
    for (const wchar_t& c : m_new_char_holder)
    {
        const GlyphInfo& gi = getGlyphInfo(c);
        insertGlyph(c, gi);
    }
    m_new_char_holder.clear();

}   // updateCharactersList
Example #5
0
bool Font::insertMissingGlyphs(text_iterator begin, text_iterator end) {
	
	Char chr;
	bool changed = false;
	
	for(text_iterator it = begin; (chr = util::UTF8::read(it, end)) != util::INVALID_CHAR; ) {
		if(glyphs.find(chr) == glyphs.end()) {
			if(chr >= FONT_PRELOAD_LIMIT && insertGlyph(chr)) {
				changed = true;
			}
		}
	}
	
	return changed;
}
Example #6
0
// ----------------------------------------------------------------------------
void FontWithFace::updateCharactersList()
{
    if (m_fallback_font != NULL)
        m_fallback_font->updateCharactersList();

    if (m_new_char_holder.empty()) return;
    for (const wchar_t& c : m_new_char_holder)
    {
        const GlyphInfo& gi = getGlyphInfo(c);
        insertGlyph(c, gi);
    }
    m_new_char_holder.clear();

    // Update last glyph page
    video::ITexture* page_texture = irr_driver->getVideoDriver()
        ->addTexture("Glyph_page", m_page);
    m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
        page_texture);

    irr_driver->getVideoDriver()->removeTexture(page_texture);
    assert(page_texture->getReferenceCount() == 1);

}   // updateCharactersList