:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / docs / design / io-frames.html
1 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
2 <html>
3 <head>
4   <meta http-equiv="Content-Type"
5         content="text/html; charset=iso-8859-1">
6   <meta name="Author"
7         content="David Turner">
8   <title>FreeType 2 Internals - I/O Frames</title>
9 </head>
10
11 <body text="#000000"
12       bgcolor="#FFFFFF"
13       link="#0000EF"
14       vlink="#51188E"
15       alink="#FF0000">
16
17 <h1 align=center>
18   FreeType 2.0 I/O Frames
19 </h1>
20
21 <h3 align=center>
22   &copy; 2000 David Turner
23     (<a href="mailto:david@freetype.org">david@freetype.org</a>)<br>
24   &copy; 2000 The FreeType Development Team
25     (<a href="http://www.freetype.org">www.freetype.org</a>)
26 </h3>
27
28 <center>
29 <table width="70%">
30 <tr><td>
31
32   <hr>
33
34   <h2>
35     Introduction
36   </h2>
37
38   <p>This document explains the concept of I/O <b>frames</b> as used in the
39   FreeType&nbsp;2 source code.  It also enumerates the various functions and
40   macros that can be used to read them.</p>
41
42   <p>It is targeted to FreeType hackers, or more simply to developers who
43   would like a better understanding of the library's source code.</p>
44
45   <hr>
46
47   <h2>
48     I. What frames are
49   </h2>
50
51   <p>Simply speaking, a frame is an array of bytes in a font file that is
52   `preloaded' into memory in order to be rapidly parsed.  Frames are useful
53   to ensure that every `load' is checked against end-of-file overruns, and
54   provides nice functions to extract data in a variety of distinct
55   formats.</p>
56
57   <p>But an example is certainly more meaningful than anything else.  The
58   following code</p>
59
60   <font color="blue">
61   <pre>
62     error = read_short( stream, &str.value1 );
63     if ( error ) goto ...
64
65     error = read_ulong( stream, &str.value2 );
66     if ( error ) goto ...
67
68     error = read_ulong( stream, &str.value3 );
69     if ( error ) goto ...</pre>
70   </font>
71
72   <p>can easily be replaced with</p>
73
74   <font color="blue">
75   <pre>
76     error = FT_Access_Frame( stream, 2 + 4 + 4 );
77     if ( error ) goto ...
78
79     str.value1 = FT_Get_Short( stream );
80     str.value2 = FT_Get_ULong( stream );
81     str.value3 = FT_Get_ULong( stream );
82
83     FT_Forget_Frame( stream );</pre>
84   </font>
85
86   <p>Here, the call to <code>FT_Access_Frame()</code> will</p>
87
88   <ul>
89     <li>
90       <p>Ensure that there are at least 2+4+4=10 bytes left in the
91       stream.</p>
92     </li>
93     <li>
94       <p>`Preload' (for disk-based streams) 10&nbsp;bytes from the current
95       stream position.</p>
96     </li>
97     <li>
98       <p>Set the frame `cursor' to the first byte in the frame.</p>
99     </li>
100   </ul>
101
102   <p>Each <code>FT_Get_Short()</code> or <code>FT_Get_ULong()</code> call
103   will read a big-endian integer from the stream (2&nbsp;bytes for
104   <code>FT_Get_Short()</code>, 4&nbsp;bytes for <code>FT_Get_ULong</code>)
105   and advance the frame cursor accordingly.</p>
106
107   <p><code>FT_Forget_Frame()</code> `releases' the frame from memory.</p>
108
109   <p>There are several advantages to using frames:</p>
110
111   <ul>
112     <li>
113       <p>Single-check when loading tables.</p>
114     </li>
115     <li>
116       <p><em>Making code clearer</em> by providing simple parsing functions
117       <em>while keeping code safe</em> from file over-runs and invalid
118       offsets.</p>
119     </li>
120   </ul>
121
122   <hr>
123
124   <h2>
125     II. Accessing and reading a frame with macros
126   </h2>
127
128   <p>By convention in the FreeType source code, macros are able to use two
129   implicit variables named <var>error</var> and <var>stream</var>.  This is
130   useful because these two variables are extremely often used in the
131   library, and doing this only reduces our typing requirements and make the
132   source code much clearer.</p>
133
134   <p>Note that <var>error</var> must be a local variable of type
135   <code>FT_Error</code>, while <var>stream</var> must be a local variable or
136   argument of type <code>FT_Stream</code>.</p>
137
138   <p>The macro used to access a frame is <font
139   color="purple"><code><b>ACCESS_Frame(_size_)</b></code></font>, it will
140   translate to</p>
141
142   <font color="blue">
143   <pre>
144     ( error = FT_Access_Frame( stream, _size_ ) )
145         != FT_Err_Ok</pre>
146   </font>
147
148   <p>Similarly, the macro <font
149   color="purple"><b><code>FORGET_Frame()</code></b></font> translates to</p>
150
151   <font color="blue">
152   <pre>
153     FT_Forget_Frame( stream )</pre>
154   </font>
155
156   <p>Extracting integers can be performed with the <code>GET_xxx()</code>
157   macros, like</p>
158
159   <table align=center
160          cellpadding=5>
161     <tr valign="top">
162       <th>
163         Macro name
164       </th>
165       <th>
166         Translation
167       </th>
168       <th>
169         Description
170       </th>
171     </tr>
172     <tr valign="top">
173       <td>
174         <font color="purple"><code><b>GET_Byte()</b></code></font>
175       </td>
176       <td>
177         <font color="blue"><code>FT_Get_Byte(stream)</code></font>
178       </td>
179       <td>
180         <p>Reads an 8-bit unsigned byte.</p>
181       </td>
182     </tr>
183     <tr valign="top">
184       <td>
185         <font color="purple"><code><b>GET_Char()</b></code></font>
186       </td>
187       <td>
188         <font color="blue"><code>(FT_Char)<br>
189         FT_Get_Byte(stream)</code></font>
190       </td>
191       <td>
192         <p>Reads an 8-bit <em>signed</em> byte.</p>
193       </td>
194     </tr>
195     <tr valign="top">
196       <td>
197         <font color="purple"><code><b>GET_Short()</b></code></font>
198       </td>
199       <td>
200         <font color="blue"><code>FT_Get_Short(stream)</code></font>
201       </td>
202       <td>
203         Reads a 16-bit signed big-endian integer.
204       </td>
205     </tr>
206     <tr valign="top">
207       <td>
208         <font color="purple"><code><b>GET_UShort()</b></code></font>
209       </td>
210       <td>
211         <font color="blue"><code>(FT_UShort)<br>
212         FT_Get_Short(stream)</code></font>
213       </td>
214       <td>
215         Reads a 16-bit unsigned big-endian integer.
216       </td>
217     </tr>
218     <tr valign="top">
219       <td>
220         <font color="purple"><code><b>GET_Offset()</b></code></font>
221       </td>
222       <td>
223         <font color="blue"><code>FT_Get_Offset(stream)</code></font>
224       </td>
225       <td>
226         Reads a 24-bit signed big-endian integer.
227       </td>
228     </tr>
229     <tr valign="top">
230       <td>
231         <font color="purple"><code><b>GET_UOffset()</b></code></font>
232       </td>
233       <td>
234         <font color="blue"><code>(FT_UOffset)<br>
235         FT_Get_Offset(stream)</code></font>
236       </td>
237       <td>
238         Reads a 24-bit unsigned big-endian integer.
239       </td>
240     </tr>
241     <tr valign="top">
242       <td>
243         <font color="purple"><code><b>GET_Long()</b></code></font>
244       </td>
245       <td>
246         <font color="blue"><code>FT_Get_Long(stream)</code></font>
247       </td>
248       <td>
249         Reads a 32-bit signed big-endian integer.
250       </td>
251     </tr>
252     <tr valign="top">
253       <td>
254         <font color="purple"><code><b>GET_ULong()</b></code></font>
255       </td>
256       <td>
257         <font color="blue"><code>(FT_ULong)<br>
258         FT_Get_Long(stream)</code></font>
259       </td>
260       <td>
261         Reads a 32-bit unsigned big-endian integer.
262       </td>
263     </tr>
264   </table>
265
266   <p>(Note that an <b>Offset</b> is an integer stored with 3&nbsp;bytes on
267   the file.)</p>
268
269   <p>All this means that the following code</p>
270
271   <font color="blue">
272   <pre>
273     error = FT_Access_Frame( stream, 2 + 4 + 4 );
274     if ( error ) goto ...
275
276     str.value1 = FT_Get_Short( stream );
277     str.value2 = FT_Get_ULong( stream );
278     str.value3 = FT_Get_ULong( stream );
279
280     FT_Forget_Frame( stream );</pre>
281     </font>
282
283     <p>can be simplified with macros:</p>
284
285     <font color="blue">
286     <pre>
287     if ( ACCESS_Frame( 2 +4 + 4 ) ) goto ...
288
289     str.value1 = GET_Short();
290     str.value2 = GET_ULong();
291     str.value3 = GET_ULong();
292
293     FORGET_Frame();</pre>
294     </font>
295
296     <p>Which is clearer.  Notice that <var>error</var> and <var>stream</var>
297     must be defined locally though for this code to work!</p>
298
299     <hr>
300
301   <h2>
302     III. Alternatives
303   </h2>
304
305   <p>It is sometimes useful to read small integers from a font file without
306   using a frame.  Some functions have been introduced in FreeType&nbsp;2 to
307   do just that, and they are of the form <font
308   color="blue"><code>FT_Read_xxxx</code></font>.</p>
309
310   <p>For example, <font color="blue"><code>FT_Read_Short(stream,
311   &error)</code></font> reads and returns a 2-byte big-endian integer from a
312   <var>stream</var>, and places an error code in the <var>error</var>
313   variable.</p>
314
315   <p>Thus, reading a single big-endian integer is shorter than using a frame
316   for it.</p>
317
318   <p>Note that there are also macros <font
319   color="purple"><code>READ_xxx()</code></font> which translate to</p>
320
321   <font color="blue">
322   <pre>
323     FT_Read_xxx( stream, &error ), error != FT_Err_Ok</pre>
324   </font>
325
326   <p>and can be used as in</p>
327
328   <font color="blue">
329   <pre>
330     if ( READ_UShort( variable1 ) ||
331          READ_ULong ( variable2 ) )
332       goto Fail;</pre>
333   </font>
334
335   <p>if <var>error</var> and <var>stream</var> are already defined
336   locally.</p>
337
338 </td></tr>
339 </table>
340 </center>
341
342 </body>
343 </html>