summaryrefslogtreecommitdiff
path: root/doc/html/FontLoader_8cpp-source.htm
blob: 56fdf0873f4713c2968b7c8552a71eb2fdf843de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>SFML - Simple and Fast Multimedia Library</title>
        <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
        <link href="doxygen.css" rel="stylesheet" type="text/css" />
        <link href="tabs.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <div id="logo">
            <img src="./logo.jpg" width="770" height="200" title="SFML home" alt="SFML logo" />
        </div>
<!-- Generated by Doxygen 1.5.8 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.htm"><span>Main&nbsp;Page</span></a></li>
      <li><a href="namespaces.htm"><span>Namespaces</span></a></li>
      <li><a href="annotated.htm"><span>Classes</span></a></li>
      <li class="current"><a href="files.htm"><span>Files</span></a></li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.htm"><span>File&nbsp;List</span></a></li>
    </ul>
  </div>
<h1>FontLoader.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 
<a name="l00002"></a>00002 <span class="comment">//</span>
<a name="l00003"></a>00003 <span class="comment">// SFML - Simple and Fast Multimedia Library</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)</span>
<a name="l00005"></a>00005 <span class="comment">//</span>
<a name="l00006"></a>00006 <span class="comment">// This software is provided 'as-is', without any express or implied warranty.</span>
<a name="l00007"></a>00007 <span class="comment">// In no event will the authors be held liable for any damages arising from the use of this software.</span>
<a name="l00008"></a>00008 <span class="comment">//</span>
<a name="l00009"></a>00009 <span class="comment">// Permission is granted to anyone to use this software for any purpose,</span>
<a name="l00010"></a>00010 <span class="comment">// including commercial applications, and to alter it and redistribute it freely,</span>
<a name="l00011"></a>00011 <span class="comment">// subject to the following restrictions:</span>
<a name="l00012"></a>00012 <span class="comment">//</span>
<a name="l00013"></a>00013 <span class="comment">// 1. The origin of this software must not be misrepresented;</span>
<a name="l00014"></a>00014 <span class="comment">//    you must not claim that you wrote the original software.</span>
<a name="l00015"></a>00015 <span class="comment">//    If you use this software in a product, an acknowledgment</span>
<a name="l00016"></a>00016 <span class="comment">//    in the product documentation would be appreciated but is not required.</span>
<a name="l00017"></a>00017 <span class="comment">//</span>
<a name="l00018"></a>00018 <span class="comment">// 2. Altered source versions must be plainly marked as such,</span>
<a name="l00019"></a>00019 <span class="comment">//    and must not be misrepresented as being the original software.</span>
<a name="l00020"></a>00020 <span class="comment">//</span>
<a name="l00021"></a>00021 <span class="comment">// 3. This notice may not be removed or altered from any source distribution.</span>
<a name="l00022"></a>00022 <span class="comment">//</span>
<a name="l00024"></a>00024 <span class="comment"></span>
<a name="l00026"></a>00026 <span class="comment">// Headers</span>
<a name="l00028"></a>00028 <span class="comment"></span><span class="preprocessor">#include &lt;SFML/Graphics/FontLoader.hpp&gt;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include &lt;SFML/Graphics/Color.hpp&gt;</span>
<a name="l00030"></a>00030 <span class="preprocessor">#include &lt;SFML/Graphics/Font.hpp&gt;</span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &lt;SFML/Graphics/Image.hpp&gt;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &lt;SFML/Graphics/GraphicsContext.hpp&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include FT_GLYPH_H</span>
<a name="l00034"></a>00034 <span class="preprocessor"></span><span class="preprocessor">#include &lt;iostream&gt;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#include &lt;map&gt;</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include &lt;vector&gt;</span>
<a name="l00037"></a>00037 <span class="preprocessor">#include &lt;math.h&gt;</span>
<a name="l00038"></a>00038 
<a name="l00039"></a>00039 
<a name="l00040"></a>00040 <span class="keyword">namespace</span>
<a name="l00041"></a>00041 {
<a name="l00043"></a>00043     <span class="comment">// Functor to sort glyphs by size</span>
<a name="l00045"></a>00045 <span class="comment"></span>    <span class="keyword">struct </span>SizeCompare
<a name="l00046"></a>00046     {
<a name="l00047"></a>00047         <span class="keywordtype">bool</span> operator ()(FT_BitmapGlyph Glyph1, FT_BitmapGlyph Glyph2)<span class="keyword"> const</span>
<a name="l00048"></a>00048 <span class="keyword">        </span>{
<a name="l00049"></a>00049             <span class="keywordflow">return</span> Glyph2-&gt;bitmap.rows &lt; Glyph1-&gt;bitmap.rows;
<a name="l00050"></a>00050         }
<a name="l00051"></a>00051     };
<a name="l00052"></a>00052 }
<a name="l00053"></a>00053 
<a name="l00054"></a>00054 <span class="keyword">namespace </span>sf
<a name="l00055"></a>00055 {
<a name="l00056"></a>00056 <span class="keyword">namespace </span>priv
<a name="l00057"></a>00057 {
<a name="l00061"></a>00061 FontLoader&amp; FontLoader::GetInstance()
<a name="l00062"></a>00062 {
<a name="l00063"></a>00063     <span class="keyword">static</span> FontLoader Instance;
<a name="l00064"></a>00064 
<a name="l00065"></a>00065     <span class="keywordflow">return</span> Instance;
<a name="l00066"></a>00066 }
<a name="l00067"></a>00067 
<a name="l00068"></a>00068 
<a name="l00072"></a>00072 FontLoader::FontLoader()
<a name="l00073"></a>00073 {
<a name="l00074"></a>00074     <span class="comment">// Initialize FreeType library</span>
<a name="l00075"></a>00075     FT_Error Error = FT_Init_FreeType(&amp;myLibrary);
<a name="l00076"></a>00076     <span class="keywordflow">if</span> (Error)
<a name="l00077"></a>00077     {
<a name="l00078"></a>00078         std::cerr &lt;&lt; <span class="stringliteral">"Failed to initialize FreeType library (error code : "</span> &lt;&lt; Error &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; std::endl;
<a name="l00079"></a>00079         <span class="keywordflow">return</span>;
<a name="l00080"></a>00080     }
<a name="l00081"></a>00081 }
<a name="l00082"></a>00082 
<a name="l00083"></a>00083 
<a name="l00087"></a>00087 FontLoader::~FontLoader()
<a name="l00088"></a>00088 {
<a name="l00089"></a>00089     <span class="comment">// Shutdown FreeType library</span>
<a name="l00090"></a>00090     <span class="keywordflow">if</span> (myLibrary)
<a name="l00091"></a>00091         FT_Done_FreeType(myLibrary);
<a name="l00092"></a>00092 }
<a name="l00093"></a>00093 
<a name="l00094"></a>00094 
<a name="l00098"></a>00098 <span class="keywordtype">bool</span> FontLoader::LoadFontFromFile(<span class="keyword">const</span> std::string&amp; Filename, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CharSize, <span class="keyword">const</span> Unicode::UTF32String&amp; Charset, Font&amp; LoadedFont)
<a name="l00099"></a>00099 {
<a name="l00100"></a>00100     <span class="comment">// Check if Freetype is correctly initialized</span>
<a name="l00101"></a>00101     <span class="keywordflow">if</span> (!myLibrary)
<a name="l00102"></a>00102     {
<a name="l00103"></a>00103         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font \""</span> &lt;&lt; Filename &lt;&lt; <span class="stringliteral">"\", FreeType has not been initialized"</span> &lt;&lt; std::endl;
<a name="l00104"></a>00104         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00105"></a>00105     }
<a name="l00106"></a>00106 
<a name="l00107"></a>00107     <span class="comment">// Create a new font face from the specified file</span>
<a name="l00108"></a>00108     FT_Face FontFace;
<a name="l00109"></a>00109     FT_Error Error = FT_New_Face(myLibrary, Filename.c_str(), 0, &amp;FontFace);
<a name="l00110"></a>00110     <span class="keywordflow">if</span> (Error)
<a name="l00111"></a>00111     {
<a name="l00112"></a>00112         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font \""</span> &lt;&lt; Filename &lt;&lt; <span class="stringliteral">"\" ("</span> &lt;&lt; GetErrorDesc(Error) &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; std::endl;
<a name="l00113"></a>00113         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00114"></a>00114     }
<a name="l00115"></a>00115 
<a name="l00116"></a>00116     <span class="comment">// Create the bitmap font</span>
<a name="l00117"></a>00117     Error = CreateBitmapFont(FontFace, CharSize, Charset, LoadedFont);
<a name="l00118"></a>00118     <span class="keywordflow">if</span> (Error)
<a name="l00119"></a>00119         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font \""</span> &lt;&lt; Filename &lt;&lt; <span class="stringliteral">"\" ("</span> &lt;&lt; GetErrorDesc(Error) &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; std::endl;
<a name="l00120"></a>00120 
<a name="l00121"></a>00121     <span class="comment">// Delete the font</span>
<a name="l00122"></a>00122     FT_Done_Face(FontFace);
<a name="l00123"></a>00123 
<a name="l00124"></a>00124     <span class="keywordflow">return</span> Error == 0;
<a name="l00125"></a>00125 }
<a name="l00126"></a>00126 
<a name="l00127"></a>00127 
<a name="l00131"></a>00131 <span class="keywordtype">bool</span> FontLoader::LoadFontFromMemory(<span class="keyword">const</span> <span class="keywordtype">char</span>* Data, std::size_t SizeInBytes, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CharSize, <span class="keyword">const</span> Unicode::UTF32String&amp; Charset, Font&amp; LoadedFont)
<a name="l00132"></a>00132 {
<a name="l00133"></a>00133     <span class="comment">// Check if Freetype is correctly initialized</span>
<a name="l00134"></a>00134     <span class="keywordflow">if</span> (!myLibrary)
<a name="l00135"></a>00135     {
<a name="l00136"></a>00136         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font from memory, FreeType has not been initialized"</span> &lt;&lt; std::endl;
<a name="l00137"></a>00137         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00138"></a>00138     }
<a name="l00139"></a>00139 
<a name="l00140"></a>00140     <span class="comment">// Create a new font face from the specified memory data</span>
<a name="l00141"></a>00141     FT_Face FontFace;
<a name="l00142"></a>00142     FT_Error Error = FT_New_Memory_Face(myLibrary, reinterpret_cast&lt;const FT_Byte*&gt;(Data), static_cast&lt;FT_Long&gt;(SizeInBytes), 0, &amp;FontFace);
<a name="l00143"></a>00143     <span class="keywordflow">if</span> (Error)
<a name="l00144"></a>00144     {
<a name="l00145"></a>00145         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font from memory ("</span> &lt;&lt; GetErrorDesc(Error) &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; std::endl;
<a name="l00146"></a>00146         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00147"></a>00147     }
<a name="l00148"></a>00148 
<a name="l00149"></a>00149     <span class="comment">// Create the bitmap font</span>
<a name="l00150"></a>00150     Error = CreateBitmapFont(FontFace, CharSize, Charset, LoadedFont);
<a name="l00151"></a>00151     <span class="keywordflow">if</span> (Error)
<a name="l00152"></a>00152         std::cerr &lt;&lt; <span class="stringliteral">"Failed to load font from memory ("</span> &lt;&lt; GetErrorDesc(Error) &lt;&lt; <span class="stringliteral">")"</span> &lt;&lt; std::endl;
<a name="l00153"></a>00153 
<a name="l00154"></a>00154     <span class="comment">// Delete the font</span>
<a name="l00155"></a>00155     FT_Done_Face(FontFace);
<a name="l00156"></a>00156 
<a name="l00157"></a>00157     <span class="keywordflow">return</span> Error == 0;
<a name="l00158"></a>00158 }
<a name="l00159"></a>00159 
<a name="l00160"></a>00160 
<a name="l00164"></a>00164 FT_Error FontLoader::CreateBitmapFont(FT_Face FontFace, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CharSize, <span class="keyword">const</span> Unicode::UTF32String&amp; Charset, Font&amp; LoadedFont)
<a name="l00165"></a>00165 {
<a name="l00166"></a>00166     <span class="comment">// Make sure we have a valid context</span>
<a name="l00167"></a>00167     priv::GraphicsContext Ctx;
<a name="l00168"></a>00168 
<a name="l00169"></a>00169     <span class="comment">// Let's find how many characters to put in each row to make them fit into a squared texture</span>
<a name="l00170"></a>00170     GLint MaxSize;
<a name="l00171"></a>00171     GLCheck(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &amp;MaxSize));
<a name="l00172"></a>00172     <span class="keywordtype">int</span> NbChars = <span class="keyword">static_cast&lt;</span><span class="keywordtype">int</span><span class="keyword">&gt;</span>(sqrt(static_cast&lt;double&gt;(Charset.length())) * 0.75);
<a name="l00173"></a>00173 
<a name="l00174"></a>00174     <span class="comment">// Clamp the character size to make sure we won't create a texture too big</span>
<a name="l00175"></a>00175     <span class="keywordflow">if</span> (NbChars * CharSize &gt;= static_cast&lt;unsigned int&gt;(MaxSize))
<a name="l00176"></a>00176         CharSize = MaxSize / NbChars;
<a name="l00177"></a>00177 
<a name="l00178"></a>00178     <span class="comment">// Initialize the dimensions</span>
<a name="l00179"></a>00179     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="namespacesf_1_1Key.htm#d32ed01d3448273340bd25af5cdd9c811b48e9fd546b2afdcbb64ae95047be94" title="Left arrow.">Left</a>      = 0;
<a name="l00180"></a>00180     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Top       = 0;
<a name="l00181"></a>00181     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TexWidth  = <a class="code" href="classsf_1_1Image.htm#b41056600a1a4848833cc8b5239a9488" title="Get a valid texture size according to hardware support.">Image::GetValidTextureSize</a>(CharSize * NbChars);
<a name="l00182"></a>00182     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TexHeight = CharSize * NbChars;
<a name="l00183"></a>00183     std::vector&lt;unsigned int&gt; Tops(TexWidth, 0);
<a name="l00184"></a>00184 
<a name="l00185"></a>00185     <span class="comment">// Create a pixel buffer for rendering every glyph</span>
<a name="l00186"></a>00186     std::vector&lt;Uint8&gt; GlyphsBuffer(TexWidth * TexHeight * 4);
<a name="l00187"></a>00187 
<a name="l00188"></a>00188     <span class="comment">// Setup the font size</span>
<a name="l00189"></a>00189     FT_Error Error = FT_Set_Pixel_Sizes(FontFace, CharSize, CharSize);
<a name="l00190"></a>00190     <span class="keywordflow">if</span> (Error)
<a name="l00191"></a>00191         <span class="keywordflow">return</span> Error;
<a name="l00192"></a>00192 
<a name="l00193"></a>00193     <span class="comment">// Select the unicode character map</span>
<a name="l00194"></a>00194     Error = FT_Select_Charmap(FontFace, FT_ENCODING_UNICODE);
<a name="l00195"></a>00195     <span class="keywordflow">if</span> (Error)
<a name="l00196"></a>00196         <span class="keywordflow">return</span> Error;
<a name="l00197"></a>00197 
<a name="l00198"></a>00198     <span class="comment">// Render all glyphs and sort them by size to optimize texture space</span>
<a name="l00199"></a>00199     <span class="keyword">typedef</span> std::multimap&lt;FT_BitmapGlyph, Uint32, SizeCompare&gt; GlyphTable;
<a name="l00200"></a>00200     GlyphTable Glyphs;
<a name="l00201"></a>00201     <span class="keywordflow">for</span> (std::size_t i = 0; i &lt; Charset.length(); ++i)
<a name="l00202"></a>00202     {
<a name="l00203"></a>00203         <span class="comment">// Load the glyph corresponding to the current character</span>
<a name="l00204"></a>00204         Error = FT_Load_Char(FontFace, Charset[i], FT_LOAD_TARGET_NORMAL);
<a name="l00205"></a>00205         <span class="keywordflow">if</span> (Error)
<a name="l00206"></a>00206             <span class="keywordflow">return</span> Error;
<a name="l00207"></a>00207 
<a name="l00208"></a>00208         <span class="comment">// Convert the glyph to a bitmap (ie. rasterize it)</span>
<a name="l00209"></a>00209         FT_Glyph Glyph;
<a name="l00210"></a>00210         Error = FT_Get_Glyph(FontFace-&gt;glyph, &amp;Glyph);
<a name="l00211"></a>00211         <span class="keywordflow">if</span> (Error)
<a name="l00212"></a>00212             <span class="keywordflow">return</span> Error;
<a name="l00213"></a>00213         FT_Glyph_To_Bitmap(&amp;Glyph, FT_RENDER_MODE_NORMAL, 0, 1);
<a name="l00214"></a>00214         FT_BitmapGlyph BitmapGlyph = (FT_BitmapGlyph)Glyph;
<a name="l00215"></a>00215 
<a name="l00216"></a>00216         <span class="comment">// Add it to the sorted table of glyphs</span>
<a name="l00217"></a>00217         Glyphs.insert(std::make_pair(BitmapGlyph, Charset[i]));
<a name="l00218"></a>00218     }
<a name="l00219"></a>00219 
<a name="l00220"></a>00220     <span class="comment">// Copy the rendered glyphs into the texture</span>
<a name="l00221"></a>00221     <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxHeight = 0;
<a name="l00222"></a>00222     std::map&lt;Uint32, IntRect&gt; Coords;
<a name="l00223"></a>00223     <span class="keywordflow">for</span> (GlyphTable::const_iterator i = Glyphs.begin(); i != Glyphs.end(); ++i)
<a name="l00224"></a>00224     {
<a name="l00225"></a>00225         <span class="comment">// Get the bitmap of the current glyph</span>
<a name="l00226"></a>00226         Glyph&amp;         CurGlyph    = LoadedFont.myGlyphs[i-&gt;second];
<a name="l00227"></a>00227         FT_BitmapGlyph BitmapGlyph = i-&gt;first;
<a name="l00228"></a>00228         FT_Bitmap&amp;     Bitmap      = BitmapGlyph-&gt;bitmap;
<a name="l00229"></a>00229 
<a name="l00230"></a>00230         <span class="comment">// Make sure we don't go over the texture width</span>
<a name="l00231"></a>00231         <span class="keywordflow">if</span> (Left + Bitmap.width + 1 &gt;= TexWidth)
<a name="l00232"></a>00232             Left = 0;
<a name="l00233"></a>00233 
<a name="l00234"></a>00234         <span class="comment">// Compute the top coordinate</span>
<a name="l00235"></a>00235         Top = Tops[Left];
<a name="l00236"></a>00236         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> x = 0; x &lt; Bitmap.width + 1; ++x)
<a name="l00237"></a>00237             Top = std::max(Top, Tops[Left + x]);
<a name="l00238"></a>00238         Top++;
<a name="l00239"></a>00239 
<a name="l00240"></a>00240         <span class="comment">// Make sure we don't go over the texture height -- resize it if we need more space</span>
<a name="l00241"></a>00241         <span class="keywordflow">if</span> (Top + Bitmap.rows + 1 &gt;= TexHeight)
<a name="l00242"></a>00242         {
<a name="l00243"></a>00243             TexHeight *= 2;
<a name="l00244"></a>00244             GlyphsBuffer.resize(TexWidth * TexHeight * 4);
<a name="l00245"></a>00245         }
<a name="l00246"></a>00246 
<a name="l00247"></a>00247         <span class="comment">// Store the character's position and size</span>
<a name="l00248"></a>00248         CurGlyph.Rectangle.Left   = BitmapGlyph-&gt;left;
<a name="l00249"></a>00249         CurGlyph.Rectangle.Top    = -BitmapGlyph-&gt;top;
<a name="l00250"></a>00250         CurGlyph.Rectangle.Right  = CurGlyph.Rectangle.Left + Bitmap.width;
<a name="l00251"></a>00251         CurGlyph.Rectangle.Bottom = Bitmap.rows - BitmapGlyph-&gt;top;
<a name="l00252"></a>00252         CurGlyph.Advance          = BitmapGlyph-&gt;root.advance.x &gt;&gt; 16;
<a name="l00253"></a>00253 
<a name="l00254"></a>00254         <span class="comment">// Texture size may change, so let the texture coordinates be calculated later</span>
<a name="l00255"></a>00255         Coords[i-&gt;second] = IntRect(Left + 1, Top + 1, Left + Bitmap.width + 1, Top + Bitmap.rows + 1);
<a name="l00256"></a>00256 
<a name="l00257"></a>00257         <span class="comment">// Draw the glyph into our bitmap font</span>
<a name="l00258"></a>00258         <span class="keyword">const</span> Uint8* Pixels = Bitmap.buffer;
<a name="l00259"></a>00259         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> y = 0; y &lt; Bitmap.rows; ++y)
<a name="l00260"></a>00260         {
<a name="l00261"></a>00261             <span class="keywordflow">for</span> (<span class="keywordtype">int</span> x = 0; x &lt; Bitmap.width; ++x)
<a name="l00262"></a>00262             {
<a name="l00263"></a>00263                 std::size_t Index = x + Left + 1 + (y + Top + 1) * TexWidth;
<a name="l00264"></a>00264                 GlyphsBuffer[Index * 4 + 0] = 255;
<a name="l00265"></a>00265                 GlyphsBuffer[Index * 4 + 1] = 255;
<a name="l00266"></a>00266                 GlyphsBuffer[Index * 4 + 2] = 255;
<a name="l00267"></a>00267                 GlyphsBuffer[Index * 4 + 3] = Pixels[x];
<a name="l00268"></a>00268             }
<a name="l00269"></a>00269             Pixels += Bitmap.pitch;
<a name="l00270"></a>00270         }
<a name="l00271"></a>00271 
<a name="l00272"></a>00272         <span class="comment">// Update the rendering coordinates</span>
<a name="l00273"></a>00273         <span class="keywordflow">for</span> (<span class="keywordtype">int</span> x = 0; x &lt; Bitmap.width + 1; ++x)
<a name="l00274"></a>00274             Tops[Left + x] = Top + Bitmap.rows;
<a name="l00275"></a>00275         Left += Bitmap.width + 1;
<a name="l00276"></a>00276         if (Top + Bitmap.rows &gt; MaxHeight)
<a name="l00277"></a>00277             MaxHeight = Top + Bitmap.rows;
<a name="l00278"></a>00278 
<a name="l00279"></a>00279         <span class="comment">// Delete the glyph</span>
<a name="l00280"></a>00280         FT_Done_Glyph((FT_Glyph)BitmapGlyph);
<a name="l00281"></a>00281     }
<a name="l00282"></a>00282 
<a name="l00283"></a>00283     <span class="comment">// Create the font's texture</span>
<a name="l00284"></a>00284     TexHeight = MaxHeight + 1;
<a name="l00285"></a>00285     GlyphsBuffer.resize(TexWidth * TexHeight * 4);
<a name="l00286"></a>00286     LoadedFont.myTexture.LoadFromPixels(TexWidth, TexHeight, &amp;GlyphsBuffer[0]);
<a name="l00287"></a>00287 
<a name="l00288"></a>00288     <span class="comment">// Now that the texture is created, we can precompute texture coordinates</span>
<a name="l00289"></a>00289     <span class="keywordflow">for</span> (std::size_t i = 0; i &lt; Charset.size(); ++i)
<a name="l00290"></a>00290     {
<a name="l00291"></a>00291         Uint32 CurChar = Charset[i];
<a name="l00292"></a>00292         LoadedFont.myGlyphs[CurChar].TexCoords = LoadedFont.myTexture.GetTexCoords(Coords[CurChar]);
<a name="l00293"></a>00293     }
<a name="l00294"></a>00294 
<a name="l00295"></a>00295     <span class="comment">// Update the character size (it may have been changed by the function)</span>
<a name="l00296"></a>00296     LoadedFont.myCharSize = CharSize;
<a name="l00297"></a>00297 
<a name="l00298"></a>00298     <span class="keywordflow">return</span> 0;
<a name="l00299"></a>00299 }
<a name="l00300"></a>00300 
<a name="l00301"></a>00301 
<a name="l00305"></a>00305 std::string FontLoader::GetErrorDesc(FT_Error Error)
<a name="l00306"></a>00306 {
<a name="l00307"></a>00307     <span class="keywordflow">switch</span> (Error)
<a name="l00308"></a>00308     {
<a name="l00309"></a>00309         <span class="comment">// Generic errors</span>
<a name="l00310"></a>00310         <span class="keywordflow">case</span> FT_Err_Cannot_Open_Resource :      <span class="keywordflow">return</span> <span class="stringliteral">"cannot open resource"</span>;
<a name="l00311"></a>00311         <span class="keywordflow">case</span> FT_Err_Unknown_File_Format :       <span class="keywordflow">return</span> <span class="stringliteral">"unknown file format"</span>;
<a name="l00312"></a>00312         <span class="keywordflow">case</span> FT_Err_Invalid_File_Format :       <span class="keywordflow">return</span> <span class="stringliteral">"broken file"</span>;
<a name="l00313"></a>00313         <span class="keywordflow">case</span> FT_Err_Invalid_Version :           <span class="keywordflow">return</span> <span class="stringliteral">"invalid FreeType version"</span>;
<a name="l00314"></a>00314         <span class="keywordflow">case</span> FT_Err_Lower_Module_Version :      <span class="keywordflow">return</span> <span class="stringliteral">"module version is too low"</span>;
<a name="l00315"></a>00315         <span class="keywordflow">case</span> FT_Err_Invalid_Argument :          <span class="keywordflow">return</span> <span class="stringliteral">"invalid argument"</span>;
<a name="l00316"></a>00316         <span class="keywordflow">case</span> FT_Err_Unimplemented_Feature :     <span class="keywordflow">return</span> <span class="stringliteral">"unimplemented feature"</span>;
<a name="l00317"></a>00317         <span class="keywordflow">case</span> FT_Err_Invalid_Table :             <span class="keywordflow">return</span> <span class="stringliteral">"broken table"</span>;
<a name="l00318"></a>00318         <span class="keywordflow">case</span> FT_Err_Invalid_Offset :            <span class="keywordflow">return</span> <span class="stringliteral">"broken offset within table"</span>;
<a name="l00319"></a>00319 
<a name="l00320"></a>00320         <span class="comment">// Glyph / character errors</span>
<a name="l00321"></a>00321         <span class="keywordflow">case</span> FT_Err_Invalid_Glyph_Index :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid glyph index"</span>;
<a name="l00322"></a>00322         <span class="keywordflow">case</span> FT_Err_Invalid_Character_Code :    <span class="keywordflow">return</span> <span class="stringliteral">"invalid character code"</span>;
<a name="l00323"></a>00323         <span class="keywordflow">case</span> FT_Err_Invalid_Glyph_Format :      <span class="keywordflow">return</span> <span class="stringliteral">"unsupported glyph image format"</span>;
<a name="l00324"></a>00324         <span class="keywordflow">case</span> FT_Err_Cannot_Render_Glyph :       <span class="keywordflow">return</span> <span class="stringliteral">"cannot render this glyph format"</span>;
<a name="l00325"></a>00325         <span class="keywordflow">case</span> FT_Err_Invalid_Outline :           <span class="keywordflow">return</span> <span class="stringliteral">"invalid outline"</span>;
<a name="l00326"></a>00326         <span class="keywordflow">case</span> FT_Err_Invalid_Composite :         <span class="keywordflow">return</span> <span class="stringliteral">"invalid composite glyph"</span>;
<a name="l00327"></a>00327         <span class="keywordflow">case</span> FT_Err_Too_Many_Hints :            <span class="keywordflow">return</span> <span class="stringliteral">"too many hints"</span>;
<a name="l00328"></a>00328         <span class="keywordflow">case</span> FT_Err_Invalid_Pixel_Size :        <span class="keywordflow">return</span> <span class="stringliteral">"invalid pixel size"</span>;
<a name="l00329"></a>00329 
<a name="l00330"></a>00330         <span class="comment">// Handle errors</span>
<a name="l00331"></a>00331         <span class="keywordflow">case</span> FT_Err_Invalid_Handle :            <span class="keywordflow">return</span> <span class="stringliteral">"invalid object handle"</span>;
<a name="l00332"></a>00332         <span class="keywordflow">case</span> FT_Err_Invalid_Library_Handle :    <span class="keywordflow">return</span> <span class="stringliteral">"invalid library handle"</span>;
<a name="l00333"></a>00333         <span class="keywordflow">case</span> FT_Err_Invalid_Driver_Handle :     <span class="keywordflow">return</span> <span class="stringliteral">"invalid module handle"</span>;
<a name="l00334"></a>00334         <span class="keywordflow">case</span> FT_Err_Invalid_Face_Handle :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid face handle"</span>;
<a name="l00335"></a>00335         <span class="keywordflow">case</span> FT_Err_Invalid_Size_Handle :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid size handle"</span>;
<a name="l00336"></a>00336         <span class="keywordflow">case</span> FT_Err_Invalid_Slot_Handle :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid glyph slot handle"</span>;
<a name="l00337"></a>00337         <span class="keywordflow">case</span> FT_Err_Invalid_CharMap_Handle :    <span class="keywordflow">return</span> <span class="stringliteral">"invalid charmap handle"</span>;
<a name="l00338"></a>00338         <span class="keywordflow">case</span> FT_Err_Invalid_Cache_Handle :      <span class="keywordflow">return</span> <span class="stringliteral">"invalid cache manager handle"</span>;
<a name="l00339"></a>00339         <span class="keywordflow">case</span> FT_Err_Invalid_Stream_Handle :     <span class="keywordflow">return</span> <span class="stringliteral">"invalid stream handle"</span>;
<a name="l00340"></a>00340 
<a name="l00341"></a>00341         <span class="comment">// Driver errors</span>
<a name="l00342"></a>00342         <span class="keywordflow">case</span> FT_Err_Too_Many_Drivers :          <span class="keywordflow">return</span> <span class="stringliteral">"too many modules"</span>;
<a name="l00343"></a>00343         <span class="keywordflow">case</span> FT_Err_Too_Many_Extensions :       <span class="keywordflow">return</span> <span class="stringliteral">"too many extensions"</span>;
<a name="l00344"></a>00344 
<a name="l00345"></a>00345         <span class="comment">// Memory errors</span>
<a name="l00346"></a>00346         <span class="keywordflow">case</span> FT_Err_Out_Of_Memory :             <span class="keywordflow">return</span> <span class="stringliteral">"out of memory"</span>;
<a name="l00347"></a>00347         <span class="keywordflow">case</span> FT_Err_Unlisted_Object :           <span class="keywordflow">return</span> <span class="stringliteral">"unlisted object"</span>;
<a name="l00348"></a>00348 
<a name="l00349"></a>00349         <span class="comment">// Stream errors</span>
<a name="l00350"></a>00350         <span class="keywordflow">case</span> FT_Err_Cannot_Open_Stream :        <span class="keywordflow">return</span> <span class="stringliteral">"cannot open stream"</span>;
<a name="l00351"></a>00351         <span class="keywordflow">case</span> FT_Err_Invalid_Stream_Seek :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid stream seek"</span>;
<a name="l00352"></a>00352         <span class="keywordflow">case</span> FT_Err_Invalid_Stream_Skip :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid stream skip"</span>;
<a name="l00353"></a>00353         <span class="keywordflow">case</span> FT_Err_Invalid_Stream_Read :       <span class="keywordflow">return</span> <span class="stringliteral">"invalid stream read"</span>;
<a name="l00354"></a>00354         <span class="keywordflow">case</span> FT_Err_Invalid_Stream_Operation :  <span class="keywordflow">return</span> <span class="stringliteral">"invalid stream operation"</span>;
<a name="l00355"></a>00355         <span class="keywordflow">case</span> FT_Err_Invalid_Frame_Operation :   <span class="keywordflow">return</span> <span class="stringliteral">"invalid frame operation"</span>;
<a name="l00356"></a>00356         <span class="keywordflow">case</span> FT_Err_Nested_Frame_Access :       <span class="keywordflow">return</span> <span class="stringliteral">"nested frame access"</span>;
<a name="l00357"></a>00357         <span class="keywordflow">case</span> FT_Err_Invalid_Frame_Read :        <span class="keywordflow">return</span> <span class="stringliteral">"invalid frame read"</span>;
<a name="l00358"></a>00358 
<a name="l00359"></a>00359         <span class="comment">// Raster errors</span>
<a name="l00360"></a>00360         <span class="keywordflow">case</span> FT_Err_Raster_Uninitialized :      <span class="keywordflow">return</span> <span class="stringliteral">"raster uninitialized"</span>;
<a name="l00361"></a>00361         <span class="keywordflow">case</span> FT_Err_Raster_Corrupted :          <span class="keywordflow">return</span> <span class="stringliteral">"raster corrupted"</span>;
<a name="l00362"></a>00362         <span class="keywordflow">case</span> FT_Err_Raster_Overflow :           <span class="keywordflow">return</span> <span class="stringliteral">"raster overflow"</span>;
<a name="l00363"></a>00363         <span class="keywordflow">case</span> FT_Err_Raster_Negative_Height :    <span class="keywordflow">return</span> <span class="stringliteral">"negative height while rastering"</span>;
<a name="l00364"></a>00364 
<a name="l00365"></a>00365         <span class="comment">// Cache errors</span>
<a name="l00366"></a>00366         <span class="keywordflow">case</span> FT_Err_Too_Many_Caches :           <span class="keywordflow">return</span> <span class="stringliteral">"too many registered caches"</span>;
<a name="l00367"></a>00367 
<a name="l00368"></a>00368         <span class="comment">// TrueType and SFNT errors</span>
<a name="l00369"></a>00369         <span class="keywordflow">case</span> FT_Err_Invalid_Opcode :            <span class="keywordflow">return</span> <span class="stringliteral">"invalid opcode"</span>;
<a name="l00370"></a>00370         <span class="keywordflow">case</span> FT_Err_Too_Few_Arguments :         <span class="keywordflow">return</span> <span class="stringliteral">"too few arguments"</span>;
<a name="l00371"></a>00371         <span class="keywordflow">case</span> FT_Err_Stack_Overflow :            <span class="keywordflow">return</span> <span class="stringliteral">"stack overflow"</span>;
<a name="l00372"></a>00372         <span class="keywordflow">case</span> FT_Err_Code_Overflow :             <span class="keywordflow">return</span> <span class="stringliteral">"code overflow"</span>;
<a name="l00373"></a>00373         <span class="keywordflow">case</span> FT_Err_Bad_Argument :              <span class="keywordflow">return</span> <span class="stringliteral">"bad argument"</span>;
<a name="l00374"></a>00374         <span class="keywordflow">case</span> FT_Err_Divide_By_Zero :            <span class="keywordflow">return</span> <span class="stringliteral">"division by zero"</span>;
<a name="l00375"></a>00375         <span class="keywordflow">case</span> FT_Err_Invalid_Reference :         <span class="keywordflow">return</span> <span class="stringliteral">"invalid reference"</span>;
<a name="l00376"></a>00376         <span class="keywordflow">case</span> FT_Err_Debug_OpCode :              <span class="keywordflow">return</span> <span class="stringliteral">"found debug opcode"</span>;
<a name="l00377"></a>00377         <span class="keywordflow">case</span> FT_Err_ENDF_In_Exec_Stream :       <span class="keywordflow">return</span> <span class="stringliteral">"found ENDF opcode in execution stream"</span>;
<a name="l00378"></a>00378         <span class="keywordflow">case</span> FT_Err_Nested_DEFS :               <span class="keywordflow">return</span> <span class="stringliteral">"nested DEFS"</span>;
<a name="l00379"></a>00379         <span class="keywordflow">case</span> FT_Err_Invalid_CodeRange :         <span class="keywordflow">return</span> <span class="stringliteral">"invalid code range"</span>;
<a name="l00380"></a>00380         <span class="keywordflow">case</span> FT_Err_Execution_Too_Long :        <span class="keywordflow">return</span> <span class="stringliteral">"execution context too long"</span>;
<a name="l00381"></a>00381         <span class="keywordflow">case</span> FT_Err_Too_Many_Function_Defs :    <span class="keywordflow">return</span> <span class="stringliteral">"too many function definitions"</span>;
<a name="l00382"></a>00382         <span class="keywordflow">case</span> FT_Err_Too_Many_Instruction_Defs : <span class="keywordflow">return</span> <span class="stringliteral">"too many instruction definitions"</span>;
<a name="l00383"></a>00383         <span class="keywordflow">case</span> FT_Err_Table_Missing :             <span class="keywordflow">return</span> <span class="stringliteral">"SFNT font table missing"</span>;
<a name="l00384"></a>00384         <span class="keywordflow">case</span> FT_Err_Horiz_Header_Missing :      <span class="keywordflow">return</span> <span class="stringliteral">"horizontal header (hhea) table missing"</span>;
<a name="l00385"></a>00385         <span class="keywordflow">case</span> FT_Err_Locations_Missing :         <span class="keywordflow">return</span> <span class="stringliteral">"locations (loca) table missing"</span>;
<a name="l00386"></a>00386         <span class="keywordflow">case</span> FT_Err_Name_Table_Missing :        <span class="keywordflow">return</span> <span class="stringliteral">"name table missing"</span>;
<a name="l00387"></a>00387         <span class="keywordflow">case</span> FT_Err_CMap_Table_Missing :        <span class="keywordflow">return</span> <span class="stringliteral">"character map (cmap) table missing"</span>;
<a name="l00388"></a>00388         <span class="keywordflow">case</span> FT_Err_Hmtx_Table_Missing :        <span class="keywordflow">return</span> <span class="stringliteral">"horizontal metrics (hmtx) table missing"</span>;
<a name="l00389"></a>00389         <span class="keywordflow">case</span> FT_Err_Post_Table_Missing :        <span class="keywordflow">return</span> <span class="stringliteral">"PostScript (post) table missing"</span>;
<a name="l00390"></a>00390         <span class="keywordflow">case</span> FT_Err_Invalid_Horiz_Metrics :     <span class="keywordflow">return</span> <span class="stringliteral">"invalid horizontal metrics"</span>;
<a name="l00391"></a>00391         <span class="keywordflow">case</span> FT_Err_Invalid_CharMap_Format :    <span class="keywordflow">return</span> <span class="stringliteral">"invalid character map (cmap) format"</span>;
<a name="l00392"></a>00392         <span class="keywordflow">case</span> FT_Err_Invalid_PPem :              <span class="keywordflow">return</span> <span class="stringliteral">"invalid ppem value"</span>;
<a name="l00393"></a>00393         <span class="keywordflow">case</span> FT_Err_Invalid_Vert_Metrics :      <span class="keywordflow">return</span> <span class="stringliteral">"invalid vertical metrics"</span>;
<a name="l00394"></a>00394         <span class="keywordflow">case</span> FT_Err_Could_Not_Find_Context :    <span class="keywordflow">return</span> <span class="stringliteral">"could not find context"</span>;
<a name="l00395"></a>00395         <span class="keywordflow">case</span> FT_Err_Invalid_Post_Table_Format : <span class="keywordflow">return</span> <span class="stringliteral">"invalid PostScript (post) table format"</span>;
<a name="l00396"></a>00396         <span class="keywordflow">case</span> FT_Err_Invalid_Post_Table :        <span class="keywordflow">return</span> <span class="stringliteral">"invalid PostScript (post) table"</span>;
<a name="l00397"></a>00397 
<a name="l00398"></a>00398         <span class="comment">// CCF, CID and Type 1 errors</span>
<a name="l00399"></a>00399         <span class="keywordflow">case</span> FT_Err_Syntax_Error :              <span class="keywordflow">return</span> <span class="stringliteral">"opcode syntax error"</span>;
<a name="l00400"></a>00400         <span class="keywordflow">case</span> FT_Err_Stack_Underflow :           <span class="keywordflow">return</span> <span class="stringliteral">"argument stack underflow"</span>;
<a name="l00401"></a>00401         <span class="keywordflow">case</span> FT_Err_Ignore :                    <span class="keywordflow">return</span> <span class="stringliteral">"ignore"</span>;
<a name="l00402"></a>00402 
<a name="l00403"></a>00403         <span class="comment">// BDF errors</span>
<a name="l00404"></a>00404         <span class="keywordflow">case</span> FT_Err_Missing_Startfont_Field :   <span class="keywordflow">return</span> <span class="stringliteral">"`STARTFONT' field missing"</span>;
<a name="l00405"></a>00405         <span class="keywordflow">case</span> FT_Err_Missing_Font_Field :        <span class="keywordflow">return</span> <span class="stringliteral">"`FONT' field missing"</span>;
<a name="l00406"></a>00406         <span class="keywordflow">case</span> FT_Err_Missing_Size_Field :        <span class="keywordflow">return</span> <span class="stringliteral">"`SIZE' field missing"</span>;
<a name="l00407"></a>00407         <span class="keywordflow">case</span> FT_Err_Missing_Chars_Field :       <span class="keywordflow">return</span> <span class="stringliteral">"`CHARS' field missing"</span>;
<a name="l00408"></a>00408         <span class="keywordflow">case</span> FT_Err_Missing_Startchar_Field :   <span class="keywordflow">return</span> <span class="stringliteral">"`STARTCHAR' field missing"</span>;
<a name="l00409"></a>00409         <span class="keywordflow">case</span> FT_Err_Missing_Encoding_Field :    <span class="keywordflow">return</span> <span class="stringliteral">"`ENCODING' field missing"</span>;
<a name="l00410"></a>00410         <span class="keywordflow">case</span> FT_Err_Missing_Bbx_Field :         <span class="keywordflow">return</span> <span class="stringliteral">"`BBX' field missing"</span>;
<a name="l00411"></a>00411     }
<a name="l00412"></a>00412 
<a name="l00413"></a>00413     <span class="keywordflow">return</span> <span class="stringliteral">"unknown error"</span>;
<a name="l00414"></a>00414 }
<a name="l00415"></a>00415 
<a name="l00416"></a>00416 } <span class="comment">// namespace priv</span>
<a name="l00417"></a>00417 
<a name="l00418"></a>00418 } <span class="comment">// namespace sf</span>
<a name="l00419"></a>00419 
</pre></div></div>

        <p id="footer">
            &nbsp;::&nbsp; Copyright &copy; 2007-2008 Laurent Gomila, all rights reserved &nbsp;::&nbsp;
            Documentation generated by <a href="http://www.doxygen.org/" title="doxygen website">doxygen 1.5.2</a> &nbsp;::&nbsp;
        </p>

    </body>
</html>