LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const
{
	if (mFTFace == NULL)
		return FALSE;

	llassert(!mIsFallback);
	//lldebugs << "Adding new glyph for " << wch << " to font" << llendl;

	FT_UInt glyph_index;

	// Initialize char to glyph map
	glyph_index = FT_Get_Char_Index(mFTFace, wch);
	if (glyph_index == 0)
	{
		//llinfos << "Trying to add glyph from fallback font!" << llendl;
		font_vector_t::const_iterator iter;
		for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++)
		{
			glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
			if (glyph_index)
			{
				return addGlyphFromFont(*iter, wch, glyph_index);
			}
		}
	}
	
	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
	if (iter == mCharGlyphInfoMap.end())
	{
		return addGlyphFromFont(this, wch, glyph_index);
	}
	return NULL;
}
void LLFontFreetype::resetBitmapCache()
{
	for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer());
	mCharGlyphInfoMap.clear();
	mFontBitmapCachep->reset();

	// Adding default glyph is skipped for fallback fonts here as well as in loadFace(). 
	// This if was added as fix for EXT-4971.
	if(!mIsFallback)
	{
		// Add the empty glyph
		addGlyphFromFont(this, 0, 0);
	}
}
Example #3
0
BOOL LLFont::addChar(const llwchar wch) const
{
	if (mFTFace == NULL)
		return FALSE;

	llassert(!mIsFallback);
	//lldebugs << "Adding new glyph for " << wch << " to font" << llendl;

	FT_UInt glyph_index;

	// Initialize char to glyph map
	glyph_index = FT_Get_Char_Index(mFTFace, wch);
	if (glyph_index == 0)
	{
		// Try looking it up in the backup Unicode font
		if (mFallbackFontp)
		{
			//llinfos << "Trying to add glyph from fallback font!" << llendl
			LLFontList::iterator iter;
			for(iter = mFallbackFontp->begin(); iter != mFallbackFontp->end(); iter++)
			{
				glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch);
				if (glyph_index)
				{
					addGlyphFromFont(*iter, wch, glyph_index);
					return TRUE;
				}
			}
		}
	}
	
	char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch);
	if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered))
	{
		BOOL result = addGlyph(wch, glyph_index);
		return result;
	}
	return FALSE;
}
BOOL LLFontFreetype::loadFace(const std::string& filename, const F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback)
{
	// Don't leak face objects.  This is also needed to deal with
	// changed font file names.
	if (mFTFace)
	{
		FT_Done_Face(mFTFace);
		mFTFace = NULL;
	}
	
	llinfos << "Loading font file: " << filename << llendl;

	int error;

	error = FT_New_Face( gFTLibrary,
						 filename.c_str(),
						 0,
						 &mFTFace );

    if (error)
	{
		return FALSE;
	}

	mIsFallback = is_fallback;
	F32 pixels_per_em = (point_size / 72.f)*vert_dpi; // Size in inches * dpi

	error = FT_Set_Char_Size(mFTFace,    /* handle to face object           */
							0,       /* char_width in 1/64th of points  */
							(S32)(point_size*64),   /* char_height in 1/64th of points */
							(U32)horz_dpi,     /* horizontal device resolution    */
							(U32)vert_dpi);   /* vertical device resolution      */

	if (error)
	{
		// Clean up freetype libs.
		FT_Done_Face(mFTFace);
		mFTFace = NULL;
		return FALSE;
	}

	F32 y_max, y_min, x_max, x_min;
	F32 ems_per_unit = 1.f/ mFTFace->units_per_EM;
	F32 pixels_per_unit = pixels_per_em * ems_per_unit;

	// Get size of bbox in pixels
	y_max = mFTFace->bbox.yMax * pixels_per_unit;
	y_min = mFTFace->bbox.yMin * pixels_per_unit;
	x_max = mFTFace->bbox.xMax * pixels_per_unit;
	x_min = mFTFace->bbox.xMin * pixels_per_unit;
	mAscender = mFTFace->ascender * pixels_per_unit;
	mDescender = -mFTFace->descender * pixels_per_unit;
	mLineHeight = mFTFace->height * pixels_per_unit;

	S32 max_char_width = llround(0.5f + (x_max - x_min));
	S32 max_char_height = llround(0.5f + (y_max - y_min));

	mFontBitmapCachep->init(components, max_char_width, max_char_height);

	if (!mFTFace->charmap)
	{
		//llinfos << " no unicode encoding, set whatever encoding there is..." << llendl;
		FT_Set_Charmap(mFTFace, mFTFace->charmaps[0]);
	}

	if (!mIsFallback || !sOpenGLcrashOnRestart)	// because this often crashes under Linux...
	{
		// Add the default glyph
		addGlyphFromFont(this, 0, 0);
	}

	mName = filename;
	mPointSize = point_size;

	return TRUE;
}
Example #5
0
BOOL LLFont::addGlyph(const llwchar wch, const U32 glyph_index) const
{
	return addGlyphFromFont(this, wch, glyph_index);
}