diff options
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llfontfreetype.cpp | 120 | ||||
| -rw-r--r-- | indra/llrender/llfontfreetype.h | 9 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 14 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.h | 4 | ||||
| -rw-r--r-- | indra/llrender/llfontregistry.cpp | 107 | ||||
| -rw-r--r-- | indra/llrender/llfontregistry.h | 4 | 
6 files changed, 185 insertions, 73 deletions
| diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index ab668dc192..e9d852c288 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) {  }  #endif -BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)  {  	// Don't leak face objects.  This is also needed to deal with  	// changed font file names. @@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  	}  	int error; -  #ifdef LL_WINDOWS -	pFileStream = new llifstream(filename, std::ios::binary); -	if (pFileStream->is_open()) -	{ -		std::streampos beg = pFileStream->tellg(); -		pFileStream->seekg(0, std::ios::end); -		std::streampos end = pFileStream->tellg(); -		std::size_t file_size = end - beg; -		pFileStream->seekg(0, std::ios::beg); - -		pFtStream = new LLFT_Stream(); -		pFtStream->base = 0; -		pFtStream->pos = 0; -		pFtStream->size = file_size; -		pFtStream->descriptor.pointer = pFileStream; -		pFtStream->read = ft_read_cb; -		pFtStream->close = ft_close_cb; - -		FT_Open_Args args; -		args.flags = FT_OPEN_STREAM; -		args.stream = (FT_StreamRec*)pFtStream; - -		error = FT_Open_Face(gFTLibrary, -							 &args, -							 0, -							 &mFTFace); -	} -	else -	{ -		delete pFileStream; -		pFileStream = NULL; -		return FALSE; -	} +	error = ftOpenFace(filename, face_n);  #else  	error = FT_New_Face( gFTLibrary,  						 filename.c_str(), @@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  	if (error)  	{  #ifdef LL_WINDOWS -		pFileStream->close(); -		delete pFileStream; -		delete pFtStream; -		pFileStream = NULL; -		pFtStream = NULL; +		clearFontStreams();  #endif  		return FALSE;  	} @@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  		// Clean up freetype libs.  		FT_Done_Face(mFTFace);  #ifdef LL_WINDOWS -		pFileStream->close(); -		delete pFileStream; -		delete pFtStream; -		pFileStream = NULL; -		pFtStream = NULL; +		clearFontStreams();  #endif  		mFTFace = NULL;  		return FALSE; @@ -297,6 +257,78 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v  	return TRUE;  } +S32 LLFontFreetype::getNumFaces(const std::string& filename) +{ +	if (mFTFace) +	{ +		FT_Done_Face(mFTFace); +		mFTFace = NULL; +	} + +	S32 num_faces = 1; + +#ifdef LL_WINDOWS +	int error = ftOpenFace(filename, 0); +		 +	if (error) +	{ +		return 0; +	} +	else +	{ +		num_faces = mFTFace->num_faces; +	} +	 +	FT_Done_Face(mFTFace); +	clearFontStreams(); +	mFTFace = NULL; +#endif + +	return num_faces; +} + +#ifdef LL_WINDOWS +S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n) +{ +	S32 error = -1; +	pFileStream = new llifstream(filename, std::ios::binary); +	if (pFileStream->is_open()) +	{ +		std::streampos beg = pFileStream->tellg(); +		pFileStream->seekg(0, std::ios::end); +		std::streampos end = pFileStream->tellg(); +		std::size_t file_size = end - beg; +		pFileStream->seekg(0, std::ios::beg); + +		pFtStream = new LLFT_Stream(); +		pFtStream->base = 0; +		pFtStream->pos = 0; +		pFtStream->size = file_size; +		pFtStream->descriptor.pointer = pFileStream; +		pFtStream->read = ft_read_cb; +		pFtStream->close = ft_close_cb; + +		FT_Open_Args args; +		args.flags = FT_OPEN_STREAM; +		args.stream = (FT_StreamRec*)pFtStream; +		error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace); +	} +	return error; +} + +void LLFontFreetype::clearFontStreams() +{ +	if (pFileStream) +	{ +		pFileStream->close(); +	} +	delete pFileStream; +	delete pFtStream; +	pFileStream = NULL; +	pFtStream = NULL; +} +#endif +  void LLFontFreetype::setFallbackFonts(const font_vector_t &font)  {  	mFallbackFonts = font; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index aadebf5e70..1afe84e770 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -84,7 +84,14 @@ public:  	// is_fallback should be true for fallback fonts that aren't used  	// to render directly (Unicode backup, primarily) -	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); +	BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0); + +	S32 getNumFaces(const std::string& filename); + +#ifdef LL_WINDOWS +	S32 ftOpenFace(const std::string& filename, S32 face_n); +	void clearFontStreams(); +#endif  	typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 8cd18c5fa1..b79615e730 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -89,14 +89,24 @@ void LLFontGL::destroyGL()  	mFontFreetype->destroyGL();  } -BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n)  {  	if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL))  	{  		mFontFreetype = new LLFontFreetype;  	} -	return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); +	return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n); +} + +S32 LLFontGL::getNumFaces(const std::string& filename) +{ +	if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL)) +	{ +		mFontFreetype = new LLFontFreetype; +	} + +	return mFontFreetype->getNumFaces(filename);  }  static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts"); diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 7d0e53f60f..10891faed9 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -87,7 +87,9 @@ public:  	void destroyGL(); -	BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); +	BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0); + +	S32 getNumFaces(const std::string& filename);  	S32 render(const LLWString &text, S32 begin_offset,   				const LLRect& rect,  diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 3c829596ce..dbe71e2882 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -44,6 +44,8 @@ using std::map;  bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);  bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node); +const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/"; +  LLFontDescriptor::LLFontDescriptor():  	mStyle(0)  { @@ -61,6 +63,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name,  }  LLFontDescriptor::LLFontDescriptor(const std::string& name, +	const std::string& size, +	const U8 style, +	const string_vec_t& file_names, +	const string_vec_t& ft_collection_listections) : +	LLFontDescriptor(name, size, style, file_names) +{ +	mFontCollectionsList = ft_collection_listections; +} + +LLFontDescriptor::LLFontDescriptor(const std::string& name,  								   const std::string& size,   								   const U8 style):  	mName(name), @@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const  	if (removeSubString(new_name,"Italic"))  		new_style |= LLFontGL::ITALIC; -	return LLFontDescriptor(new_name,new_size,new_style,getFileNames()); +	return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList());  }  LLFontRegistry::LLFontRegistry(bool create_gl_textures) @@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename)  			success = success || init_succ;  		}  	} +  	//if (success)  	//	dump(); @@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc)  		{  			std::string font_file_name = child->getTextContents();  			desc.getFileNames().push_back(font_file_name); +			 +			if (child->hasAttribute("load_collection")) +			{ +				BOOL col = FALSE; +				child->getAttributeBOOL("load_collection", col); +				if (col) +				{ +					desc.getFontCollectionsList().push_back(font_file_name); +				} +			}  		}  		else if (child->hasName("os"))  		{ @@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node)  					match_file_names.insert(match_file_names.begin(),  											desc.getFileNames().begin(),  											desc.getFileNames().end()); + +					string_vec_t collections_list = match_desc->getFontCollectionsList(); +					collections_list.insert(collections_list.begin(), +						desc.getFontCollectionsList().begin(), +						desc.getFontCollectionsList().end()); +  					LLFontDescriptor new_desc = *match_desc;  					new_desc.getFileNames() = match_file_names; +					new_desc.getFontCollectionsList() = collections_list;  					registry->mFontMap.erase(*match_desc);  					registry->mFontMap[new_desc] = NULL;  				} @@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)  	// Build list of font names to look for.  	// Files specified for this font come first, followed by those from the default descriptor.  	string_vec_t file_names = match_desc->getFileNames(); +	string_vec_t ft_collection_list = match_desc->getFontCollectionsList();  	string_vec_t default_file_names;  	LLFontDescriptor default_desc("default",s_template_string,0);  	const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc); @@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)  		file_names.insert(file_names.end(),  						  match_default_desc->getFileNames().begin(),  						  match_default_desc->getFileNames().end()); +		ft_collection_list.insert(ft_collection_list.end(), +			match_default_desc->getFontCollectionsList().begin(), +			match_default_desc->getFontCollectionsList().end());  	}  	// Add ultimate fallback list - generated dynamically on linux, @@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)  		file_name_it != file_names.end();   		++file_name_it)  	{ -		LLFontGL *fontp = new LLFontGL; -		std::string font_path = local_path + *file_name_it; +		LLFontGL *fontp = NULL; +		string_vec_t font_paths; +		font_paths.push_back(local_path + *file_name_it); +		font_paths.push_back(sys_path + *file_name_it); +#if LL_DARWIN +		font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it); +#endif +		 +		bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());  		// *HACK: Fallback fonts don't render, so we can use that to suppress  		// creation of OpenGL textures for test apps. JC  		BOOL is_fallback = !is_first_found || !mCreateGLTextures;  		F32 extra_scale = (is_fallback)?fallback_scale:1.0; -		if (!fontp->loadFace(font_path, extra_scale * point_size, -							 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) +		F32 point_size_scale = extra_scale * point_size; +		bool is_font_loaded = false; +		for(string_vec_t::iterator font_paths_it = font_paths.begin(); +			font_paths_it != font_paths.end(); +			++font_paths_it)  		{ -			font_path = sys_path + *file_name_it; - -			if (!fontp->loadFace(font_path, extra_scale * point_size, -								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) +			fontp = new LLFontGL; +			S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1; +			for (S32 i = 0; i < num_faces; i++)  			{ -				LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL; -				delete fontp; -				fontp = NULL; +				if (fontp == NULL) +				{ +					fontp = new LLFontGL; +				} +				if (fontp->loadFace(*font_paths_it, point_size_scale, +								 LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i)) +				{ +					is_font_loaded = true; +					if (is_first_found) +					{ +						result = fontp; +						is_first_found = false; +					} +					else +					{ +						fontlist.push_back(fontp->mFontFreetype); +						delete fontp; +						fontp = NULL; +					} +				} +				else +				{ +					delete fontp; +					fontp = NULL; +				}  			} +			if (is_font_loaded) break;  		} -		 -		if(fontp) +		if(!is_font_loaded)  		{ -			if (is_first_found) -			{ -				result = fontp; -				is_first_found = false; -			} -			else -			{ -				fontlist.push_back(fontp->mFontFreetype); -				delete fontp; -				fontp = NULL; -			} +			LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it <<  LL_ENDL; +			delete fontp; +			fontp = NULL;  		}  	} diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 177eb6c8a5..e30c81c630 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -40,6 +40,7 @@ public:  	LLFontDescriptor();  	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style);  	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names); +	LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections);  	LLFontDescriptor normalize() const;  	bool operator<(const LLFontDescriptor& b) const; @@ -52,6 +53,8 @@ public:  	void setSize(const std::string& size) { mSize = size; }  	const std::vector<std::string>& getFileNames() const { return mFileNames; }  	std::vector<std::string>& getFileNames() { return mFileNames; } +	const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; } +	std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; }  	const U8 getStyle() const { return mStyle; }  	void setStyle(U8 style) { mStyle = style; } @@ -59,6 +62,7 @@ private:  	std::string mName;  	std::string mSize;  	string_vec_t mFileNames; +	string_vec_t mFontCollectionsList;  	U8 mStyle;  }; | 
