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