1 /*
2  * This source file is part of libRocket, the HTML/CSS Interface Middleware
3  *
4  * For the latest information, see http://www.librocket.com
5  *
6  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  */
27 
28 #include "../precompiled.h"
29 #include <Rocket/Core/BitmapFont/FontProvider.h>
30 #include "../FontFaceHandle.h"
31 #include <Rocket/Core/FontDatabase.h>
32 #include <Rocket/Core/StreamMemory.h>
33 #include "FontFamily.h"
34 #include <Rocket/Core.h>
35 #include "BitmapFontDefinitions.h"
36 #include "FontParser.h"
37 
38 namespace Rocket {
39 namespace Core {
40 namespace BitmapFont {
41 
42 
43 FontProvider* FontProvider::instance = NULL;
44 
FontProvider()45 FontProvider::FontProvider()
46 {
47 	ROCKET_ASSERT(instance == NULL);
48 	instance = this;
49 }
50 
~FontProvider()51 FontProvider::~FontProvider()
52 {
53 	ROCKET_ASSERT(instance == this);
54 	instance = NULL;
55 }
56 
Initialise()57 bool FontProvider::Initialise()
58 {
59 	if (instance == NULL)
60 	{
61 		new FontProvider();
62 
63 		FontDatabase::AddFontProvider(instance);
64 	}
65 
66 	return true;
67 }
68 
Shutdown()69 void FontProvider::Shutdown()
70 {
71 	if (instance != NULL)
72 	{
73 		FontDatabase::RemoveFontProvider(instance);
74 		delete instance;
75 		instance = NULL;
76 	}
77 }
78 
79 // Adds a new font face to the database, ignoring any family, style and weight information stored in the face itself.
LoadFontFace(const String & file_name)80 bool FontProvider::LoadFontFace(const String& file_name)
81 {
82 	BitmapFontDefinitions *bm_font = (BitmapFontDefinitions*) instance->LoadFace(file_name);
83 
84 	if (bm_font == NULL)
85 	{
86 		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
87 		return false;
88 	}
89 
90 	Font::Style style = bm_font->Face.Style;
91 	Font::Weight weight = bm_font->Face.Weight;
92 
93 	if (instance->AddFace(bm_font, bm_font->Face.FamilyName, style, weight, true))
94 	{
95 		Log::Message(Log::LT_INFO, "Loaded font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
96 		return true;
97 	}
98 	else
99 	{
100 		Log::Message(Log::LT_ERROR, "Failed to load font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
101 		return false;
102 	}
103 
104 	return true;
105 }
106 
107 // Loads a new font face.
LoadFontFace(const String & file_name,const String & family,Font::Style style,Font::Weight weight)108 bool FontProvider::LoadFontFace(const String& file_name, const String& family, Font::Style style, Font::Weight weight)
109 {
110 	BitmapFontDefinitions *bm_font = (BitmapFontDefinitions*) instance->LoadFace(file_name);
111 	if (bm_font == NULL)
112 	{
113 		Log::Message(Log::LT_ERROR, "Failed to load font face from %s.", file_name.CString());
114 		return false;
115 	}
116 
117 	if (instance->AddFace(bm_font, family, style, weight, true))
118 	{
119 		Log::Message(Log::LT_INFO, "Loaded font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
120 		return true;
121 	}
122 	else
123 	{
124 		Log::Message(Log::LT_ERROR, "Failed to load font face %s (from %s).", bm_font->Face.FamilyName.CString(), file_name.CString());
125 		return false;
126 	}
127 
128 	return true;
129 }
130 
LoadFontFace(const byte * data,int data_length)131 bool FontProvider::LoadFontFace(const byte* data, int data_length)
132 {
133 	// TODO: Loading from memory
134 	return false;
135 }
136 
137 // Adds a new font face to the database, loading from memory.
LoadFontFace(const byte * data,int data_length,const String & family,Font::Style style,Font::Weight weight)138 bool FontProvider::LoadFontFace(const byte* data, int data_length, const String& family, Font::Style style, Font::Weight weight)
139 {
140 	// TODO Loading from memory
141 	return false;
142 }
143 
144 // Adds a loaded face to the appropriate font family.
AddFace(void * face,const String & family,Font::Style style,Font::Weight weight,bool release_stream)145 bool FontProvider::AddFace(void* face, const String& family, Font::Style style, Font::Weight weight, bool release_stream)
146 {
147 	Rocket::Core::FontFamily* font_family = NULL;
148 	FontFamilyMap::iterator iterator = instance->font_families.find(family);
149 	if (iterator != instance->font_families.end())
150 		font_family = (*iterator).second;
151 	else
152 	{
153 		font_family = new FontFamily(family);
154 		instance->font_families[family] = font_family;
155 	}
156 
157 	return font_family->AddFace((BitmapFontDefinitions *) face, style, weight, release_stream);
158 	return true;
159 }
160 
161 // Loads a FreeType face.
LoadFace(const String & file_name)162 void* FontProvider::LoadFace(const String& file_name)
163 {
164 	BitmapFontDefinitions *bm_face = new BitmapFontDefinitions();
165 	FontParser parser( bm_face );
166 
167 	FileInterface* file_interface = GetFileInterface();
168 	FileHandle handle = file_interface->Open(file_name);
169 
170 	if (!handle)
171 	{
172 		return NULL;
173 	}
174 
175 	size_t length = file_interface->Length(handle);
176 
177 	byte* buffer = new byte[length];
178 	file_interface->Read(buffer, length, handle);
179 	file_interface->Close(handle);
180 
181 	StreamMemory* stream = new StreamMemory( buffer, length );
182 	stream->SetSourceURL( file_name );
183 
184 	parser.Parse( stream );
185 
186 	bm_face->Face.Source = file_name;
187 	return bm_face;
188 }
189 
190 // Loads a FreeType face from memory.
LoadFace(const byte * data,int data_length,const String & source,bool local_data)191 void* FontProvider::LoadFace(const byte* data, int data_length, const String& source, bool local_data)
192 {
193 	URL file_url = source + ".fnt";
194 
195 	BitmapFontDefinitions *bm_face = new BitmapFontDefinitions();
196 	FontParser parser( bm_face );
197 	StreamMemory* stream = new StreamMemory( data, data_length );
198 	stream->SetSourceURL( file_url );
199 
200 	parser.Parse( stream );
201 
202 	bm_face->Face.Source = file_url.GetPathedFileName();
203 	return bm_face;
204 }
205 
206 }
207 }
208 }
209